Чтобы получить чистое Markdown-содержимое этой страницы, добавьте .md к этому URL. Полный индекс документации см. на https://docs.nvidia.com/dynamo/llms.txt. Полное содержимое, включая справочник API и примеры SDK, см. на https://docs.nvidia.com/dynamo/llms-full.txt.
Настройка производительности дизагрегированного режима
Дизагрегация повышает производительность за счет разделения prefill и decode по разным движкам, что снижает взаимное влияние этих этапов. Однако для производительной дизагрегации требуется тщательная настройка параметров инференса. В частности, нужно настроить три набора параметров:
- Конфигурацию и параметры движка (например, схему параллелизации, максимальное число токенов и т. д.).
- Конфигурацию и параметры дизагрегированного маршрутизатора.
- Количество движков prefill и decode.
Это руководство описывает процесс настройки этих параметров.
Конфигурация и настройка движка
Самая важная настройка конфигурации движка — схема параллелизации. Для большинства плотных моделей лучший вариант — использовать TP внутри узла и PP между узлами. Например, для Llama-405b w8a8 на H100 обычно оптимальны TP8 на одном узле или TP8PP2 на двух узлах. Далее нужно определить, сколько GPU использовать для обслуживания модели. Обычно зависимость количества GPU и производительности выглядит так:
| Количество GPU | Производительность |
|---|---|
| Веса не помещаются в VRAM | OOM |
| (Веса едва помещаются в VRAM) | (KV cache слишком мал для достаточно большой длины последовательности или разумного размера батча) |
| Минимальное количество с приемлемым объемом KV cache | Лучшая общая пропускная способность/GPU, худшая задержка/пользователь |
| Между минимумом и максимумом | Компромисс между пропускной способностью/GPU и задержкой/пользователь |
| Максимум, ограниченный масштабируемостью коммуникаций | Худшая общая пропускная способность/GPU, лучшая задержка/пользователь |
| Больше максимума | Доминируют коммуникационные накладные расходы, производительность низкая |
для движков только decode иногда большее количество GPU дает больший KV cache на GPU и больше параллельно выполняющихся запросов decoding, что улучшает и пропускную способность/GPU, и задержку/пользователь.
Например, для Llama-3.3-70b с квантизацией NVFP4 на B200 в vLLM при доле свободной памяти GPU 0.9:
| Размер TP | Размер KV Cache (GB) | KV Cache на GPU (GB) | Улучшение на GPU относительно TP1 |
|---|---|---|---|
| 1 | 113 | 113 | 1.00x |
| 2 | 269 | 135 | 1.19x |
| 4 | 578 | 144 | 1.28x |
Лучшее количество GPU для движков prefill и decode можно определить, запустив несколько фиксированных тестов ISL/OSL/concurrency с помощью AIPerf и сравнив результаты с SLA. AIPerf предустановлен в контейнере Dynamo.
Если вы не знакомы с AIPerf, начните с этого полезного руководства.
Помимо схемы параллелизации, часто настраивают максимальный размер батча, максимальное число токенов и размер блока.
Для движков prefill обычно предпочтительны небольшой размер батча и большое значение max_num_token.
Для движков decode обычно предпочтительны большой размер батча и среднее значение max_num_token.
Подробности настройки max_num_token и max_batch_size см. в следующем разделе.
Если размер блока слишком мал, при передаче P->D KV cache используются небольшие фрагменты памяти, что ухудшает производительность. Слишком малый размер блока также приводит к фрагментации памяти при вычислении attention, но обычно этот эффект незначителен. Если размер блока слишком велик, снижается доля попаданий в prefix cache. Для большинства плотных моделей размер блока 128 является хорошим выбором.
Доля памяти GPU
У каждого бэкенда движка есть собственный CLI-флаг для управления долей памяти GPU, зарезервированной под KV cache (после выделения памяти под веса модели и буферы активаций):
| Движок | CLI-флаг | Переменная окружения движка | По умолчанию |
|---|---|---|---|
| vLLM | --gpu-memory-utilization | — | 0.9 |
| SGLang | --mem-fraction-static | — | 0.88 |
| TRT-LLM | --free-gpu-memory-fraction | DYN_TRTLLM_FREE_GPU_MEMORY_FRACTION | 0.9 |
Скрипты запуска Dynamo используют абсолютные переопределения KV cache для детерминированного управления памятью GPU, безопасного при параллельном выполнении. Для vLLM _PROFILE_OVERRIDE_VLLM_KV_CACHE_BYTES соответствует --kv-cache-memory-bytes. Для SGLang _PROFILE_OVERRIDE_SGLANG_MAX_TOTAL_TOKENS соответствует --max-total-tokens. Эти значения задаются tests/utils/profile_pytest.py во время профилирования бинарным поиском и tests/utils/pytest_parallel_gpu.py во время выполнения.
Более низкая доля памяти оставляет больше запаса для других выделений CUDA (например, буферов активаций и буферов NCCL), но уменьшает KV cache. Более высокая доля позволяет обслуживать больше одновременных запросов, но повышает риск OOM из-за выделений памяти не под KV cache. Типичные production-значения — 0.85-0.95.
В vLLM, когда --kv-cache-memory-bytes задан явным значением (не None), он переопределяет и игнорирует --gpu-memory-utilization при расчете размера KV cache (документация vLLM CacheConfig). Именно поэтому мы используем --kv-cache-memory-bytes для allocation, безопасного при параллельном выполнении: он задает детерминированный абсолютный лимит KV cache, устойчивый к race conditions при профилировании.
Дизагрегированный маршрутизатор
Дизагрегированный маршрутизатор решает, выполнять ли prefill запроса в удаленном движке prefill или локально в движке decode с помощью chunked prefill. В большинстве фреймворков, когда включен chunked prefill и в одну forward-итерацию попадает смесь запросов prefilling и decoding, запускаются три ядра:
-
Ядро attention для контекстных токенов (ядро context_fmha в TRTLLM).
-
Ядро attention для токенов decode (ядро xqa в TRTLLM).
-
Dense-ядро для объединенных активных токенов в prefills и decodes.
Движок Prefill
Для движка prefill лучшая стратегия — работать с минимальным размером батча, который насыщает GPU, чтобы минимизировать среднее время до первого токена (TTFT). Например, для Llama3.3-70b с квантизацией NVFP4 на B200 TP1 в vLLM на рисунке ниже показано время prefill при разных isl (prefix caching отключен):

При isl меньше 1000 эффективность prefill низкая, потому что GPU не полностью насыщен. При isl больше 4000 время prefill на токен растет, потому что attention дольше вычисляется на более длинной истории.
В настоящее время движки prefill в Dynamo работают с размером батча 1.
Чтобы убедиться, что движок prefill насыщен, пользователи могут задать max-local-prefill-length в точку насыщения, чтобы обеспечить оптимальную работу движка prefill.
Движок Decode
В движке decode максимальный размер батча и максимальное число токенов влияют на размер промежуточных тензоров. При большем размере батча и большем числе токенов размер промежуточных тензоров увеличивается, а размер KV cache уменьшается. В TensorRT-LLM (TRTLLM) есть хорошее резюме по потреблению памяти; похожие идеи применимы и к другим LLM-фреймворкам.
Когда включен chunked prefill, максимальное число токенов управляет самым длинным prefill, который можно присоединить к decode, и контролирует межтокенную задержку (ITL). Для одних и тех же запросов prefill большое максимальное число токенов приводит к меньшему числу, но более длительным паузам в генерации, а малое максимальное число токенов — к большему числу, но более коротким паузам. Однако в настоящее время chunked prefill не поддерживается в Dynamo (бэкенд vLLM). Поэтому текущая лучшая стратегия — задать максимальный размер батча равным оптимизированному размеру KV cache, а максимальное число токенов — равным максимальной длине локального prefill + максимальному размеру батча (поскольку у одного decode-запроса есть один активный токен).
Количество движков Prefill и Decode
Оптимальный выбор настроек Dynamo зависит от рабочего режима модели. В зависимости от нагрузки мы определяем три рабочих режима:
-
Низкая нагрузка: В большую часть времени endpoint получает запросы от одного пользователя (single-stream).
-
Средняя нагрузка: Endpoint получает запросы от нескольких пользователей, но KV cache движков decode никогда не используется полностью.
-
Высокая нагрузка: Endpoint получает запросы от нескольких пользователей, и запросы становятся в очередь из-за отсутствия доступного KV cache в движках decode.
При низкой нагрузке дизагрегация не дает большого выигрыша, поскольку prefill и decode обычно вычисляются раздельно. Обычно лучше использовать один монолитный движок.
При средней нагрузке дизагрегация обеспечивает лучшую ITL по сравнению с движками с приоритетом prefill и chunked prefill, а также лучшую TTFT для каждого пользователя по сравнению с движком chunked prefill и движком только decode. Пользователи Dynamo могут настраивать количество движков prefill и decode на основе SLA по TTFT и ITL.
При высокой нагрузке, когда узким местом является емкость KV cache, дизагрегация следующим образом влияет на использование KV cache в движках decode:
-
Увеличивает общий объем KVcache:
-
Возможность использовать большие значения TP в движках decode дает больше KV cache на GPU и более высокую долю попаданий в prefix cache.
-
Когда prefill запросов выполняется удаленно, движку decode не нужно поддерживать свой KV cache (в настоящее время не реализовано в Dynamo).
-
Более низкая ITL сокращает время decode и позволяет тому же объему KV cache обслуживать больше запросов.
-
-
Уменьшает общий объем KV cache:
- Некоторые GPU настроены как движки prefill, чей KV cache не используется на этапе decode.
Поскольку в настоящее время Dynamo выделяет KV-блоки сразу, когда движок decode получает запросы,
рекомендуется использовать как можно меньше движков prefill (вплоть до полного отказа от движка prefill), чтобы максимизировать доступный KV cache в движках decode.
Чтобы предотвратить очереди у движков prefill, пользователи могут задать большое значение max-local-prefill-length и присоединять больше запросов prefill к движкам decode.