La mesa compartida: NVLink, NVSwitch y NCCL, el cable por el que pasa cada token en tensor parallel
Este post baja un piso por debajo del motor. En el stack de inferencia en siete capas y en una grande vs N pequeñas se decidía cuántas GPUs y cómo repartir el modelo; aquí se explica el cable que hace que ese reparto funcione —o que lo estrangule. Es el primero de una mini-serie “por debajo del motor”: interconnect (este) → kernel y NUMA → resource managers de Kubernetes.
TL;DR
Tensor parallelism (TP) no parte un modelo en cuatro trozos que corren solos. Reparte cada capa entre las GPUs, pero después de la atención y después del MLP las GPUs tienen que sumar sus resultados parciales con un all-reduce. En un Llama-70B con 80 capas, eso son ~160 all-reduces por cada token generado. Ese all-reduce viaja por el interconnect, así que el interconnect está en la ruta crítica de cada token, no en la fontanería de fondo. En un baseboard HGX H100, las 8 GPUs hablan todas-con-todas a 900 GB/s bidireccionales vía cuatro NVSwitch; sin NVSwitch/NVLink, ese mismo tráfico cae al CPU vía PCIe y pierde un orden de magnitud. NCCL es la librería que decide cómo se hace cada colectivo (ring, tree, o NVLS = NVLink-SHARP, que descarga la suma en el propio switch). Y hay una asimetría que casi nadie tiene en la cabeza: el decode es latency-bound (mensajes diminutos, 16 KB) y el prefill es bandwidth-bound (activaciones enormes batcheadas) — por eso “más ancho de banda NVLink” acelera el prefill pero apenas toca el decode token-a-token. Este post explica el mecanismo, da los 10 knobs reales de NCCL/driver donde se toca, y conecta con el custom all-reduce de vLLM, el disaggregated serving y la observabilidad GPU. Con escepticismo sobre qué palancas mueven la aguja.
Dónde estás: el piso por debajo del motor
La analogía: cuatro mecánicos y una sola mesa
Cuatro mecánicos montan un mismo motor de coche. No es que cada uno monte su propio motor en paralelo —eso sería tener cuatro coches (cuatro réplicas del modelo, otra estrategia). Aquí montan uno solo, a la vez, repartiéndose las piezas: uno hace los pistones, otro la culata, otro el cigüeñal. El problema es que las piezas encajan entre sí: antes de seguir, los cuatro tienen que juntar lo que llevan y comprobar que casa. Ese “juntar y comprobar” pasa decenas de veces durante el montaje.
Hay dos formas de organizar el taller:
Una sola mesa grande, todos alrededor (NVSwitch). Cada mecánico alarga el brazo y pasa su pieza directamente a cualquier otro, todos a la vez, sin levantarse. Es instantáneo y simultáneo. Esto es NVLink + NVSwitch: las GPUs forman un all-to-all donde cualquiera habla con cualquiera a 900 GB/s al mismo tiempo.
Cuatro talleres separados con un mensajero (PCIe vía CPU). Cada pieza que un mecánico quiere pasar a otro va metida en una caja, baja a recepción (la memoria del host, vía CPU), y de ahí sube al taller destino. Más lento, y serializado por la recepción. Esto es lo que ocurre cuando no hay NVLink: el tráfico inter-GPU cae a PCIe y rebota por el CPU, ~14× más lento que NVLink.
La tesis del post se deriva sola: tensor parallelism solo tiene sentido si los mecánicos comparten la mesa. En cuanto el “juntar y comprobar” (el all-reduce) tiene que pasar por la recepción, el reparto del trabajo cuesta más de lo que ahorra. Por eso, en una plataforma seria, TP no cruza el límite del NVLink: TP=4 u 8 dentro del baseboard donde hay NVSwitch, y de ahí para arriba se replica o se usa pipeline, nunca se estira TP por PCIe o por red. Cuándo conviene cada cosa está en una grande vs N pequeñas; aquí explicamos por qué el cable manda esa decisión.
El mecanismo: qué es realmente un all-reduce y por qué hay 160 por token
Tensor parallelism parte las matrices de pesos por columnas/filas entre las $N$ GPUs. Cada GPU calcula una porción de la salida de la capa. Pero la siguiente operación necesita la salida completa, así que hay que recombinar. Esa recombinación es una operación colectiva: un all-reduce, que suma elemento a elemento los tensores parciales de todas las GPUs y deja el resultado idéntico en todas.
En un bloque transformer estándar hay dos puntos de sincronización por capa:
- Tras la proyección de salida de la atención (el
o_projque recombina las cabezas repartidas). - Tras la segunda matriz del MLP (el
down_projque recombina el feed-forward repartido).
$$ \text{all-reduces por token} = 2 \times L_{\text{capas}} $$
Para un Llama-70B ($L = 80$): $2 \times 80 = 160$ all-reduces por token generado. No por petición, no por secuencia: por token. Multiplica por el throughput de decode y entiendes por qué el interconnect no es infraestructura de fondo sino ruta caliente.
Cómo se hace el all-reduce: ring, tree, NVLS
NCCL no tiene una sola forma de hacer un all-reduce; elige un algoritmo según topología y tamaño del mensaje:
- Ring. Las GPUs forman un anillo; cada una pasa un trozo al vecino, suma, y rota. Hace falta dar $2(N-1)$ pasos. Es óptimo en ancho de banda para mensajes grandes: el coste de mover los datos es $\frac{2(N-1)}{N} \times M$ bytes por el enlace, casi independiente de $N$. Lo malo: $2(N-1)$ saltos de latencia, malo para mensajes pequeños.
- Tree. Reducción en árbol: $\log N$ niveles. Mejor latencia para mensajes pequeños y muchos nodos, peor aprovechamiento de banda.
- NVLS (NVLink SHARP). El truco de Hopper: la suma no la hacen las GPUs, la hace el NVSwitch. El switch tiene unidades de reducción; las GPUs envían sus tensores, el switch los suma en tránsito y devuelve el resultado. Quita trabajo a las GPUs (libera SMs) y reduce saltos. Disponible solo con NVSwitch de 3ª generación (NVLink4) + Hopper o superior.
La regla mental: decode (mensajes diminutos) quiere latencia → tree/LL o el custom kernel de vLLM; prefill (mensajes enormes) quiere banda → ring/NVLS. Por eso no hay un “NCCL_ALGO óptimo” global; depende de qué fase estés mirando.
Las matemáticas que importan: por qué decode y prefill estresan el cable al revés
Aquí está la asimetría que casi todo el mundo se salta. El tamaño del tensor que se all-reducea en cada capa es, aproximadamente:
$$ M \approx B \times S \times h \times 2\ \text{bytes (BF16)} $$
donde $B$ = batch, $S$ = tokens procesados en este forward, $h$ = hidden size.
En decode, generas 1 token por secuencia por iteración. Para una sola secuencia ($B \times S = 1$) y $h = 8192$ (Llama-70B):
$$ M_{\text{decode}} \approx 1 \times 8192 \times 2 = 16\ \text{KB por all-reduce} $$
16 KB es minúsculo. A 900 GB/s, mover 16 KB tarda ~18 nanosegundos de transferencia pura —pero el coste real lo domina la latencia de lanzamiento del colectivo (sincronización, kernel launch), del orden de single-digit microsegundos. Con 160 all-reduces por token:
$$ t_{\text{comms/token}} \approx 160 \times (5\text{–}10,\mu s) \approx 0{,}8\text{–}1{,}6\ \text{ms} $$
Ese es el suelo de comunicación por token, independiente del ancho de banda. Implicación incómoda y contraintuitiva: comprar más ancho de banda NVLink no acelera el decode token-a-token de una sola secuencia. Lo que ayuda en decode es bajar la latencia por colectivo (protocolo LL, el custom all-reduce de vLLM, NVLS para quitar saltos) y batchear (subir $B$ amortiza la latencia fija sobre más tokens — la razón profunda por la que el continuous batching existe, cubierto en continuous batching).
En prefill, procesas el prompt entero de golpe: $S$ puede ser miles de tokens, y con batching $B \times S$ llega a decenas de miles. Ahí:
$$ M_{\text{prefill}} \approx 8000 \times 8192 \times 2 \approx 131\ \text{MB por all-reduce} $$
131 MB sí estresan el ancho de banda. A 900 GB/s (NVSwitch) el all-reduce ring mueve $\frac{2 \cdot 3}{4} \times 131 \approx 196$ MB efectivos en ~0,22 ms; por PCIe (~64 GB/s agregados, rebotando por CPU) serían ~3 ms y serializados. Aquí el cable es el cuello de botella y NVLS/banda mandan.
Resumen en una línea: prefill es bandwidth-bound, decode es latency-bound. Cualquier tuning del interconnect que no diga en qué fase ayuda es ruido.
El hardware: NVLink 4 y NVSwitch sobre el baseboard HGX
Sobre el cluster genérico de referencia —4×H100 SXM dentro de un baseboard HGX— las cifras concretas:
- Cada H100 SXM5 tiene 18 enlaces NVLink 4, cada uno 50 GB/s bidireccionales ⇒ 900 GB/s bidireccionales agregados por GPU. Eso es >14× el ancho de banda de un PCIe Gen4 x16 (~64 GB/s bidir).
- En un baseboard HGX H100 de 8 GPUs, los 18 enlaces de cada GPU se reparten contra cuatro NVSwitch de 3ª generación (agrupación 5+4+4+5). El resultado es all-to-all: cualquier GPU habla con cualquier otra a 900 GB/s simultáneamente, sin pasar por CPU ni PCIe.
- Un baseboard de 4 GPUs es media-placa: mismo principio, NVSwitch mediante. Clave de diseño: si tus 4 H100 están conectadas por NVSwitch, tienes all-to-all real; si están en placas distintas conectadas por PCIe (algunas configuraciones “4×PCIe”), no tienes NVLink entre todas y TP=4 sufre. Verifícalo, no lo asumas.
Los 10 knobs donde tocar
Casi todos son variables de entorno de NCCL (se inyectan en el proceso del motor de inferencia) o ajustes de driver. Ordenados por impacto/frecuencia en un despliegue on-premise. El detalle canónico está en la doc de env vars de NCCL.
Knob 1 — NCCL_DEBUG + topology dump: ver qué está pasando antes de tocar nada
No optimices a ciegas: primero confirma qué topología y algoritmos eligió NCCL. Esto te dice si de verdad está usando NVLink o si, en silencio, cayó a PCIe/SHM —el fallo nº1 y el más caro.
NCCL_DEBUG=INFO # imprime topología, rings/trees construidos, transporte elegido
NCCL_DEBUG_SUBSYS=GRAPH,TUNING,NET # acota a lo que importa
# busca en el log: "via NVLink" / "via P2P" (bien) vs "via SHM" / "via PCI" (mal)
Si ves via SHM o via PCI entre GPUs que deberían tener NVLink, tienes un problema de topología (ACS de PCIe activo, IOMMU, GPUs en placas distintas) y ningún otro knob lo arregla. Este es el knob 1 por una razón: la mitad de los “NVLink va lento” son “NVLink no se está usando”.
Knob 2 — NCCL_ALGO: ring vs tree vs NVLS
Fuerza o excluye algoritmos. Por defecto NCCL elige según tamaño, y suele acertar; tócalo solo con medición delante.
NCCL_ALGO=NVLS,Tree,Ring # orden de preferencia
NCCL_ALGO=^Ring # excluir Ring (prefijo ^)
Regla: prefill/entrenamiento (banda) ⇒ Ring/NVLS; decode (latencia) ⇒ Tree o, mejor, el custom kernel de vLLM (knob 10/stack). En la mayoría de inferencia, dejarlo en auto y validar con el knob 1 es lo correcto; forzarlo “por si acaso” suele empeorar.
Knob 3 — NCCL_PROTO: LL / LL128 / Simple
El protocolo controla el trade-off latencia/banda a bajo nivel:
NCCL_PROTO=Simple # máxima banda, más latencia (mensajes grandes)
NCCL_PROTO=LL # low-latency, half-bandwidth (mensajes diminutos: decode)
NCCL_PROTO=LL128 # compromiso, default en plataformas que lo soportan
LL (low-latency) usa flags en vez de barreras y gana en los mensajes de 16 KB del decode; Simple gana en los 131 MB del prefill. El default LL,LL128,Simple deja a NCCL elegir por tamaño —de nuevo, normalmente lo mejor.
Knob 4 — NCCL_NVLS_ENABLE: descargar la suma en el NVSwitch
NVLink SHARP (NVLS) hace que el switch reduzca, liberando SMs de las GPUs:
NCCL_NVLS_ENABLE=1 # default: ON donde hay NVSwitch NVLink4+ (Hopper)
Matiz escéptico importante: NVLS requiere NVSwitch (3ª gen, NVLink4). En un nodo con NVLink por bridges directos GPU-a-GPU (sin switch) o en 4×PCIe, NVLS no está disponible y este knob no hace nada. Antes de “activarlo”, confirma con el knob 1 que tu topología tiene switch. Donde aplica, su mayor ventaja es liberar SMs para el cómputo —relevante cuando comms y kernels compiten (knob 5).
Knob 5 — NCCL_MIN_NCHANNELS / NCCL_MAX_NCHANNELS: cuántos SM roba la comunicación
Cada “channel” de NCCL consume SMs de la GPU para mover datos. Más channels = más ancho de banda de colectivo, pero menos SMs para el kernel de inferencia. Es un reparto de un recurso fijo.
NCCL_MIN_NCHANNELS=4
NCCL_MAX_NCHANNELS=16 # subir ayuda al prefill (banda); roba SMs al decode
En decode, donde la GPU está infrautilizada de cómputo pero atada a latencia, recortar channels rara vez duele y a veces ayuda; en prefill, más channels exprimen la banda. Knob de medición, no de fe.
Knob 6 — NCCL_BUFFSIZE: el tamaño del buffer por channel
NCCL_BUFFSIZE=8388608 # 8 MB (default 4 MB); buffers mayores → mejor BW en mensajes grandes
Subirlo ayuda al prefill bandwidth-bound a costa de memoria por channel. Para cargas dominadas por mensajes pequeños (decode puro), el default sobra.
Knob 7 — NCCL_P2P_LEVEL / NCCL_P2P_DISABLE: garantizar P2P sobre NVLink
P2P es lo que permite que una GPU lea la memoria de otra directamente por NVLink sin pasar por el host. Si se desactiva o degrada, el tráfico cae a SHM/PCIe.
NCCL_P2P_LEVEL=NVL # usa P2P hasta el nivel NVLink
# NCCL_P2P_DISABLE=1 ← solo como workaround si P2P CUELGA (PCIe multi-NUMA, ciertas Blackwell)
Atención a la trampa: NCCL_P2P_DISABLE=1 y --disable-custom-all-reduce se recomiendan como parche cuando vLLM se cuelga en topologías PCIe-only multi-NUMA. Es un parche de robustez que sacrifica rendimiento: úsalo si cuelga, nunca “por defecto”.
Knob 8 — GPUDirect RDMA para multinodo: NCCL_NET_GDR_LEVEL
Cuando el TP cabe en un nodo, esto no aplica. Cuando hay que cruzar nodos (modelo enorme, pipeline parallel entre baseboards), GPUDirect RDMA permite que la GPU hable con la NIC sin rebotar por la memoria del host:
NCCL_NET_GDR_LEVEL=PHB # habilita GDR según cercanía GPU–NIC en el bus PCIe
Sin GDR, cada salto inter-nodo añade una copia host. Con InfiniBand/RoCE + GDR, el KV o las activaciones viajan GPU→NIC→red→NIC→GPU. Es la base del multinodo serio y de entornos mixtos.
Knob 9 — NCCL_IB_HCA / NCCL_SOCKET_IFNAME: fijar la NIC correcta
El error multinodo más común y silencioso: NCCL elige la NIC de gestión (1 GbE) en vez de la de fabric (InfiniBand/100 GbE). Resultado: colectivos a paso de tortuga sin error visible.
NCCL_SOCKET_IFNAME=eth0 # interfaz de control (bootstrap)
NCCL_IB_HCA=mlx5_0,mlx5_1 # las HCA InfiniBand reales del fabric
NCCL_IB_GID_INDEX=3 # GID correcto para RoCE v2
Fíjalas explícitamente. “Auto” acierta en clusters limpios y falla en cuanto hay más de una NIC.
Knob 10 — Driver: persistence mode, clocks y contadores de error NVLink
Por debajo de NCCL, el driver tiene palancas y, sobre todo, telemetría que hay que mirar:
nvidia-smi -pm 1 # persistence mode: evita re-init del driver (latencia/jitter)
nvidia-smi nvlink --status # ¿los 18 enlaces activos y a velocidad plena?
nvidia-smi nvlink -e # contadores de error/CRC por enlace
nvidia-smi -q -d ECC # errores de memoria que degradan en silencio
Un enlace NVLink que negocia a media velocidad o acumula errores CRC degrada el all-reduce sin lanzar ningún error —el sistema “funciona”, solo va más lento. Estos contadores son la diferencia entre diagnosticar en cinco minutos o perseguir un fantasma durante días. Se integran en DCGM (knob/stack: observabilidad).
Tabla resumen
| # | Knob | Variable / comando | Fase que ayuda |
|---|---|---|---|
| 1 | Diagnóstico topología | NCCL_DEBUG=INFO + SUBSYS=GRAPH | siempre, primero |
| 2 | Algoritmo colectivo | NCCL_ALGO (NVLS/Tree/Ring) | según fase; auto suele ganar |
| 3 | Protocolo | NCCL_PROTO (LL/LL128/Simple) | LL=decode, Simple=prefill |
| 4 | NVLink SHARP | NCCL_NVLS_ENABLE=1 | prefill; libera SMs (requiere NVSwitch) |
| 5 | Channels (SMs) | NCCL_MIN/MAX_NCHANNELS | +banda prefill / −robo SM decode |
| 6 | Buffer | NCCL_BUFFSIZE | prefill bandwidth-bound |
| 7 | P2P NVLink | NCCL_P2P_LEVEL=NVL | crítico; disable solo si cuelga |
| 8 | GPUDirect RDMA | NCCL_NET_GDR_LEVEL | multinodo |
| 9 | NIC de fabric | NCCL_IB_HCA/SOCKET_IFNAME | multinodo (evita NIC mgmt) |
| 10 | Driver + telemetría | nvidia-smi -pm 1 / nvlink -e | jitter + diagnóstico silencioso |
Cómo se conecta con el resto del stack
El interconnect no es una isla; toca casi todas las capas de arriba.
Con vLLM — el custom all-reduce. vLLM no siempre usa NCCL: para los mensajes diminutos del decode (world_size==2 o topología fully-connected por NVLink, por debajo de cierto max_size) usa un kernel propio de all-reduce que bate a NCCL en latencia —exactamente el cuello de botella del decode que vimos en las matemáticas. Cae a NCCL para mensajes grandes y para topologías sin NVLink (donde su custom kernel “aporta poco sobre NCCL”). El flag --disable-custom-all-reduce / VLLM_DISABLE_CUSTOM_ALL_REDUCE lo apaga; es el parche cuando cuelga en PCIe multi-NUMA. Traducción: el knob de latencia de decode más efectivo a veces no es de NCCL, es elegir bien entre el custom kernel de vLLM y NCCL.
Con TP vs réplicas. Todo lo de una grande vs N pequeñas descansa sobre esto: TP alto solo es viable dentro del dominio NVLink. La frontera de “¿TP=4 o 4 réplicas TP=1?” la dibuja el cable: cruzar NVLink con TP es pagar el all-reduce a precio de PCIe.
Con disaggregated serving. En prefill/decode desagregado, el KV cache generado en el pool de prefill tiene que viajar al pool de decode. Ese traslado es otro consumidor del interconnect (NVLink intra-nodo, GPUDirect RDMA inter-nodo) y compite con los all-reduce. Diseñar la desagregación sin contar el coste de transferencia de KV es la trampa clásica.
Con MoE. Los modelos Mixture-of-Experts añaden expert parallelism: un all-to-all (no all-reduce) que enruta cada token a su experto, posiblemente en otra GPU. Es un patrón de comunicación distinto y más pesado en banda; MoE en inferencia vive o muere por el mismo cable, con un colectivo aún más exigente.
Con la observabilidad GPU. Los contadores NVLink (nvidia-smi nvlink -e, bytes TX/RX por enlace, errores CRC) y la utilización de NVSwitch se exponen vía DCGM y aterrizan en Prometheus/Grafana. La pregunta “¿está el interconnect sano y saturado?” se responde ahí, junto al resto de observabilidad GPU con DCGM. Un all-reduce lento se ve antes en un contador de errores NVLink que en la latencia de la API.
Con capacity planning. El dimensionado de inferencia que asume “TP=4 escala casi lineal” solo se cumple dentro del NVLink. Fuera de él, la eficiencia de escalado se cae y el plan de capacidad miente. El cable es un parámetro del modelo de capacidad, no un detalle.
Trampas y cosas que no son lo que parecen
“Más ancho de banda NVLink = decode más rápido.” Falso para una secuencia. El decode es latency-bound; el ancho de banda apenas se toca con mensajes de 16 KB. Lo que acelera el decode es batchear (amortizar la latencia fija) y bajar latencia por colectivo (LL, custom kernel, NVLS). El ancho de banda manda en prefill.
“Tengo 4 H100, luego tengo NVLink entre las cuatro.” No necesariamente. Hay configuraciones donde las GPUs están en placas distintas unidas por PCIe, o con bridges NVLink solo por pares. Confírmalo con nvidia-smi nvlink --status y el knob 1 antes de planificar TP=4. Un TP=4 sobre P2P-por-PCIe rinde mucho peor de lo que dice el folleto.
Forzar NCCL_ALGO/NCCL_PROTO “para ir más rápido”. NCCL elige bien por tamaño en la mayoría de casos. Forzar un algoritmo sin medir suele empeorar una de las dos fases. La secuencia correcta es: knob 1 (ver qué hace) → medir → tocar solo si hay evidencia.
Desactivar P2P/custom all-reduce por defecto. Son parches de robustez para topologías rotas (PCIe multi-NUMA, ciertas Blackwell). Dejarlos puestos “por estabilidad” en un nodo con NVLink sano tira rendimiento a la basura.
Estirar TP por la red. TP=8 cruzando dos nodos por InfiniBand porque “hay banda” ignora que el all-reduce por capa ahora paga latencia de red ×160 por token. Para cruzar nodos, pipeline parallel (que comunica una vez por micro-batch, no por capa) casi siempre gana. El patrón de comunicación, no solo la banda, decide.
Ignorar los contadores de error NVLink. Un enlace degradado no lanza excepción: el sistema funciona, solo va lento. Sin vigilar nvlink -e y ECC, persigues un fantasma de rendimiento que un contador te habría señalado en cinco minutos.
Conclusión
Tensor parallelism vende una promesa simple —parte el modelo, multiplica la VRAM, sirve modelos que no caben en una GPU— pero la letra pequeña es que cada capa obliga a las GPUs a juntarse y sumar, dos veces, decenas de veces por token. Ese all-reduce es el verdadero protagonista oculto del rendimiento, y vive en el cable: NVLink lo hace por la mesa compartida del NVSwitch a 900 GB/s, o PCIe lo arrastra por la recepción del CPU 14× más lento. De los diez knobs, el primero —mirar con NCCL_DEBUG qué está pasando de verdad— resuelve la mitad de los problemas, porque la mitad de los “NVLink va lento” son “NVLink no se usa”. El resto son afinados que solo significan algo si sabes en qué fase estás: prefill quiere banda (NVLS, Simple, channels, buffer), decode quiere latencia (LL, el custom kernel de vLLM, batching). Y por encima de todo, una idea que reordena la intuición: en inferencia on-premise, el interconnect no es fontanería que se instala y se olvida —es ruta caliente, parámetro de capacidad y, cuando se degrada en silencio, la causa raíz que ningún dashboard de la API te va a señalar si no miras los contadores del propio cable.
Ver también
- El stack de inferencia LLM on-premise en siete capas — el edificio completo donde el interconnect es el cimiento sobre el que se apoyan las siete capas; aquí se abre ese cimiento.
- Una grande vs N pequeñas: TP y réplicas — la decisión de cuántas GPUs y cómo repartir el modelo; este post explica por qué el límite del NVLink dibuja esa frontera.
- Disaggregated serving: prefill y decode separados — el traslado del KV cache entre pools es otro consumidor del mismo interconnect que compite con los all-reduce.
- Continuous batching — la razón profunda por la que batchear acelera el decode es que amortiza la latencia fija del all-reduce sobre más tokens.
- Optimizaciones de decode en vLLM — la fase latency-bound donde el custom all-reduce de vLLM y el protocolo LL deciden el TPS por secuencia.
- MoE en inferencia — el expert parallelism añade un
all-to-allaún más exigente sobre el mismo cable. - Observabilidad GPU con DCGM — dónde aterrizan los contadores NVLink y de NVSwitch para responder “¿está el interconnect sano y saturado?”.
- Capacity planning de inferencia on-premise — por qué “TP escala casi lineal” solo es cierto dentro del dominio NVLink, y cómo el cable entra en el modelo de capacidad.
- Entornos mixtos NVIDIA + Intel — cuando se cruza el límite del nodo, GPUDirect RDMA sobre InfiniBand/RoCE sustituye a NVLink como medio del colectivo.
Referencias
- NVIDIA, NVIDIA Hopper Architecture In-Depth (NVLink 4, 900 GB/s): https://developer.nvidia.com/blog/nvidia-hopper-architecture-in-depth/.
- NVIDIA, Introducing NVIDIA HGX H100 (4× NVSwitch, all-to-all): https://developer.nvidia.com/blog/introducing-nvidia-hgx-h100-an-accelerated-server-platform-for-ai-and-high-performance-computing/.
- NVIDIA, NCCL Environment Variables (todos los knobs de este post): https://docs.nvidia.com/deeplearning/nccl/user-guide/docs/env.html.
- NVIDIA, The NVLink-Network Switch (Hot Chips 2022, NVLink SHARP): https://hc34.hotchips.org/.
- vLLM, Why does vLLM use a custom all-reduce method? (discussion #6159) y
custom_all_reduce.py: https://github.com/vllm-project/vllm/discussions/6159. - NVIDIA, NCCL Multi-Node NVLink Tuning Guide: https://docs.nvidia.com/multi-node-nvlink-systems/multi-node-tuning-guide/nccl.html.