← На главную

Разогнали Qwen 3.5 на M3 Ultra в 137 раз через правку трёх багов в qMLX

11.07.2026 22:54 · hackernews

Ждать три-пять минут первого токена на 50-тысячном диалоге — это не чат-бот, а batch job. Именно с таким кошмаром столкнулся автор, когда попытался гонять большую модель локально на Mac Studio. Он купил M3 Ultra с 96GB RAM, чтобы запускать frontier-модель на одном устройстве. Изначально использовал DS4 Flash от antirez — блестящий эксперимент, но для длинных контекстов он не подошёл. После 50к токенов простой follow-up превращался в паузу на чай, а pair programming так не работает.

Автор переключился на Qwen 3.5 122B. Это MoE с ~10B активных параметров — идеально под bandwidth M3 Ultra. Модель помещается в 96GB unified memory с запасом под SSD-backed KV cache (ключ к длинному контексту без свопов). Для неё пришлось форкнуть rapid-mlx в qMLX (доступен на GitHub), заточенный под hybrid attention.

Но модель работала из рук вон плохо. Из-за гибридной архитектуры (GatedDeltaNet + dense attention) in-memory cache был мёртв: zero hits против 109 disk. А disk-кеш ломался тремя багами, прятавшимися друг за другом.

Первый: агентский фреймворк вставлял в system prompt уникальный message ID на каждый turn. KV reuse работает byte-exact, поэтому промпт никогда не совпадал, и кеш сбрасывался. Фикс — удалить строчку. Никто её не читал, ID и так передавался в user message.

Второй: если отправить сообщение, пока модель ещё отвечает, агент прерывал генерацию без сохранения уже настримленных токенов. В истории появлялись четыре user-сообщения без assistant-ответа между ними. Фикс — сохранять ответ на interrupt path.

Третий: в чекпоинт-сторе завелся фоновый писака, который каждые 256 токенов кидал неключируемый чекпоинт. Он занимал место и при превышении лимита eviction выкидывал полезные чекпоинты вместе с мусором. На диске лежало 27 ГБ невосстанавливаемых данных. Фикс — сначала удалять unmatchable чекпоинты и отключать мусорщика.

После фиксов prefill упал с минут до долей секунды. На 32к токенах ускорение в 137 раз: с 88 секунд до 0.64. Метрики честные: prefill и decode измеряются раздельно, без «средней температуры по больнице». Decode (то, что чувствует пользователь) — 28-55 токенов/с на контексте до 64к. Prefill с кешем практически бесплатный.

Всё это работает на конкретном железе: Mac Studio M3 Ultra, 28-core CPU, 60-core GPU, 96GB RAM, macOS 26.4. Есть одна шероховатость — слишком консервативный guard памяти, который отказывается восстанавливать кеш, хотя память есть. Автор отключил его по умолчанию.

Графики нарисованы собственной библиотекой charted.

Читать оригинал →