For clean Markdown content of this page, append .md to this URL. For the complete documentation index, see https://docs.nvidia.com/dynamo/llms.txt. For full content including API reference and SDK examples, see https://docs.nvidia.com/dynamo/llms-full.txt.
Распределённая среда выполнения
Обзор
DistributedRuntime в Dynamo - это базовая инфраструктура фреймворка, которая обеспечивает распределённую коммуникацию и координацию между разными компонентами Dynamo. Она реализована на Rust (/lib/runtime) и доступна из других языков программирования через bindings (например, Python bindings находятся в /lib/bindings/python). Runtime поддерживает несколько backend'ов обнаружения (нативный Kubernetes или etcd) и request plane'ов (TCP, HTTP или NATS). DistributedRuntime имеет иерархическую структуру:
DistributedRuntime: This is the highest level object that exposes the distributed runtime interface. It manages connections to discovery backends (K8s API or etcd) and optional messaging (NATS for KV events), and handles lifecycle with cancellation tokens.Namespace:Namespace- это логическая группировка компонентов, которая изолирует разные развёртывания модели.Component:Component- это обнаруживаемый объект внутриNamespace, представляющий логическую единицу воркеров.Endpoint:Endpoint- это сетевой сервис, доступный по сети и предоставляющий конкретную услугу или функцию.
Хотя теоретически у каждого DistributedRuntime может быть несколько Namespace, если их имена уникальны (та же логика применима и к Component/Namespace, а также Endpoint/Component), на практике каждый компонент Dynamo обычно развёртывается в собственном процессе и поэтому имеет собственный объект DistributedRuntime. При этом они используют один и тот же namespace, чтобы находить друг друга.
Например, типичная конфигурация развёртывания (например, examples/backends/vllm/deploy/agg.yaml или examples/backends/sglang/deploy/agg.yaml) содержит несколько компонентов:
Frontend: запускает HTTP-сервер (OpenAI-compatible API на порту 8000), обрабатывает входящие запросы, применяет chat templates, выполняет tokenization и маршрутизирует запросы к воркерам. Функцияmake_engineинкапсулирует этот функционал.- Компоненты
Worker(например,VllmDecodeWorker,VllmPrefillWorker,SGLangDecodeWorker,TRTLLMWorker): выполняют фактические вычисления для inference с помощью своих движков (SGLang, TensorRT-LLM, vLLM).
Поскольку эти компоненты развёрнуты в разных процессах, у каждого есть собственный DistributedRuntime. Внутри своего DistributedRuntime они все используют один и тот же Namespace (например, vllm-agg, sglang-disagg). Внутри этого namespace у каждого есть свой Component:
Frontendиспользует функциюmake_engine, которая автоматически обрабатывает HTTP-serving, предварительную обработку запросов и обнаружение воркеров- Компоненты воркеров регистрируются под именами вроде
backend,prefill,decodeилиencoderв зависимости от своей роли - Воркеры регистрируют endpoints вроде
generate,clear_kv_blocksилиload_metrics
Их DistributedRuntime инициализируются в соответствующих main-функциях, их Namespace настраиваются в deployment YAML, а их Endpoint получаются по path. В Python используйте runtime.endpoint("namespace.component.endpoint") (например, runtime.endpoint("dynamo.backend.generate")).
Инициализация
В этом разделе мы объясняем, что происходит под капотом при создании объектов DistributedRuntime/Namespace/Component/Endpoint. В зависимости от среды развёртывания существует несколько режимов инициализации DistributedRuntime.
Иерархия и именование со временем могут измениться, и этот документ может не отражать последние изменения. Несмотря на такие изменения, основные концепции останутся прежними.
Backend'ы обнаружения сервисов
DistributedRuntime поддерживает два backend'а обнаружения сервисов, настраиваемые через DYN_DISCOVERY_BACKEND:
-
KV Store Discovery (
DYN_DISCOVERY_BACKEND=etcd): использует etcd для обнаружения сервисов. Это значение по умолчанию для всех развёртываний, если оно явно не переопределено. Также доступны другие KV store backend'ы (file,mem). -
Kubernetes Discovery (
DYN_DISCOVERY_BACKEND=kubernetes): использует нативные ресурсы Kubernetes (CRD DynamoWorkerMetadata, EndpointSlices) для обнаружения сервисов. Должен быть задан явно. Dynamo operator автоматически устанавливает эту переменную окружения для Kubernetes-развёртываний. etcd не требуется.
Примечание: автоматического определения среды развёртывания нет. По умолчанию runtime использует
etcd. Для Kubernetes-развёртываний operator внедряетDYN_DISCOVERY_BACKEND=kubernetesв окружение pod'ов.
При использовании Kubernetes Discovery backend KV store автоматически переключается на in-memory storage, поскольку etcd не нужен.
Инициализация Runtime
DistributedRuntime: когда создаётся объектDistributedRuntime, он устанавливает соединения в зависимости от backend'а обнаружения:- Kubernetes mode: использует K8s API для регистрации сервисов через DynamoWorkerMetadata CRD. Внешние зависимости не требуются.
- KV Store mode: подключается к etcd для обнаружения сервисов. Создаёт основной lease с фоновым task keep-alive. Все объекты, зарегистрированные в этом
DistributedRuntime, используют этотlease_idдля поддержания своего жизненного цикла. - NATS (optional): используется для messaging событий KV при KV-aware routing. Его можно отключить через
--no-router-kv-events, что включает routing на основе prediction без сохранения событий. - Request Plane: по умолчанию TCP. Можно настроить использование HTTP или NATS через переменную окружения
DYN_REQUEST_PLANE.
Namespace:Namespaceв первую очередь является механизмом логической группировки. Он задаёт root path для всех компонентов внутри этогоNamespace.Component: когда создаётся объектComponent, он регистрирует service во внутреннем registryDistributedRuntime, который отслеживает все services и endpoints.Endpoint: когда объект Endpoint создаётся и запускается, он выполняет регистрацию в зависимости от backend'а обнаружения:- Kubernetes mode: информация об Endpoint хранится в ресурсах DynamoWorkerMetadata CRD, за которыми для обнаружения следят другие компоненты.
- KV Store mode: информация об Endpoint хранится в etcd по path, который соответствует схеме именования:
/services/{namespace}/{component}/{endpoint}-{lease_id}. Обратите внимание, что endpoints разных воркеров одного типа (например, двухVllmPrefillWorkerв одном развёртывании) разделяют одно и то же имяNamespace,ComponentиEndpoint. Они различаются разными основнымиlease_id.
Вызов Endpoint'ов
Dynamo использует объект Client для вызова endpoint. Когда создаётся Client, ему передаются имена Namespace, Component и Endpoint. Затем он отслеживает изменения endpoint:
- Kubernetes mode: отслеживает ресурсы DynamoWorkerMetadata CRD на предмет обновлений endpoint.
- KV Store mode: настраивает etcd watcher для мониторинга префикса
/services/{namespace}/{component}/{endpoint}.
Watcher непрерывно обновляет Client информацией о доступных Endpoint.
Пользователь может выбрать, какую стратегию load balancing использовать при вызове Endpoint из Client; это реализовано в push_router.rs. Dynamo поддерживает три стратегии load balancing:
random: случайно выбрать endpoint для запросаround_robin: выбирать endpoints по кругуdirect: направить запрос на конкретный endpoint, указав instance ID
После выбора endpoint, к которому нужно обратиться, Client отправляет запрос через настроенный request plane (по умолчанию TCP). Request plane отвечает за фактическую передачу данных:
- TCP (default): прямое TCP-соединение с connection pooling
- HTTP: transport на базе HTTP/2
- NATS: transport через message broker (legacy)
Примеры
Мы приводим примеры базового использования DistributedRuntime на native Rust и Python (через bindings):
- Rust:
/lib/runtime/examples/ - Python: мы также приводим полные примеры использования
DistributedRuntime. За полными деталями реализации обратитесь к engines вcomponents/src/dynamo.