Бывает так: сидишь, листаешь ленту, и в очередной раз натыкаешься на пост, где стафф-инженер из солнечной Калифорнии крутит свежую модельку на паре RTX PRO 6000 общей стоимостью с подержанную машину. Ты смотришь на свою RTX 4060 в ноутбуке, который покупал «не только для игр», и понимаешь: ну ладно, это не для нас.
Так вот, это как раз для нас. На той самой ноутбучной 4060 с восемью гигабайтами и урезанным вдвое PCIe-линком все-таки можно получить 39.3 tok/s на 35-миллиардной модели — между прочим быстрее, чем медианная скорость декода Codex в проде. Вопрос внезапно до сих пор был не в железе, а в софте, который это железо обслуживает.
Для того чтобы понять, как добиться таких результатов разберем FreeToken — движок для локального инференса MoE-моделей от команды, которая до этого сделала vLLM и SGLang.
Зачем вообще ещё один движок
Короткий ответ: потому что существующие недобирают от машины кратно, и особенно сильно — там, где локальные модели сейчас реально нужны, то есть в агентных сценариях.
Длинный ответ занимает остаток статьи, но давайте сразу обозначим, что именно измерили авторы. Не одиночный промпт, как принято в бенчмарках локальных движков, а реальные многотуровые сессии: SWE-задача через OpenCode, та же задача через Claude Code по нативному протоколу с параллельными сабагентами и контекстом до 56–65 тысяч токенов, и почтово-календарный агент через OpenClaw на тринадцать ходов.
Дальше по тексту постоянно будет мелькать TTFT — time to first token, время до первого токена. Это задержка между отправкой запроса и появлением первого символа ответа, то есть по сути стоимость префилла: пока модель не прожевала весь входной контекст, генерировать ей нечего.
В чате на пару абзацев это доли секунды, и на неё никто не смотрит — все меряются скоростью генерации. В агенте всё иначе. Контекст там — это системный промпт, история диалога, содержимое прочитанных файлов и выводы всех предыдущих вызовов инструментов, и он растёт с каждым ходом. А префилл случается заново на каждом вызове инструмента, а не один раз за сессию. Поэтому TTFT в агентных сценариях — это не «задержка перед ответом», а то, сколько вы ждёте между каждыми двумя шагами работы агента. Десять вызовов инструментов подряд — десять префиллов на растущем контексте.
И вот на этих сценариях вылезает цифра, которую однопромптовые бенчмарки не показывают в принципе:
Худший TTFT за сессию: 44 секунды у FreeToken против 232 у llama.cpp и 946 у KTransformers.
Здесь надо остановиться. У OpenClaw в стоке стоит idle-watchdog на 120 секунд. У Claude Code дефолтный таймаут запроса — примерно десять минут. То есть 946 секунд — это не «медленно». Это «агент упал». Средний tok/s при этом может выглядеть вполне пристойно, и вы будете сидеть и думать, почему у вас всё отваливается.
Хвост TTFT здесь — не метрика латентности, а граница работоспособности. Это, пожалуй, главный практический вывод всей работы.
Почему MoE вообще даёт шанс локальному железу
Если вы впервые слышите аббревиатуру — совсем коротко. В обычной, плотной (dense) модели каждый параметр участвует в обработке каждого токена: чтобы выдать один токен, модель на 30B честно вычитывает из памяти все тридцать миллиардов весов. В Mixture of Experts feed-forward слои разбиты на множество «экспертов», и роутер на каждом токене выбирает небольшое подмножество. У модели вида 30B-A3B тридцать миллиардов параметров всего, но активных — три.
Отсюда главное правило: память масштабируется с общим числом параметров, а скорость генерации — с активным. Держать наготове надо всех экспертов, потому что маршрутизация меняется на каждом токене. А читать на каждом шаге приходится только активных.
Если хочется базы поплотнее — про dense против MoE, квантизации, GGUF и про то, почему локальный инференс вообще упирается в пропускную способность памяти, я подробно писал в «Всё, что вы хотели знать о локальном ИИ, но стеснялись спросить». Разнице архитектур там посвящена отдельная часть. Дальше буду считать, что база есть.
Теперь приложим это к фронтир-масштабу. DeepSeek-V4-Flash: 6 маршрутизируемых экспертов из 256 в каждом из 43 слоёв. То есть в обработке одного токена участвует 13B параметров из 284B, и в деплойной точности этот активный след спокойно укладывается в 32 ГБ RTX 5090.
Но. Разреженность режет вычисления на токен, а не память под полный пул экспертов. Модель целиком по-прежнему не влезает в VRAM с большим запасом, неактивные эксперты живут в памяти хоста и заходят в путь исполнения по требованию.
Отсюда формулировка, вокруг которой строится вся работа: разреженная активация делает вычисление возможным, а полный пул экспертов делает эффективную отдачу сложной. Вопрос сместился с «влезет ли модель в GPU» на «насколько хорошо система умеет оркестрировать машину целиком» — GPU, CPU, память хоста и шину между ними.
Масштаб, к слову, приличный: дискретные GPU стоят более чем в сотне миллионов пользовательских машин. По Steam Hardware Survey за июнь 2026 карты NVIDIA — примерно в 72% опрошенных систем, а самая массовая модель — как раз RTX 4060 Laptop с долей 3.81%. Железо у людей есть. Не хватает софта, который умеет собрать из него единую платформу инференса.
Где ломаются существующие движки
Авторы FreeToken раскладывают проблему на три части, так что разбор получился неожиданно поучительным сам по себе — даже если вы никогда не запустите FreeToken.
Проблема 1: на префилле разреженность исчезает
Это тот момент, который лично я осознал не сразу.
При декоде токен идёт через несколько экспертов — красиво, экономно. При префилле токенов тысячи, и объединение их маршрутов покрывает практически весь набор экспертов в каждом слое. Рабочее множество становится фактически плотным. Вся экономия испаряется.
Что это значит в байтах: FP4-деплой DeepSeek-V4-Flash требует прогнать через межсоединение около 140 ГБ весов экспертов. Считаем:
-
RTX 5090, PCIe 5.0 x16, ~60 ГБ/с → около 2 секунд
-
RTX 4090 / 3090, PCIe 4.0 x16, ~25 ГБ/с → около 5 секунд
-
ноутбучные x8-линки → десять и больше секунд
И движок, который тянет экспертов по требованию, выставляет всё это окно наружу как чистый простой GPU. На каждый префилл. В агентном сценарии — на каждый ход диалога.
Проблема 2: агентные харнессы постоянно инвалидируют контекст
Второй источник боли — повторные вычисления, и он специфичен именно для агентов.
Современные модели уходят в гибридное внимание: чередование полного внимания со скользящим окном (DeepSeek-V4-Flash, GPT-OSS) или рекуррентные слои (gated DeltaNet в Qwen3.6-35B-A3B, Kimi Delta Attention в Kimi-K3). Рекуррентный слой сжимает весь префикс в одно эволюционирующее состояние, которое нельзя переиспользовать частично — только целиком с чекпоинта. А каждый чекпоинт весит как KV-кэш сотен токенов, поэтому их физически можно держать единицы.
Теперь смотрим, что делают агентные фреймворки с контекстом:
-
OpenClaw вырезает thinking-блоки из всех ходов ассистента, кроме последнего
-
OpenCode заменяет tool-выходы старше защищённого окна фиксированной заглушкой
-
SWE-agent выкидывает все наблюдения, кроме последних n
Любой чекпоинт после точки правки становится невалидным. Движок откатывается к последнему живому — и переигрывает тысячи токенов. Заново.
Спрятать это некуда: RTX 5090 даёт примерно пятую часть плотной BF16-производительности H100 и десятую от B200. Каждый лишний ре-префилл длинного контекста занимает GPU на десятки секунд. Вот вам и 946 секунд в хвосте.
Проблема 3: статическое размещение экспертов мимо трафика
llama.cpp назначает MoE-тензоры устройствам при загрузке модели. KTransformers закрепляет «горячее» подмножество экспертов в VRAM, а остальное гонит на CPU. Оба варианта фиксируют решение до того, как узнают, куда реально пойдёт маршрутизация.
А маршрутизация меняется с каждым токеном. Размещение, выбранное на этапе префилла, ловит малую долю фактического трафика. Их замер на одинаковых трассах маршрутизации, при ёмкости кэша, доступной на RTX 5090 (37% пула экспертов Qwen3.6 и 11% пула DSV4-Flash):
|
Политика |
Промахи, Qwen3.6 |
Промахи, DSV4-Flash |
|---|---|---|
|
FreeToken, глобальный LRU |
16% |
39% |
|
KTransformers, размещение по префиллу |
41% |
59% |
|
llama.cpp, статический сплит |
62% |
89% |
При этом переложить всё на CPU нельзя чисто физически. Потребительская платформа даёт два канала DRAM: примерно 50 ГБ/с на двухканальном DDR4 и 80–90 на DDR5. Против 1–1.8 ТБ/с, которые RTX 4090 или 5090 тянет из своей памяти. Сколько ядер ни дай, CPU-only путь упирается в память.
Проблема 4: на локальной машине ничего не выделено эксклюзивно
Сюжет, которого в датацентре просто нет. VRAM делится с композитором рабочего стола, браузером, играми, дискордом. Бюджет меняется между запусками и прямо посреди сессии.
И оптимальный сплит бюджета тоже плывёт: агентная сессия накапливает контекст, спрос на KV-кэш растёт, а рабочее множество экспертов остаётся примерно тем же. Сплит, выбранный на первом ходу, к двадцатому уже неверен.
Плюс старт. Прочитать 140 ГБ пула экспертов с NVMe на 7 ГБ/с — около 20 секунд, и это до всякого прогрева. А на локальной машине движок запускают и гасят постоянно: поработал, закрыл, освободил железо под игру.
Проиллюстрирую на себе. У меня RTX 5080 на 16 ГБ — по крайней мере так написано на коробке.
Открываю nvidia-smi на свежезагруженной Windows. Ничего не запущено, только рабочий стол. 1.2 ГБ уже занято. Это монитор, воткнутый в карту по DisplayPort: фреймбуфер, композитор рабочего стола, DWM. Плата просто за то, что на экране что-то отображается. Дальше открывается браузер с аппаратным ускорением, и цифра уползает ещё выше.
Ради интереса я переткнул монитор в интегрированную графику, оставив 5080 чисто под вычисления. Те самые 1.2 ГБ вернулись. На шестнадцатигиговой карте это 7.5% всего бюджета — не революция, но ровно на той границе, где модель либо влезает, либо не влезает, эти проценты решают всё.
И вот здесь главная боль, которая не про сами гигабайты, а про их непостоянство. Запуская llama.cpp с фиксированным -ngl, я фактически загадываю, сколько памяти будет свободно в ближайшие пару часов. Загадал щедро — движок отваливается по OOM где-то на середине агентной сессии, причём обычно ровно тогда, когда контекст дорос и KV-кэш попросил добавки. Загадал скромно — сижу с недогруженной картой и добровольно отдаю производительность. Правильного ответа не существует, потому что правильный ответ меняется в течение сессии.
Ровно эту проблему FreeToken решает архитектурно — к этому вернёмся в разделе про эластичную память.
Что делает FreeToken
Базовая конструкция — двухуровневая иерархия памяти экспертов.
Полный пул экспертов лежит в памяти хоста и остаётся источником истины. Не-экспертные веса постоянно на GPU. Вся оставшаяся память GPU превращается в один эластичный кэш экспертов, общий для всех MoE-слоёв: слот держит всё необходимое для вычисления пары (слой, эксперт), и резидентность, поиск и исполнение работают с логическими идентификаторами, а не со шардами тензоров.
Важное следствие: раз пул на хосте — источник истины, память GPU влияет только на производительность и никогда на корректность. Из этого свойства растёт вся эластичность, о которой ниже.
Префилл: полнослойная двойная буферизация
Раз префилл активирует почти всех экспертов слоя (см. проблему 1), тянуть их по требованию бессмысленно. Берутся два полнослойных буфера из общего пула слотов: пока GPU считает слой l из одного буфера, отдельный поток передачи заливает полный набор экспертов слоя l+1 в другой. Потом буферы меняются ролями.
Ключевой трюк — грузится весь слой целиком, поэтому передачу можно начать до того, как маршрутизация этого слоя вообще известна. Движение весов идёт непрерывно в фоне, а не последовательно между слоями.
Результат: префилл становится transfer-bound, то есть упирается в шину, а не в вычисления. Чанк на 8192 токена укладывается в 1.19–1.22 с — ровно время однократной прокачки 64.4 ГБ пула на 52.7 ГБ/с, практический потолок PCIe 5.0 x16. Пропускная растёт до 6.7k tok/s на 16k токенов.
Если отключить второй буфер, теряется 19% на 4k токенов, 25% на 8k и 26% на 16k. Штраф растёт вместе с длиной промпта — логично, чем длиннее промпт, тем большую долю занимают спрятанные вычисления.
Семантические якоря
Самая изящная идея во всей работе, и при этом самая простая.
Чекпоинты рекуррентного состояния ставятся не каждые N токенов, а на границах спецтокенов: открытие и закрытие thinking-блока, вызов инструмента, его вывод, граница хода диалога.
Логика прямая. Харнессы правят контекст не произвольно, а целыми блоками, размеченными спецтокенами, и точный префикс до правленого блока при этом сохраняется. Значит, чекпоинт, поставленный на такой границе, переживёт усечение с несопоставимо большей вероятностью, чем поставленный в случайном месте.
При правке слои с полным вниманием переиспользуют KV-кэш до точки правки, рекуррентные — восстанавливаются с якоря, и переигрывается только реально новый суффикс. Слоты чекпоинтов вытесняются по LRU, независимо от KV-пула.
Отдельно любопытно, что это протекающая абстракция в чистом виде. Движок инференса теперь должен знать про формат агентного диалога конкретного харнесса. Раньше он видел плоский поток токенов и знать не знал, что там за <think>. Хорошо это или плохо — вопрос открытый, но тенденция показательная: слои стека начинают договариваться напрямую.
Декод: формула q*
Вот это ядро работы, здесь стоит замедлиться.
При декоде роутер и просмотр кэша идут на GPU, попавшие эксперты считаются сразу же. Вопрос — что делать с m промахнувшимися. Путей ровно два:
-
Перекинуть эксперта по PCIe и посчитать на GPU (заодно он останется в кэше на будущее)
-
Посчитать на CPU прямо там, где веса уже лежат
Существующие системы выбирают что-то одно и придерживаются выбора. KTransformers держит маршрутизируемых экспертов на CPU даже когда PCIe простаивает и место в кэше есть. llama.cpp делит статически при загрузке. Отдельная большая линия работ (Mixtral-offloading, MoE-Infinity, ProMoE, ExpertFlow, FineMoE) точит предсказание промахов — но не то, как промахи обслуживаются. А там потолок: любой промах в итоге превращается в передачу по PCIe, и латентность декода упирается в линк, каким бы точным ни стал предиктор. Хостовые вычислительные мощности при этом просто простаивают.
Наблюдение FreeToken: DMA-передача экспертов и их исполнение на CPU читают из одной и той же подсистемы памяти хоста. Значит, это вообще не выбор «или-или». Это задача о дележе полосы.
Пусть B_P — измеренная пропускная передачи эксперта по PCIe, B_H — измеренная эффективная пропускная CPU-ядра MoE. Насыщенная передача по PCIe оставляет остаточную полосу:
B_R = max(B_H − B_P, 0)
Именно она доступна параллельному исполнению на CPU. Балансируем время двух веток:
T_fill(q) ≈ q·S / B_P
T_cpu(m − q) ≈ (m − q)·S / (B_H − B_P)
где S — размер одного полного эксперта в байтах. Приравниваем и получаем:
q* ≈ m · B_P / B_H
Одна формула покрывает все балансы железа. Когда B_H приближается к B_P, q* стремится к m, и система вырождается в чистую загрузку по требованию — без отдельных веток и специальных политик.
А теперь самое наглядное. Подставим их же измеренные на стенде пропускные и посмотрим, какая доля промахов уезжает по PCIe на разных машинах:
|
Машина |
B_P, ГБ/с |
B_H, ГБ/с |
Доля промахов на PCIe |
|---|---|---|---|
|
RTX 4060 Laptop (PCIe 4.0 x8, LPDDR5) |
11.8 |
47.5 |
25% |
|
RTX 4090 (PCIe 4.0 x16, DDR4) |
25.1 |
63.2 |
40% |
|
RTX 3090 (PCIe 4.0 x16, DDR4) |
25.3 |
56.7 |
45% |
|
RTX PRO 6000 (PCIe 5.0 x16, DDR5 512) |
51.5 |
178 |
29% |
|
RTX 5090 сервер (PCIe 5.0 x16, DDR5) |
52.7 |
77.3 |
68% |
|
RTX 5090 десктоп (PCIe 5.0 x16, DDR5 2ch) |
49.0 |
53.8 |
91% |
Разброс от четверти до девяти десятых. На ноутбучной 4060 три четверти промахов считаются на CPU, потому что узкий x8-линк — главное ограничение. На десктопе с 5090 почти всё уезжает по PCIe, потому что двухканальная DDR5 едва обгоняет шину. Никакая фиксированная политика не может быть права одновременно в обоих случаях — и вот ровно поэтому движки со статическим сплитом проигрывают то 1.3×, то 2.1×.
Практические детали, которые стоит знать: q* округляется до целого, выбор конкретных экспертов для заливки отдаётся политике вытеснения, и минимум одна заливка сохраняется всегда — чтобы кэш продолжал прогреваться даже когда CPU тащит почти всё. Частичные суммы GPU и CPU сливаются точно, никакой алгоритмической аппроксимации: выход MoE побитово тот же, что был бы при полном размещении в VRAM. Модель не модифицируется, роутер не переучивается.
Как это упаковано в CUDA Graph
Раздел для тех, кому интересна реализация. Остальные могут пролистать, но там красиво, либо у меня очень специфические вкусы, потому что в первом университете я был неуклюжим и бился головой об серверные стойки с видеокартами и свитчи.
Проблема в том, что кэширование экспертов по природе динамическое: какие эксперты промахнутся, сколько их будет, какие слоты вытеснить — меняется на каждом шаге. Хостовое управление кэшем означало бы дорогую синхронизацию с устройством на каждом MoE-слое. Именно поэтому llama.cpp в гибридном режиме не удерживает graph execution, а хостовые эвристики конкурентов в граф не захватываются.
FreeToken держит всё зависящее от маршрутизации управление строго на GPU и представляет его как данные внутри статически захваченного графа: буферы фиксированной формы плюс счётчики валидности в памяти устройства.
Одно ядро на MoE-слой делает всё сразу: дедуплицирует маршрутизированных экспертов, классифицирует их против таблицы резидентности, выводит q, выбирает жертв для вытеснения и переписывает логические ID в физические слоты или спецфлаг «этот на CPU».
Отдельно решена классическая ловушка LRU. Наивная реализация требует полного прохода по кэшу на каждый вытесняемый слот. Здесь один проход находит K кандидатов сразу, а путь промаха забирает первые q ≤ K. Стоимость поиска жертв — ровно один проход, независимо от числа промахов.
CPU-ветка захвачена в тот же граф целиком: пиннованные I/O-буферы, персистентные дескрипторы задач, узел submit хостовой функции, параллельный GPU-путь, узел синхронизации, обратное копирование результата. Реплей выполняет весь гетерогенный шаг без пошагового планирования из Python. Воркеры — постоянный C++ пул, привязанный к физическим ядрам, с SIMD и деквантизацией прямо в ядре.
Эластичная память и быстрый старт
Кэш экспертов перестраивается под пересмотренный бюджет VRAM в любой безопасной точке планировщика — без рестарта движка и без перезагрузки пула с хоста. Свернули игру, освободилось три гигабайта — движок их подберёт.
Плюс собственный формат FTW: веса заранее сложены в рантайм-раскладку банков, при старте читаются выровненными кусками через параллельный direct I/O сразу в хостовые банки нужного размера. Память пиннуется после заполнения — пиннить пустые буферы значит зафолтить и обнулить гигабайты страниц, которые тут же будут перезаписаны.
Прогрев не нужен по построению: первый запрос обслуживается холодным кэшем через обычный путь декода, а кэш нагревается сам в процессе нормальной работы.
Цифры
Стенд: шесть машин от ноутбучной RTX 4060 с 8 ГБ до RTX PRO 6000 на 96 ГБ. Модели:
-
Qwen3.6-35B-A3B — BF16 (для точного паритета точности между движками), на 8-гиговом ноутбуке официальный NVFP4-релиз
-
DeepSeek-V4-Flash — 284B при 13B активных, родные MXFP4-блоки экспертов
-
GLM-5.2 — 753B при 40B активных, NVFP4, чекпоинт на 433 ГБ
Все движки едят одни и те же веса побитово. Сценарии — четыре агентных, описанных выше.
Декод на RTX 5090: 77–83 tok/s на Qwen3.6 и 22–25 tok/s на DSV4-Flash. Это 1.8–2.3× и 1.5–1.9× к сильнейшему бейзлайну в каждом сценарии.
Стабильность под агентной нагрузкой — то, ради чего вообще стоит на это смотреть. Скорость FreeToken держится в пределах 12% от однотурового значения на всех трёх агентных сценариях. KTransformers на DSV4-Flash теряет 31% уже на втором. Вывод авторов, который я бы повесил на стену: однопоточные бенчмарки систематически завышают агентную производительность бейзлайнов.
По железу (SWE-задача через OpenCode, Qwen3.6): 1.3× на 3090 и 4090, 1.9× на 5090-сервере, 2.1× на 5090-десктопе, 1.8× на ноутбучной 4060 — где NVFP4-сборка выдаёт те самые 39.3 tok/s на 8 ГБ и PCIe x8. Это 92% от скорости полноценной RTX 4090.
Отдельно красивое сравнение двух колонок с 5090: одинаковый кремний, разный хост. Переход с многоканального сервера на двухканальный десктоп стоит FreeToken 4% скорости декода. llama.cpp на том же переходе сохраняет только 80% — его CPU-резидентные эксперты голодают на двух каналах DDR5.
И фронтир, ради которого заголовок. GLM-5.2 на одной RTX PRO 6000 — 14.9 tok/s против 7.3 у llama.cpp, при побитово одинаковых весах и сравнимом среднем TTFT (7.5 против 7.8 с). У KTransformers пути для этой модели на этой машине нет вообще: его методы требуют 753 ГБ–1.5 ТБ хостовых экспертов против 512 ГиБ доступной памяти, а CPU-ядра не читают NVFP4-раскладку GLM-5.2.
Да, PRO 6000 — это дорогая профессиональная карта. Но обратите внимание, что происходит на ступеньку ниже: 284B DeepSeek-V4-Flash интерактивно на обычном игровом десктопе с 32 ГБ. Это модель, чей пул экспертов в FP4 весит порядка 140 ГБ.
Куда это встаёт в общей картине
Немного суммируем, что эта публикация вообще меняет.
Линия предсказания и кэширования. EdgeMoE задал саму архитектуру (полный пул на хосте, подмножество в кэше GPU), Mixtral-offloading добавил LRU со спекулятивным префетчем, MoE-Infinity трассирует паттерны активации на уровне запросов, ProMoE, ExpertFlow и FineMoE точат предикторы. Потолок линии описан выше: любой промах — всё равно передача.
Линия гибридного CPU-GPU исполнения. Fiddler первым посмотрел на промахнувшегося эксперта как на работу, которую можно выполнить на CPU, а не только как на данные, которые надо переместить. KTransformers сделал это быстрым за счёт AMX-ядер. HybriMoE балансирует очереди симуляцией расписания. Слабое место: деление либо фиксируется на старте, либо считается хостовыми эвристиками, чья стоимость и синхронизация в CUDA Graph не влезают.
Линия размена точности на полосу. HOBBIT тянет пониженную точность промахнувшихся экспертов, SiDA и SMoE подменяют или пропускают низкорейтинговых, Pre-gated MoE вообще переучивает роутер. FreeToken сюда не идёт принципиально.
Собственная формулировка авторов: они меняют не то, насколько хорошо промахи предсказываются, а то, как они обслуживаются. Плюс отдельный вклад — это именно рантайм для многотуровых сессий, а не однозапросный харнесс. Ни одна из перечисленных систем не даёт переиспользования префикса между запросами, а агентная сессия заходит в префилл на каждом вызове инструмента.
Чего в статье нет и что стоит проверить самому
Всегда есть пару но, куда же без этого
Три из шести машин — арендованные двухсокетные серверы, эмулирующие локальное железо ограничением в 6 потоков CPU и привязкой к NUMA-ноде GPU. Авторы это раскрывают и валидируют на двух реальных машинах, но держать в голове стоит.
Сквозное время решения задачи не сравнивается. Траектории агентов между движками расходятся, поэтому меряются decode tok/s и TTFT. Методологически честно, но означает, что «во сколько раз быстрее решается задача» из статьи не следует.
Пиннинг памяти доступен не везде. Если полный пул экспертов не удаётся запиннить или зарегистрировать под DMA — а это ограничение некоторых ОС и конфигураций драйвера — FreeToken откатывается на чисто CPU-шный MoE-бэкенд. Для Windows оговорка более чем актуальная.
Qwen3.6 гоняется в BF16 ради паритета между движками. В реальной жизни все сидят на квантах, и там баланс B_P/B_H неизбежно поедет: эксперт станет меньше, промахов на тот же объём кэша будет меньше, а соотношение полос останется прежним.
Не покрыт средний тир. У них есть 8 ГБ и есть 24–32 ГБ. Карт с 16 ГБ — самой массовой на сегодня конфигурации — в замерах нет вообще.
Тир этот, к слову, легко достроить на бумаге. Возьмём RTX 5080 с 16 ГБ — вдвое больше VRAM, чем у их ноутбука, вдвое меньше, чем у десктопа с 5090, хост потребительский, двухканальная DDR5. По балансу полос она должна сидеть почти вплотную к их колонке «5090 десктоп».
Что говорит арифметика. PCIe 5.0 x16 у 5080 тот же, значит B_P должен лежать в районе 49–50 ГБ/с — как у них на десктопе. Двухканальная DDR5 там же дала B_H = 53.8. Подставляем:
q* ≈ 49 / 53.8 ≈ 0.91
Девять промахов из десяти уезжают по шине, на CPU остаётся символический хвост. Для 16-гиговой карты это означает, что вся ставка — на PCIe, и подходы в духе «держим экспертов на CPU» здесь заведомо в проигрыше: они простаивают линком, который почти догоняет всю оставшуюся полосу памяти хоста.
Встречный фактор — размер кэша экспертов. Это та самая память GPU, которая остаётся после не-экспертных весов и KV-кэша: на 5090 её хватало, чтобы держать 37% пула экспертов Qwen3.6 и 11% пула DSV4-Flash.
И здесь «вдвое меньше» — оценка оптимистичная. Не-экспертные веса и KV-кэш занимают примерно одинаковый абсолютный объём независимо от карты, но вычитаются из вдвое меньшего бюджета. То есть под сам кэш экспертов на 16 ГБ останется меньше половины того, что было на 32. Доля пула в кэше падает сильнее, чем в два раза, промахов m становится заметно больше — на графике зависимости промахов от ёмкости кэша шестнадцать гигабайт попадают сильно левее. А больше промахов при неизменной доле q*/m означает, что вся дополнительная нагрузка ложится на ту же шину. Куда сойдутся эти две силы, из статьи узнать нельзя: такой точки в замерах просто нет.
Что в сухом остатке
Главный вывод — мы всё ещё не до конца эффективно используем железо, и грамотный вклад сообщества и оптимизация позволяют выжимать из железа всё больше. Мы уже перешли порог, где локальные модели бьют по производительности прошлогодние фронтиры, делая агентный кодинг всё эффективнее, а постройки дорогих датацентров всё сомнительнее.
Возможно, стоит сфокусироваться на инвестициях в людей и исследования, а не в очередное раздутие оценки чипмейкеров на бирже.
Практический вывод для всех, кто гоняет модели локально: перестаньте мерить движки одиночным промптом. Меряйте хвост TTFT на многотуровой агентной сессии. Именно там разница из двукратной превращается в разницу между «работает» и «клиент отвалился по таймауту».
А ноутбук с 4060 — вполне себе платформа. Не для всего, но для куда большего, чем вам кажется, когда вы читаете очередной пост про два PRO 6000.
Короткая версия этого разбора, сырые замеры с моей машины, конфиги и всё, что не влезает в формат статьи — в @techn0danya. Там же разбираю новые релизы по мере выхода, а заодно рассказываю про железки, инфру и науку.
Ссылки
-
Статья: arXiv:2608.16157
-
Дистрибутив: flashml.ai
-
Смежное: Fiddler (2402.07033), MoE-Infinity (2401.14361), TraceLab про характеризацию нагрузок кодовых агентов (2606.30560)
Автор: danyathewriter


