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

Для чистого 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.

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

Стек коммуникации

Стек коммуникации disaggregated inference, показывающий NIXL, UCX/libfabric и транспортные уровни

Роли компонентов

КомпонентРольРасположение
NIXLВысокоуровневый API передачи KV cacheRuntime-библиотека Dynamo
UCX или libfabricНизкоуровневый коммуникационный фреймворкСистемная библиотека
ТранспортыФизическое перемещение данныхДрайверы оборудования/ядра

Фундаментальное ограничение

NVLink — это прямое GPU-to-GPU соединение, которое работает на уровне оборудования. Для него нужно:

  1. Один и тот же процесс - обе GPU должны быть видны одному процессу, чтобы можно было вызвать cudaDeviceEnablePeerAccess()
  2. Прямой доступ к памяти - у процесса должны быть права на доступ к обеим областям памяти GPU
  3. Peer-to-peer mapping - CUDA runtime должен создать отображения памяти между GPU

Kubernetes pod'ы нарушают все три требования:

Почему NVLink не может работать между Kubernetes pod'ами из-за изоляции процессов

Техническое объяснение

  1. Изоляция процессов: Kubernetes pod'ы работают в отдельных Linux namespaces. Даже на одном узле Pod A не может напрямую обращаться к пространству памяти Pod B.

  2. Разделение GPU: Kubernetes device plugin назначает конкретные GPU каждому pod'у через CUDA_VISIBLE_DEVICES. GPU 0 у Pod A и GPU 0 у Pod B — это физически разные устройства.

  3. Изоляция процессов/namespace: Каждый pod работает в отдельном namespace процесса. Peer-to-peer transfers NVLink требуют, чтобы обе GPU находились в рамках одного процесса, чтобы можно было вызвать cudaDeviceEnablePeerAccess().

  4. Регистрация памяти: Передачи NVLink используют cudaMemcpy с включенным peer access. Для этого нужно вызвать cudaDeviceEnablePeerAccess() - что невозможно через границы процессов.

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-NodeCross-NodeGPU Direct
NVLink450-900 GB/s~µs✅ (только intra-pod)
InfiniBand RDMA20-50 GB/s~1 µs✅ (с GPUDirect)
RoCE RDMA10-25 GB/s~2 µs✅ (с GPUDirect)
TCP1-3 GB/s~50 µs❌ (host staging)

Коммуникация на одном узле

Когда prefill и decode workers находятся на одном физическом узле:

RDMA-коммуникация на одном узле между prefill и decode pod'ами

Варианты (от лучшего к худшему):

  1. InfiniBand RDMA с GPUDirect → GPU-to-GPU, минуя CPU
  2. RoCE RDMA с GPUDirect → GPU-to-GPU, минуя CPU
  3. Host-staged RDMA → GPU→CPU→RDMA→CPU→GPU
  4. TCP (fallback) → GPU→CPU→TCP→CPU→GPU

Лучшая практика: Используйте RDMA даже для коммуникации на одном узле. Накладные расходы минимальны, и вы получаете одинаковое поведение независимо от того, попали pod'ы на один узел или на разные.

Межузловая коммуникация

Когда prefill и decode workers находятся на разных узлах:

RDMA-коммуникация между prefill и decode pod'ами на разных узлах

Требования для оптимальной межузловой производительности:

  • 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_xReliable Connection (ускоренный)Основной RDMA transport
rcReliable Connection (стандартный)RDMA fallback
dc_xDynamically Connected (ускоренный)Масштабируемый RDMA (много endpoints)
dcDynamically Connected (стандартный)Fallback для масштабируемого RDMA
cuda_copyStaging памяти GPU↔HostТребуется для GPU buffers
cuda_ipcCUDA IPC (same-node, same-pod)Внутриподовaя передача GPU
tcpTCP socketsFallback, когда RDMA недоступен
srdScalable 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_SCHEMEget_zcopyZero-copy RDMA GET (receiver pulls data)
UCX_RNDV_SCHEMEput_zcopyZero-copy RDMA PUT (sender pushes data)
UCX_RNDV_SCHEMEautoПусть UCX выбирает по размеру сообщения
UCX_RNDV_THRESH0Использовать rendezvous для всех размеров сообщений
UCX_RNDV_THRESH8192Использовать rendezvous для сообщений ≥8KB
UCX_RNDV_THRESHautoПусть 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Описание
odpOn-Demand Paging (динамическая регистрация)
rcacheRegistration 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_TLSrc_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_SCHEMEget_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.1GDRCopy 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_connectorNixlConnectorВключает NIXL для передачи KV-cache
kv_rolekv_bothСимметричная функциональность (producer и consumer)
kv_buffer_devicecudaИспользует память 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.sizeIPC между процессами16Gi для vLLM, 80Gi для TRT-LLM

Инфраструктурные предварительные требования

  1. RDMA Device Plugin: Экспонирует ресурсы rdma/ib или vpc.amazonaws.com/efa в Kubernetes

    # InfiniBand/RoCE
    kubectl get nodes -o jsonpath='{.items[*].status.allocatable.rdma/ib}'
    # AWS EFA
    kubectl get nodes -o jsonpath='{.items[*].status.allocatable.vpc\.amazonaws\.com/efa}'
  2. RDMA Network: Один из вариантов:

    • InfiniBand or RoCE fabric
    • AWS EFA (Elastic Fabric Adapter)
  3. 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)0N/AKV transfer не нужен
Disagg + InfiniBand RDMA с GPUDirect+200-500 ms20-50 GB/sОжидаемо по аппаратным спецификациям
Disagg + RoCE RDMA с GPUDirect+300-800 ms10-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 s1-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.

МетрикаAggregatedDisaggregatedРазница
TTFT (min, unqueued)173 ms210 ms+37 ms
TTFT (p95)2097 ms1752 ms-16%
ITL (avg)28.5 ms16.9 ms-41%
Output throughput (ISL=8000, OSL=50)204 tok/s248 tok/s+22%

Преимущество disagg масштабируется с длиной входа (ISL) (все измерения при OSL=50, concurrency=10):

ISLThroughput Δ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"

Решения:

  1. Убедитесь, что установлен RDMA device plugin
  2. Добавьте запросы ресурса rdma/ib в pod spec
  3. Добавьте capability IPC_LOCK
  4. Задайте переменные окружения UCX

Проблема: ошибки "Unsupported operation"

Симптомы: В логах видно Unexpected UCX error: Unsupported operation

Корневая причина: UCX пытается использовать GPU RDMA на оборудовании, которое это не поддерживает

Решения:

  1. Проверьте, включен ли GPUDirect RDMA: ucx_info -d | grep cuda
  2. Если не поддерживается, установите UCX_RNDV_THRESH=inf, чтобы отключить GPU RDMA
  3. Проверьте, что загружен модуль 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 недоступен):

  1. Использовать kernel ниже 6.8 (Ubuntu 22.04 с kernel 5.15)
  2. Принять штраф по производительности от 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

Корневые причины:

  1. Bonded IB device с LID=0: UCX по умолчанию выбирает mlx5_bond_0, но bonded devices могут иметь LID=0 (недопустимо для UD transport). Исправление: задайте UCX_NET_DEVICES на не bonded-устройство с валидным LID.

  2. Несовпадение версий UCX/OFED: Библиотека UCX mlx5 в контейнере может быть собрана против другого devx ABI, чем драйвер ядра на хосте. Любой transport, использующий IB (rc, cuda_ipc с IB), вызывает падение devx.

  3. Отсутствует инъекция 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/

Решения:

  1. Запросите ресурсы rdma/ib (по 1 на GPU) в pod spec
  2. Задайте UCX_NET_DEVICES на не bonded-устройство, если у mlx5_bond_0 LID=0
  3. Убедитесь, что сборка 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

Связанная документация