Перейти к содержанию
Публикация AiManual

DeepSeek-V4-Flash на двух Radeon AI PRO R9700: affinity, квант 2.875 bpw и 35,8 tok/s

Две Radeon AI PRO R9700 по 32 ГБ запускают DeepSeek-V4-Flash-0731 в движке affinity: prefill 1260-1360 tok/s, decode 31-50 tok/s, готовый квант 2.875 bpw. Разби

Коротко

Что будет в материале

  1. 01

    Что такое affinity и зачем он нужен для DeepSeek-V4-Flash

  2. 02

    Готовый квант 2.875 bpw: что внутри и почему только для affinity

  3. 03

    Реальные скорости: prefill, decode и результаты BetterBench

  4. 04

    Требования к железу и ограничения: кому подойдёт эта сборка

DeepSeek-V4-Flash-0731 выдаёт 35,8 tok/s в взвешенном результате BetterBench v0.6.0 на связке из двух Radeon AI PRO R9700 по 32 ГБ и 192 ГБ системной памяти. Prefill держится в диапазоне 1260-1360 tok/s при контексте 4K-64K, decode доходит до 40-50 tok/s на структурированных ответах и опускается до 31-35 tok/s на свободной прозе и рассуждениях.

Всё это работает не в llama.cpp и не в vLLM, а в движке affinity, который писали под DeepSeek-V4-Flash и архитектуру RDNA4. Готовый квант на 2.875 бита на вес выложен автором отчёта, но загружается он только в affinity.

Что такое affinity и зачем он нужен для DeepSeek-V4-Flash

affinity - движок локального инференса, написанный Yoshi Exeler (ник StillDeadcode) под одну задачу: запуск DeepSeek-V4-Flash на одной или двух картах RDNA4. Это отдельная кодовая база с собственным квантайзером, не форк llama.cpp.

Кто стоит за affinity и почему это важно

Автор движка Yoshi Exeler, известный под ником StillDeadcode. Отчёт о запуске опубликовал пользователь neuromacmd: он собрал конфигурацию из двух Radeon AI PRO R9700, выложил готовый квант и форк с исправлениями стабильности. Исходный пост с замерами лежит в r/LocalLLaMA.

Движок писали с нуля под конкретную модель и конкретную архитектуру GPU. Причины две. Готовых ядер для RDNA4 под эту модель в популярных движках на момент отчёта не хватало, а плотная упаковка весов при низкой битности требует контроля над форматом кванта. Исправления стабильности автор отправил upstream в виде PR.

Как affinity умещает модель на двух картах

DeepSeek-V4-Flash построена как MoE (mixture of experts, смесь экспертов). На каждом токене активируется лишь небольшая часть экспертов, но самих экспертов много, и их веса целиком в 64 ГБ видеопамяти двух R9700 не укладываются. affinity держит горячих экспертов, то есть самых часто используемых, прямо на GPU, а остальных стримит из оперативной памяти по мере надобности. Быстрые карты не простаивают, медленная память подключается только для редких экспертов.

Второй источник скорости - спекулятивный драфт, нативный для DeepSeek. Небольшая черновая часть модели предлагает несколько следующих токенов, основная модель проверяет их и принимает пачкой. Чем чаще догадки принимаются, тем выше итоговый decode. Тот же принцип экономии VRAM через вынос части данных в RAM используют и другие проекты, например форк llama.cpp с адаптивным KV-стримингом, хотя реализация и целевая модель там другие.

Готовый квант 2.875 bpw: что внутри и почему только для affinity

Автор выложил готовый квант 0731, сделанный собственным квантайзером affinity. Состав: routed experts на 2.875 bpw, калибровочная матрица imatrix от teamblobfish, dense-веса в FP8 плюс встроенный draft из той же 0731. bpw расшифровывается как bits per weight, то есть среднее число бит на параметр. Для сравнения: FP16 это 16 бит, FP8 - 8, а здесь основная масса весов сжимается почти втрое плотнее FP8.

Экономия приходится на routed experts, потому что они занимают большую часть весов MoE-модели. Dense-веса (внимание, эмбеддинги и прочие слои, работающие на каждом токене) оставлены в FP8, чтобы не терять точность там, где ошибка влияет на весь вывод.

Почему квант не работает в llama.cpp и vLLM

Формат упаковки весов у affinity свой. Готовый квант загружается только в affinity, в llama.cpp и vLLM он не открывается. Если ваш стек построен на llama.cpp, придётся либо переходить на affinity, либо искать другой квант той же модели. Это цена плотной упаковки: чем ниже битность, тем сильнее формат завязан на конкретный движок и его ядра.

Что даёт imatrix teamblobfish и FP8 для dense-весов

imatrix (importance matrix) это калибровочные данные, по которым квантайзер понимает, какие веса чувствительнее к ошибке. При 2.875 bpw без такой калибровки качество обычно просаживается заметно, с матрицей потери удаётся удержать. teamblobfish здесь обозначает конкретный набор калибровочных данных, который использовал автор.

FP8 для dense-слоёв даёт компромисс: они остаются точнее основных экспертов, но занимают меньше места, чем FP16. Встроенный draft из 0731 избавляет от поиска отдельной черновой модели и совпадает с целевой по словарю, что повышает частоту принятия догадок.

Реальные скорости: prefill, decode и результаты BetterBench

Все цифры ниже - замеры автора отчёта, а не независимое тестирование. Конфигурация: две Radeon AI PRO R9700 по 32 ГБ, 192 ГБ системной RAM, квант 2.875 bpw, движок affinity. Полный набор замеров приведён в отчёте.

Prefill: как быстро обрабатывается контекст

На длинных промптах prefill держится в диапазоне 1260-1360 tok/s при контексте 4K-64K. В прогоне BetterBench с холодным кэшем кривая другая: 1150 tok/s на 1.6K, 1900 на 6K, 2090 на 12K и около 2200 на 24K-47K. Рост с длиной промпта объясняется тем, что на коротких запросах выше доля накладных расходов, а на длинных экспертный кэш успевает прогреться.

Prefill напрямую определяет TTFT, время до первого токена. В прогоне BetterBench TTFT составил около 0,7 секунды в каждой категории. На реальных документах автор получил prefill ниже, порядка 1,3K tok/s: филлерный текст бенчмарка, вероятно, дружелюбнее к кэшу экспертов, чем настоящие файлы.

Decode: скорость генерации на разных типах задач

На длинных структурированных ответах decode держится на 40-50 tok/s, на свободной прозе и рассуждениях падает до 31-35 tok/s. Разброс объясняется частотой принятия догадок драфта: предсказуемый формат вроде JSON или таблицы попадает в них чаще, чем вольный текст. Идея экономить VRAM за счёт размещения драфтера проверялась и на NVIDIA: на одной RTX PRO 6000 перенос драфтера DSpark в RAM дал итоговый прирост 15-17%, но по другой причине - освободившаяся память вместила больше экспертных слоёв.

В быстром прогоне BetterBench v0.6.0 (5 проходов на категорию) взвешенный результат 35,8 tok/s, update p99 около 110 мс. Медианы decode по категориям:

КатегорияМедианный decode, tok/s
math47,1
json43,4
summarization40,5
file_edit40,4
code34,8
reasoning33,5
chat33,1
prose26,8

Читать таблицу стоит с оговорками. Пять проходов на категорию мало, значения ориентировочные. Thinking был включён, и 60% запусков упёрлись в лимит max_tokens корпуса, всё ещё рассуждая, так что это в основном скорости фазы размышления, а время до финального ответа на таком корпусе измерить нельзя. Сэмплирование стояло по умолчанию у бенчмарка, temp 0.7. Concurrency sweep пропущен: affinity обслуживает одну последовательность за раз, и замер показал бы только очередь.

Тесты качества: needle-in-a-haystack и агентная задача

Кроме скоростей автор проверил, не рассыпается ли модель при агрессивной квантизации. Тест needle-in-a-haystack пройден 3/3 на контекстах 4K, 16K и 64K: нужный фрагмент находится на всех трёх длинах. Многоходовая агентная задача (Excel в DuckDB через shell-инструменты, 15 ходов) прошла все проверки без единого некорректного вызова инструмента.

Для практики второй результат важнее первого. Агентные сценарии чувствительны к формату вызовов, и лишний символ в аргументе ломает всю цепочку. Если модель держит 15 ходов без ошибок в разметке инструментов, квант 2.875 bpw годится для автоматизации, а не только для чата.

Требования к железу и ограничения: кому подойдёт эта сборка

Какие GPU подходят: только RDNA4 (gfx1201)

affinity работает только на RDNA4, в терминах ROCm это gfx1201, и максимум на двух картах. Radeon AI PRO R9700 подходит, карты серии RX 9000 тоже. Более старые RDNA2 и RDNA3 отпадают: движок опирается на инструкции и особенности памяти RDNA4, переносить ядра на предыдущие поколения автор не планирует.

Ограничение в две карты означает, что третий ускоритель ничего не добавит. Отсюда же следует бюджет сборки: две карты по 32 ГБ плюс объёмная системная память.

Сколько RAM нужно и почему 64 ГБ+

Эксперты, которые не влезли в VRAM, стримятся из оперативной памяти, поэтому её объём задаёт нижнюю границу конфигурации. Ориентир автора: около 64 ГБ и больше. В его системе стоит 192 ГБ, и это запас, а не минимум. Чем больше RAM, тем больше экспертов можно держать в памяти и тем меньше промахов в кэше.

64 ГБ это порог, ниже которого сборка просто не поедет, а не комфортная рекомендация. Экономить на памяти при двух картах R9700 смысла нет.

Температура 1.0: почему 0.6 ломает рассуждения

Автор советует брать сэмплирование из карточки модели, то есть temperature 1.0. На temp 0.6 этот квант уходил в циклы рассуждений: модель повторяла один и тот же ход мысли вместо выхода на ответ. Это особенность конкретного кванта 2.875 bpw, а не правило для DeepSeek-V4-Flash вообще. Другие кванты той же модели на других движках могут вести себя иначе.

Проблемы стабильности и форк с исправлениями

Что такое hugepage collapse и как он ломает генерацию

Главный баг проявлялся на двух картах по 32 ГБ. После первого длинного промпта сервер начинал генерировать бессвязный текст и не восстанавливался. Причиной был коллапс hugepage при GPU-маппинге в условиях, когда свободной VRAM осталось слишком мало. Проблема лежала в управлении памятью, а не в самой модели: веса оставались на месте, страницы памяти разваливались на мелкие, и движок читал мусор.

Именно на двух 32-ГБ картах раскладка памяти самая тесная, поэтому баг воспроизводился там и не бил по конфигурациям с большим запасом VRAM.

Где взять форк и что он исправляет

Автор выложил форк с исправлениями стабильности и тем же составом отправил их upstream в виде PR. Если вы уже поставили оригинальный affinity, есть два пути: перейти на форк или дождаться, пока правки примут в основную ветку. На двух картах тянуть с этим не стоит, потому что баг делает сервер непригодным после первой же длинной задачи. Детали бага и ссылки на сборки автор приводит в том же отчёте.

Как запустить: Docker, TheRock ROCm 7.14 и настройка

Docker-сборка на TheRock ROCm 7.14: что это даёт

Есть Docker-сборка на TheRock ROCm 7.14, поэтому на хосте не нужна установка ROCm. TheRock - сборка стека ROCm, 7.14 - версия. Практический смысл в том, что все зависимости живут внутри контейнера, и на чистой системе не приходится разбираться с драйверами и библиотеками уровня ОС. Обновление тоже сводится к замене образа.

Настройки сэмплирования и с чем ещё работать

Сэмплирование берите из карточки модели: temperature 1.0. На 0.6 квант сваливался в повторы рассуждений. Для прогонов на той же машине автор использовал llama-swap: этот инструмент поднимает несколько моделей за одним API и переключает их по запросу. Параллельные запросы при этом не проверялись: affinity обслуживает одну последовательность за раз.

Сравнение с альтернативами: llama.cpp, vLLM и DeepSeek-V4.1-Flash

Почему llama.cpp и vLLM не подходят для этого кванта

Готовый квант 2.875 bpw загружается только в affinity. В llama.cpp и vLLM он не откроется по простой причине: формат упаковки и ядра под RDNA4 написаны внутри affinity. Сами движки рабочие и кроссплатформенные, но под связку этой модели, этого кванта и этой архитектуры их никто не настраивал. Выбор простой: максимальная скорость на RDNA4 через affinity или привычный стек на другой связке модели и GPU.

DeepSeek-V4.1-Flash: экспериментальная ветка и её скорость

В репозитории есть экспериментальная ветка под DeepSeek-V4.1-Flash. Она уже выдаёт корректный вывод, но скорость на двух картах всего около 14 tok/s. Это в разы меньше, чем у DeepSeek-V4-Flash на affinity, и для практической работы на двух R9700 такая скорость неудобна. Цифры сильно зависят от конфигурации: в тестах TensorSharp на восьми NVIDIA A40 та же ветка показывала 40,3-40,7 tok/s в Q2_K и 31-32,5 tok/s в Q4_K_M, но там другой класс железа и другая схема размещения экспертов.

Кому подходит эта сборка и стоит ли пробовать

Сценарии использования: для чего хватит 35 tok/s

35,8 tok/s в среднем и 40-50 tok/s на структурированных задачах дают комфортную скорость для чата, генерации кода и агентных цепочек. Свободная проза идёт медленнее, медиана 26,8 tok/s, но текст всё равно печатается быстрее, чем читается. Разбор документов, генерация JSON и работа с таблицами укладываются в 40+ tok/s.

Хуже обстоит дело с сервисами на несколько пользователей: affinity обслуживает одну последовательность, поэтому параллельные запросы встанут в очередь.

Когда лучше подождать или выбрать другое решение

Сборка для узкого круга: две карты RDNA4 по 32 ГБ, 64 ГБ оперативной памяти и выше, готовность работать с кастомным движком и форматом кванта, который больше нигде не открывается. Если у вас одна карта RDNA4 или карты предыдущих поколений, этот путь закрыт. Для одной карты разумнее смотреть на менее требовательные варианты: Qwen3.8-Flash на 12 ГБ VRAM выдаёт 14-15 токенов/с и не требует двух ускорителей, хотя возможностей у неё меньше.

Если RDNA4 нет, но нужна именно DeepSeek-V4-Flash, ориентируйтесь на NVIDIA-конфигурации и другие движки: там свои настройки размещения драфтера и экспертов и своя картина по скоростям. affinity в этом случае не вариант, он привязан к gfx1201.

Подписаться на канал