Вы когда-нибудь видели, как ваш GPU внезапно нагревается до 95°C, а время ответа сервиса прыгает от 200 мс до 10 секунд? В этот момент вы понимаете: что-то пошло не так. Чаще всего проблема не в модели, а в том, как вы её крутите. Смешиваете инференс с батчингом, препроцессингом и бизнес-логикой в одном процессе — и получаете ад. Выход — изолированный inference bundle. Разберём, как это работает на практике.
Типичная ошибка: Один процесс на GPU, очередь запросов, общий Python GIL и никакого continuous batching. GPU простаивает 50% времени, потом резко перегружается — latency скачет, температура ползёт вверх.
Почему классический подход ломает GPU
Представьте: вы запускаете LLM-сервис на одном GPU, например NVIDIA A100 или даже новом Blackwell B200 на AWS G7e. Входящие запросы обрабатываются последовательно: один запрос — один forward pass. GPU загружен только на 30-40%, но при росте RPS очередь растёт, batch latency взлетает, а GPU начинает греться, потому что драйвер пытается утилизировать ресурсы, а вы ему не даёте. Вдобавок вы держите в памяти несколько моделей или копируете данные туда-сюда между CPU и GPU. Результат — просадки TTFT (time to first token) и перегрев памяти HBM.
Решение — отделить инференс от всего остального. Выделить специальный bundle (процесс/контейнер), который занимается только forward pass, использует continuous batching, управляет KV cache и держит модель «горячей». Всё остальное — препроцессинг, аутентификация, бизнес-логика — живёт в отдельных сервисах. Так GPU не простаивает и не перегревается, а latency становится предсказуемым.
Что такое inference bundle и из чего он состоит
Inference bundle — это минимальный изолированный компонент, который принимает подготовленные запросы, выполняет один forward pass модели (или несколько в батче) и возвращает результат. Ключевые части:
- Движок инференса — vLLM, SGLang, TensorRT-LLM, либо кастомный.
- Планировщик батчей — реализует continuous batching (динамическое добавление запросов в батч по мере завершения генерации).
- Управление памятью GPU — pre-allocated KV cache pools, paged attention, prefix caching.
- Транспорт — gRPC, HTTP, Redis Streams — для приёма запросов и отправки ответов.
- Мониторинг — метрики: GPU utilisation, temperature, memory usage, batch occupancy, TTFT, TPOT, wait time.
Всё это упаковано в отдельный контейнер (или процесс) и привязано к одному GPU (или MIG-партиции). Больше никаких «а давайте здесь же поднимем веб-сервер и БД». Нет.
Выбор движка: vLLM vs SGLang (и при чём здесь Groq 3)
На май 2026 года два мейнстримных движка — vLLM (последняя стабильная 0.8.3) и SGLang (0.6.2). Оба поддерживают continuous batching, paged attention, prefix caching, но есть нюансы.
| Характеристика | vLLM | SGLang |
|---|---|---|
| Continuous batching | Зрелое, настраиваемое (max_num_seqs, max_model_len) | Более агрессивное, но требует точной настройки schedule |
| Prefix caching | Автоматическое (block-level) | Только для exact match, но есть radix attention |
| Управление KV cache | PagedAttention + swap to CPU | Собственный allocator (более эффективен при высоком occupancy) |
| Поддержка Tensor Parallel | Да, через NCCL | Да, но с ограничениями |
| Экосистема | OpenAI-совместимый API, широкая интеграция | Свой язык (SGLang), гибкий pipeline, но сложнее интеграция |
Если у вас high-load с большим разнообразием запросов (разные системные промпты, разная длина контекста) — выбирайте vLLM. Если ваши промпты строго структурированы (например, код-генерация с фиксированным префиксом), SGLang может дать +20% throughput за счёт radix prefix caching. А если вам нужна максимальная производительность и вы готовы пожертвовать гибкостью — смотрите в сторону специализированных чипов вроде Groq 3, где инференс-баундл уже реализован на уровне архитектуры.
Пошаговый план: как построить изолированный inference bundle
1 Выберите движок и разверните базовый сервис
Возьмём vLLM. Установите последнюю версию, примонтируйте модель (например, Llama-4-70B или DeepSeek-V3). Запустите с параметрами, которые гарантируют стабильный utilisation GPU без простоя:
docker run --gpus all --shm-size 32g \
-v /models:/models \
-p 8000:8000 \
vllm/vllm-openai:latest \
--model /models/Llama-4-70B \
--tensor-parallel-size 1 \
--max-model-len 8192 \
--gpu-memory-utilization 0.95 \
--max-num-seqs 512 \
--enable-prefix-caching \
--use-v2-block-manager
Флаг --gpu-memory-utilization 0.95 резервирует 95% памяти GPU под KV cache, оставляя 5% на оверхеды. --max-num-seqs 512 задаёт максимальный размер батча. Если запросов приходит больше — они становятся в очередь внутри движка (встроенный бэкпрессур).
2 Изолируйте от остальной системы
Запустите сервис в отдельном контейнере, привязанном к конкретному GPU (через NVIDIA_VISIBLE_DEVICES). Если используете Kubernetes — используйте resources.limits.nvidia.com/gpu: 1 и добавьте time-sharing только если GPU поддерживает MIG. Лучше один GPU на один баундл.
apiVersion: v1
kind: Pod
metadata:
name: inference-bundle-llama4
spec:
containers:
- name: vllm
image: vllm/vllm-openai:latest
args: ["--model", "/models/Llama-4-70B", "--max-num-seqs", "256"]
resources:
limits:
nvidia.com/gpu: 1
env:
- name: NVIDIA_VISIBLE_DEVICES
value: "0"
volumeMounts:
- name: models
mountPath: /models
volumes:
- name: models
persistentVolumeClaim:
claimName: model-store
Ошибка: Запуск нескольких моделей на одном GPU без MIG. Если модель не влезает целиком, начнутся out-of-memory и перегрев. Всегда проверяйте nvidia-smi на предмет свободной памяти.
3 Настройте continuous batching и backpressure
Continuous batching — это когда движок добавляет новые запросы в текущий батч по мере завершения старых. В vLLM за это отвечают параметры --max-num-seqs и --scheduling-policy (по умолчанию fcfs). Чтобы избежать перегрева, ограничьте количество параллельно генерируемых токенов: выставьте --max-parallel-requests на уровне reverse proxy (например, Envoy).
Также используйте Request-Aware Scheduling: если в батче есть длинные запросы, они не должны блокировать короткие. vLLM и SGLang умеют переупорядочивать запросы. Включаем:
--scheduling-policy priority \
--priority-keys user_id
Но помните: continuous batching увеличивает utilisation GPU, но при near-100% utilisation растёт и температура. Необходим мониторинг.
4 Связывайте с основным сервисом через лёгкий транспорт
Не используйте HTTP с большими телами внутри одного пода. gRPC streaming — идеально: потоковый запрос (промпт), потоковый ответ (токены). Это снижает накладные расходы на сериализацию. Пример сервера на Python:
import grpc
from vllm import AsyncLLMEngine, SamplingParams
class InferenceService(...):
async def Generate(self, request, context):
params = SamplingParams(
temperature=request.temperature,
max_tokens=request.max_tokens
)
async for output in engine.generate(request.prompt, params):
yield output
Если gRPC сложно — используйте Redis Streams: основной сервис пишет запрос в stream, inference bundle читает и пишет ответ в другой stream. Так баундл остаётся полностью изолированным и легко масштабируется.
5 Мониторинг температуры и троттлинг
GPU перегревается не только из-за высокой нагрузки, но из-за неравномерного распределения памяти. Отслеживайте:
- GPU temperature (nvidia-smi) — если >85°C, снижайте max_num_seqs.
- Memory temperature (HBM) — часто упускают, но именно перегрев HBM вызывает троттлинг.
- GPU utilisation — плавная кривая без резких пиков — признак здорового continuous batching.
- KV cache utilisation — если >95% и есть evictions, latency вырастет.
Реализуйте адаптивный троттлинг: если температура превышает порог, сервис автоматически уменьшает max_num_seqs или отклоняет новые запросы с HTTP 429. Пример на Prometheus + custom exporter:
if gpu_temp > 85:
engine.max_num_seqs = max(1, engine.max_num_seqs - 10)
time.sleep(5)
Нюансы и типовые ошибки
Вот что чаще всего идёт не так, когда инженеры впервые внедряют изолированный баундл:
- Забывают про prefix caching. Если 80% запросов имеют одинаковый системный промпт, а caching выключен — GPU пересчитывает attention для одних и тех же токенов, latency растёт. В vLLM включите
--enable-prefix-caching, в SGLang — radix attention. - Не настраивают backpressure на уровне клиента. Когда inference bundle начинает отдавать 429, клиент должен правильно повторять запросы с экспоненциальной задержкой. Иначе очередь растёт и GPU греется впустую.
- Пытаются вместить несколько моделей на один GPU без MIG/Time-slicing. Лучше выделить каждому баундлу свой GPU. Если GPU дорогие — используйте MIG (на A100/H100) или виртуализацию Nvidia vGPU (новые Blackwell).
- Игнорируют temperature headroom. Даже если utilisation 70%, температура может быть 90°C из-за плохого охлаждения в датацентре. Мониторьте!
- Не тестируют под пиковой нагрузкой. Continuous batching прекрасен, пока RPS не превышает пропускную способность. Если это случилось — latency улетает в космос. Заранее настройте circuit breaker.
Ещё совет: не пытайтесь оптимизировать то, что не нужно. Часто latency растёт не из-за GPU, а из-за медленного препроцессинга на CPU. Отделите его в отдельный микросервис. Про архитектуру на Kubernetes с KServe можно почитать в материале Архитектура платформы Nova AI.
А что насчёт будущего? (Спойлер: GPU станут горячее)
С выходом Blackwell TDP вырос до 700 Вт, а у следующего поколения Vera Rubin обещает до 1 кВт. Теплоотвод станет главной проблемой. Уже сейчас датацентры внедряют RF-over-Fiber для связи стоек, а охлаждение переходит на direct-to-chip жидкостное. Но ваша задача как DevOps — сделать так, чтобы софт не создавал лишних тепловых пиков. Изолированный inference bundle — первый шаг.
Если вам кажется, что всё это слишком сложно, вспомните: некоторые компании умудряются делать AI-инференс в 10 раз дешевле, просто за счёт грамотной изоляции и continuous batching. Не обязательно покупать Groq 3 — можно взять обычный GPU, но спроектировать архитектуру правильно.
Last but not least: если вы всё ещё сомневаетесь, стоит ли заморачиваться с отдельным баундлом — попробуйте запустить нагрузочный тест. Сначала без изоляции, потом с ней. Разница в latency и температуре вас удивит. А если нет — значит, у вас идеальный датацентр. Тогда просто сохраните статью — пригодится.