Сервис развивается: тестируем формат, собираем идеи, улучшаем сервис. Есть идеи?

Написать
Войти
Дайджесты
Высокопроизводительный кластер GPU для инференса Qwen 3.5

1 Million Tokens Per Second: масштабирование Qwen 3.5 27B на GKE с GPU B200

Детальный разбор технического эксперимента по масштабированию инференса dense-модели Qwen 3.5 27B на кластере GKE с 96 графическими процессорами NVIDIA Blackwell B200. Описание преодоления архитектурных барьеров, перехода к параллелизму данных (DP=8), оптимизации KV-кэша, внедрения формата FP8 и технологии MTP-1.

1 Million Tokens Per Second: масштабирование Qwen 3.5 27B на GKE с GPU B200

Скорость обработки запросов — определяющий фактор для систем LLM. При развертывании больших моделей инженеры ищут компромисс между задержкой первого токена (TTFT) и пропускной способностью (throughput). В эксперименте Google Cloud от 26 марта 2026 года исследовалось масштабирование dense-модели Qwen 3.5 27B на GKE (Google Kubernetes Engine) с GPU NVIDIA Blackwell B200. В итоге удалось достичь 1 103 941 токена в секунду на 12 нодах (96 GPU B200).

Qwen 3.5 27B — dense-модель: все 27 млрд параметров активны на каждом шаге. Это сложнее, чем для MoE, но даёт предсказуемое поведение. Архитектура Efficient Hybrid включает 64 слоя, сочетающих Gated Delta Networks (GDN) и Grouped-Query Attention (GQA). Тест проводился на инстансах A4 с 8 картами Blackwell B200 SXM (180 ГБ HBM3e памяти, 8 ТБ/с, FP8 мощность 9 PFLOPS). При декодировании пропускная способность памяти критична, так как веса и KV-кэш считываются из HBM на каждом токене.

Почему тензорный параллелизм оказался тупиком для небольших моделей

Первая гипотеза с использованием тензорного параллелизма (Tensor Parallelism, TP=8) на 8 чипах одной ноды оказалась неэффективной. Qwen 3.5 27B слишком мала для совместной работы на восьми B200. Вычислительная часть выполнялась мгновенно, после чего видеокарты простаивали в ожидании синхронизации весов по NVLink через NCCL (команда all-reduce). Время сетевого взаимодействия превышало время вычислений. Лучшая пропускная способность в режиме TP=8 со спекулятивным декодированием MTP-1 составила лишь 22 300 токенов в секунду.

Конфигурационный нюанс vLLM: для гибридной архитектуры Qwen 3.5 критически важно передавать параметры --mamba-cache-mode=align и --mamba-block-size=8. Без них движок неэффективно пересчитывает префикс запроса (prefill), снижая скорость генерации на порядок.

Переход к параллелизму данных и проблема распределения KV-кэша

Инженеры перешли на параллелизм данных (Data Parallelism, DP=8) на уровне ноды. На каждой из 8 видеокарт запускается независимая копия модели. Каждая GPU обслуживает свой поток запросов без межпроцессорного взаимодействия. Локальная скорость выросла до 74 848 токенов/сек, но утилизация ядер упала до 0%, а в логах vLLM появились сообщения о переполнении памяти под KV-кэш (GPU KV cache usage 99.4%).

Причина — дефолтный лимит контекста (max-model-len=131072). Движок резервировал огромные статические блоки памяти в HBM под каждый запрос при реальной длине около 1500 токенов. Ограничение max-model-len до 4096 токенов подняло скорость до 85 509 токенов/сек. Однако при агрессивной настройке (gpu-memory-utilization=0.95) возникали ошибки OOM из-за наложения весов модели, кэша CUDA-графов и черновой модели. Эффективным sweet spot стал показатель 0.92.

Катализаторы производительности: vLLM, FP8 KV-cache и многократный спекулятивный декодинг

Для рекордных скоростей потребовалось объединить новые функции оптимизации в vLLM v0.18.0. Ключевым решением стал переход на квантование KV-кэша в формат FP8 с помощью аргумента --kv-cache-dtype=fp8_e4m3. Это снизило потребление памяти в два раза и увеличило размер пула кэша до 959 тысяч токенов на один движок.

Вторым ускорителем стало спекулятивное декодирование с технологией Multi-Token Prediction (MTP-1). Меньшая, быстрая модель-черновик делает предположение о следующем токеноме, а основная модель проверяет его за один шаг. Поскольку точность предположений (acceptance rate) составила около 90%, каждый шаг декодирования приносил в среднем 1.9 токена вместо 1, загрузив ядра полезной работой. Результаты тестов локальной ноды показывают эффект настроек:

Конфигурация инференсаВыделение памяти (GPU Mem)Пропускная способность (tok/s)Утилизация ядер GPU (%)
MTP-1 (Speculative 1)0.9296 02384% — 90%
MTP-2 (Speculative 2)0.9590 56778% — 82%
Без спекулятивного режима0.9566 0210%

Использование MTP-5 сначала показало прирост скорости на 21%, но затем привело к ошибке cudaErrorIllegalAddress из-за нестабильности драйверов при работе с памятью Blackwell. Точность предсказания на пятом токене резко падала до 41.2%.

Масштабирование до 12 нод и преодоление клиентских узких мест

При масштабировании производительность упёрлась в мощность бенчмарк-клиента. Скрипт vllm bench serve при 16 тысячах соединений полностью загружал процессорное ядро на 99% и не успевал генерировать запросы. Нагрузку распределили между несколькими клиентами (по 1000 запросов на ноду C4 с 16 vCPU).

После этого масштабирование кластера стало практически линейным (эффективность 96.5%):

  • 1 нода (8x B200): 95 317 токенов/сек
  • 2 ноды (16x B200): 190 000 токенов/сек
  • 4 ноды (32x B200): 376 074 токенов/сек
  • 8 нод (64x B200): 740 192 токенов/сек
  • 12 нод (96x B200): 1 103 941 токенов/сек

При равномерной нагрузке балансировка на уровне Kubernetes (ClusterIP Round-Robin) показала себя эффективнее GKE Inference Gateway. Использование Gateway привело к падению пропускной способности на 31% для 2 нод и на 37% для 8 нод. Это связано с тем, что в Inference Gateway каждый запрос и каждый отправляемый токен проходят через прокси-контейнер Ext Proc gRPC Stream. В сценарии с нулевым попаданием в кэш префиксов (0% prefix cache hit rate) интеллектуальная маршрутизация по кэшу не давала преимуществ, а задержка на проксирование оставалась высокой.

Экономика локального хостинга и сравнительный анализ стоимости

Эксперимент позволил рассчитать стоимость инференса при самостоятельном хостинге на GKE в сравнении с популярными проприетарными API. Расчеты производились для сценария с соотношением входящих и исходящих токенов 2:1 при высокой утилизации оборудования:

  • Self-hosted GKE (Qwen 3.5 27B FP8): ~$0.30 за 1 миллион токенов
  • Gemini 3.1 Flash-Lite (API): $0.67 за 1 миллион токенов
  • Gemini 3.1 Pro (API): $5.33 за 1 миллион токенов
  • Claude 4.6 Sonnet (API): $7.00 за 1 миллион токенов
  • Claude 4.6 Opus (API): $11.67 за 1 миллион токенов

Собственный кластер Blackwell B200 оказывается более чем в два раза дешевле коммерческой модели Flash-Lite и почти в 20 раз выгоднее API-моделей уровня Pro при постоянной высокой загрузке кластера (RAG-системы, массовая разметка документов). Для систем с нерегулярным трафиком коммерческие API остаются более гибким решением.

Практическое руководство по развертыванию

Развертывание инференс-сервера Qwen 3.5 27B на кластере GKE выполняется по следующей схеме с использованием CLI gcloud и kubectl.

Шаг 1. Настройка окружения и секрета
export PROJECT_ID="my-gcp-project-id"
export HF_TOKEN="hf_your_read_only_token_here"
gcloud container clusters create-auto vllm-inference-cluster --project="${PROJECT_ID}" --region=europe-west4 --release-channel=rapid
gcloud container clusters get-credentials vllm-inference-cluster --project="${PROJECT_ID}" --region=europe-west4
kubectl create secret generic hf-token --from-literal=token="${HF_TOKEN}"
Шаг 2. Деплой инференс-сервиса vLLM

Создайте YAML-манифест qwen35-inference.yaml и примените его:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: qwen-35-inference
spec:
  replicas: 1
  selector:
    matchLabels:
      app: qwen-35-inference
  template:
    metadata:
      labels:
        app: qwen-35-inference
    spec:
      containers:
      - name: vllm-server
        image: vllm/vllm-openai:v0.18.0
        command: ["python3", "-m", "vllm.entrypoints.openai.api_server"]
        args:
        - --model=Qwen/Qwen3.5-27B-FP8
        - --data-parallel-size=8
        - --max-model-len=2560
        - --kv-cache-dtype=fp8_e4m3
        - --gpu-memory-utilization=0.92
        resources:
          limits:
            nvidia.com/gpu: "8"
kubectl apply -f qwen35-inference.yaml
Шаг 3. Верификация запуска и ограничения

Запуск подов и компиляция CUDA-графов занимает около 15 минут. Проверьте запуск и сделайте тестовый запрос:

kubectl get pods -l app=qwen-35-inference
kubectl logs -f deployment/qwen-35-inference
# Тест API изнутри кластера:
kubectl run curl-test --image=curlimages/curl -i --tty --rm -- \
  curl http://qwen-35-inference:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{"model": "Qwen/Qwen3.5-27B-FP8", "messages": [{"role": "user", "content": "Hello"}], "max_tokens": 10}'
  • Значение max-model-len=2560 оптимизировано для бенчмарков. Для реальных диалоговых систем с длинным контекстом его необходимо увеличить (например, до 32K).
  • Spot-виртуальные машины использовались для снижения стоимости эксперимента, но они могут быть принудительно отключены. Для критического продакшна необходимо использовать стабильные инстансы.
  • Убедитесь, что вы используете стабильную версию vLLM старше v0.18.0, так как в начальных сборках этой версии присутствовал баг с точностью FP8 KV-кэша.