English translation is not available yet. Showing Russian content.

Как вы деплоите LLM с TensorRT-LLM в production?

Краткий тезис

TensorRT-LLM — это библиотека от NVIDIA для оптимизированного инференса LLM на GPU. Деплой в production включает конвертацию модели в формат engine (файл .plan), настройку Triton Inference Server с TensorRT-LLM backend, включение dynamic batching через sequence slots и мониторинг метрик. Ключевые преимущества — низкая latency, высокая throughput и поддержка продвинутых оптимизаций (квантизация, in-flight batching, paged attention).


1. Что такое TensorRT-LLM и зачем он нужен в production

TensorRT-LLM — это open-source библиотека NVIDIA, которая компилирует модели LLM в оптимизированные планы выполнения для GPU. Она включает:

  • Fusion — объединение нескольких операций в одну (например, слои attention и MLP).
  • Квантизацию — снижение точности весов (FP16 → FP8/INT4) без значительной потери качества.
  • In-flight batching — обработка запросов разной длины в одном батче с динамическим выделением ресурсов.
  • PagedAttention — эффективное управление KV cache (как в vLLM).

В production TensorRT-LLM позволяет достичь 2–5× ускорения по сравнению с обычным PyTorch-инференсом и снизить стоимость GPU за счёт более плотной утилизации.


2. Подготовка модели: конвертация в engine (.plan)

Процесс начинается с загрузки модели (например, LLaMA, Mistral, Falcon) в формате Hugging Face. Затем с помощью скриптов TensorRT-LLM выполняется build engine:

# Пример для LLaMA-2 7B
python build.py --model_dir /path/to/llama \
                --dtype float16 \
                --use_gpt_attention_plugin float16 \
                --use_gemm_plugin float16 \
                --output_dir /tmp/llama_engine \
                --max_batch_size 64 \
                --max_input_len 2048 \
                --max_output_len 512

Ключевые параметры:

  • --dtype — тип данных (float16, bfloat16).
  • --use_*_plugin — включение плагинов для fusion.
  • --max_batch_size — максимальный размер батча (определяет выделение памяти).
  • --max_input_len / max_output_len — максимальная длина контекста и генерации.

Результат — папка с файлами .plan (один или несколько для разных GPU). Этот файл содержит скомпилированный граф вычислений, готовый к запуску.


3. Оптимизации при сборке engine

3.1 Квантизация

TensorRT-LLM поддерживает FP8, INT8, INT4 и AWQ. Квантизация уменьшает размер модели и ускоряет инференс, но требует калибровки на репрезентативном датасете.

python build.py ... --use_weight_only --weight_only_precision int4_awq

3.2 In-flight batching (IFB)

Включение IFB позволяет обрабатывать запросы с разной длиной в одном батче, динамически добавляя и удаляя последовательности. Это повышает throughput на 30–50%.

3.3 PagedAttention

Управление KV cache страницами (как в vLLM) — снижает фрагментацию памяти и позволяет обслуживать больше параллельных запросов.


4. Деплой через Triton Inference Server

Triton Inference Server — это production-ready сервер инференса от NVIDIA. Он поддерживает TensorRT-LLM backend, который загружает engine и управляет выполнением.

4.1 Структура репозитория моделей Triton

model_repository/
└── tensorrt_llm/
    ├── config.pbtxt
    └── 1/
        └── model.plan

4.2 Пример config.pbtxt

name: "tensorrt_llm"
backend: "tensorrt_llm"
max_batch_size: 0  # отключено, используем dynamic batching
input [
  {
    name: "input_ids"
    data_type: TYPE_INT32
    dims: [-1]
  }
]
output [
  {
    name: "output_ids"
    data_type: TYPE_INT32
    dims: [-1, -1]
  }
]
instance_group [
  {
    count: 1
    kind: KIND_GPU
  }
]
parameters [
  {
    key: "max_beam_width"
    value: { string_value: "1" }
  },
  {
    key: "max_tokens_in_paged_kv_cache"
    value: { string_value: "4096" }
  }
]

4.3 Запуск Triton

docker run --gpus all -p 8000:8000 -p 8001:8001 -p 8002:8002 \
  -v /path/to/model_repository:/models \
  nvcr.io/nvidia/tritonserver:24.08-trtllm-python-py3 \
  tritonserver --model-repository=/models

После запуска модель доступна через gRPC (порт 8001) или HTTP (порт 8000).


5. Dynamic batching через sequence slots

Sequence slot — это единица ресурса, выделенная для одного запроса (последовательности). Triton с TensorRT-LLM backend использует dynamic batching на уровне sequence slots:

  • При поступлении запроса ему назначается свободный slot.
  • Все активные slots объединяются в один батч для выполнения forward pass.
  • После генерации токена slot освобождается, и его место занимает новый запрос.

Настройка в config.pbtxt:

parameters [
  {
    key: "max_num_sequences"
    value: { string_value: "128" }
  }
]

Этот параметр определяет максимальное количество параллельных последовательностей (аналог max_batch_size в других системах). Правильный выбор зависит от размера GPU и длины контекста.


6. Управление памятью: KV cache и paged attention

TensorRT-LLM использует paged KV cache — кэш разбивается на страницы фиксированного размера (например, 16 токенов). Это позволяет:

  • Избежать выделения памяти под максимальную длину для каждого запроса.
  • Эффективно использовать память при переменной длине генерации.
  • Поддерживать больше параллельных запросов.

Параметр max_tokens_in_paged_kv_cache в config.pbtxt задаёт общий размер кэша. Его можно вычислить как max_num_sequences * (max_input_len + max_output_len), но на практике берут с запасом.


7. Мониторинг и логирование

В production необходимо отслеживать:

  • Latency (p50, p95, p99) — время ответа на запрос.
  • Throughput (запросов/сек, токенов/сек).
  • GPU utilization и memory usage.
  • Количество sequence slots — сколько параллельных запросов обрабатывается.

Triton предоставляет метрики Prometheus по умолчанию (порт 8002). Пример запроса:

curl http://localhost:8002/metrics

Также можно добавить кастомные логи через Triton client:

import tritonclient.http as httpclient
client = httpclient.InferenceServerClient(url="localhost:8000")
model_stats = client.get_model_statistics("tensorrt_llm")
print(model_stats)

8. Масштабирование: multi-GPU и multi-node

TensorRT-LLM поддерживает Tensor Parallel (TP) и Pipeline Parallel (PP) для распределения модели на несколько GPU.

  • TP — каждый слой разрезается по головам attention и делится между GPU. Подходит для одной ноды с NVLink.
  • PP — разные слои размещаются на разных GPU. Используется для очень больших моделей (70B+).

При сборке engine указывается количество GPU:

python build.py ... --tensor_parallel_size 4

Triton автоматически распределяет запросы между GPU через instance_group с count: 4.


9. Сравнение TensorRT-LLM с vLLM и TGI

КритерийTensorRT-LLMvLLMTGI (Text Generation Inference)
ОптимизацияМаксимальная (fusion, квантизация, IFB)PagedAttention, continuous batchingFlash Attention, continuous batching
Поддержка моделейHugging Face + кастомныеHugging FaceHugging Face
КвантизацияFP8, INT4, AWQAWQ, GPTQGPTQ, AWQ
Простота деплояСредняя (нужна сборка engine)Высокая (один pip install)Высокая (Docker)
ПроизводительностьЛучшая для NVIDIA GPUОчень хорошаяХорошая
ЭкосистемаTriton, KubernetesВстроенный серверHugging Face Hub

Выбор зависит от команды: если нужна максимальная производительность и есть инженеры для настройки — TensorRT-LLM. Если важна скорость разработки — vLLM или TGI.


10. Best practices и частые проблемы

  • Выбор размера sequence slots: слишком мало → низкий throughput, слишком много → OOM. Начинайте с max_num_sequences = 64 для 24GB GPU.
  • Квантизация: всегда проверяйте качество на валидационном датасете после квантизации.
  • Обновление модели: при смене версии TensorRT-LLM нужно пересобирать engine.
  • Graceful shutdown: настройте Triton на корректное завершение запросов при рестарте.
  • A/B тестирование: деплойте две версии engine (например, FP16 vs FP8) и сравнивайте метрики.

Пет-проект для закрепления

Задача: Развернуть LLaMA-2 7B с TensorRT-LLM на Triton Inference Server в локальной среде.

Инструменты: Docker, TensorRT-LLM (образ nvcr.io/nvidia/tritonserver:24.08-trtllm-python-py3), Python, Hugging Face.

Шаги:

  1. Скачайте модель LLaMA-2 7B (или TinyLlama для экономии) с Hugging Face.
  2. Соберите engine с параметрами: dtype=float16, max_batch_size=32, max_input_len=1024, max_output_len=256.
  3. Создайте репозиторий Triton с config.pbtxt (включите max_num_sequences=64).
  4. Запустите Triton в Docker с пробросом портов.
  5. Напишите клиент на Python, который отправляет запросы и измеряет latency.
  6. Поэкспериментируйте с разными значениями max_num_sequences и замерьте throughput.

Ожидаемый результат: Работающий эндпоинт, который обрабатывает запросы с latency < 100 мс на токен и throughput > 100 токенов/сек.


Связь с другими вопросами

ВопросТема
320Оптимизация инференса LLM
321Квантизация моделей
322Batching и throughput
324Деплой с vLLM
325Деплой с TGI
326Мониторинг LLM в production

Навигация