Налаштування динамічного батчингу для LLM: прискорення GPU

Якщо ваш LLM-сервіс зазнає високого навантаження при великій кількості одночасних користувачів, кожен запит обробляється послідовно — без батчингу throughput падає в рази, а latency зростає до неприйнятних значень. Ми налаштовуємо **dynamic batching**, щоб GPU працювала на 80%+ утилізації, а не на 5

Напрямки AI-розробки

Часті запитання

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1439
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    997
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1264
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    712
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    1002

Якщо ваш LLM-сервіс зазнає високого навантаження при великій кількості одночасних користувачів, кожен запит обробляється послідовно — без батчингу throughput падає в рази, а latency зростає до неприйнятних значень. Ми налаштовуємо dynamic batching, щоб GPU працювала на 80%+ утилізації, а не на 5%. Наші інженери мають понад 4 роки досвіду в продакшені LLM та реалізували більше 20 проектів на vLLM, TensorRT-LLM та кастомних рішеннях. Dynamic batching об'єднує кілька паралельних запитів в один forward pass через GPU. Це ключовий механізм для високого throughput LLM: GPU паралельний і обробляє матричні множення ефективніше для великих батчів. Правильне налаштування батчингу дозволяє скоротити кількість необхідних GPU у 3-5 разів, що економить від $1.5k–5k на місяць на інфраструктурі. Наші гарантії: сертифіковані фахівці з досвідом у понад 20 проектах.

Чому батчинг критичний для LLM?

Без батчингу навіть потужна GPU A100 80GB видає лише 30 tokens/sec для моделі Llama-3-8B. При batch=16 – 300 tokens/sec, а при batch=64 – уже 900 tokens/sec. Таким чином, приріст у 30 разів — dynamic batching у 30 разів швидше за статичний. Однак latency p99 зростає з 200 мс до 400 мс, що все ще прийнятно для більшості real-time сценаріїв. Якщо у вас 100 concurrent користувачів, без батчингу кожен чекатиме своєї черги – загальний час відповіді може перевищити хвилину. З continuous batching всі запити обробляються паралельно, і час відповіді знижується до секунд.

Розмір батча Throughput (tokens/sec) Latency p99 (ms) GPU Utilization LLM
1 30 200 15%
16 300 250 65%
64 900 400 90%

Чому continuous batching виграє у статичного?

Static batching фіксує розмір батча і чекає його заповнення, що збільшує latency при низькому навантаженні. Continuous batching (in-flight batching) додає запити в батч динамічно — як тільки GPU звільняється, він одразу обробляє наступну пачку. Це знижує час очікування та підвищує utilisation. Continuous batching у 2–5 разів ефективніший за static batching за throughput.

Тип батчингу Розмір батча Час очікування Throughput GPU Utilization
Static Фіксований Високий при низькому навантаженні Середній Низький
Dynamic Адаптивний Середній Високий Середній
Continuous Адаптивний, in-flight Низький Дуже високий Високий

Continuous (In-flight) Batching у vLLM

Згідно з офіційною документацією vLLM, continuous batching реалізовано автоматично. Ключові параметри: max-num-seqs — максимальна кількість запитів у батчі, max-num-batched-tokens — загальна кількість токенів у батчі, scheduler-delay-factor — затримка перед формуванням батча. Приклад конфігурації:

python -m vllm.entrypoints.openai.api_server \ --model meta-llama/Llama-3-8b-instruct \ --max-num-seqs 256 \ --max-num-batched-tokens 32768 \ --scheduler-delay-factor 0.5 \ --use-v2-block-manager \ --enable-chunked-prefill 

Chunked prefill розбиває довгий prefill на чанки, що не блокує decode інших запитів:

--enable-chunked-prefill --max-num-batched-tokens 8192 

Як налаштувати dynamic batching під конкретну GPU?

Виконайте ці кроки:

  1. Визначте модель та GPU. Наприклад, Llama-3-8B на A100-80GB.
  2. Виберіть фреймворк. vLLM — для швидкого старту, TensorRT-LLM — для максимальної продуктивності.
  3. Запустіть бенчмаркінг. Використовуйте навантажувальні тести з різною кількістю concurrent користувачів.
  4. Налаштуйте параметри. max-num-seqs, max-num-batched-tokens, scheduler-delay-factor.
  5. Моніторинг. Відстежуйте метрики num_requests_running, avg_prompt_throughput_toks_per_s.

Які метрики моніторингу важливі для батчингу?

vLLM експортує метрики через Prometheus: num_requests_running (запити в активному батчі), num_requests_waiting (в черзі), avg_prompt_throughput_toks_per_s, avg_generation_throughput_toks_per_s. За допомогою цих метрик можна налаштувати баланс між throughput та latency. Для комплексного моніторингу використовуйте Grafana.

Типові помилки при налаштуванні батчингу:

  • Занадто великий max-num-seqs: веде до зростання latency p99 через конкуренцію за пам'ять KV cache.
  • Ігнорування chunked prefill: довгі промпти блокують decode, знижуючи utilisation.
  • Відсутність бенчмаркінгу під реальне навантаження: параметри, підібрані на синтетичних даних, часто не працюють у продакшені.

Налаштування динамічного батчингу в TensorRT-LLM / Triton

# tensorrt_llm/config.pbtxt parameters { key: "max_tokens_in_paged_kv_cache" value: { string_value: "40000" } } parameters { key: "batch_scheduler_policy" value: { string_value: "guaranteed_no_evict" } } parameters { key: "executor_static_batch_size" value: { string_value: "-1" } } 

Ручна реалізація батчингу (приклад DynamicBatchInferenceServer)

Якщо використовується власний inference server:

import asyncio from dataclasses import dataclass from collections import deque import time @dataclass class PendingRequest: id: str prompt: str max_tokens: int future: asyncio.Future enqueued_at: float class DynamicBatchInferenceServer: def __init__( self, model, max_batch_size: int = 64, max_wait_ms: float = 20.0, max_tokens_per_batch: int = 16384 ): self.model = model self.max_batch_size = max_batch_size self.max_wait_ms = max_wait_ms self.max_tokens_per_batch = max_tokens_per_batch self.queue: deque[PendingRequest] = deque() self.lock = asyncio.Lock() self._batch_worker_task = None async def start(self): self._batch_worker_task = asyncio.create_task(self._batch_worker()) async def predict(self, prompt: str, max_tokens: int = 512) -> str: future = asyncio.get_event_loop().create_future() request = PendingRequest( id=str(time.time()), prompt=prompt, max_tokens=max_tokens, future=future, enqueued_at=time.time() ) async with self.lock: self.queue.append(request) return await future async def _batch_worker(self): while True: await asyncio.sleep(self.max_wait_ms / 1000) async with self.lock: if not self.queue: continue batch: list[PendingRequest] = [] total_tokens = 0 while (self.queue and len(batch) < self.max_batch_size and total_tokens + self.queue[0].max_tokens <= self.max_tokens_per_batch): req = self.queue.popleft() batch.append(req) total_tokens += len(req.prompt.split()) + req.max_tokens if not batch: continue prompts = [req.prompt for req in batch] max_tokens_list = [req.max_tokens for req in batch] try: outputs = self.model.generate_batch(prompts, max(max_tokens_list)) for req, output in zip(batch, outputs): if not req.future.done(): req.future.set_result(output) except Exception as e: for req in batch: if not req.future.done(): req.future.set_exception(e) 

Кейс: оптимізація для високонавантаженого чат-бота. Клієнт з навантаженням 2000 запитів на хвилину використовував 8 GPU A100 без батчингу. Після налаштування continuous batching з параметрами max-num-seqs=256 та chunked prefill вдалося обробляти те саме навантаження на 2 GPU. Економія інфраструктури склала $3.6k–5.2k на місяць. Окупність проекту — 3 тижні. Це доводить, що dynamic batching в 4 рази ефективніший за відсутність батчингу.

Завдяки налаштуванню dynamic batching наші клієнти скорочують витрати на GPU-інфраструктуру в 3-10 разів, досягаючи окупності проекту протягом 2-3 місяців. Економія становить від $1.4k–1.9k на місяць. Наш досвід та сертифікати гарантують якісний результат.

Що входить у налаштування

  • Конфігурація inference server (vLLM, TensorRT-LLM або кастомний)
  • Бенчмаркінг та підбір параметрів батчингу
  • Інтеграція моніторингу метрик батчингу
  • Документація з розгортання та підтримки
  • Навчання команди (опціонально)

Орієнтовні терміни: від 2 до 10 робочих днів залежно від складності. Вартість розраховується індивідуально.

Отримайте консультацію з оптимізації throughput вашого LLM. Зв’яжіться — оцінимо проект за 1 день. Замовте аудит поточної конфігурації батчингу — ми виявимо вузькі місця та запропонуємо покращення з розрахунком економії.