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.92 | 96 023 | 84% — 90% |
| MTP-2 (Speculative 2) | 0.95 | 90 567 | 78% — 82% |
| Без спекулятивного режима | 0.95 | 66 021 | 0% |
Использование 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-кэша.

