181 tok/s aggregate на 2× DGX Spark с Qwen3.8-Flash-Next означает суммарную скорость генерации по нескольким параллельным запросам, а не скорость одного ответа. Показатель складывает токены всех активных сессий за время измерения, поэтому его нельзя напрямую сравнивать со скоростью single-stream decode.
Один поток обычно генерирует заметно меньше токенов в секунду: каждый новый токен зависит от предыдущего, а модель обращается к KV-cache и синхронизируется между узлами. Несколько agent-сессий позволяют vLLM плотнее загрузить вычислительные блоки и скрыть часть стоимости межузлового обмена. Цена такого режима, рост потребления KV-cache и увеличение задержек отдельных запросов.
На результат влияют четыре связанные группы настроек: фактический транспорт NCCL между узлами, распределение памяти unified-memory-системы, размещение таблиц n-грамм через mmap на NVMe и параметры vLLM для batching и длинных prefills. Silent TCP fallback способен сохранить работоспособность сервинга, но заметно ухудшить throughput. Точное значение 181 tok/s нужно трактовать вместе с числом потоков, длиной входов и выходов, прогревом и правилом подсчёта токенов.
Что означает 181 tok/s aggregate на 2× DGX Spark
Заявленные 181 tok/s aggregate описывают производительность всей конфигурации из двух DGX Spark при конкретной нагрузке. Эта цифра не гарантирует 181 tok/s для одного пользователя, любого промпта или любого числа параллельных сессий. Без полного описания теста показатель остаётся ориентиром для конкретного профиля сервинга.
Aggregate throughput и скорость одного запроса - это разные метрики
Aggregate throughput считают по всем активным запросам. Упрощённая формула выглядит так: aggregate tok/s = общее число сгенерированных токенов / время измерения. При четырёх сессиях по 45 tok/s система даст около 180 tok/s aggregate, хотя каждый отдельный запрос будет получать 45 tok/s.
Для корректного сравнения рядом с aggregate throughput нужны минимум четыре показателя:
| Метрика | Что показывает | Почему нужна |
|---|---|---|
| Aggregate throughput | Суммарную генерацию по всем запросам | Показывает пропускную способность сервинга |
| Per-request throughput | Скорость отдельной сессии | Описывает опыт одного пользователя или агента |
| TTFT | Время до первого токена | Показывает цену очереди и prefill |
| Inter-token latency | Интервал между последующими токенами | Помогает оценить плавность streaming-ответа |
На итог влияют длина входа, длина вывода, число последовательностей, warm или cold режим, наличие повторно используемого KV-cache и способ подсчёта токенов. Два теста с одинаковой моделью и одинаковым железом могут дать разные цифры, если один считает только decode, а второй включает prefill и время ожидания в очереди.
Какая нагрузка нужна для выхода на заявленный показатель
Само слово aggregate не сообщает число параллельных запросов. В описании кейса нужно зафиксировать concurrency, размеры промптов и ответов, длительность прогона, время прогрева и долю ошибок. Если 181 tok/s получены на нескольких agent-сессиях, показатель следует сравнивать с другими тестами при сопоставимом concurrency.
- Один запрос: измеряется single-stream decode, TTFT и inter-token latency.
- Несколько коротких запросов: проверяется, как continuous batching загружает систему при умеренном объёме KV-cache.
- Несколько длинных сессий: проявляется давление на память, prefill и межузловую сеть.
- Смешанная agent-нагрузка: короткие вызовы инструментов соседствуют с длинными ответами и новыми prefills.
Результат нужно считать после прогрева, но отдельно сохранять cold-метрики. Иначе быстрый прогретый прогон скроет стоимость первого размещения весов, page faults и заполнения KV-cache.
Как проверить воспроизводимость результата до настройки системы
Для повторения кейса сначала составьте паспорт эксперимента. В нём должны быть точное название чекпойнта Qwen3.8-Flash-Next, формат и уровень квантизации, версии драйвера, CUDA, NCCL, vLLM и операционной системы, схема распределения модели и сетевой путь между двумя узлами.
- Зафиксируйте аппаратную конфигурацию обоих DGX Spark, доступный объём unified memory и тип межузлового соединения.
- Укажите, используется ли tensor parallelism, отдельные реплики или другая схема распределения.
- Сохраните параметры vLLM, лимит контекста, число последовательностей, бюджет batched tokens и настройки KV-cache.
- Опишите входные запросы: число токенов, наличие длинных контекстов, повторяемость префиксов и формат agent-вызовов.
- Разделите warm и cold прогоны, укажите время прогрева и продолжительность измерения.
- Опубликуйте aggregate throughput вместе с per-request throughput, TTFT, p50, p95 и p99.
Для сравнения с другими конфигурациями DGX Spark полезен материал о практических результатах тестов DeepSeek V4 Flash и Qwen3.8-Flash-Next: он показывает, почему пиковая скорость плохо описывает поведение системы при разных длинах контекста и режимах нагрузки.
Почему single-stream decode заметно медленнее
Разрыв между single-stream decode и aggregate throughput возникает из-за разной степени параллелизма. Один запрос последовательно создаёт токены, а несколько запросов позволяют планировщику объединять операции и эффективнее использовать вычислительные ресурсы двух узлов.
Один поток упирается в последовательную природу decode
На шаге генерации токен t зависит от состояния после токена t-1. Модель не может заранее вычислить весь ответ целиком. Каждый шаг требует чтения весов, обращения к KV-cache, вычислений attention и синхронизации тех частей модели, которые находятся на другом узле.
При одном активном запросе часть ресурсов может простаивать. Причина зависит от профиля: узким местом бывают пропускная способность памяти, размер KV-cache, межузловая задержка, неудачный сетевой транспорт или недостаточная загрузка вычислительных блоков. Без профилирования нельзя приписывать просадку только модели или только сети.
Префиксный prefill обычно лучше распараллеливается по токенам входа. Decode работает с одним новым токеном на последовательность, поэтому при коротком batch система получает меньше независимой работы. На распределённой конфигурации к этому добавляются коллективные операции NCCL.
Что дают параллельные agent-сессии
Каждая активная agent-сессия создаёт независимую последовательность токенов. Планировщик vLLM может обрабатывать их в одном шаге batch, объединяя операции decode и распределяя вычисления между узлами. Так увеличивается загрузка системы, а задержка сетевых синхронизаций частично скрывается работой над другими последовательностями.
Рост throughput продолжается до момента, когда ограничителем становится один из ресурсов:
- KV-cache перестаёт вмещать нужное число активных токенов;
- длинные prefills вытесняют короткие запросы из очереди;
- межузловой обмен занимает значительную долю шага;
- NVMe начинает обслуживать слишком много случайных page faults;
- планировщик увеличивает время ожидания при большом concurrency.
Aggregate throughput в таком режиме полезен для очередей задач, RAG-пайплайнов и нескольких AI-агентов. Пользователь получает не 181 tok/s в одном ответе, а больше завершённых ответов за единицу времени.
Где проходит компромисс между throughput и latency
| Режим | Главная цель | Контрольные метрики |
|---|---|---|
| Один интерактивный пользователь | Минимальная задержка ответа | TTFT и inter-token latency |
| Несколько агентов | Баланс throughput и предсказуемой задержки | Aggregate tok/s, p95, KV-cache |
| Пакетная генерация | Максимум токенов за единицу времени | Aggregate tok/s, p99, длительность очереди |
Оптимальный concurrency определяется целевым p95 и доступным KV-cache. Если добавление новых сессий увеличивает aggregate throughput, но одновременно резко поднимает p95, система уже вышла за подходящую точку для интерактивных задач.
Сеть между узлами: NCCL over RDMA против silent TCP fallback
Распределённый инференс зависит от фактического транспорта между узлами. Рабочий IP-канал подтверждает доступность машин, но не доказывает, что NCCL использует RDMA. При сбое RDMA-компонента библиотека может выбрать TCP-сокеты, после чего модель продолжит отвечать, а benchmark покажет необъяснимую просадку.
Какие данные проходят между узлами при распределённом инференсе
При tensor parallelism части вычислений выполняются на разных устройствах. Узлы обмениваются промежуточными результатами через коллективные операции NCCL. Конкретный объём обмена зависит от архитектуры модели, размера tensor parallel group, формы batch и текущего этапа, prefill или decode.
Для decode особенно чувствительны задержка каждой синхронизации и стабильность пропускной способности. Даже короткая задержка, повторяющаяся на каждом токене, накапливается в inter-token latency. При нескольких сессиях сеть получает больше работы, но batch может лучше скрывать её стоимость.
Как распознать переход NCCL на TCP
Проверка должна начинаться с логов и состояния устройств, а не с итоговой цифры tok/s. Для диагностического запуска можно включить подробный вывод:
NCCL_DEBUG=INFO
NCCL_DEBUG_SUBSYS=NET
В логах ищут выбранный сетевой путь, упоминания socket-транспорта, доступные RDMA-интерфейсы и ошибки загрузки verbs-библиотек. Название HCA и сетевого интерфейса нельзя подставлять вслепую: сначала нужно увидеть, какие устройства реально обнаружены на обоих узлах.
- Проверьте состояние RDMA-устройств и наличие нужных библиотек.
- Сопоставьте интерфейс, выбранный NCCL, с физическим соединением между узлами.
- Сравните логи обоих процессов, потому что асимметричная конфигурация тоже меняет путь обмена.
- Запустите отдельный тест пропускной способности и задержки сети.
- Сопоставьте сетевые результаты с throughput, p95 и загрузкой CPU.
Жёсткая фиксация имени HCA или интерфейса может скрыть проблему обнаружения устройства и сломать запуск после изменения нумерации. Такие переменные задают после проверки конкретной системы, а не как универсальный рецепт.
Что сравнивать в диагностическом тесте
В контролируемом сравнении меняется только транспорт. Модель, чекпойнт, размеры входов и выходов, число последовательностей, версии ПО и длительность прогона должны оставаться одинаковыми.
| Параметр | Рабочий RDMA | Контрольный TCP-сценарий |
|---|---|---|
| Транспорт в логах NCCL | RDMA-путь | Socket-путь |
| Aggregate throughput | Фиксируется после прогрева | Фиксируется тем же способом |
| TTFT и inter-token latency | Сравниваются по одинаковым запросам | Сравниваются по одинаковым запросам |
| Загрузка CPU и сеть | Сохраняется для анализа | Сохраняется для анализа |
Если TCP-вариант снижает aggregate throughput и увеличивает хвостовые задержки при прочих равных, это подтверждает влияние транспорта. Одной записи о запуске недостаточно: система может перейти на TCP только при определённой форме batch или после потери RDMA-сервиса.
Память DGX Spark: как освободить место для KV-cache
На unified-memory-железе один общий бюджет обслуживает веса, runtime-буферы, KV-cache, mmap-области, page cache и операционную систему. Освобождение нескольких гигабайт под KV-cache может увеличить доступную длину контекста и число параллельных сессий, но виртуальное отображение файла само по себе не означает экономию физической памяти.
Почему KV-cache важнее пикового объёма свободной памяти
KV-cache растёт вместе с числом обработанных токенов и количеством активных последовательностей. Каждый длинный контекст занимает память даже после завершения prefill, пока соответствующая сессия остаётся активной или её блоки не освобождены.
Упрощённо доступную ёмкость можно оценивать так: KV-cache budget / bytes per token. Реальное значение зависит от числа слоёв, схемы attention, размера KV-heads, типа данных, block size и внутренних резервов vLLM.
Пиковое значение свободной памяти в начале запуска мало говорит о стабильности сервинга. После старта могут появиться новые runtime-буферы, страницы mmap, сетевые буферы и KV-блоки. Поэтому проверка должна проходить на длительной смешанной нагрузке, а не сразу после загрузки модели.
В разборе памяти DeepSeek V4 Flash на двух DGX Spark отдельно показаны расходы весов, KV-cache, RSS-процессов и ОС. Эта карта памяти unified-memory сервинга полезна как методика разбиения бюджета, но её числовые значения нельзя переносить на Qwen3.8-Flash-Next без нового измерения.
Что происходит с mmap-таблицами n-грамм в unified memory
mmap создаёт виртуальное отображение файла. Физические страницы подгружаются при обращении к ним, а часть данных может оставаться в page cache. Поэтому размер файла на NVMe и фактически занятая память, это разные показатели.
Таблицы n-грамм могут занимать большой адресный диапазон, но их реальная цена зависит от шаблона доступа. Повторное обращение к одним страницам уменьшает I/O, случайный доступ вызывает больше page faults и чаще вытесняет полезные страницы. В unified memory эти страницы конкурируют с KV-cache и памятью runtime.
При нехватке физической памяти ядро начинает активнее обслуживать page faults и вытеснять страницы. Сервинг при этом может продолжать отвечать, но растут TTFT, inter-token latency и p95. Формальное наличие свободного адресного пространства не защищает от такого давления.
Как оценивать влияние перераспределения памяти
Сравнение до и после изменения mmap или KV-cache budget нужно проводить на одинаковой нагрузке. Запишите исходный профиль, внесите одно изменение и повторите прогон с теми же prompt lengths, concurrency и временем прогрева.
| Что измерять | Что искать |
|---|---|
| Доступный KV-cache | Рост числа токенов и активных последовательностей до переполнения |
| RSS и page cache | Фактическую, а не виртуальную стоимость mmap |
| Page faults | Рост задержки при обращении к таблицам |
| NVMe I/O | Конкуренцию чтения таблиц с другими операциями |
| p95 и p99 | Стабильность под длительной нагрузкой |
| OOM и вытеснения | Наличие срывов после прогрева |
NVMe mmap и madvise(MADV_RANDOM): цена экономии оперативной памяти
Перенос таблиц n-грамм на локальный NVMe освобождает часть физической памяти для KV-cache, но добавляет зависимость от page cache и задержки накопителя. mmap помогает управлять адресным пространством, а не отменяет стоимость чтения страниц.
Что меняет madvise(MADV_RANDOM)
Вызов madvise(addr, length, MADV_RANDOM) сообщает ядру, что обращения к отображённой области могут идти без выраженной последовательности. Ядро получает основание изменить упреждающую подкачку и не читать крупные соседние диапазоны заранее.
Для таблиц с действительно случайными обращениями это может уменьшить бесполезное чтение. При локальном повторном доступе или почти последовательном шаблоне результат способен оказаться обратным. Эффект зависит от размера страниц, нагрузки на page cache, скорости NVMe и числа одновременно работающих агентов.
MADV_RANDOM не ускоряет вычисления модели и не превращает NVMe в оперативную память. Это подсказка ядру, её влияние проверяют профилированием page faults и I/O.
Какие риски появляются при переносе таблиц на NVMe
Случайное обращение к mmap-области может вызвать синхронный page fault в момент, когда decode ждёт данные. Один такой промах способен увеличить latency отдельного шага, а серия промахов под concurrency начинает конкурировать с чтением весов и работой других процессов.
- Холодный NVMe-профиль даёт больше page faults, чем прогретый.
- Несколько агентов увеличивают число независимых обращений к таблицам.
- Длинный prefill способен одновременно нагрузить CPU, память и накопитель.
- Рост page cache может уменьшить место, которое планировалось отдать KV-cache.
- Средний throughput может сохраниться при ухудшении p95 и p99.
Практический разбор Qwen3.8-Flash-Next в llama.cpp отдельно сравнивает mmap, загрузку в RAM и разные режимы KV. Материал о влиянии VRAM, PLE, mmap и контекста помогает выбрать показатели для такого сравнения, но поведение vLLM нужно измерять отдельно.
Как измерить, что память действительно ушла в KV-cache
Сначала сохраните RSS процессов, объём page cache, число page faults, скорость чтения NVMe и доступный KV-cache. После этого повторите тест с тем же набором запросов и проверьте, какой ресурс вырос физически.
- Если виртуальный размер процесса уменьшился, это ещё не доказывает уменьшение RSS.
- Если RSS снизился, проверьте, не вырос ли page cache.
- Если KV-cache стал больше, измерьте, увеличилась ли длина активного контекста без OOM.
- Если throughput вырос, проверьте p95, p99 и cold-запросы.
- Если page faults участились, сравните прогретый и холодный сценарии.
Положительный результат выглядит как устойчивый рост доступного KV-cache без неприемлемого роста latency и I/O. Одной цифры свободной памяти для такого вывода недостаточно.
Настройка vLLM на DGX Spark для распределённого сервинга
Настройку vLLM нужно вести от совместимости и транспорта к памяти и нагрузке. Набор флагов нельзя переносить между версиями без проверки: поведение tensor parallelism, chunked prefill, MTP и параметров KV-cache зависит от версии vLLM, модели и используемого backend.
Базовые параметры, которые нужно зафиксировать
Для заявленной конфигурации сначала определите фактическую схему распределения. Два DGX Spark не доказывают сами по себе, что используется TP=2: в запуске могут применяться реплики или другая топология.
| Группа | Что зафиксировать | Какой вопрос закрывает |
|---|---|---|
| Модель | Точное имя, формат, квантизация, tokenizer | Что именно измеряется |
| Параллелизм | Tensor parallel size и распределение процессов | Как модель разделена между узлами |
| Контекст | max_model_len и фактические длины входов | Сколько KV-cache потребуется |
| Batching | max_num_seqs, бюджет batched tokens, chunked prefill | Как система объединяет запросы |
| Память | gpu_memory_utilization, KV-cache dtype и резерв | Какой бюджет остаётся под активные последовательности |
| Режим запуска | Eager, CUDA Graphs, MTP и другие функции, если они поддержаны | Какие ускорения реально включены |
| Сеть | NCCL-переменные, интерфейсы и RDMA-путь | Как узлы обмениваются данными |
Практическая схема запуска Qwen3.8-Flash-Next на двух Spark с vLLM, NVFP4, eager, MTP и сетевыми проверками разобрана в материале о настройке Qwen3.8-Flash-Next под vLLM. Конкретные версии и значения флагов из такого рецепта нужно сверять с собственным чекпойнтом и стеком.
Порядок подбора параметров
- Проверьте загрузку модели на обоих узлах при минимальной нагрузке.
- Подтвердите фактический сетевой транспорт в логах NCCL.
- Измерьте один короткий запрос, записав TTFT, inter-token latency и память.
- Добавьте несколько последовательностей и проверьте рост aggregate throughput.
- Увеличивайте длину контекста, пока KV-cache и p95 остаются в допустимых пределах.
- Оцените chunked prefill, eager, MTP и другие функции по одинаковому benchmark, меняя по одному параметру.
- Перенесите таблицы n-грамм на NVMe и отдельно сравните mmap с резидентной загрузкой.
- Проведите смешанный тест с агентами, короткими запросами и cold long prefills.
Такой порядок сокращает число переменных. Если сразу включить несколько ускорений, изменить память и добавить concurrency, причина изменения throughput останется неизвестной.
Какие изменения нельзя оценивать по одной цифре throughput
Рост aggregate tok/s может сопровождаться увеличением очереди, TTFT и хвостовых задержек. Для каждого прогона сохраняйте:
- aggregate и per-request throughput;
- TTFT, inter-token latency, p50, p95 и p99;
- число активных последовательностей и фактический KV-cache;
- ошибки, OOM, вытеснения и перезапуски процессов;
- RSS, page faults, page cache и NVMe I/O;
- логи NCCL и признаки TCP fallback.
Конфигурация считается удачной, когда она выдерживает целевую нагрузку с приемлемым p95 и без постепенного ухудшения после прогрева. Пиковая цифра throughput без этих условий описывает короткий benchmark.
Ограничение cold long prefills для стабильной работы
Cold long prefill, это обработка большого входного контекста без полезного прогретого состояния. Такой запрос на короткое время потребляет много вычислительных ресурсов, KV-cache и сетевого обмена. На unified-memory-железе он способен ухудшить задержку уже активных сессий.
Почему холодный длинный prefill опасен для соседних запросов
Во время prefill модель обрабатывает большой объём входных токенов и создаёт KV-состояние. Если одновременно работают несколько агентов, длинный cold-запрос конкурирует с их decode за вычисления, память и коллективные операции NCCL.
Средний throughput может выглядеть нормально, пока p95 и p99 растут из-за единичных тяжёлых запросов. Для интерактивного сервинга это означает рывки в streaming-ответах и непредсказуемое время первого токена.
Ситуация усугубляется при mmap-доступе к таблицам n-грамм: prefill вызывает собственные page faults, а активные decode-последовательности продолжают обращаться к KV-cache. Операционная система распределяет один общий ресурс между этими задачами.
Какие ограничения применять к long-context нагрузке
Конкретные значения подбираются по целевому latency SLO и доступному KV-cache. Универсальный лимит для всех моделей и конфигураций здесь не работает.
- Ограничьте максимальную длину входа через настройку контекста.
- Задайте отдельный лимит на число одновременных длинных prefills.
- Контролируйте бюджет batched tokens, чтобы один запрос не занял весь шаг.
- Зарезервируйте часть KV-cache под короткие интерактивные сессии.
- Разделите очередь коротких запросов и тяжёлых batch-задач, если это поддерживает ваш serving-слой.
- Ограничьте concurrency по p95, а не по точке максимального aggregate throughput.
Лимит должен защищать рабочий режим. Слишком жёсткое ограничение снизит загрузку системы, слишком мягкое превратит редкий длинный запрос в причину деградации всех соседних сессий.
Как проверить устойчивость после настройки
Финальный тест должен смешивать несколько типов нагрузки:
- Короткие интерактивные запросы с требованием низкого TTFT.
- Несколько обычных agent-сессий с чередованием prefill и decode.
- Длинные cold prefills с контролируемым числом одновременных запросов.
- Повторяющиеся обращения к таблицам n-грамм после холодного и прогретого старта.
Измеряйте нагрузку до прогрева, после прогрева и после длительного непрерывного прогона. В отчёте должны остаться p95 и p99, ошибки, OOM, KV-cache, RSS, page faults, NVMe I/O, aggregate throughput и признаки смены сетевого транспорта.
Если после нескольких часов работы throughput сохраняется, хвостовые задержки не растут, а память не уходит в постепенное давление page cache, режим можно считать устойчивым для выбранной нагрузки.
Кому подходит такой режим и где он не заменит один быстрый узел
Конфигурация из двух DGX Spark с Qwen3.8-Flash-Next подходит для сценариев, где несколько независимых сессий должны обрабатываться одновременно. 181 tok/s aggregate имеет практический смысл для пакетной генерации, очередей задач, локального RAG и рабочих AI-агентов.
Когда aggregate throughput важнее скорости одного ответа
Суммарная пропускная способность важнее per-request latency, когда система обслуживает несколько независимых задач. Агент может ждать ответ инструмента, пока другой агент генерирует план, а третий обрабатывает документы. В этом случае завершённые задачи за минуту лучше описывают ценность сервинга, чем скорость одного идеального запроса.
Подход подходит для:
- нескольких параллельных agent-сессий;
- массовой генерации ответов и классификаций;
- очередей локальных задач без облачного API;
- RAG-процессов с большим числом независимых документов;
- тестов, где важен общий объём обработанных токенов.
В каждом случае задайте допустимые p95 и p99. Иначе система может формально показывать высокий aggregate throughput, но задерживать отдельные рабочие процессы.
Когда лучше оптимизировать single-stream latency
Для чата с одним пользователем, коротких команд и интерактивной отладки важнее TTFT и равномерный inter-token latency. Двухузловой tensor-parallel запуск добавляет сетевые синхронизации и усложняет контроль RDMA. При низком concurrency эти расходы могут перевесить пользу от большей общей пропускной способности.
В таком сценарии сравнивайте один быстрый узел и 2× DGX Spark по одинаковому промпту, длине ответа, warm/cold режиму и p95. Номинальная скорость генерации без времени первого токена не даёт полной картины.
Итоговый чек-лист перед повторением кейса
- Проверьте точное имя Qwen3.8-Flash-Next, формат чекпойнта и совместимость с версией vLLM.
- Зафиксируйте, как модель распределена между двумя DGX Spark.
- Подтвердите RDMA-путь в логах NCCL и исключите silent TCP fallback.
- Опишите benchmark: concurrency, prompt length, output length, прогрев и правило подсчёта токенов.
- Рассчитайте бюджет KV-cache после размещения весов, runtime-буферов, mmap-областей и памяти ОС.
- Сравните mmap на NVMe с резидентной загрузкой по RSS, page faults, I/O и latency.
- Проверьте эффект
MADV_RANDOMна холодной и прогретой нагрузке. - Ограничьте cold long prefills и повторите тест под целевым concurrency.
- Публикуйте aggregate throughput вместе с per-request throughput, TTFT, p95, p99 и расходом памяти.
181 tok/s aggregate стоит воспринимать как результат конкретного режима, где сходятся параллельные agent-сессии, рабочий NCCL over RDMA, достаточный KV-cache и аккуратно ограниченные длинные prefills. Для одного ответа важнее single-stream latency. Для нескольких локальных AI-систем важнее предсказуемый throughput после прогрева и под нагрузкой.