Оптимізація TensorRT-LLM: Освоєння інференс-стеку NVIDIA
Оновлено 11 грудня 2025 року
Оновлення грудня 2025: TensorRT-LLM досягає понад 10 000 вихідних токенів/сек на H100 з FP8, TTFT менше 100 мс. Продакшн-розгортання демонструють 4-кратне збільшення пропускної здатності порівняно з нативним PyTorch. Злиття ядер поєднує LayerNorm, матричні множення, функції активації в єдині CUDA-ядра. Inflight batching максимізує утилізацію GPU. FP8 attention на Hopper/Blackwell забезпечує додаткове прискорення.
TensorRT-LLM від NVIDIA забезпечує сиру продуктивність інференсу, з якою альтернативи важко конкурують. На GPU H100 з точністю FP8 фреймворк досягає понад 10 000 вихідних токенів на секунду при пікової пропускній здатності з затримкою до першого токена менше 100 мілісекунд.¹ Продакшн-розгортання повідомляють про до 4-кратне збільшення пропускної здатності порівняно з нативним інференсом PyTorch. За продуктивність доводиться платити: TensorRT-LLM вимагає більшої експертизи в конфігурації та довших циклів оптимізації, ніж зручні для користувача альтернативи на кшталт vLLM.
Для організацій, які зробили ставку на обладнання NVIDIA і готові інвестувати інженерний час в оптимізацію, TensorRT-LLM витягує максимальну продуктивність з дорогої GPU-інфраструктури. Розуміння архітектури фреймворку, опцій квантизації та параметрів налаштування дозволяє командам будувати інференс-системи, які виправдовують інвестиції в преміум-обладнання завдяки кращій економіці токенів.
Архітектура та основні оптимізації
TensorRT-LLM побудований на оптимізаторі інференсу TensorRT від NVIDIA, розширюючи компіляційний фреймворк трансформер-специфічними оптимізаціями. Бібліотека надає Python API для визначення моделей разом з C++ runtime-компонентами для продакшн-розгортання.
Злиття ядер: TensorRT-LLM поєднує кілька трансформерних операцій в єдині оптимізовані CUDA-ядра. LayerNorm, матричні множення, додавання зміщень та функції активації виконуються разом, замість того щоб вимагати окремих запусків ядер та передачі пам'яті. Злиття зменшує накладні витрати на запуск ядер та усуває матеріалізацію проміжних тензорів.²
Кастомні ядра attention: Оптимізовані вручну реалізації multi-head та grouped-query attention використовують інструкції Tensor Core для максимальної пропускної здатності. Варіанти Flash Attention зменшують вимоги до пропускної здатності пам'яті, зберігаючи числову точність. FP8 attention ядра на GPU Hopper та Blackwell забезпечують додаткове прискорення.
Inflight batching: Традиційний статичний батчинг змушує всі запити в батчі чекати завершення найдовшої послідовності. Inflight batching додає нові запити до працюючих батчів на кожному кроці генерації, обробляючи фази контексту та генерації разом.³ Цей підхід максимізує утилізацію GPU, підтримуючи обчислювальні блоки зайнятими навіть коли окремі запити завершуються.
Paged KV caching: Натхненний віртуальною пам'яттю операційних систем, paged attention виділяє KV cache в несуміжних блоках замість того, щоб вимагати неперервних регіонів пам'яті.⁴ Виділення на рівні блоків дозволяє спільно використовувати KV cache між запитами зі спільними префіксами та досягає майже нульових втрат пам'яті від внутрішньої фрагментації.
Порівняння продуктивності: TensorRT-LLM vs vLLM
Обидва фреймворки орієнтовані на продакшн LLM-інференс, але архітектурні відмінності створюють різні профілі продуктивності:
| Метрика | TensorRT-LLM | vLLM |
|---|---|---|
| Пікова пропускна здатність (Llama 70B, A100) | ~700 токенів/сек | ~600-650 токенів/сек |
| Час до першого токена | 35-50 мс | 50-80 мс |
| Перевага на коротких послідовностях | 1.34x | Базовий рівень |
| Перевага TPOT на довгих послідовностях | 2.72x | Базовий рівень |
| Складність налаштування | Висока (тижні) | Низька (години) |
TensorRT-LLM стабільно перевершує vLLM з конфігураціями за замовчуванням, забезпечуючи на 1.34x вищу пропускну здатність на коротких послідовностях та на 2.72x кращий час на вихідний токен на довгих послідовностях.⁵ На GPU B200 глибша оптимізація TensorRT-LLM для архітектури Blackwell ще більше збільшує розрив у продуктивності.
vLLM пропонує переваги в досвіді розробника:⁶ - OpenAI-сумісний API для заміни без змін - Простіше розгортання без етапу компіляції - Автоматична оптимізація моделей з розумними значеннями за замовчуванням - Ширша підтримка обладнання за межами GPU NVIDIA
Рекомендація: Розгортайте TensorRT-LLM, коли максимізація ефективності обладнання виправдовує інженерні інвестиції. Обирайте vLLM для швидшого виходу в продакшн або при роботі в меншому масштабі, де абсолютна продуктивність має менше значення, ніж швидкість розробки.
Стратегії квантизації
TensorRT-LLM підтримує широкі можливості квантизації для обміну точності на продуктивність та ефективність використання пам'яті. Вибір правильного методу квантизації залежить від розміру батчу, вимог до точності та цільового обладнання.
FP8 квантизація (рекомендується спочатку)
FP8 забезпечує найкращий баланс покращення продуктивності з мінімальною втратою точності:⁷
python quantize.py \
--model_dir $MODEL_PATH \
--qformat fp8 \
--kv_cache_dtype fp8 \
--output_dir $OUTPUT_PATH
FP8 квантизація вимагає калібрування для визначення відповідних масштабуючих коефіцієнтів. Процес калібрування виконує інференс на репрезентативних зразках для вимірювання діапазонів активацій:
from tensorrt_llm.quantization import QuantConfig, CalibConfig
quant_config = QuantConfig(
quant_algo="fp8",
kv_cache_quant_algo="fp8"
)
calib_config = CalibConfig(
calib_dataset="cnn_dailymail",
calib_batch_size=8,
calib_num_samples=512
)
FP8 забезпечує середнє покращення продуктивності з дуже низьким впливом на точність і вимагає лише хвилин для калібрування. GPU Hopper та Blackwell забезпечують апаратну підтримку FP8; GPU Ada підтримують FP8 зі зниженою ефективністю.
INT4 AWQ для обмежених за пам'яттю розгортань
Коли обмеження пам'яті лімітують розмір моделі, INT4 Activation-aware Weight Quantization стискає ваги до 4 біт, зберігаючи прийнятну точність:⁸
python quantize.py \
--model_dir $MODEL_PATH \
--qformat int4_awq \
--awq_block_size 64 \
--tp_size 4 \
--output_dir $OUTPUT_PATH
INT4 AWQ відзначається в сценаріях з малими батчами (розмір батчу ≤ 4), де інференс стає memory-bound. Час завантаження ваг домінує над обчисленнями, тому агресивне стиснення ваг забезпечує суттєве прискорення. Для великих батчів перевага продуктивності INT4 AWQ зменшується, оскільки щільність обчислень зростає.
INT8 SmoothQuant для збалансованої оптимізації
SmoothQuant переносить складність квантизації з активацій на ваги, забезпечуючи ефективну INT8 квантизацію без значної втрати точності:
python quantize.py \
--model_dir $MODEL_PATH \
--qformat int8_sq \
--kv_cache_dtype int8 \
--output_dir $OUTPUT_PATH
INT8 SmoothQuant забезпечує середнє покращення продуктивності з середнім впливом на точність. Організаціям слід спочатку спробувати FP8, переходячи до INT8 SQ, якщо результати FP8 не відповідають вимогам.
Фреймворк вибору квантизації
NVIDIA рекомендує наступний порядок пріоритету:⁹
- FP8 - Найкращий компроміс продуктивність/точність, вимагає Hopper/Blackwell
- INT8 SmoothQuant - Хороша альтернатива для GPU Ada або коли точність FP8 недостатня
- INT4 AWQ/GPTQ - Максимальне стиснення для сценаріїв з обмеженою пам'яттю
Зокрема для KV cache, FP8 квантизація рекомендується замість INT8 на GPU Hopper та Ada через нижчий вплив на точність у більшості випадків.
Конфігурація продакшн-розгортання
Оптимальне розгортання TensorRT-LLM вимагає налаштування багатьох параметрів на основі характеристик навантаження:
Конфігурація збірки engine
trtllm-build \
--checkpoint_dir $CHECKPOINT_PATH \
--output_dir $ENGINE_PATH \
--max_batch_size 256 \
--max_num_tokens 8192 \
--max_input_len 4096 \
--max_seq_len 8192 \
--gemm_plugin auto \
--use_paged_context_fmha enable \
--workers 8
max_batch_size: За замовчуванням 256 в останніх версіях. Продакшн-розгортання, що досягають максимальної пропускної здатності, часто збільшують до 2048, повністю використовуючи можливості inflight batching.¹⁰
max_num_tokens: Контролює загальну кількість токенів, оброблюваних за ітерацію батчу. За замовчуванням 8192 балансує пропускну здатність зі споживанням пам'яті. Зменшуйте для розгортань з обмеженою пам'яттю; збільшуйте обережно з моніторингом.
use_paged_context_fmha: Вмикає paged attention для ефективного управління KV cache. Обов'язково при використанні inflight batching. Реалізація попередньо виділяє пам'ять KV cache, вимагаючи приблизно на 60% більше VRAM, ніж лише ваги моделі.¹¹
Інтеграція з Triton Inference Server
Продакшн-розгортання зазвичай використовують NVIDIA Triton Inference Server з бекендом TensorRT-LLM:
model_repository/
└── llama-70b/
├── 1/
│ └── model.py
├── config.pbtxt
└── tensorrt_llm/
└── 1/
├── config.json
└── engine/
Triton забезпечує оркестрацію кількох моделей, чергування запитів, збір метрик та нативне масштабування для Kubernetes. Попередньо зібраний NGC контейнер включає бекенд TensorRT-LLM з увімкненими inflight batching та paged KV cache.
Планування пам'яті
Оцініть вимоги до пам'яті перед розгортанням:
Загальний VRAM = Ваги моделі + KV Cache + Пам'ять активацій + Накладні витрати runtime
Ваги моделі (FP8): Параметри × 1 байт
Ваги моделі (INT4): Параметри × 0.5 байт
KV Cache: batch_size × seq_len × num_layers × 2 × hidden_dim × precision_bytes
Модель з 70B параметрів у FP8 вимагає приблизно: - Ваги: 70GB - KV Cache (batch 256, seq 8192): ~120GB - Активації + накладні витрати: ~30GB - Всього: ~220GB (3x H100 80GB або 2x H200 141GB)
Робочий процес налаштування продуктивності
Систематична оптимізація витягує максимальну продуктивність з розгортань TensorRT-LLM:
Фаза 1: Базове вимірювання
Використовуйте trtllm-bench для швидкої оцінки продуктивності:
python -m tensorrt_llm.bench \
--model_dir $ENGINE_PATH \
--input_len 512 \
--output_len 256 \
--batch_size 32 \
--num_requests 1000
Утиліта бенчмаркінгу автоматично встановлює оптимальні параметри engine, забезпечуючи базову продуктивність без складності повного розгортання Triton.¹²
Фаза 2: Вибір квантизації
Спочатку протестуйте FP8 на відповідність вимогам точності. Якщо точність погіршується за межі прийнятних порогів, оцініть INT8 SQ або INT4 AWQ. Запускайте бенчмарки оцінки на репрезентативних задачах, а не лише вимірювання perplexity.
Фаза 3: Оптимізація розміру батчу
Профілюйте пропускну здатність для розмірів батчу від 1 до max_batch_size. Визначте коліно кривої пропускної здатності, де додатковий батчинг дає спадну віддачу. Встановіть max_batch_size на 20-30% вище цієї точки для компенсації сплесків трафіку.
Фаза 4: Налаштування KV cache
Моніторте утилізацію KV cache під час продакшн-навантажень. Якщо утилізація стабільно перевищує 80%, збільште max_num_tokens або зменште max_batch_size. Якщо утилізація залишається нижче 50%, зменште виділення для звільнення пам'яті для більших батчів.
Фаза 5: Безперервний моніторинг
Відстежуйте ключові метрики в продакшні: - Токени на секунду (пропускна здатність) - Час до першого токена (затримка) - Глибина черги (ємність) - Утилізація KV cache (пам'ять) - Утилізація GPU (ефективність)
Просунуті оптимізації
Speculative decoding
TensorRT-LLM підтримує speculative decoding з використанням менших draft-моделей для передбачення кількох токенів, які перевіряються основною моделлю. Техніка забезпечує прискорення в 1.5-2 рази для сумісних навантажень:
# Увімкнення speculative decoding при збірці engine
trtllm-build \
--speculative_decoding_mode draft_tokens_external \
--max_draft_len 5 \
...
Speculative decoding корисний для застосунків, чутливих до затримки, де час завершення важливіший за пропускну здатність. Оптимізація вимагає зберігання в пам'яті як draft, так і цільової моделі.
Багато-GPU конфігурації
TensorRT-LLM підтримує tensor parallelism (TP), pipeline parallelism (PP) та expert parallelism (EP) для розподіленого інференсу:
# 4-way tensor parallelism
trtllm-build \
--tp_size 4 \
--pp_size 1 \
...
TP розділяє кожен шар між GPU, вимагаючи операцій all-reduce на межі кожного шару. PP розділяє шари між GPU в етапи конвеєра. Для інференсу TP зазвичай забезпечує кращу затримку, тоді як PP дозволяє
[Вміст скорочено для перекладу]