Для чистого Markdown-контента этой страницы добавьте
.mdк этому URL. Полный индекс документации см. в https://docs.nvidia.com/dynamo/llms.txt. Полный контент, включая API reference и примеры SDK, см. в https://docs.nvidia.com/dynamo/llms-full.txt.
Руководство по коммуникации в disaggregated inference
Это руководство объясняет, как prefill и decode workers обмениваются данными в disaggregated inference-архитектуре Dynamo на Kubernetes. Оно отвечает на частый вопрос: почему prefill и decode workers не могут использовать NVLink для связи на одном узле?
Краткое резюме
- NVLink нельзя использовать между Kubernetes pod'ами из-за изоляции процессов и разделения GPU
- RDMA (InfiniBand, RoCE или AWS EFA) требуется для production-развертываний disaggregated-систем
- Без RDMA ожидайте ухудшение производительности в 200-500 раз для Time To First Token (TTFT) — наблюдалось ~98 с TTFT с TCP против ~200–500 мс с RDMA
- UCX или libfabric — это уровни коммуникации, которые NIXL использует для передачи KV cache между workers
- Topology-aware KV transfer может ограничивать или направлять routing decode так, чтобы KV transfer оставался внутри выбранного домена топологии, например зоны или rack. См. Topology-Aware KV Transfer.
Обзор архитектуры
Стек коммуникации
Роли компонентов
| Компонент | Роль | Расположение |
|---|---|---|
| NIXL | Высокоуровневый API передачи KV cache | Runtime-библиотека Dynamo |
| UCX или libfabric | Низкоуровневый коммуникационный фреймворк | Системная библиотека |
| Транспорты | Физическое перемещение данных | Драйверы оборудования/ядра |
Почему NVLink нельзя использовать между pod'ами
Фундаментальное ограничение
NVLink — это прямое GPU-to-GPU соединение, которое работает на уровне оборудования. Для него нужно:
- Один и тот же процесс - обе GPU должны быть видны одному процессу, чтобы можно было вызвать
cudaDeviceEnablePeerAccess() - Прямой доступ к памяти - у процесса должны быть права на доступ к обеим областям памяти GPU
- Peer-to-peer mapping - CUDA runtime должен создать отображения памяти между GPU
Kubernetes pod'ы нарушают все три требования:
Техническое объяснение
-
Изоляция процессов: Kubernetes pod'ы работают в отдельных Linux namespaces. Даже на одном узле Pod A не может напрямую обращаться к пространству памяти Pod B.
-
Разделение GPU: Kubernetes device plugin назначает конкретные GPU каждому pod'у через
CUDA_VISIBLE_DEVICES. GPU 0 у Pod A и GPU 0 у Pod B — это физически разные устройства. -
Изоляция процессов/namespace: Каждый pod работает в отдельном namespace процесса. Peer-to-peer transfers NVLink требуют, чтобы обе GPU находились в рамках одного процесса, чтобы можно было вызвать
cudaDeviceEnablePeerAccess(). -
Регистрация памяти: Передачи NVLink используют
cudaMemcpyс включенным peer access. Для этого нужно вызватьcudaDeviceEnablePeerAccess()- что невозможно через границы процессов.
Где NVLink РАБОТАЕТ
NVLink работает внутри pod'а для стратегий параллелизма (TP, EP), где все GPU находятся в одном процессе:
# Decode worker с TP=4 использует NVLink между своими 4 GPU
VLLMDecodeWorker:
resources:
limits:
gpu: "4" # Все 4 GPU видны одному процессу
args:
- --tensor-parallel-size
- "4" # NVLink используется для коммуникации TP/EP внутри pod'а
Поддерживаемые варианты коммуникации
Сравнение транспортов
| Transport | Пропускная способность | Задержка | Same-Node | Cross-Node | GPU Direct |
|---|---|---|---|---|---|
| NVLink | 450-900 GB/s | ~µs | ✅ (только intra-pod) | ❌ | ✅ |
| InfiniBand RDMA | 20-50 GB/s | ~1 µs | ✅ | ✅ | ✅ (с GPUDirect) |
| RoCE RDMA | 10-25 GB/s | ~2 µs | ✅ | ✅ | ✅ (с GPUDirect) |
| TCP | 1-3 GB/s | ~50 µs | ✅ | ✅ | ❌ (host staging) |
Коммуникация на одном узле
Когда prefill и decode workers находятся на одном физическом узле:
Варианты (от лучшего к худшему):
- InfiniBand RDMA с GPUDirect → GPU-to-GPU, минуя CPU
- RoCE RDMA с GPUDirect → GPU-to-GPU, минуя CPU
- Host-staged RDMA → GPU→CPU→RDMA→CPU→GPU
- TCP (fallback) → GPU→CPU→TCP→CPU→GPU
Лучшая практика: Используйте RDMA даже для коммуникации на одном узле. Накладные расходы минимальны, и вы получаете одинаковое поведение независимо от того, попали pod'ы на один узел или на разные.
Межузловая коммуникация
Когда prefill и decode workers находятся на разных узлах:
Требования для оптимальной межузловой производительности:
- RDMA network fabric (InfiniBand, RoCE или AWS EFA)
- Включенный GPUDirect RDMA (память GPU зарегистрирована в NIC)
- Корректная конфигурация UCX или libfabric
Справочник по конфигурации UCX
Переменные окружения
Поведение UCX управляется через переменные окружения. Установите их в pod'ах prefill и decode workers.
Выбор основного транспорта
env:
- name: UCX_TLS
value: "rc_x,rc,dc_x,dc,cuda_copy,cuda_ipc"
| Transport | Описание | Когда использовать |
|---|---|---|
rc_x | Reliable Connection (ускоренный) | Основной RDMA transport |
rc | Reliable Connection (стандартный) | RDMA fallback |
dc_x | Dynamically Connected (ускоренный) | Масштабируемый RDMA (много endpoints) |
dc | Dynamically Connected (стандартный) | Fallback для масштабируемого RDMA |
cuda_copy | Staging памяти GPU↔Host | Требуется для GPU buffers |
cuda_ipc | CUDA IPC (same-node, same-pod) | Внутриподовaя передача GPU |
tcp | TCP sockets | Fallback, когда RDMA недоступен |
srd | Scalable Reliable Datagram (AWS EFA) | Специфика AWS (предоставляется EFA, не входит в core UCX) |
Исключение транспортов: Используйте префикс ^ для исключения (например, UCX_TLS=^mm исключает memory mapping).
Примечание: При явном задании UCX_TLS для GPU memory нужно включать cuda_copy или cuda_ipc, чтобы UCX распознал GPU buffers.
Параметры протокола rendezvous
env:
- name: UCX_RNDV_SCHEME
value: "get_zcopy"
- name: UCX_RNDV_THRESH
value: "0"
| Переменная | Значение | Описание |
|---|---|---|
UCX_RNDV_SCHEME | get_zcopy | Zero-copy RDMA GET (receiver pulls data) |
UCX_RNDV_SCHEME | put_zcopy | Zero-copy RDMA PUT (sender pushes data) |
UCX_RNDV_SCHEME | auto | Пусть UCX выбирает по размеру сообщения |
UCX_RNDV_THRESH | 0 | Использовать rendezvous для всех размеров сообщений |
UCX_RNDV_THRESH | 8192 | Использовать rendezvous для сообщений ≥8KB |
UCX_RNDV_THRESH | auto | Пусть UCX вычислит оптимальный порог |
Рекомендация: Для передачи KV cache (всегда большой) используйте get_zcopy с порогом 0.
⚠️ Исключение для AWS EFA: Не используйте
get_zcopyна AWS с Ubuntu 24.04 + Kernel ≥6.8. См. AWS EFA Configuration для нужных настроек.
Регистрация памяти
env:
- name: UCX_IB_REG_METHODS
value: "odp,rcache"
| Method | Описание |
|---|---|
odp | On-Demand Paging (динамическая регистрация) |
rcache | Registration cache (повторное использование регистраций) |
direct | Прямая регистрация (для каждой передачи) |
Отладка и диагностика
env:
- name: UCX_LOG_LEVEL
value: "info" # Options: fatal, error, warn, info, debug, trace, data, func
- name: UCX_LOG_FILE
value: "/tmp/ucx.log" # Optional: log to file instead of stdout
Примечание: Статистика UCX (UCX_STATS_DEST, UCX_STATS_TRIGGER) требует сборки UCX с флагом --enable-stats, который по умолчанию не включен.
Полная production-конфигурация
env:
# Transport selection - RDMA with GPU support
- name: UCX_TLS
value: "rc_x,rc,dc_x,dc,cuda_copy,cuda_ipc"
# Rendezvous for large transfers
- name: UCX_RNDV_SCHEME
value: "get_zcopy"
- name: UCX_RNDV_THRESH
value: "0"
# Memory registration optimization
- name: UCX_IB_REG_METHODS
value: "odp,rcache"
# RDMA settings
- name: UCX_IB_GID_INDEX
value: "3" # RoCE v2 GID index (cluster-specific)
Конфигурация InfiniBand
Для кластеров с InfiniBand RDMA (например, NIC ConnectX) используйте UCX с транспортом rc (Reliable Connection). Это стандартный путь для on-premises и bare-metal Kubernetes-кластеров.
RDMA Resources:
Запрашивайте по одному устройству rdma/ib на каждую GPU. RDMA device plugin автоматически подключает устройства /dev/infiniband/*:
resources:
limits:
gpu: "4"
custom:
rdma/ib: "4"
Аннотации pod'ов не нужны. Устройства InfiniBand добавляются device plugin.
Security Context:
Добавьте capabilities IPC_LOCK и SYS_RESOURCE. IPC_LOCK позволяет закреплять память RDMA, а SYS_RESOURCE позволяет повышать лимит memlock:
securityContext:
runAsUser: 0
capabilities:
add:
- IPC_LOCK
- SYS_RESOURCE
Переменные окружения (контейнеры worker):
env:
# --- UCX (RDMA transport) ---
- name: UCX_TLS
value: "rc_x,rc,cuda_copy,cuda_ipc"
- name: UCX_NET_DEVICES
value: "<ib-device>:1" # e.g. "mlx5_0:1" — run `ibv_devinfo` to find your device
- name: UCX_IB_ADDR_TYPE
value: "eth" # required for cross-pod IB on Kubernetes
- name: UCX_RNDV_SCHEME
value: "get_zcopy"
- name: UCX_RNDV_THRESH
value: "0"
- name: UCX_RC_TIMEOUT
value: "600s"
- name: UCX_KEEPALIVE_INTERVAL
value: "300s"
| Переменная | Описание |
|---|---|
UCX_TLS | rc_x (ускоренный RC) идет первым для оптимальной RDMA-производительности |
UCX_NET_DEVICES | Привязка к конкретному IB-устройству. Выполните ibv_devinfo внутри pod'а, чтобы увидеть доступные устройства. Используйте не bonded-устройство с валидным LID. |
UCX_IB_ADDR_TYPE | Должно быть eth для межpodовой коммуникации в Kubernetes. Без этого UCX использует LID-based addressing, которое не маршрутизируется между pod'ами. |
UCX_RNDV_SCHEME | get_zcopy включает zero-copy RDMA GET, оптимальный для больших KV cache transfer |
Примечание:
UCX_IB_ADDR_TYPE=eth— самая частая отсутствующая настройка при запуске NIXL disagg на InfiniBand-кластерах. Если инициализация NIXL проходит успешно, но передачи завершаются ошибкойNIXL_ERR_REMOTE_DISCONNECT, вероятно, причина именно в этом.
Известная проблема — bonded IB devices:
Некоторые кластеры предоставляют bonded InfiniBand-устройства (например, mlx5_bond_0) с LID=0. Если UCX выберет bonded-устройство, передачи могут завершиться неудачей. Проверьте LID устройства и выберите не bonded-устройство:
# Inside a pod with rdma/ib resources:
ibv_devinfo | grep -E "hca_id|lid"
# Use a device with a non-zero LID in UCX_NET_DEVICES
Конфигурация AWS EFA
NIXL поддерживает libfabric в качестве backend для развертываний AWS EFA. Это рекомендуемый подход для disaggregated inference на AWS, обеспечивающий пропускную способность передачи KV около ~9.6 GB/s. Полные инструкции по настройке см. в AWS EFA with NIXL documentation.
Требования:
- EFA installer версии 1.47.0 или новее
- Libfabric (устанавливается через EFA installer в
/opt/amazon/efa) - GDRCopy для операций GPU Direct RDMA (GPU Operator v26.x устанавливает это автоматически)
- Образ контейнера с поддержкой EFA (например,
nvcr.io/nvidia/ai-dynamo/vllm-runtime:1.2.0-efa-amd64)
Совместимость с ядром:
В GDRCopy v2.5.1 есть ошибка сборки на kernel 6.15+ из-за переопределения vm_flags_set. Зафиксируйте Ubuntu EKS AMI на kernel 6.14 или ниже, пока GDRCopy v2.5.2 не появится в GPU Operator.
| Версия ядра | GDRCopy v2.5.1 | GDRCopy v2.5.2 |
|---|---|---|
| 6.14 и ниже | ✅ Работает | ✅ Работает |
| 6.15+ | ❌ Сборка падает | ✅ Работает |
Pod Anti-Affinity (обязательно):
EFA рассчитан на межузловую коммуникацию. Prefill и decode workers должны размещаться на разных узлах, чтобы избежать ошибок EAGAIN во время KV transfer.
VllmDecodeWorker:
extraPodSpec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: nvidia.com/dynamo-component
operator: In
values:
- VllmPrefillWorker
topologyKey: kubernetes.io/hostname
Примечание: Anti-affinity нужно задавать только с одной стороны (здесь — у decode worker). Kubernetes scheduler применяет ограничение симметрично — если decode нельзя разместить рядом с prefill, они окажутся на разных узлах независимо от того, у какого pod'а задано правило.
Запросы ресурсов EFA:
Запрашивайте интерфейсы EFA в pod spec. Экземпляр p5.48xlarge имеет 32 EFA interfaces (32 сетевые карты × 1 интерфейс каждая) с общей пропускной способностью 3200 Gbps. Количество интерфейсов на одного worker зависит от вашего развертывания:
| Развертывание | EFA на worker | Обоснование |
|---|---|---|
| 1P + 1D на пару узлов | 4 | Достигается ~9.6 GB/s; остается 24 интерфейса для других pod'ов |
| Несколько workers на узел | 2-4 | Баланс между workers, делящими узел |
| Максимальная пропускная способность | 8-16 | Для очень больших KV cache transfer или TP>1 |
Пример с 4 интерфейсами EFA (проверенная конфигурация):
extraPodSpec:
mainContainer:
securityContext:
capabilities:
add: ["IPC_LOCK"]
resources:
limits:
vpc.amazonaws.com/efa: "4"
requests:
vpc.amazonaws.com/efa: "4"
Примечание: NIXL/libfabric автоматически распределяет трафик по всем выделенным EFA-интерфейсам. Конфигурация с 4 интерфейсами дала ~9.6 GB/s в тестах, чего достаточно для KV cache transfer Llama-3.1-8B при ISL=8000. Увеличьте количество, если вашей нагрузке нужна более высокая пропускная способность (например, для более крупных моделей или большего TP).
Переменные окружения:
env:
- name: NIXL_LOG_LEVEL
value: "INFO"
- name: LD_LIBRARY_PATH
value: "/usr/local/nixl/lib/x86_64-linux-gnu:/opt/amazon/efa/lib64:$(LD_LIBRARY_PATH)"
Конфигурация vLLM:
vllm serve <your-model> \
--kv-transfer-config '{"kv_connector":"NixlConnector","kv_role":"kv_both","kv_buffer_device":"cuda","kv_connector_extra_config":{"backends":["LIBFABRIC"]}}'
| Параметр | Значение | Назначение |
|---|---|---|
kv_connector | NixlConnector | Включает NIXL для передачи KV-cache |
kv_role | kv_both | Симметричная функциональность (producer и consumer) |
kv_buffer_device | cuda | Использует память GPU для KV-cache buffer |
backends | ["LIBFABRIC"] | Направляет NIXL traffic через EFA |
Проверка:
# Confirm EFA/libfabric installation
fi_info -p efa -t FI_EP_RDM
# Verify GDRCopy device
ls -la /dev/gdrdrv
# Check NIXL initialization in pod logs (should show 32 EFA devices on p5.48xlarge)
kubectl logs <worker-pod> | grep -i "NIXL\|libfabric\|efa"
Ожидаемый вывод в логах:
NIXL INFO Loaded backend plugin: LIBFABRIC
NIXL INFO Found 32 fabric devices
Конфигурация развертывания
Требования к ресурсам Kubernetes
apiVersion: nvidia.com/v1alpha1
kind: DynamoGraphDeployment
spec:
services:
VLLMPrefillWorker:
resources:
limits:
gpu: "2"
extraPodSpec:
mainContainer:
securityContext:
capabilities:
add: ["IPC_LOCK"] # Required for RDMA memory pinning
resources:
limits:
rdma/ib: "2" # RDMA resources (match TP size)
requests:
rdma/ib: "2"
Требуемые capabilities и ресурсы
| Настройка | Назначение | Примечания |
|---|---|---|
IPC_LOCK capability | Закрепление памяти для RDMA | Обходит RLIMIT_MEMLOCK; требуется для ibv_reg_mr() для закрепления GPU/host buffers |
rdma/ib resources | Доступ к RDMA NIC | Предоставляется RDMA device plugin |
sharedMemory.size | IPC между процессами | 16Gi для vLLM, 80Gi для TRT-LLM |
Инфраструктурные предварительные требования
-
RDMA Device Plugin: Экспонирует ресурсы
rdma/ibилиvpc.amazonaws.com/efaв Kubernetes# InfiniBand/RoCEkubectl get nodes -o jsonpath='{.items[*].status.allocatable.rdma/ib}'# AWS EFAkubectl get nodes -o jsonpath='{.items[*].status.allocatable.vpc\.amazonaws\.com/efa}' -
RDMA Network: Один из вариантов:
- InfiniBand or RoCE fabric
- AWS EFA (Elastic Fabric Adapter)
-
GPUDirect RDMA (необязательно, но рекомендуется):
- NVIDIA driver с включенным GPUDirect
- Загружен kernel module
nvidia-peermem(InfiniBand/RoCE) - Установлен GDRCopy (AWS EFA with libfabric)
Диагностика и проверка производительности
Проверка перед развертыванием
1. Проверьте доступность RDMA
# Check RDMA devices on node
kubectl debug node/<node-name> -it --image=ubuntu:22.04 -- bash
ibv_devinfo
Ожидаемый вывод показывает устройства InfiniBand или RoCE:
hca_id: mlx5_0
transport: InfiniBand (0)
fw_ver: 28.35.2000
...
2. Проверьте возможности транспортов UCX
# Inside a Dynamo worker pod
ucx_info -d
Ищите поддержку GPU memory:
# Memory domain: mlx5_0
# Component: ib
# memory types: host (access,reg,cache), cuda (access,reg,cache)
# ^^^^ GPU memory supported
Если видите только host: GPUDirect RDMA не работает. KV transfers будут использовать host staging.
3. Проверьте производительность UCX
# Server (on decode worker pod)
ucx_perftest -t tag_bw -n 100 -s 134217728
# Client (on prefill worker pod)
ucx_perftest <server-ip> -t tag_bw -n 100 -s 134217728
Ожидаемая пропускная способность:
- InfiniBand HDR: 20-25 GB/s на порт
- RoCE 100GbE: 10-12 GB/s
- TCP fallback: 1-2 GB/s
NIXL Benchmark Tool
Разверните NIXL benchmark, чтобы проверить end-to-end производительность KV transfer:
cd deploy/pre-deployment/nixl
./build_and_deploy.sh
Это развертывает benchmark, который измеряет фактическую скорость GPU-to-GPU передачи через NIXL.
Runtime-диагностика
Проверьте инициализацию backend NIXL
kubectl logs <worker-pod> | grep -i "NIXL\|UCX"
Хороший вывод:
NIXL INFO Backend UCX was instantiated
Плохой вывод (RDMA не работает):
UCX WARN no RDMA transports available
NIXL INFO falling back to TCP transport
Отслеживайте производительность передачи
Проверьте Grafana dashboards на предмет:
- NIXL transfer bandwidth: должен быть в GB/s, а не в MB/s
- KV cache transfer latency: должна быть меньше 500 мс для типичных нагрузок
Красные флаги, указывающие на проблемы с RDMA:
- Пропускная способность передачи ниже 1 GB/s
- TTFT > 10 секунд
- Ошибки
Unsupported operationв логах
Частые диагностические команды
# Check UCX transport selection
kubectl exec <pod> -- env | grep UCX
# Verify RDMA device visibility
kubectl exec <pod> -- ls /dev/infiniband/
# Check GPUDirect RDMA status (on node)
kubectl debug node/<node> -it --image=ubuntu:22.04 -- \
nsenter -t 1 -m -u -n -p -- dmesg | grep -i "nvidia\|peermem\|gdr"
# Test basic connectivity between pods
kubectl exec <prefill-pod> -- ping -c 3 <decode-pod-ip>
Ожидания по производительности
Накладные расходы KV Cache Transfer
| Конфигурация | Накладные расходы TTFT (сред.) | KV Transfer BW | Источник |
|---|---|---|---|
| Aggregated (baseline) | 0 | N/A | KV transfer не нужен |
| Disagg + InfiniBand RDMA с GPUDirect | +200-500 ms | 20-50 GB/s | Ожидаемо по аппаратным спецификациям |
| Disagg + RoCE RDMA с GPUDirect | +300-800 ms | 10-25 GB/s | Ожидаемо по аппаратным спецификациям |
| Disagg + AWS EFA с libfabric + GDRCopy | +37 ms | ~9.6 GB/s | Измерено на AWS p5.48xlarge (Llama-3.1-8B, ISL=8000, OSL=50) |
| Disagg + Host-staged (без GPUDirect) | +1-3 s | 1-3 GB/s | Ожидаемо - узкое место CPU |
| Disagg + AWS EFA с UCX (без GPUDirect) | ~в 3 раза медленнее aggregated | ~1 GB/s | Измерено на AWS p5.48xlarge |
| Disagg + TCP fallback | +90-100 s | ~100 MB/s | Измерено ~98 s TTFT на AWS p5.48xlarge |
Примечание: Для развертываний AWS EFA используйте libfabric с GDRCopy, чтобы включить GPUDirect RDMA. UCX на AWS EFA не поддерживает GPUDirect на kernel ≥6.8 и приводит к сильно деградировавшей производительности. См. AWS EFA Configuration для инструкций по настройке.
Когда disaggregated имеет смысл
Используйте disaggregated-архитектуру, когда:
- Длина входной последовательности (ISL) ≥ 4000 токенов (прирост throughput 14-22%)
- Нужно независимое масштабирование prefill и decode capacity
- У prefill и decode разные требования к оборудованию
Используйте aggregated-архитектуру, когда:
- Критична низкая задержка TTFT
- Длина входных последовательностей меньше 2000 токенов (минимальная выгода от disagg)
- RDMA недоступна
Break-even analysis
Накладные расходы KV transfer амортизируются на выходных токенах. Измеренные данные Llama-3.1-8B-Instruct на AWS p5.48xlarge с NIXL+libfabric:
KV Transfer Overhead (TTFT min, unqueued):
- Aggregated: ~173ms
- Disaggregated: ~210ms
- KV transfer cost: ~37ms
Performance at ISL=8000, OSL=50, concurrency=10:
- ITL improvement: 41% faster per-token generation
- Throughput gain: 22% higher output throughput
Ключевой вывод: Накладные расходы KV transfer через libfabric+EFA составляют всего ~37 ms. В сочетании с ускорением decode (ITL) на 41% disaggregated inference дает на 22% более высокий throughput для prefill-bound workloads.
| Метрика | Aggregated | Disaggregated | Разница |
|---|---|---|---|
| TTFT (min, unqueued) | 173 ms | 210 ms | +37 ms |
| TTFT (p95) | 2097 ms | 1752 ms | -16% |
| ITL (avg) | 28.5 ms | 16.9 ms | -41% |
| Output throughput (ISL=8000, OSL=50) | 204 tok/s | 248 tok/s | +22% |
Преимущество disagg масштабируется с длиной входа (ISL) (все измерения при OSL=50, concurrency=10):
| ISL | Throughput Δ | ITL Δ | Рекомендация |
|---|---|---|---|
| 1000 | ~0% | -7% | Используйте aggregated |
| 2000 | +3% | -11% | Подходит любой вариант |
| 4000 | +14% | -18% | Предпочтителен disagg |
| 8000 | +22% | -41% | Disagg настоятельно рекомендуется |
Руководство по устранению неполадок
Проблема: TTFT 10+ секунд
Симптомы: TTFT ухудшается с ожидаемых 200-500 мс до 10+ секунд
Корневая причина: RDMA не активна, идет fallback на TCP
Диагностика:
kubectl logs <worker-pod> | grep -i "transport\|UCX\|TCP"
Решения:
- Убедитесь, что установлен RDMA device plugin
- Добавьте запросы ресурса
rdma/ibв pod spec - Добавьте capability
IPC_LOCK - Задайте переменные окружения UCX
Проблема: ошибки "Unsupported operation"
Симптомы: В логах видно Unexpected UCX error: Unsupported operation
Корневая причина: UCX пытается использовать GPU RDMA на оборудовании, которое это не поддерживает
Решения:
- Проверьте, включен ли GPUDirect RDMA:
ucx_info -d | grep cuda - Если не поддерживается, установите
UCX_RNDV_THRESH=inf, чтобы отключить GPU RDMA - Проверьте, что загружен модуль
nvidia-peermem
Проблема: AWS EFA не использует GPU Direct
Симптомы: Ухудшение производительности в 3 раза на AWS, хотя EFA настроен
Корневая причина: GPU Direct RDMA не работает на kernel ≥6.8 с EFA при использовании UCX
Решение: Используйте libfabric вместо UCX для развертываний AWS EFA. Libfabric с GDRCopy обеспечивает эффективные операции GPU Direct RDMA на AWS. См. раздел AWS EFA Configuration для инструкций по настройке.
Альтернативные варианты (если libfabric недоступен):
- Использовать kernel ниже 6.8 (Ubuntu 22.04 с kernel 5.15)
- Принять штраф по производительности от host-staging
Проблема: ошибки EFA EAGAIN (fi_read still retrying)
Симптомы: В логах decode worker повторяются ошибки EAGAIN:
fi_read still retrying EAGAIN on rail 0
fi_read still retrying EAGAIN on rail 1
...
Корневая причина: Prefill и decode workers размещены на одном узле. AWS EFA предназначен для межузловой коммуникации и некорректно работает для внутринодовых передач.
Диагностика:
# Check if workers are on the same node
kubectl get pods -o wide | grep vllm
Если и prefill, и decode workers показывают один и тот же NODE, это и есть проблема.
Решение: Добавьте правила pod anti-affinity, чтобы гарантировать размещение workers на разных узлах:
VllmDecodeWorker:
extraPodSpec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: nvidia.com/dynamo-component
operator: In
values:
- VllmPrefillWorker
topologyKey: kubernetes.io/hostname
Примечание: Используйте
nvidia.com/dynamo-componentкак ключ label, а неapp.kubernetes.io/component. Dynamo operator использует этот label для определения типов компонентов.
Проблема: NIXL_ERR_BACKEND при create_backend на InfiniBand
Симптомы: Создание backend NIXL сразу завершается с NIXL_ERR_BACKEND. В логах UCX видно:
mlx5dv_devx_obj_destroy(SRQ) failed: Invalid argument
mlx5dv_devx_obj_destroy(CQ) failed: Invalid argument
Или:
select.c: no active messages transport: Unsupported operation
Корневые причины:
-
Bonded IB device с LID=0: UCX по умолчанию выбирает
mlx5_bond_0, но bonded devices могут иметь LID=0 (недопустимо для UD transport). Исправление: задайтеUCX_NET_DEVICESна не bonded-устройство с валидным LID. -
Несовпадение версий UCX/OFED: Библиотека UCX mlx5 в контейнере может быть собрана против другого devx ABI, чем драйвер ядра на хосте. Любой transport, использующий IB (rc, cuda_ipc с IB), вызывает падение devx.
-
Отсутствует инъекция RDMA device: Если в pod spec не запрошен
rdma/ib, в контейнер не будут добавлены IB-устройства.
Диагностика:
# Check which IB devices are visible and their LIDs
ibv_devinfo | grep -E "hca_id|lid"
# Verify rdma/ib was requested
kubectl get pod <pod> -o jsonpath='{.spec.containers[0].resources}'
# Check /dev/infiniband exists
ls -la /dev/infiniband/
Решения:
- Запросите ресурсы
rdma/ib(по 1 на GPU) в pod spec - Задайте
UCX_NET_DEVICESна не bonded-устройство, если уmlx5_bond_0LID=0 - Убедитесь, что сборка UCX в образе контейнера соответствует версии OFED на хосте
Проблема: периодические сбои передачи
Симптомы: Спорадические getXferStatus: backend 'UCX' returned error status
Диагностика:
# Enable UCX debug logging
kubectl set env deployment/<worker> UCX_LOG_LEVEL=debug
kubectl logs <worker-pod> | grep -i error
Частые причины:
- Сетевые перегрузки или потери пакетов
- Несовпадение версий UCX между pod'ами
- Истощение RDMA-ресурсов
Краткий справочник
Минимально жизнеспособная RDMA-конфигурация
env:
- name: UCX_TLS
value: "rc_x,rc,dc_x,dc,cuda_copy,cuda_ipc"
- name: UCX_RNDV_SCHEME
value: "get_zcopy"
- name: UCX_RNDV_THRESH
value: "0"
securityContext:
capabilities:
add: ["IPC_LOCK"]
resources:
limits:
rdma/ib: "2"
requests:
rdma/ib: "2"
Чек-лист диагностики
- Ресурсы
rdma/ibвидны:kubectl get nodes -o jsonpath='{..allocatable.rdma/ib}' - NIXL инициализирован:
kubectl logs <pod> | grep "Backend" - Пропускная способность передачи > 1 GB/s (проверьте метрики Grafana)
Для развертываний UCX:
- UCX видит RDMA-устройства:
ucx_info -d | grep "Transport: rc" - UCX видит GPU memory:
ucx_info -d | grep "memory types.*cuda"
Для развертываний libfabric (AWS EFA):
- EFA-устройства доступны:
fi_info -p efa - GDRCopy установлен:
ls /dev/gdrdrv