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

Как собрать и настроить Qwen3.8-Flash-Next NVFP4 на двух Spark под vLLM: конфиг, сетевые нюансы и узкие места

Практическая настройка Qwen3.8-Flash-Next NVFP4 на двух DGX Spark под vLLM: tensor parallelism, eager, MTP, prefill, NCCL/RoCE, flashinfer и Docker.

Коротко

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

  1. 01

    Короткий ответ: что нужно для запуска Qwen3.8-Flash-Next на двух Spark

  2. 02

    Базовая конфигурация: запуск Qwen3.8-Flash-Next NVFP4 через vLLM

  3. 03

    Настройка производительности: prefill, decode, batch и контекст

  4. 04

    Сеть между Spark: как отличить рабочий RoCE от TCP-деградации

Короткий ответ: что нужно для запуска Qwen3.8-Flash-Next на двух Spark

Qwen3.8-Flash-Next NVFP4 запускается на двух DGX Spark через vLLM с tensor parallelism, но результат зависит от режима исполнения, межузловой сети и совместимости стека. Модель распределяется между узлами, поэтому к требованиям к памяти добавляются требования к стабильной и быстрой коммуникации. Ключевые точки контроля: eager-режим, MTP, chunked prefill, лимиты контекста и батча, NCCL/RoCE, flashinfer и sm_121. Приведенные значения throughput относятся к конкретной конфигурации и не являются универсальной нормой.

Что именно настраивается в этой схеме

Разбирается распределенный инференс Qwen3.8-Flash-Next NVFP4 на двух DGX Spark с vLLM и tensor parallelism. Модель распределяется между узлами, поэтому к требованиям к памяти добавляются требования к стабильной и быстрой межузловой коммуникации. Один запуск модели на одном устройстве не покрывает всех сложностей: нужны настройки vLLM, проверка NCCL и совместимость зависимостей.

Главный риск: модель запустилась, но инфраструктура стала узким местом

Процесс инференса может работать, но prefill или decode заметно теряют скорость из-за сетевой деградации, неподходящих лимитов, особенностей eager и несовместимых зависимостей. Факт успешного старта не означает полноценную работоспособность конфигурации.

Базовая конфигурация: запуск Qwen3.8-Flash-Next NVFP4 через vLLM

Конфигурация задается командой или файлом. Путь к модели, tensor parallelism, адреса узлов, порт координации и параметры памяти указываются в шаблоне, значения подставляются под окружение. Ниже пример структуры без точных версий, которые нужно подтверждать по актуальному стеку.

vllm serve /path/to/Qwen3.8-Flash-Next-NVFP4 \
  --tensor-parallel-size 2 \
  --enforce-eager \
  --max-model-len 32768 \
  --max-num-batched-tokens 8192 \
  --max-num-seqs 64 \
  --enable-chunked-prefill \
  --speculative-config '{"method": "mtp", "num_speculative_tokens": 1}' \
  --distributed-executor-backend mp \
  --host 0.0.0.0 --port 8000

Параметры --tensor-parallel-size 2 и --distributed-executor-backend mp отвечают за распределение. На каждом Spark запускается отдельный процесс vLLM, они обмениваются данными через NCCL. Необходимо согласовать запуск на обоих узлах: одинаковая модель, совместимое окружение, доступность портов и синхронный старт процессов.

Распределение модели между двумя узлами

vLLM использует tensor parallelism в распределенной схеме. Параметр --tensor-parallel-size 2 указывает, что модель разделена на две части, каждая на одном Spark. Оба процесса должны видеть одинаковые веса и иметь совместимые версии vLLM, PyTorch и CUDA. Порты для координации должны быть доступны между узлами.

Почему в этой конфигурации нужен eager-режим

Eager-режим может быть необходим из-за совместимости конкретной модели, архитектуры GPU или используемых компонентов vLLM. Влияние на скорость нужно оценивать вместе с остальным стеком, а не сравнивать изолированно по одному параметру. В некоторых случаях eager отключает CUDA graphs, что может снизить производительность, но без него модель может не запуститься или работать нестабильно.

MTP: где он может помочь, а где не отменяет ограничения сети

MTP (Multi-Token Prediction) влияет на генерацию, потенциально ускоряя decode за счет спекулятивного декодирования. На prefill его влияние ограничено. Результат зависит от версии vLLM, модели, нагрузки и поведения конкретной конфигурации. MTP не заменяет корректно настроенную межузловую коммуникацию: при деградации сети до TCP выигрыш от MTP может быть сведен на нет.

Настройка производительности: prefill, decode, batch и контекст

Этапы prompt processing и generation требуют раздельной оценки. Высокие batch и ub могут заметно улучшать prefilling speed на больших промптах, но увеличивают потребление видеопамяти. Лимиты контекста и батча связаны с KV-cache, стабильностью и возможностью обслуживать несколько запросов.

Chunked prefill: полезный механизм с ограниченным эффектом

Chunked prefill разбивает обработку длинного промпта на части и балансирует prefill с обслуживанием генерации. В данной связке его эффект зависит от длины контекста, размера батча, памяти и межузлового обмена. Часть привычных оптимизаций могла не дать выигрыша из-за сетевого ограничения или дефицита памяти.

Как подбирать batch и ub без переполнения памяти

Начните с консервативных лимитов, наблюдайте VRAM и throughput, затем постепенно повышайте batch и ub. Рост нагрузки может улучшать prefill, но расходует дополнительную видеопамять и способен ухудшать стабильность или оставить меньше ресурса для decode. Компромисс: высокие batch и ub дают заметное ускорение на больших промптах, но потребляют дополнительную video memory.

Лимиты контекста и батчей как часть производительности

Слишком большие лимиты могут снижать практическую эффективность даже при успешном старте. Длина контекста, KV-cache, количество одновременных запросов и доступная память связаны. Значения должны соответствовать рабочему профилю, а не теоретическому максимуму модели.

Почему prefill и decode нельзя оценивать одной цифрой

Prefill чувствителен к большим промптам и batch, а decode сильнее зависит от последовательного характера генерации, MTP, KV-cache и коммуникаций. Примерные значения из исходных материалов: около 78-87 t/s на части prefill, около 59-67 t/s ближе к завершению и около 7-10 t/s для generation, обязательно обозначив зависимость от конкретной конфигурации.

Сеть между Spark: как отличить рабочий RoCE от TCP-деградации

Распределенный запуск работает формально, но NCCL использует не тот транспорт и теряет производительность. Проверка: интерфейсы и маршрутизация, запуск с диагностикой NCCL, чтение логов, определение транспорта, проверка повторяемости после перезапуска. Наличие соединения между узлами еще не доказывает работу RoCE.

Что должно быть видно в NCCL_DEBUG

Включите NCCL_DEBUG=INFO и ищите строки, указывающие на выбранный сетевой путь. Признаки использования RDMA/RoCE: упоминание rdma, roce, ib или конкретного HCA. Сообщения о Socket/TCP: socket, tcp, Using network Socket. Не подменяйте диагностику предположением по названию интерфейса или успешному запуску.

Признаки перехода на NCCL Socket

TCP/NCCL Socket может оставлять распределенный запуск работоспособным, но увеличивать задержки и снижать throughput, особенно при обмене между узлами. Падение prefill и decode без утверждения фиксированного масштаба потерь. В логах NCCL_DEBUG появляются строки с socket вместо rdma.

Почему нельзя жестко фиксировать имя HCA

Имя HCA может отличаться между узлами, окружениями, драйверами и контейнерами. Сначала определите фактические имена и доступные устройства в конкретной системе, затем используйте устойчивую схему выбора, не копируя значение из чужой конфигурации. Пример: mlx5_0 на одном узле и mlx5_1 на другом.

Минимальный порядок сетевой диагностики

  1. Проверить связность и интерфейсы: ip a, ibstat или rdma link.
  2. Запустить минимальный тест с NCCL_DEBUG=INFO и NCCL_PROTO=simple.
  3. Убедиться в выборе RoCE по логам.
  4. Повторить запуск vLLM и сравнить логи и throughput.
  5. Отдельно фиксировать, на каком узле и в каком окружении наблюдается расхождение.

Зависимости и среда запуска: flashinfer, sm_121, native и Docker

Требования к версиям и патчам: архитектура sm_121 и используемые CUDA-компоненты могут требовать отдельного патча. Native-окружение и Docker сравниваются по контролю зависимостей, доступу к GPU и сетевым устройствам.

Требуемая версия flashinfer

Для этой конфигурации важна определенная версия flashinfer, но точное значение должно быть взято из проверенного источника или рабочего окружения, а не воспроизведено без подтверждения. Сверка с версиями vLLM, PyTorch, CUDA и драйвера обязательна.

Патч для sm_121

sm_121 - отдельное ограничение совместимости. Наличие NVFP4-модели не гарантирует готовность всех ядер и зависимостей к этой архитектуре. Патч и его применимость нужно проверять до запуска.

Native-окружение против Docker

Native дает прямой доступ к CUDA, NCCL, RDMA/RoCE и HCA, но требует ручной установки и согласования версий. Docker упрощает воспроизводимость пакетов, но контейнер может скрыть или ограничить сетевые устройства, даже если модель и GPU внутри контейнера видны. Для доступа к HCA в Docker нужны --device=/dev/infiniband и соответствующие capabilities.

Чек-лист совместимости перед запуском

  • Модель и формат NVFP4
  • vLLM, PyTorch/CUDA
  • flashinfer
  • Патч sm_121
  • Драйверы
  • NCCL
  • Доступность устройств на обоих Spark
  • Совпадение окружений

Где возникают потери: разбор узких мест и неудачных оптимизаций

Причины делятся на вычислительные, сетевые, memory-bound и связанные с планированием запросов. Симптомы: низкий prefill, нестабильный decode, рост VRAM, просадка при увеличении batch, Socket в логах NCCL. Qwen3.8-Flash-Next может иметь существенно более низкий prefill, чем Qwen3.8-27b-IQ4_XS на похожем железе, поэтому сравнение моделей без учета архитектуры и формата некорректно.

Когда проблема в вычислениях, а когда в коммуникациях

Сопоставьте наблюдения из логов NCCL, загрузку устройств, поведение throughput и влияние длины промпта. Распределенный tensor parallelism добавляет коммуникации, поэтому слабое место сети может проявляться даже при свободной памяти.

Почему сравнение с другой моделью может вводить в заблуждение

В исходном сравнении для Qwen3.8-27b-IQ4_XS упоминался prefill около 1000 t/s, а для Qwen3.8-Flash-Next-IQ4_XS около 50 t/s на похожем железе. Это данные конкретного обсуждения, а различия могут быть связаны с архитектурой, реализацией и режимом запуска.

Какие оптимизации не стоит включать вслепую

Chunked prefill, большие batch/ub или изменение режима исполнения могут не дать выигрыша при сетевом ограничении, дефиците памяти или неподходящем профиле нагрузки. Каждый параметр оценивайте по изменению prefill, decode, VRAM и стабильности.

Пошаговый план проверки после запуска

Порядок валидации: сначала запуск без агрессивных лимитов, затем проверка распределения процессов и NCCL, после этого тест короткого и длинного промпта, затем изменение batch, ub и контекста по одному параметру. Результаты фиксируйте отдельно для prefill и decode.

Проверка корректности распределенного запуска

Проверьте видимость GPU, процессы vLLM на обоих узлах, выбранный tensor parallelism и отсутствие ошибок синхронизации. Убедитесь, что модель и зависимости совпадают.

Проверка транспорта NCCL

Сохраните логи с NCCL_DEBUG, найдите признаки RoCE или NCCL Socket и проверьте, что выбранный транспорт одинаково ожидаем на обоих узлах. Имя HCA не считайте доказательством корректной настройки.

Измерение prefill и decode на разных профилях нагрузки

Сравните короткие и длинные промпты, разные batch и ub, а также рабочие лимиты контекста. Записывайте prompt processing, generation throughput, расход VRAM и признаки деградации сети. Числовые результаты подавайте как показатели конкретного стенда.

Итоги: какой конфиг считать рабочим

Четыре уровня: модель запускается, оба Spark участвуют в tensor parallelism, NCCL использует ожидаемый транспорт, а параметры batch/ub/контекста дают приемлемый баланс prefill, decode и VRAM. Точные версии flashinfer и патча sm_121 нужно подтверждать по актуальному совместимому стеку, а throughput нельзя переносить на другие конфигурации без повторной проверки.

Краткий чек-лист перед эксплуатацией

  • Совместимость стека
  • Native или Docker-окружение
  • Eager
  • MTP
  • Chunked prefill
  • Лимиты контекста и батча
  • Состояние VRAM
  • Участие обоих узлов
  • Транспорт NCCL/RoCE

Что менять в первую очередь при низком throughput

  1. Проверить NCCL_DEBUG и отсутствие перехода на Socket
  2. Проверить совместимость flashinfer и sm_121
  3. Подобрать batch/ub и лимиты контекста под реальную нагрузку
  4. Изменять параметры по одному и сравнивать отдельно prefill и decode

Полезные материалы по теме: оптимизация памяти при serving DeepSeek-V4-Flash на 2× DGX Spark, запуск DeepSeek-V4-Flash на B300, сравнение моделей на DGX Spark.

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