Перейти к основному содержимому

Чтобы получить чистое Markdown-содержимое этой страницы, добавьте .md к этому URL. Полный индекс документации см. на https://docs.nvidia.com/dynamo/llms.txt. Полное содержимое, включая справочник API и примеры SDK, см. на https://docs.nvidia.com/dynamo/llms-full.txt.

GPT-OSS

Общие возможности TensorRT-LLM и его настройка описаны в справочном руководстве.


Dynamo поддерживает раздельное обслуживание gpt-oss-120b с TensorRT-LLM. В этом руководстве показано, как развернуть gpt-oss-120b с раздельным обслуживанием prefill/decode на одном узле B200 с 8 GPU: 1 prefill worker на 4 GPU и 1 decode worker на 4 GPU.

Обзор

В этом развертывании используется раздельное обслуживание в TensorRT-LLM, где:

  • Prefill Worker: эффективно обрабатывает входные промпты, используя 4 GPU с тензорным параллелизмом
  • Decode Worker: генерирует выходные токены, используя 4 GPU, с оптимизацией под пропускную способность генерации токенов
  • Frontend: предоставляет OpenAI-совместимую конечную точку API с маршрутизацией round-robin

Раздельный подход оптимизирует сценарии как с низкой задержкой (максимум токенов в секунду на пользователя), так и с высокой пропускной способностью (максимум суммарных токенов на GPU в секунду), отделяя вычислительно интенсивную фазу prefill от ограниченной памятью фазы decode.

Требования

  • 1 узел NVIDIA B200 с 8 GPU (это руководство посвящено развертыванию на одном узле B200)
  • CUDA Toolkit 12.8 или новее
  • Docker с установленным NVIDIA Container Toolkit
  • Быстрое SSD-хранилище для весов модели (требуется около 240 ГБ)
  • Учетная запись HuggingFace и токен доступа
  • HuggingFace CLI

Убедитесь, что сервисы etcd и nats запущены, выполнив следующую команду:

docker compose -f dev/docker-compose.yml up

Инструкции

1. Скачайте модель

export MODEL_PATH=<LOCAL_MODEL_DIRECTORY>
export HF_TOKEN=<INSERT_TOKEN_HERE>

pip install -U "huggingface_hub[cli]"

huggingface-cli download openai/gpt-oss-120b --exclude "original/*" --exclude "metal/*" --local-dir $MODEL_PATH

2. Запустите контейнер

Задайте образ контейнера:

export DYNAMO_CONTAINER_IMAGE=nvcr.io/nvidia/ai-dynamo/tensorrtllm-runtime:1.2.0

Запустите контейнер Dynamo TensorRT-LLM с необходимой конфигурацией:

docker run \
--gpus all \
-it \
--rm \
--network host \
--volume $MODEL_PATH:/model \
--volume $PWD:/workspace \
--shm-size=10G \
--ulimit memlock=-1 \
--ulimit stack=67108864 \
--ulimit nofile=65536:65536 \
--cap-add CAP_SYS_PTRACE \
--ipc host \
-e HF_TOKEN=$HF_TOKEN \
-e TRTLLM_ENABLE_PDL=1 \
-e TRT_LLM_DISABLE_LOAD_WEIGHTS_IN_PARALLEL=True \
$DYNAMO_CONTAINER_IMAGE

Эта команда:

  • автоматически удаляет контейнер после остановки (--rm)
  • позволяет контейнеру взаимодействовать с IPC-ресурсами хоста для оптимальной производительности (--ipc=host)
  • запускает контейнер в интерактивном режиме (-it)
  • настраивает разделяемую память и лимиты стека для оптимальной производительности
  • монтирует каталог модели в контейнер по пути /model
  • монтирует текущую рабочую область Dynamo в контейнер по пути /workspace/dynamo
  • включает PDL и отключает параллельную загрузку весов
  • задает токен HuggingFace как переменную окружения в контейнере

3. Разберитесь в конфигурации

Развертывание использует конфигурационные файлы и аргументы командной строки для управления поведением:

Конфигурационные файлы

Конфигурация prefill (examples/backends/trtllm/engine_configs/gpt-oss-120b/prefill.yaml):

  • enable_attention_dp: false - параллелизм данных attention отключен для prefill
  • enable_chunked_prefill: true - включает эффективную обработку chunked prefill
  • moe_config.backend: CUTLASS - использует оптимизированные ядра CUTLASS для слоев MoE
  • cache_transceiver_config.backend: ucx - использует UCX для эффективной передачи KV cache
  • cuda_graph_config.max_batch_size: 32 - максимальный размер batch для CUDA graphs

Конфигурация decode (examples/backends/trtllm/engine_configs/gpt-oss-120b/decode.yaml):

  • enable_attention_dp: true - параллелизм данных attention включен для decode
  • disable_overlap_scheduler: false - включает перекрытие операций для эффективности decode
  • moe_config.backend: CUTLASS - использует оптимизированные ядра CUTLASS для слоев MoE
  • cache_transceiver_config.backend: ucx - использует UCX для эффективной передачи KV cache
  • cuda_graph_config.max_batch_size: 128 - максимальный размер batch для CUDA graphs

Аргументы командной строки

Оба worker получают эти ключевые аргументы:

  • --tensor-parallel-size 4 - использует 4 GPU для тензорного параллелизма
  • --expert-parallel-size 4 - параллелизм экспертов на 4 GPU
  • --free-gpu-memory-fraction 0.9 - выделяет 90% памяти GPU

Аргументы, специфичные для prefill:

  • --max-num-tokens 20000 - максимальное число токенов для обработки prefill
  • --max-batch-size 32 - максимальный размер batch для prefill

Аргументы, специфичные для decode:

  • --max-num-tokens 16384 - максимальное число токенов для обработки decode
  • --max-batch-size 128 - максимальный размер batch для decode

4. Запустите развертывание

Обратите внимание, что GPT-OSS - это reasoning-модель с поддержкой tool calling. Чтобы ответ обрабатывался корректно, worker следует запускать с правильными --dyn-reasoning-parser и --dyn-tool-call-parser.

Можно использовать предоставленный скрипт запуска или запустить компоненты вручную:

Вариант A: использование скрипта запуска

cd /workspace/examples/backends/trtllm
./launch/gpt_oss_disagg.sh

Вариант B: ручной запуск

  1. Запустите frontend:
# Start frontend with round-robin routing
python3 -m dynamo.frontend --router-mode round-robin --http-port 8000 &
  1. Запустите prefill worker:
CUDA_VISIBLE_DEVICES=0,1,2,3 python3 -m dynamo.trtllm \
--model-path /model \
--served-model-name openai/gpt-oss-120b \
--extra-engine-args examples/backends/trtllm/engine_configs/gpt-oss-120b/prefill.yaml \
--dyn-reasoning-parser gpt_oss \
--dyn-tool-call-parser harmony \
--disaggregation-mode prefill \
--max-num-tokens 20000 \
--max-batch-size 32 \
--free-gpu-memory-fraction 0.9 \
--tensor-parallel-size 4 \
--expert-parallel-size 4 &
  1. Запустите decode worker:
CUDA_VISIBLE_DEVICES=4,5,6,7 python3 -m dynamo.trtllm \
--model-path /model \
--served-model-name openai/gpt-oss-120b \
--extra-engine-args examples/backends/trtllm/engine_configs/gpt-oss-120b/decode.yaml \
--dyn-reasoning-parser gpt_oss \
--dyn-tool-call-parser harmony \
--disaggregation-mode decode \
--max-num-tokens 16384 \
--free-gpu-memory-fraction 0.9 \
--tensor-parallel-size 4 \
--expert-parallel-size 4

5. Проверьте готовность развертывания

Опрашивайте конечную точку /health, чтобы убедиться, что конечные точки prefill и decode worker запустились:

curl http://localhost:8000/health

Перед отправкой inference-запроса убедитесь, что доступны обе конечные точки:

{
"endpoints": [
"dyn://dynamo.backend.generate",
"dyn://dynamo.prefill.generate"
],
"status": "healthy"
}

Если указана только одна конечная точка worker, другая, возможно, еще запускается. Следите за логами worker, чтобы отслеживать ход запуска.

6. Протестируйте развертывание

Отправьте тестовый запрос, чтобы проверить развертывание:

curl -X POST http://localhost:8000/v1/responses \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-oss-120b",
"input": "Explain the concept of disaggregated serving in LLM inference in 3 sentences.",
"max_output_tokens": 200,
"stream": false
}'

Сервер предоставляет стандартную OpenAI-совместимую конечную точку API, принимающую JSON-запросы. Можно настраивать параметры вроде max_tokens, temperature и других под свои задачи.

7. Reasoning и Tool Calling

Dynamo поддерживает reasoning и tool calling в конечной точке OpenAI Chat Completion. Типичный рабочий процесс для приложения, построенного поверх Dynamo, выглядит так: у приложения есть набор инструментов, помогающих ассистенту дать точный ответ, и процесс обычно является многоходовым, поскольку включает выбор инструмента и генерацию ответа на основе результата работы инструмента.

Кроме того, reasoning effort можно настроить через chat_template_args. Увеличение reasoning effort повышает точность модели, но также замедляет ее. Поддерживаются три уровня: low, medium и high.

Ниже приведен пример отправки многораундовых запросов для выполнения пользовательского запроса с reasoning и tool calling: Настройка приложения (псевдокод)

# The tool defined by the application
def get_system_health():
for component in system.components:
if not component.health():
return False
return True

# The JSON representation of the declaration in ChatCompletion tool style
tool_choice = '{
"type": "function",
"function": {
"name": "get_system_health",
"description": "Returns the current health status of the LLM runtime—use before critical operations to verify the service is live.",
"parameters": {
"type": "object",
"properties": {}
}
}
}'

# On user query, perform below workflow.
def user_query(app_request):
# first round
# create chat completion with prompt and tool choice
request = ...
response = send(request)

if response["finish_reason"] == "tool_calls":
# second round
function, params = parse_tool_call(response)
function_result = function(params)
# create request with prompt, assistant response, and function result
request = ...
response = send(request)
return app_response(response)

Первый запрос с tools

curl localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '
{
"model": "openai/gpt-oss-120b",
"messages": [
{
"role": "user",
"content": "Hey, quick check: is everything up and running?"
}
],
"chat_template_args": {
"reasoning_effort": "low"
},
"tools": [
{
"type": "function",
"function": {
"name": "get_system_health",
"description": "Returns the current health status of the LLM runtime—use before critical operations to verify the service is live.",
"parameters": {
"type": "object",
"properties": {}
}
}
}
],
"response_format": {
"type": "text"
},
"stream": false,
"max_tokens": 300
}'

Первый ответ с выбором инструмента

{
"id": "chatcmpl-d1c12219-6298-4c83-a6e3-4e7cef16e1a9",
"choices": [
{
"index": 0,
"message": {
"tool_calls": [
{
"id": "call-1",
"type": "function",
"function": {
"name": "get_system_health",
"arguments": "{}"
}
}
],
"role": "assistant",
"reasoning_content": "We need to check system health. Use function."
},
"finish_reason": "tool_calls"
}
],
"created": 1758758741,
"model": "openai/gpt-oss-120b",
"object": "chat.completion",
"usage": null
}

Второй запрос с результатом tool calling

curl localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '
{
"model": "openai/gpt-oss-120b",
"messages": [
{
"role": "user",
"content": "Hey, quick check: is everything up and running?"
},
{
"role": "assistant",
"tool_calls": [
{
"id": "call-1",
"type": "function",
"function": {
"name": "get_system_health",
"arguments": "{}"
}
}
]
},
{
"role": "tool",
"tool_call_id": "call-1",
"content": "{\"status\":\"ok\",\"uptime_seconds\":372045}"
}
],
"chat_template_args": {
"reasoning_effort": "low"
},
"tools": [
{
"type": "function",
"function": {
"name": "get_system_health",
"description": "Returns the current health status of the LLM runtime—use before critical operations to verify the service is live.",
"parameters": {
"type": "object",
"properties": {}
}
}
}
],
"response_format": {
"type": "text"
},
"stream": false,
"max_tokens": 300
}'

Второй ответ с финальным сообщением

{
"id": "chatcmpl-9ebfe64a-68b9-4c1d-9742-644cf770ad0e",
"choices": [
{
"index": 0,
"message": {
"content": "All systems are green—everything’s up and running smoothly! 🚀 Let me know if you need anything else.",
"role": "assistant",
"reasoning_content": "The user asks: \"Hey, quick check: is everything up and running?\" We have just checked system health, it's ok. Provide friendly response confirming everything's up."
},
"finish_reason": "stop"
}
],
"created": 1758758853,
"model": "openai/gpt-oss-120b",
"object": "chat.completion",
"usage": null
}

Бенчмаркинг

Тестирование производительности с AIPerf

Контейнер Dynamo включает AIPerf, инструмент NVIDIA для бенчмаркинга генеративных AI-моделей. Этот инструмент помогает измерять пропускную способность, задержку и другие метрики производительности вашего развертывания.

Выполните следующий бенчмарк изнутри контейнера (после завершения шагов развертывания выше):

# Create a directory for benchmark results
mkdir -p /tmp/benchmark-results

# Run the benchmark - this command tests the deployment with high-concurrency synthetic workload
aiperf profile \
--model openai/gpt-oss-120b \
--tokenizer /model \
--endpoint-type chat \
--endpoint /v1/chat/completions \
--streaming \
--url localhost:8000 \
--synthetic-input-tokens-mean 32000 \
--synthetic-input-tokens-stddev 0 \
--output-tokens-mean 256 \
--output-tokens-stddev 0 \
--extra-inputs max_tokens:256 \
--extra-inputs min_tokens:256 \
--extra-inputs ignore_eos:true \
--extra-inputs "{\"nvext\":{\"ignore_eos\":true}}" \
--concurrency 256 \
--request-count 6144 \
--warmup-request-count 1000 \
--num-dataset-entries 8000 \
--random-seed 100 \
--artifact-dir /tmp/benchmark-results \
-H 'Authorization: Bearer NOT USED' \
-H 'Accept: text/event-stream'

Что делает этот бенчмарк

Эта команда:

  • тестирует chat completions с потоковыми ответами на раздельном развертывании
  • имитирует высокую нагрузку с 256 параллельными запросами и 6144 запросами всего
  • использует входы с длинным контекстом (32K токенов) для проверки производительности prefill
  • генерирует стабильные выходы (256 токенов) для измерения пропускной способности decode
  • включает период прогрева (1000 запросов) для стабилизации метрик производительности
  • сохраняет подробные результаты в /tmp/benchmark-results для анализа

Ключевые параметры, которые можно настроить:

  • --concurrency: число одновременных запросов (влияет на утилизацию GPU)
  • --synthetic-input-tokens-mean: средняя длина входа (проверяет емкость prefill)
  • --output-tokens-mean: средняя длина выхода (проверяет пропускную способность decode)
  • --request-count: общее число запросов для бенчмарка

Установка AIPerf вне контейнера

Если вы предпочитаете запускать бенчмарки вне контейнера:

# Install AIPerf
pip install aiperf

# Then run the same benchmark command, adjusting the tokenizer path if needed

Обзор архитектуры

Раздельная архитектура отделяет фазы prefill и decode:

flowchart TD
Client["Users/Clients<br/>(HTTP)"] --> Frontend["Frontend<br/>Round-Robin Router"]
Frontend --> Prefill["Prefill Worker<br/>(GPUs 0-3)"]
Frontend --> Decode["Decode Worker<br/>(GPUs 4-7)"]

Prefill -.->|KV Cache Transfer<br/>via UCX| Decode

Ключевые возможности

  1. Раздельное обслуживание: отделяет вычислительно интенсивный prefill от ограниченных памятью операций decode
  2. Оптимизированное использование ресурсов: разные стратегии параллелизма для prefill и decode
  3. Масштабируемая архитектура: число worker легко менять в зависимости от рабочей нагрузки
  4. Оптимизации TensorRT-LLM: использует эффективные ядра и управление памятью TensorRT-LLM

Устранение неполадок

Распространенные проблемы

  1. Ошибки CUDA out of memory

    • Уменьшите --max-num-tokens в командах запуска (сейчас 20000 для prefill, 16384 для decode)
    • Уменьшите --free-gpu-memory-fraction с 0.9 до 0.8 или 0.7
    • Убедитесь, что checkpoints модели совместимы с ожидаемым форматом
  2. Workers не подключаются

    • Убедитесь, что сервисы etcd и NATS запущены: docker ps | grep -E "(etcd|nats)"
    • Проверьте сетевую связность между контейнерами
    • Убедитесь, что настройки CUDA_VISIBLE_DEVICES соответствуют вашей конфигурации GPU
    • Проверьте, что назначенные GPU не используются другими процессами
  3. Проблемы производительности

    • Следите за утилизацией GPU с помощью nvidia-smi, пока развертывание работает
    • Проверьте логи worker на наличие узких мест или ошибок
    • Убедитесь, что размеры batch в ручных командах совпадают с размерами в конфигурационных файлах
    • Настройте параметры chunked prefill в соответствии со своей рабочей нагрузкой
    • При проблемах с подключением убедитесь, что порт 8000 не используется другим приложением
  4. Проблемы запуска контейнера

    • Убедитесь, что NVIDIA Container Toolkit установлен правильно
    • Проверьте, что Docker daemon запущен с поддержкой GPU
    • Убедитесь, что на диске достаточно места для весов модели и образов контейнеров
  5. Повторение токенов / генерация не останавливается

    • При использовании reasoning_effort: high модель может генерировать повторяющиеся токены и не останавливаться
    • Решение: задайте top_p=1 в запросе. Это рекомендуемые OpenAI параметры sampling
    • Пример запроса с рекомендуемыми параметрами:
      curl localhost:8000/v1/chat/completions -H "Content-Type: application/json" -d '{
      "model": "openai/gpt-oss-120b",
      "messages": [{"role": "user", "content": "Explain why Roger Federer is considered one of the greatest tennis players of all time"}],
      "chat_template_args": {
      "reasoning_effort": "high"
      },
      "top_p": 1,
      "max_tokens": 300
      }'

Следующие шаги

  • Расширенная конфигурация: изучите возможности сборки engine TensorRT-LLM для дальнейшей оптимизации
  • Мониторинг: настройте Prometheus и Grafana для production-мониторинга
  • Бенчмаркинг производительности: используйте AIPerf для измерения и оптимизации производительности вашего развертывания