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

Запити надходять нерівномірно: частина прискорювачів простоює, а черга до моделі зростає. Ми налаштовуємо динамічний батчинг під ключ — збирання пакетів на льоту скорочує час відгуку й підвищує пропускну здатність на тому самому парку. Обговоримо завдання та повернемося з оцінкою і планом.
Часті запитання

Динамічний батчинг LLM: чому прискорювачі простоюють

Прискорювач, що обслуговує один запит за раз, майже завжди працює в півсили. Поки мовна модель генерує відповідь токен за токеном, на кожному кроці виконуються невеликі операції над однією послідовністю, а пам'ять зайнята вагами. Обчислювальні блоки простоюють — і це не рідкісний збій, а штатний режим обробки запитів по одному.

У профілі реального навантаження картина видна одразу: запити надходять нерівномірно, з піками та паузами. Обробка по одному перетворює такий розподіл на пилкоподібну криву — короткий сплеск навантаження, потім провал і очікування наступного запиту.

Черга зростає, 95-й процентиль часу відповіді йде вгору, а пропускна здатність залишається низькою: прискорювач простоює саме тоді, коли міг би обробляти роботу пакетом.

Динамічний батчинг LLM закриває цю прогалину: запити, що надійшли за коротке вікно, об'єднуються в один пакет. Ключова відмінність від статичної схеми — склад перезбирається на кожному кроці генерації: завершені послідовності залишають пакет, нові займають їхнє місце. Він залишається заповненим, і обробка не чекає на найповільніший запит у наборі.

Налаштування не зводиться до одного параметра: під конкретний профіль навантаження підбираються розмір вікна очікування, верхня межа пакета та правила черги при переповненні.

Від них залежить компроміс між часом відповіді та кількістю оброблених запитів за одиницю часу — нижче розбираємо, як ці значення підбираються за метриками вашого сервісу.

Що змінюється після налаштування: швидкість відгуку та завантаження прискорювачів

Поки запити надходять у прискорювач по одному, він простоює між прогонами: обчислення займають частки часу, решта йде на очікування наступного виклику.

Динамічний батчинг збирає запити, що надійшли за коротке вікно, в один прогін — Triton Inference Server і споріднені середовища роблять це на рівні планувальника, а не коду моделі.

Пропускна здатність на тому самому парку зростає кратно: вузьке місце зміщується з прискорювача на мережу та підготовку даних.

Другий наслідок — затримка відгуку перестає залежати від напливу користувачів. Поки вікно очікування та верхня межа батчу задані явно, одиночний запит не чекає «поки набереться компанія», а піковий потік не вишиковується в зростаючу чергу.

Знімаємо медіану та 95-й перцентиль до і після: зазвичай виграє не середній, а найгірший випадок — саме тому інтерфейс перестає підвисати на піках.

Третій ефект — зникає цілий клас відмов через перевантаження. Раніше під час сплеску запити накопичувалися у вхідній черзі, частина падала за таймаутом, і сервіс вимагав ручного розбору інциденту.

Тепер батч сам добирає роботу з черги, а при вичерпанні ліміту спрацьовує передбачувана відмова зі зрозумілим кодом.

Економіка тут читається через утилізацію ресурсів: прискорювач, що простоює, — це потужність, яка не видає результат. Коли завантаження прискорювачів тримається рівним, розширення парку відкладається, а вартість простою перестає бути постійним рядком у плануванні.

Варіанти збору запитів у пакети: порівняння режимів

Режим збору запитів у пакети впливає на завантаження прискорювача сильніше, ніж вибір самої моделі: за невдалої схеми карта простоює між ітераціями, а хвіст черги розтягується на секунди.

Інтерактивний чат, пакетний розбір документів і фонова аналітика навантажують сервіс по-різному, тому універсального налаштування немає — режим підбирають під профіль трафіку.

Режим Коли підходить Обмеження режиму
Статична пакетна обробка Однорідні запити відомої довжини: нічні вивантаження, розмітка архіву, пакетні звіти Пакет чекає на найдовшу відповідь, короткі запити простоюють, прискорювач завантажений нерівномірно
Неперервний збір пакетів Змішаний потік із розкидом довжин: чат, асистенти, потік заявок Потрібен планувальник рівня сервера виведення — vLLM та аналоги; складніше відтворювати заміри
Черга з пріоритетами Різні класи задач в одному сервісі: інтерактив важливіший за аналітику Голодування низькопріоритетних задач, потрібні явні правила витіснення
Ручне підлаштування розміру пакета Стабільний потік без сплесків за обмеженої пам'яті прискорювача Крихкий баланс: завищений розмір дає відмови, занижений — недовантаження

На практиці режими комбінують: неперервний збір пакетів задає базовий ритм, черга з пріоритетами розводить інтерактив і фонові задачі, а розмір пакета обмежують зверху за доступною пам'яттю.

Вибір перевіряємо на профілі реального трафіку — інакше обмеження режиму спливають на піку, коли змінювати схему вже пізно.

Порядок впровадження: від профілю навантаження до введення в роботу

Динамічний батчинг не вмикається одним перемикачем: вікно збору, максимальний розмір батчу та ліміти очікування підбираються під конкретний профіль трафіку. Нижче — етапи впровадження: від заміру реального навантаження до передачі сервісу в експлуатацію.

  1. Замір профілю навантаження — розподіл запитів за довжиною входу та виходу, частка коротких і довгих відповідей, пікові інтервали. Без цих чисел розмір батчу підбирається навмання.

  2. Схема збору черги — де запити об'єднуються: у застосунку, у проміжному шарі чи в самому сервісі виведення, і як узгоджуються вікна очікування між рівнями.

  3. Налаштування сервісу виведення — граничний розмір батчу, вікно очікування, поведінка при переповненні черги та пріоритет інтерактивних запитів перед фоновими.

  4. Розподіл за класами трафіку — короткі діалогові запити йдуть у невеликі батчі, пакетна обробка — у великі, щоб довгі завдання не затримували відповідь користувачеві.

  5. Навантажувальна перевірка — прогін потоку з профілем з першого етапу, контроль затримки першого токена, пропускної здатності та довжини черги на піку.

  6. Запобіжники та відкат — повернення до одиночної обробки одним перемиканням і пороги, за яких батчинг вимикається автоматично.

  7. Передача в експлуатацію — конфігурація, панелі з ключовими метриками, регламент зміни лімітів і розбір типових відмов.

Що передаємо на руки: конфігурації, схеми, регламенти

Передаємо не презентацію, а робочий комплект: за ним ваш інженер зможе змінювати поведінку батчингу, діагностувати сплески затримок і повернути попередній режим, не чекаючи на нас. Нижче — що залишається в репозиторії та у внутрішній базі знань на момент здачі.

  • Конфігурація сервісу: файли параметрів вікна набору — максимальний розмір, час очікування добору, пороги завантаження прискорювача — з коментарями, чому вибрано саме ці значення, і окремим профілем під пікові години.
  • Схема потоків запитів: шлях від приймання до видачі відповіді, точки накопичення черги, момент формування вікна, поведінка при переповненні та при простої, коли чекати нічого.
  • Регламент експлуатації: як змінити розмір вікна без перезапуску сервісу, які метрики дивитися після правки та за яких значень повертати попередній профіль.
  • Політики доступу: розмежування прав на читання метрик і на зміну конфігурації, ролі чергового та старшого чергового, порядок ротації ключів доступу до сервісу.
  • Метрики та панель спостереження: частка заповнення вікна, затримка за кожним запитом, завантаження прискорювача, кількість відхилених за таймаутом — з порогами, за якими починається деградація.
  • Документація: опис архітектури, розбір відмовних сценаріїв, інструкції з типових операцій і журнал змін конфігурації із зазначенням автора правки.
  • Сценарії перевірки: набір навантажувальних прогонів, що відтворюють рівний потік, короткий сплеск і довгий пік, — щоб правка конфігурації перевірялася до викочування в робочий контур.

Кейс: зростання пропускної здатності на тому самому парку прискорювачів

Замовник — сервіс підтримки з потоком звернень через чат: один парк прискорювачів, уночі навантаження рівне, удень короткі піки в 4-5 разів вищі за середню.

Розширювати парк не хотіли: у такі піки прискорювачі простоювали, і вкладення в нові карти потрібно було чимось обґрунтувати.

До змін розмір батчу був виставлений фіксованим — за середнім навантаженням. На піку запити накопичувалися в черзі: 95-й перцентиль часу відгуку сягав 4,5 секунди, а 9% звернень падали через перевищення часу очікування — при нерівномірному завантаженні прискорювачів.

Роботу перебудували на сервер виведення моделей vLLM з неперервним батчингом: планувальник перезбирає батч на кожному кроці генерації та підставляє нові запити у звільнені слоти, не чекаючи на завершення поточного набору.

Паралельно обмежили довжину черги, задали верхню межу за пам'яттю під кеш і розвели пріоритети — короткі звернення більше не чекають на довгі генерації.

Що стало на тому самому парку: пропускна здатність зросла приблизно втричі — з 18 до 52 запитів за секунду, 95-й перцентиль відгуку опустився до 1,2 секунди, частка відмов через перевантаження — з 9% до 0,4%, завантаження прискорювачів у пікові години вийшла на 85-90% замість 40-60%.

Конфігурацію з очікуваним бюджетом затримки та лімітами черги перенесли на інші моделі сервісу без зміни обладнання.

Чим неперервний збір пакетів відрізняється від динамічного?

Різниця в тому, коли фіксується склад пакета. Динамічний збір накопичує запити у вікні очікування, збирає пакет за розміром або таймаутом і веде його незмінним до кінця — звільнені місця простоюють, поки не завершиться найдовша відповідь.

Неперервний збір пакетів перезбирає склад на кожній ітерації генерації: послідовність, що завершилася, виходить, а її місце одразу займає наступний запит із черги.

Звідси різниця в ефекті. На змішаному трафіку, де поруч ідуть коротка репліка та довге міркування, прискорювач перестає чекати на тих, хто відстає, — пропускна здатність зростає в рази на тому самому обладнанні, а затримка до першої відповіді стає передбачуваною.

Плата за це — в управлінні. Потрібно обмежувати кількість одночасних послідовностей, стежити за пам'яттю під проміжні стани та підбирати вікно очікування: занадто довге з'їдає виграш, занадто коротке не дає наповнити пакет.

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

Якщо сервіс виведення моделей уже розгорнуто, ідемо поступовим переходом: вмикаємо динамічний збір, знімаємо базові метрики, потім переводимо на неперервний частину трафіку за балансувальником і порівнюємо частку зайнятого часу прискорювача зі стабільністю відповідей.

Повне перемикання — коли порівняння показало виграш; відкат — повернення попереднього режиму на одному вузлі.

Сумніви перед впровадженням: черги, затримки, стійкість

На етапі вибору підрядника технічні сумніви звучать майже однаково: чи не стане гірше від того, що запити тепер обробляються пакетами. Динамічний батчинг LLM виглядає логічно на графіках утилізації прискорювача, але в інженера одразу виникає зустрічне питання — якою ціною. Нижче п'ять питань, які найчастіше ставлять на розборі, і короткі відповіді по суті.

Чи не зросте затримка відповіді на одиночних запитах?

Вікно очікування адаптивне: за низького навантаження воно стискається майже до нуля, і одиночний запит іде на обробку одразу. Пакет збирається лише коли в черзі вже є запити, готові до одночасної обробки, — чекати марно ніхто не буде.

Що при нерівномірному навантаженні — простій чи захлинання?

Диспетчер перераховує розмір пакета та вікно за фактичним вхідним потоком: уночі він тримає пакети великими та вижимає прискорювач, на різкому сплеску — зменшує їх, щоб не накопичувати затримку. Межі задаються в конфігурації як політика, а не підбираються на око.

Чи почне сервіс відкидати запити при перевантаженні?

Черга обмежена зверху, але запити не втрачаються — вони чекають із передбачуваним строком, а частину трафіку можна відвести на резервний вузол. Відкидання залишається аварійним режимом із явним кодом помилки, а не штатною поведінкою під піком.

Чи вистачить пам'яті прискорювача під великі пакети?

Розмір пакета обмежується зверху за обсягом доступної пам'яті, тому аварійна зупинка обробки виключена. Під час піку політика сама знижує розмір пакета — пропускна здатність просідає плавно, без повної відмови.

Як перевіряємо стійкість і що з відкатом?

Стійкість під піком підтверджуємо прогоном за профілем реального навантаження — ступінчасте зростання, обрив з'єднань, повторні запити. Відкат до статичного режиму робиться одним параметром конфігурації, без перезбирання сервісу та правок у коді застосунку.

Обговоримо задачу: що потрібно для оцінки та плану робіт

Оцінка проєкту з динамічного батчингу для LLM спирається не на загальні міркування, а на профіль вашого навантаження та поточну схему обслуговування запитів.

Чим конкретніші вхідні дані, тим менше уточнювальних кіл і тим точніший план робіт — із порядком етапів і точками, де можливий відкат.

  • Профіль навантаження. Скільки запитів надходить у середньому та в піку, як вони розподілені за довжиною входу й виходу, чи є добові сплески. Це визначає, скільки запитів об'єднується в один пакет і де виграш буде помітний.
  • Поточна схема. Один екземпляр моделі чи кілька, як розподіляються запити, чи є черга та кеш відповідей, як оновлюються ваги. Без цього незрозуміло, що саме змінювати.
  • Обмеження за часом відповіді. Де затримка критична — інтерактив, потокова видача, — а де можна зачекати. Динамічний батчинг балансує між пропускною здатністю та очікуванням, і межі задаєте ви.
  • Інфраструктура та доступи. Які прискорювачі та в якій кількості, як влаштоване розгортання, чи є тестовий контур для прогону навантаження без ризику для продуктивного середовища.
  • Метрики. Чим вимірюєте пропускну здатність і затримку зараз, які зрізи збираєте та за якими показниками будете приймати роботу.
  • Команда та ролі. Хто на вашому боці відповідає за інфраструктуру, хто за модель, хто приймає результат — щоб не чекати відповідей по колу.

Опишіть задачу у вільній формі — повернемося з оцінкою, планом робіт і уточнювальними питаннями, якщо чогось не вистачить.

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

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

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1393
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1368
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    815
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1139