惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
T
The Exploit Database - CXSecurity.com
IT之家
IT之家
酷 壳 – CoolShell
酷 壳 – CoolShell
T
Tailwind CSS Blog
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Hugging Face - Blog
Hugging Face - Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
博客园 - 聂微东
博客园 - Franky
美团技术团队
WordPress大学
WordPress大学
博客园 - 司徒正美
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
D
DataBreaches.Net
腾讯CDC
大猫的无限游戏
大猫的无限游戏
人人都是产品经理
人人都是产品经理
Microsoft Azure Blog
Microsoft Azure Blog
D
Docker
Security Archives - TechRepublic
Security Archives - TechRepublic
F
Fortinet All Blogs
T
Tor Project blog
G
GRAHAM CLULEY
Simon Willison's Weblog
Simon Willison's Weblog
I
InfoQ
Cyberwarzone
Cyberwarzone
V
V2EX
T
Tenable Blog
NISL@THU
NISL@THU
Scott Helme
Scott Helme
K
Kaspersky official blog
Latest news
Latest news
S
Schneier on Security
Martin Fowler
Martin Fowler
博客园 - 三生石上(FineUI控件)
Know Your Adversary
Know Your Adversary
Microsoft Security Blog
Microsoft Security Blog
S
Securelist
M
MIT News - Artificial intelligence
V
Vulnerabilities – Threatpost
P
Proofpoint News Feed
L
LangChain Blog
T
Threat Research - Cisco Blogs
Spread Privacy
Spread Privacy
T
Threatpost
有赞技术团队
有赞技术团队

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
DeepSeek‑V4‑Flash на двух DGX Spark: как мы убрали очередь и получили multi‑user
A.G. · 2026-06-22 · via Все публикации подряд на Хабре

Средний

11 мин

318

Подняли DeepSeek‑V4‑Flash на двух GB10, упёрлись в потолок consumer Blackwell, прошли три тупика со спекулятивным декодингом — и в итоге получили параллельную работу ресёрч‑агента и длинной генерации без очереди. Цифры — из Grafana.

Что реально сработало

После всех тупиков остались скучные, но работающие изменения.

Главное — поднять --max-num-seqs с 1 до 8. Единица означала, что в рантайме одновременно живёт ровно один запрос; всё остальное ждало в очереди, и второй пользователь получал первый токен через 14–15 секунд.

Откуда взялась эта единица — отдельная история. Когда мы только подняли V4 и дали ей два параллельных запроса с длинным контекстом, скорость генерации падала почти до нуля: видеокарта загружена полностью, а на выходе доли токена в секунду. Проще всего было убрать симптом, запретив параллельность, — что мы и сделали, заодно решив, что GB10 параллельную нагрузку не вывозит. Диагноз оказался неверным. Дело было не в параллельности, а в том, что под SM121 не был включён нужный attention‑путь (sparse‑MLA, о нём ниже), и размер батча работал против нас. Единица ничего из этого не лечила — она прятала симптом, выключая ровно ту возможность, ради которой всё затевалось. Стоило включить sparse‑MLA и вернуть нормальный размер пула — провал не вернулся.

Sparse‑MLA под SM121 — VLLM_TRITON_MLA_SPARSE=1. Включает sparse‑MLA путь, заточенный под эту линию GB10. Без него модель либо не стартует, либо сваливается в неподходящий attention‑бэкенд.

Prefix caching — --enable-prefix-caching. Для агентных нагрузок критично. Ресёрч‑агент гоняет один и тот же длинный контекст по кругу между шагами. Без кэша каждый запрос заново прогоняет prefill на сорок с лишним тысяч токенов, и кластер занят не генерацией, а пережёвыванием одного и того же. В бою доля попаданий в кэш дошла до 88% — к этой цифре вернёмся в разделе с метриками.

Штатная MTP‑спекуляция DeepSeek на нашей нагрузке работала: acceptance держался в районе 55–64%, то есть драфтер угадывал заметную часть токенов, а не просто добавлял накладные расходы.

Отдельно про проверку. После смены MoE‑ или attention‑пути смотреть надо не на код ответа, а на его связность. Наш sanity‑check был предельно простым: спросить столицу Франции и убедиться, что в ответе Париж. curl вернёт 200 и тогда, когда численный путь сломан, а модель выдаёт грамматически правильный, но бессмысленный текст.

TL;DR

  • Железо: 2× NVIDIA DGX Spark: GB10, Grace‑Blackwell, SM121, по 128 ГБ unified memory на ноду, связь через QSFP 200G / RoCEv2 / RDMA.

  • Модель: DeepSeek‑V4‑Flash — 284B total / ~13B active MoE: 256 экспертов, 6 активных на токен + 1 shared, 43 слоя, MLA attention, нативные FP8+MXFP4 веса. Важно: 284B — это Flash; 671B — это полная DeepSeek‑V4, не эта конфигурация.

  • Параллелизм: tensor parallel TP=2 на две ноды.

  • Главный фикс: --max-num-seqs 1 → 8. До этого любой второй запрос фактически вставал в очередь.

  • Что реально помогло: max-num-seqs, sparse‑MLA path для SM121, prefix caching и штатная MTP‑спекуляция DeepSeek.

  • Что не помогло: MRV2, Expert Parallel поверх B12X MoE и внешний DFlash‑драфтер.

  • Боевые цифры: 220 запросов за 2 часа, средний prompt 42 565 токенов, пик 4 running / 0 waiting, KV‑cache до 44.6%, peak aggregate 71 tok/s, prefix‑cache hit 88%.

1. Зачем мы вообще полезли в это болото

У нас есть кластер из двух DGX Spark. GB10 — это не датацентровый Blackwell уровня B200/GB200, а «настольный» Grace‑Blackwell с compute capability SM121 и unified memory: CPU и GPU делят один пул памяти на 128 ГБ.

Unified memory тут одновременно и причина, по которой всё это вообще затевалось, и источник большей части боли. Плюс очевиден: крупная модель видит большой общий пул и не упирается в привычную стену «сколько VRAM на одной карте». Минус всплывает чуть позже: добрая половина оптимизированных CUDA‑кернелов и готовых контейнеров писалась под датацентровый Blackwell, и про SM121 они либо не знают, либо знают, но криво.

Задача была сугубо прикладная: поднять сильную reasoning‑модель как общий inference‑backend на несколько потребителей. От неё хотелось сразу:

  • агент‑ресёрчер с длинным контекстом;

  • интерактивную генерацию;

  • отсутствие очереди при нескольких пользователях;

  • связные ответы, а не просто HTTP 200 от /v1/chat/completions.

DeepSeek‑V4‑Flash под это подходила почти идеально на бумаге: MoE с ~13B активных параметров на токен, компактный KV за счёт MLA, веса FP8+MXFP4 примерно на 149 ГБ и MTP‑спекуляция из коробки. Оставалось «всего лишь» её запустить.

2. Почему «просто поставить vLLM» не получилось

Главная засада: upstream vLLM на тот момент к DeepSeek‑V4 на consumer Blackwell готов не был.

Сама архитектура DeepSeek‑V4 в vLLM уже зарегистрирована — model class, tokenizer/parser, MTP и сопутствующие куски на месте. Но аппаратный путь под V4 заточен под датацентр: Hopper H200, Blackwell B200/B300/GB200, AMD MI355X. Внутри живут SM100-only оптимизации: DeepGEMM, FlashMLA sparse, Lightning Indexer.

На SM121 всё это рассыпается. В vLLM issue #45317 симптоматика видна как на ладони: все MLA‑бэкенды по очереди отвергаются, и в конце прилетает классика:

text

No valid attention backend found ... compute capability not supported

Рабочий путь для GB10 на сегодня — community‑форк jasl/vllm, где для SM12x добавлены Triton fallback‑кернелы: sparse‑MLA, FP8 lightning‑indexer и замена SM100‑DeepGEMM. Мы взяли community‑образ aidendle94/sparkrun-vllm-ds4-gb10 из этой линии, vLLM 0.21.1rc1.dev.

NGC‑контейнеры тоже мимо: образы 26.03+ требуют драйвер ≥590, а на Spark у нас стоял 580. На 590 нас встретили UMA leak и CUDAGraph deadlock, так что драйвер пришлось прибить гвоздями к 580.

Резюме: DeepSeek‑V4‑Flash на DGX Spark — это bleeding edge на неслитом PR. Оно работает, но только если держишь в голове, какие пути исполнения на SM121 реально доступны, а какие лишь делают вид.

3. Три тупика спекулятивного декодинга

Мы хотели разогнать single‑stream и по дороге снять «бесплатный» прирост со свежих оптимизаций. Сняли вместо этого три тупика. Каждый скушал время — но каждый и показал, как на этом железе реально устроен исполнительный путь.

Тупик 1. Model Runner V2 + reasoning

Model Runner V2 — новый execution layer vLLM: GPU‑native Triton kernels, async scheduling, аккуратнее работа с KV и обещанный прирост throughput. Включается переменной окружения:

bash

VLLM_USE_V2_MODEL_RUNNER=1

На нашей сборке с reasoning‑моделью vLLM падал прямо на старте:

text

pydantic ValidationError:
VLLM_USE_V2_MODEL_RUNNER does not yet support: reasoning budget enforcement

Самое интересное тут даже не текст ошибки. Для DeepSeek‑V4 MRV2 в принципе не является обязательным путём: такие MoE/MLA‑модели vLLM всё равно уводит на Model Runner v1. То есть даже гипотетически удачный запуск не дал бы того прироста, ради которого мы туда полезли. Мораль предсказуемая: «ускоряющая» фича из чейнджлога не обязана иметь отношение к твоей конкретной архитектуре.

Тупик 2. Expert Parallel + B12X MoE

Для MoE рука сама тянется включить Expert Parallel:

bash

--enable-expert-parallel

На нашей конфигурации это легло так:

text

ValueError: Mxfp4 MoE backend 'B12X' does not support ... ep_size=2 ... use_ep=True

B12X MoE‑кернел — это тот самый fallback для SM121, который в нашем случае отвечает за численную корректность. Без него последний MoE‑слой умеет выдавать грамматически безупречный, но абсолютно бессмысленный текст. А с Expert Parallel он не дружит: community‑деплои с EP обычно идут через native DeepGEMM path, которого на нашем SM121 попросту нет.

Выбор оказался бинарный: либо EP, либо ответы, которые что‑то значат. Мы выбрали второе.

Тупик 3. DFlash‑драфтер, который перезалили «вчера»

Параллельно мы пробовали разогнать через внешний DFlash‑драфтер соседнюю модель того же кластера. Запуск падал на assert:

text

unify_kv_cache_spec_page_size

Раскопки показали, что мейнтейнер перезалил драфтер с другой head‑геометрией: 64 КиБ на блок против 32 КиБ у target‑модели. Старый драфтер работал, новый — нет, и между этими двумя состояниями не было ничего, кроме молчаливого апдейта в репозитории.

Отсюда простой вывод на будущее: внешний драфтер — это не «маленькая модель где‑то рядом», а полноценная зависимость, которую могут тихо обновить и сломать. В production его нужно пиновать по ревизии, как любой другой артефакт, от которого ты зависишь.

4. Что реально сработало

После всех тупиков в сухом остатке оказались скучные, зато работающие изменения.

4.1. max‑num‑seqs 1 → 8

Тот самый главный фикс.

Мы держали:

bash

--max-num-seqs 1

В переводе на человеческий это значило: в рантайме одновременно живёт ровно один запрос. Любой второй запрос вставал в очередь, а пользователь любовался TTFT в 14–15 секунд.

После перехода на:

bash

--max-num-seqs 8

появилась настоящая параллельность — не та, что красиво выглядит на графике, а нормальный multi‑user: несколько запросов идут одновременно, очередь не растёт, latency становится предсказуемым.

4.2. Sparse‑MLA для SM121

Второй важный флаг:

bash

VLLM_TRITON_MLA_SPARSE=1

Он включает sparse‑MLA path, заточенный именно под эту SM121-линию. Без него модель либо не стартует вовсе, либо сваливается в неподходящий attention backend.

4.3. Prefix caching

Для агентных нагрузок — без преувеличения критично:

bash

--enable-prefix-caching

Ресёрч‑агент гоняет один и тот же длинный контекст между шагами по кругу. Если каждый раз заново прогонять prefill на 40K+ токенов, кластер будет занят не генерацией, а бесконечным пережёвыванием одного и того же промпта.

В бою prefix‑cache hit дошёл до 88% — к этой цифре мы ещё вернёмся в разделе с метриками.

4.4. Штатная MTP‑спекуляция DeepSeek

MTP у DeepSeek‑V4‑Flash на нашей нагрузке оказался вполне живым: acceptance rate держался в районе 55–64%. То есть драфтер угадывал заметную часть будущих токенов, а не просто добавлял overhead ради галочки.

Один нюанс, который легко забыть: после смены MoE/attention‑пути проверять надо не HTTP‑код, а связность ответа. У нас sanity check был максимально тупой:

text

Вопрос: столица Франции?
Ожидаемый ответ: Париж

curl радостно вернёт 200 и тогда, когда numerical path сломан, а модель выдаёт грамматически валидный мусор.

5. Замеры: синтетика против боевой нагрузки

Дальше — две принципиально разные истории: стендовый benchmark на пустом кластере и реальные метрики из Prometheus/Grafana. Путать их не стоит.

5.1. Стендовый benchmark и ошибка в методике

Гоняли тяжёлый prompt на генерацию production‑кода, ~600 токенов вывода. Кластер пустой: num_requests_running=0. Токены считали через usage.completion_tokens.

Concurrency

Per‑user, tok/s

Aggregate, tok/s

1

44.9

44.9

4

20.0

79.9

8

18.0

144.1

Single‑stream дал 44.9 tok/s. На concurrency 8 вышли на 144.1 tok/s aggregate — уже рядом с community‑бенчами на той же паре GB10.

И тут была главная грабля. Первая версия нашего бенча считала SSE‑события стрима — +1 за каждый chunk. При MTP‑спекуляции это враньё: в одном chunk может лежать сразу 2–3 принятых токена. В итоге счётчик занижал throughput примерно в 2.5 раза и показывал те самые «18 t/s» вместо реальных 44.9 t/s. Grafana, кстати, с самого начала рисовала правдоподобную картину — мы просто ей сначала не поверили.

Правильно — считать usage.completion_tokens или смотреть Prometheus‑метрику vllm:generation_tokens_total.

5.2. Реальная нагрузка: 2 часа, 220 запросов

Теперь не синтетика, а живая работа: агент‑ресёрчер с большим контекстом плюс интерактивная генерация.

Метрика

Значение

Запросов за окно

220

Средний prompt на запрос

42 565 токенов

Средняя генерация на запрос

443 токена

Пик параллельных запросов

4 running / 0 waiting

Пик KV‑cache

44.6%

Пик aggregate throughput

71 tok/s

Inter‑token latency, avg

84 мс

Prefix‑cache hit

8.23M из 9.36M prompt‑токенов = 88%

Несколько вещей, на которые стоит посмотреть внимательнее.

Средний prompt в 42K токенов — это не игрушка, а нормальная агентная нагрузка, и кластер держал на ней 4 параллельных запроса без очереди. Для нашей задачи именно это было критерием «годится / не годится».

KV‑cache доходил до 44.6%. Короткие синтетические тесты в этом месте умеют показывать смешные 5–6% и создавать ложное ощущение бездонного запаса; на длинных агентных контекстах картина резко другая.

Prefix‑cache hit 88% — пожалуй, ключевая цифра всего эксперимента. Агент переиспользует длинный контекст между шагами, и кэш съедает почти весь повторный prefill, который иначе сжёг бы кластер впустую.

Inter‑token latency 84 мс хорошо объясняет субъективные «спотыкания» в потоке. При параллельном decode ресурсы делятся между запросами, а MTP acceptance плавает, поэтому поток не идеально ровный. Но это именно лёгкая неровность, а не затыки и очередь, которые были при max-num-seqs=1.

6. Чеклист для тех, кто повторяет на DGX Spark

  • DeepSeek‑V4‑Flash на GB10 сейчас требует community‑форк. Stock vLLM 0.22/0.23 и «универсальные» образы без SM121-кернелов дадут crash или garbled output.

  • Не проверяйте модель по HTTP 200. Сломанный numerical path спокойно возвращает валидный JSON и бессмысленный текст.

  • Не оставляйте --max-num-seqs 1, если нужен multi‑user.

  • Включайте --enable-prefix-caching для агентных нагрузок. На переиспользовании длинного контекста экономия prefill огромна.

  • Expert Parallel с B12X MoE fallback несовместим. На SM121 пришлось выбирать между EP и корректностью; мы выбрали корректность.

  • MRV2 — не серебряная пуля для MoE/MLA. Для DeepSeek‑V4 этот путь не дал практического выигрыша и упёрся в reasoning‑budget enforcement.

  • Не путайте NCCL compile‑time и runtime. У нас torch.cuda.nccl.version() показывал 2.28.9, а runtime в образе был 2.30.4 — важно помнить при диагностике RoCE‑зависаний.

  • На GB10 не доверяйте привычным NVML‑панелям памяти. nvidia-smi --query-gpu=memory.used умеет возвращать [N/A]. Реальную занятость unified memory честнее смотреть через free, compute apps и отдельные Prometheus‑метрики.

  • Пиньте внешние драфтеры. Их могут перезалить и сломать head‑геометрию или KV layout без единого предупреждения.

Итог

DeepSeek‑V4‑Flash на двух DGX Spark — рабочая конфигурация для параллельного multi‑user inference. Но не в режиме «скачал официальный образ и поехали»: для GB10/SM121 нужны community‑кернелы, осознанный выбор execution path и нормальная проверка связности ответа.

Самый большой выигрыш дали не экзотические оптимизации, а скучная инженерия: поднять max-num-seqs, включить prefix caching, использовать sparse‑MLA под SM121 и не ломать корректный MoE backend ради Expert Parallel.

По синтетике вышло 44.9 tok/s single и 144.1 tok/s aggregate на concurrency 8. В реальной нагрузке важнее другое: средний prompt 42K токенов, 4 параллельных запроса без очереди, KV‑cache до 44.6% и 88% prefix‑cache hit. Именно эти цифры и показывают, что конфигурация живёт не только в демо, но и в настоящем агентном сценарии.

Цикл статей про DGX Spark и self‑hosted inference:

  1. Как я собрал на DGX Spark приватный AI‑сервер — из чего собран стек AGmind и кластер из двух Spark.

  2. Мониторинг unified memory, когда NVML и dcgm‑exporter молчат — почему на GB10 nvidia-smi отдаёт [N/A] и как это обойти.

  3. Кириллица в LLM: почему русский стоит дороже и работает медленнее — токенизация, цена контекста и выбор моделей под русский.

  4. DGX Spark на 256K контексте: конфигурации vLLM и почему NVFP4 в mainline сломан — шесть конфигов vLLM на SM121, включая DFlash.