Compraste una segunda GPU esperando que la gráfica subiera y todo fuera mejor. En su lugar, tu trabajo de entrenamiento empezó a tener variaciones, la latencia de inferencia se volvió extraña y la mitad de tu “utilización de GPU”
resultó ser una barra de progreso de espera. Los paneles parecen ocupados. El reloj real se siente avergonzado.
Esta es la parte que nadie anuncia: dos GPUs no significan automáticamente “el doble de cómputo”. A menudo significan el doble de modos de fallo, el doble de consumo eléctrico y una nueva categoría
de cuellos de botella que no tenías ayer.
El mito: “Dos GPUs = 2× más rápido”
El mito persiste porque es cierto en un mundo muy concreto: cargas de trabajo «embarazosamente paralelas» con mínima sincronización, mínimo movimiento de datos y una pila de software que
realmente programa trabajo entre dispositivos de forma eficiente. Ese mundo existe. Simplemente no es el mundo en el que operan la mayoría de los equipos.
En sistemas de producción, la escalabilidad rara vez está limitada por FLOPs brutos. Está limitada por todo lo que los rodea: copias de memoria, sobrecarga de lanzamiento de kernels, burbujas de pipeline, contención de CPU,
topología PCIe, colocación NUMA, comportamiento del controlador, estrangulamiento térmico y la realidad operativa de que más hardware aumenta la superficie para lo raro.
Así que cuando la gente dice “multi‑GPU”, lo que suele querer decir es “añadí complejidad y ahora estoy negociando con la física”.
Las razones reales por las que dos GPUs decepcionan
1) La VRAM no es aditiva (la mayoría de las veces), y esa es la primera traición
Dos GPUs de 24 GB no se convierten mágicamente en 48 GB de memoria usable para el modelo. A menos que dividas explícitamente el modelo (paralelismo tensorial, paralelismo por pipeline, paralelismo por expertos),
cada GPU necesita su propia copia de los parámetros (o grandes subconjuntos), además de activaciones, estado del optimizador y memoria de trabajo.
El entrenamiento en paralelo de datos es el modo multi‑GPU “fácil” y común: cada GPU ejecuta el mismo modelo sobre mini‑lotes distintos. Obtienes más rendimiento solo si puedes mantenerlas alimentadas
y la sincronización (reducción de gradientes) no devora la ganancia. Pero la capacidad de memoria para el modelo en sí no se duplica. Sigues teniendo un techo por GPU.
Ese techo se convierte en una trampa de planificación incómoda: los equipos compran una segunda GPU “por capacidad” y luego descubren que necesitaban una GPU individual más grande, o una estrategia de paralelismo distinta,
o ambas cosas.
2) Sobrecarga de sincronización: el impuesto que no ves hasta que es demasiado tarde
La mayoría del entrenamiento multi‑GPU no está limitado por cómputo; está limitado por la rapidez con la que las GPUs pueden ponerse de acuerdo sobre lo que acaba de pasar. En data‑parallel, eso es un all‑reduce de gradientes.
Cuantas más GPUs añades, más tiempo pasas coordinando.
Incluso con enlaces de alta velocidad, la sincronización no es gratuita. También es explosiva: tienes una buena racha de kernels y luego una gran fase de comunicación donde la utilización cae y
finges que “está bien” porque “la GPU está asignada”.
La sobrecarga de comunicación se vuelve especialmente desagradable cuando:
- El tamaño de batch por GPU se vuelve demasiado pequeño (la eficiencia del kernel cae y la sobrecarga domina).
- Tu modelo tiene muchos tensores pequeños (más llamadas de reducción, peor sensibilidad a la latencia).
- Tu interconexión es solo PCIe y el tráfico compite con I/O del host.
- La topología fuerza tráfico entre sockets de CPU (penalización NUMA que se disfraza de “comunicaciones GPU”).
3) Topología PCIe: tus GPUs están “cerca” en el chasis, lejos en la realidad
Dos GPUs pueden estar conectadas de varias maneras que parecen idénticas en una orden de compra y muy distintas en rendimiento:
- Ambas GPUs bajo el mismo root complex PCIe (a menudo mejor).
- Cada GPU conectada a un socket de CPU distinto (común en servidores dual‑socket).
- Canales compartidos o bifurcación que reduce el ancho de banda efectivo.
- Tráfico enrutado a través de un salto de chipset (penalizaciones de latencia y ancho de banda).
Si GPU0 es “local” a CPU0 y GPU1 es “local” a CPU1, y tu proceso está pegado al socket equivocado, enhorabuena: inventaste una regresión de rendimiento usando solo
la adquisición.
4) P2P y NVLink no son magia; son contratos que puedes romper accidentalmente
El acceso peer‑to‑peer (P2P) permite que una GPU lea la memoria de otra GPU sin pasar por la RAM del host. NVLink eleva aún más el techo. Pero no siempre lo obtienes:
- P2P puede estar deshabilitado por peculiaridades de plataforma, ajustes de IOMMU, capas de virtualización o valores predeterminados del BIOS.
- La disponibilidad de NVLink depende del SKU exacto de GPU y del cableado del servidor.
- Incluso cuando está disponible, tu framework puede no elegir la ruta óptima a menos que esté configurado correctamente.
Multi‑GPU suele fallar no porque el hardware sea lento, sino porque tu stack cae silenciosamente a copias mediadas por el host y tu “interconexión rápida” se convierte en un rumor.
5) Los cuellos de botella de CPU empeoran cuando añades GPUs
Una sola GPU puede ocultar muchos pecados de CPU. Dos GPUs los hacen visibles. La CPU tiene que:
- Decodificar y aumentar más datos por unidad de tiempo (presión del data loader).
- Lanzar más kernels (sobrecarga del driver, sobrecarga de Python, sobrecarga del framework).
- Orquestar comunicaciones colectivas (configuración de NCCL, gestión de streams).
- Manejar más interrupciones y contabilidad de DMA.
Si tu pipeline ya está al límite, duplicar el número de GPUs simplemente duplica la tasa a la que llegas a “esperando entrada”.
6) I/O y almacenamiento: el cuello de botella silencioso que arruina “escalar”
Si entrenas con imágenes o datasets fragmentados y no tienes un plan serio de I/O, dos GPUs son una forma muy cara de descubrir que tu almacenamiento está bien “para un trabajo” pero no para dos.
He visto entrenamientos multi‑GPU convertir un sistema estable en una estampida de lecturas pequeñas y operaciones de metadatos.
Añadir GPUs aumenta la demanda de:
- Rendimiento de lectura del dataset (MB/s e IOPS).
- Operaciones de metadatos (muchos archivos pequeños, listado de object store, indexado de tar).
- Escrituras de checkpoints (escrituras por ráfaga, presión de fsync).
Cuando el almacenamiento se convierte en el limitador, la utilización de GPU es teatro: “ocupado” no es lo mismo que “productivo”.
7) Microstutter y ritmo desigual en cargas gráficas / interactivas
En gaming y visualización, multi‑GPU históricamente dependía de trucos como alternate‑frame rendering. Eso puede aumentar el FPS promedio a la vez que hace que los tiempos de frame sean irregulares.
Los humanos notan la irregularidad. Los gráficos de benchmark no.
Por eso “llega a 120 FPS” puede sentirse peor que una sola GPU a un constante 75 FPS. La unidad que importa no es “frames por segundo”. Es “cuánto tardó el último frame”,
repetidamente, bajo carga.
8) Las rutas de software multi‑GPU están menos probadas y son más frágiles
El código de GPU única es la ruta por defecto. Multi‑GPU es el “modo avanzado”, y los modos avanzados atraen casos límite como moscas al zambullidor de bugs.
Puntos típicos de fragilidad:
- Deadlocks en colectivas distribuidas cuando un rank sufre una excepción y otros siguen esperando.
- Timeouts y bloqueos que solo ocurren bajo jitter de red o alta carga.
- No determinismo por ejecución asíncrona y menor visibilidad para depuración.
- Resets del driver que aniquilan todo el job, no solo un dispositivo.
9) Matemática de fiabilidad: dos GPUs duplican las formas de perder una ejecución
Dos dispositivos significan el doble de ventiladores, el doble de VRAM, el doble de probabilidad de que uno esté en el límite por temperatura y el doble de oportunidad de que un riser o conector de alimentación defectuoso
introduzca fallos intermitentes.
Los trabajos de entrenamiento son largos. Los trabajos largos amplifican eventos raros. El modo de fallo cambia de “rendimiento” a “¿acabará esto antes de que algo se enfade?”
Una cita que tiende a envejecer bien en círculos de operaciones es de John Allspaw: “La fiabilidad es la característica”. Ese es todo el juego una vez que tu sistema está en producción.
10) Energía, térmicas y comportamiento de boost: la segunda GPU puede ralentizar a ambas
Este es un clásico “¿por qué mi actualización es más lenta?” Dos GPUs consumen más energía y liberan más calor dentro de la misma caja. Eso puede provocar:
- Relojes de boost más bajos por límites de potencia.
- Estrangulamiento térmico porque el flujo de aire ahora está bloqueado por un segundo ladrillo caliente.
- Curvas de ventilador que se aceleran, quejas por ruido y eventualmente “alguien cambió el BIOS”.
Si el chasis no está diseñado para cargas sostenidas de doble GPU, puedes acabar con dos GPUs funcionando más lentas que una GPU en un entorno térmico sano.
Broma #1: Añadir una segunda GPU para velocidad es como añadir un segundo volante para control. Principalmente aumenta el número de opiniones en el coche.
11) Inferencia multi‑GPU: el throughput puede subir, la latencia suele empeorar
Para serving, te importan p95 y p99, no solo tokens/seg en un martes tranquilo. Dividir la inferencia entre GPUs (paralelismo tensorial) puede mejorar el throughput para modelos muy grandes, pero añade comunicación entre GPUs en la ruta crítica de cada petición.
Eso significa:
- Más oportunidades para latencias cola por sincronización y encolamiento.
- Mayor sensibilidad al jitter (planificación del SO, interrupciones, vecinos ruidosos).
- Lógica de batching más compleja, que puede fallar si el tráfico es irregular.
Dos GPUs pueden ser geniales para throughput agregado en inferencia por lotes grandes. Pueden ser terribles para objetivos de latencia interactiva.
12) La depuración empeora y tu respuesta a incidentes lo notará
Cuando un job de GPU única se ralentiza, normalmente puedes encontrar el culpable rápidamente: está limitado por memoria, por cómputo o por I/O. Con dos GPUs, añades nuevas categorías:
- Distribución de trabajo desequilibrada (una GPU esperando a la otra).
- Eficiencia inadecuada en comunicación colectiva (la “pared del all‑reduce”).
- Incompatibilidad de topología (P2P deshabilitado, nodo NUMA incorrecto, mala elección de slot PCIe).
La verdad desagradable: depurar rendimiento multi‑GPU no es “2× más difícil”. Es más difícil por “más dimensiones de las que puedes acordarte a las 2 a.m.”.
Hechos e historia que explican el desorden
- SLI y CrossFire se construyeron para gráficos, usando a menudo alternate‑frame rendering; optimizaban FPS promedio, no un pacing consistente.
- El microstutter se convirtió en un problema conocido multi‑GPU porque las primeras tuberías multi‑GPU producían tiempos de frame desiguales incluso cuando el FPS promedio parecía excelente.
- CUDA multi‑GPU originalmente dependía mucho de PCIe; la industria aprendió rápido que las copias mediadas por host son un callejón sin salida para escalar en muchas cargas.
- NVIDIA introdujo NVLink para abordar límites de ancho de banda y latencia entre GPUs que PCIe no podía resolver en sistemas multi‑GPU grandes.
- NCCL se convirtió en el estándar para colectivas porque el entrenamiento distribuido necesita all‑reduce de alto rendimiento; implementaciones ingenuas aplastaban la escalabilidad.
- “Pool de memoria GPU” no es el modelo por defecto; la mayoría de modelos de programación tratan a las GPUs como espacios de direcciones separados a menos que manejes el compartido explícitamente.
- Las generaciones de PCIe importan: PCIe 3.0 vs 4.0 vs 5.0 pueden cambiar si la comunicación es una molestia o el costo dominante.
- Los servidores dual‑socket crearon trampas de topología: conectar GPUs a través de sockets puede introducir penalizaciones de latencia y ancho de banda que parecen “ineficiencia del framework”.
- El deep learning moderno topó pronto con la “pared de comunicación”; más allá de cierto punto, añadir GPUs da retornos decrecientes a menos que cambien batch/modelo/estrategia de paralelismo.
Tres mini-historias corporativas (cómo falla esto en la vida real)
Mini‑historia 1: El incidente causado por una suposición errónea
Una empresa mediana desplegó un nuevo pipeline de entrenamiento para un modelo de recomendación. Lo habían validado en una estación de trabajo con una sola GPU: estable, predecible y “lo suficientemente rápido.”
El siguiente paso fue “simplemente añadir otra GPU” en el servidor de staging para reducir el tiempo de entrenamiento a la mitad antes de una fecha límite.
La suposición era limpia y errónea: esperaban que el paralelismo de datos fuera gratis. Duplicaron GPUs, duplicaron el tamaño de batch y esperaban el mismo tiempo por paso. Lo que obtuvieron
fue un trabajo de entrenamiento que empezó fuerte y luego se ralentizó dramáticamente después de los primeros minutos.
La falla no fue de cómputo. Fue I/O. Su dataset residía en un sistema de archivos de red con muchos archivos pequeños, y la segunda GPU duplicó la presión del loader. El
servidor de metadatos empezó a thrashear. Otros servicios compartiendo el mismo almacenamiento se volvieron más lentos también, porque “entrenamiento” se había convertido en una denegación de servicio distribuida con logs educados.
El incidente escaló porque los síntomas eran engañosos: la utilización de GPU se mantenía en 40–60%, lo que parecía “bien” para quienes equiparan utilización con progreso.
Mientras tanto, el tiempo por paso se había inflado. Intentaron “arreglar las GPUs” reinstalando drivers y ajustando configuraciones de NCCL, lo cual era como cambiar neumáticos para arreglar una fuga de combustible.
La resolución fue aburrida: consolidar el dataset en shards más grandes, añadir cache NVMe local para los trabajos de entrenamiento y limitar la concurrencia del data‑loader. La segunda GPU
no causó el problema; lo expuso con un megáfono.
Mini‑historia 2: La optimización que salió mal
Otro equipo servía un modelo tipo LLM para herramientas internas. La latencia importaba: los ingenieros lo usaban de forma interactiva y cualquier cosa por encima de un par de segundos se sentía “rota.”
Tenían una GPU grande que era cara pero estable.
Alguien sugirió dividir el modelo entre dos GPUs más pequeñas usando paralelismo tensorial. La hoja de cálculo se veía bien: más VRAM agregada, menor coste por caja y “debería escalar”.
Lo construyeron, lo pusieron en producción y vieron cómo la latencia p99 empeoraba aunque el throughput mejoraba en benchmarks sintéticos.
La causa raíz estaba en la ruta crítica: cada paso de generación de token requería comunicación entre GPUs. Bajo tráfico real, el tamaño de las peticiones variaba y el batching era imperfecto.
Así que tuvieron encolamiento más sincronización. El sistema pasó más tiempo coordinando que computando. Peor aún, la latencia de cola se disparaba cuando una GPU se calentaba un poco y bajaba de frecuencia,
porque la otra GPU tenía que esperar en puntos de sincronización.
Intentaron una serie de ajustes: tamaños de batch, prioridades de streams, fijar hilos, tocar perillas en el servidor de inferencia. Mejoró algo, pero la arquitectura fundamental
era ahora hostil a la latencia.
La solución fue contraintuitiva pero obvia en retrospectiva: volver a una GPU más grande para endpoints sensibles a la latencia, y conservar la configuración dual‑GPU solo para jobs por lotes offline
donde importaba el throughput y las colas no.
Mini‑historia 3: La práctica aburrida pero correcta que salvó el día
Un equipo de plataforma gestionaba un clúster GPU compartido para varios grupos de producto. Estaban cansados de ralentizaciones misteriosas y tickets de “ayer iba rápido”. En lugar de perseguir las rarezas de cada
workload, adoptaron una práctica que suena sosa y por ello es poderosa: estandarizaron la colocación de GPUs y documentaron la topología.
Para cada modelo de servidor produjeron un mapa simple: qué ranuras PCIe corresponden a qué nodo NUMA, qué pares de GPU tienen rutas P2P rápidas y qué ajustes del BIOS son necesarios
para comportamiento estable. Incorporaron esas configuraciones en el aprovisionamiento. También añadieron una prueba preflight que marca la máquina como mala si P2P está deshabilitado inesperadamente.
Meses después, un proveedor envió una revisión de placa madre. Todo arrancó. Sin alarmas. Pero los jobs multi‑GPU empezaron a escalar mal en un subconjunto de nodos. Debido a que
el equipo tenía comprobaciones de topología y pruebas de ancho de banda base en CI para la flota, lo detectaron rápido y aislaron los nodos antes de que los clientes lo notaran.
El postmortem fue corto. La respuesta: “cambió el ruteo del hardware; la ruta P2P difiere; ajustar la colocación y actualizar la baseline.” A nadie le gustó. Nadie perdió una semana.
Así es como se ve lo “aburrido” cuando funciona.
Guía rápida de diagnóstico
Cuando dos GPUs rinden menos de lo esperado, no empieces reescribiendo tu modelo. Empieza probando a dónde va el tiempo. El objetivo no es ser ingenioso; es ser rápido.
Primero: confirma que el problema es real (y mide el tiempo de pared)
- Compara tiempo por paso / tokens por segundo / peticiones por segundo, no “utilización de GPU”.
- Mide latencia p50/p95/p99 para inferencia, no solo el promedio.
- Prueba una GPU frente a dos GPUs con versiones de software idénticas y la misma porción del dataset.
Segundo: identifica la clase de cuello de botella (cómputo, memoria, comunicaciones, CPU, I/O, térmico)
- Si las GPUs están ocupadas pero la escalabilidad es mala: sospecha comunicación y sincronización.
- Si las GPUs están inactivas: sospecha pipeline de entrada, CPU o almacenamiento.
- Si el rendimiento se degrada con el tiempo: sospecha térmicas, límites de potencia o fragmentación de memoria/efectos del recolector.
Tercero: valida supuestos de topología e interconexión
- Comprueba la velocidad/anchura del enlace PCIe y si P2P está habilitado.
- Verifica la localidad NUMA: los hilos de CPU que alimentan GPU0 deberían estar normalmente en el mismo socket que GPU0.
- Confirma que NVLink esté realmente presente y activo (cuando aplique).
Cuarto: revisa lo aburrido del sistema
- Relojes y throttling (temperatura, límites de potencia).
- Errores de driver/Xid y resets.
- Saturación de disco y red durante checkpoints y lecturas de dataset.
Quinto: solo entonces ajusta el framework
- Configuraciones NCCL, tamaños de bucket en DDP, acumulación de gradientes, precision mixta, opciones de compilación.
- Tamaños de batch que mantengan las GPUs eficientes sin explotar las comunicaciones.
- Superponer comunicación con cómputo cuando sea soportado.
Broma #2: Escalar multi‑GPU es cuando pagas por dos motores y pasas el tiempo depurando la caja de cambios.
Tareas prácticas: comandos, salidas y decisiones (12+)
Esto no son “consejos”. Son las comprobaciones que ejecutas cuando estás de guardia y alguien jura que la segunda GPU “no está haciendo nada”.
Cada tarea incluye: comando, qué significa la salida y qué decisión tomas a continuación.
Tarea 1: Confirma que ambas GPUs existen y el driver las ve
cr0x@server:~$ nvidia-smi -L
GPU 0: NVIDIA A10 (UUID: GPU-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee)
GPU 1: NVIDIA A10 (UUID: GPU-ffffffff-1111-2222-3333-444444444444)
Significado: Si falta una GPU, todo lo demás es ruido. Dispositivos ausentes pueden deberse a alimentación, asiento, BIOS o driver.
Decisión: Si no aparecen ambas, para y arregla hardware/firmware/driver antes de depurar la escalabilidad del software.
Tarea 2: Comprueba la velocidad y anchura del enlace PCIe (la comprobación de “por qué mi bus es lento”)
cr0x@server:~$ nvidia-smi -q -d PCI | sed -n '1,120p'
GPU 00000000:65:00.0
PCIe Generation
Current : Gen4
Max : Gen4
Link Width
Current : x8
Max : x16
GPU 00000000:B3:00.0
PCIe Generation
Current : Gen4
Max : Gen4
Link Width
Current : x16
Max : x16
Significado: GPU0 está funcionando a x8 aunque soporta x16. Eso puede reducir el ancho de banda host/device y también afectar rutas P2P.
Decisión: Reasentar la GPU, revisar cableado de slots, ajustes de BIOS, risers y si otro dispositivo robó lanes.
Tarea 3: Mapear GPUs a nodos NUMA (para dejar de pagar el impuesto cross‑socket)
cr0x@server:~$ nvidia-smi topo -m
GPU0 GPU1 CPU Affinity NUMA Affinity
GPU0 X SYS 0-31 0
GPU1 SYS X 32-63 1
Significado: GPU0 es local al nodo NUMA 0; GPU1 es local al nodo NUMA 1; la ruta GPU‑a‑GPU es SYS (pasa por el interconector del sistema/CPU).
Decisión: Si tu workload sincroniza mucho entre GPUs, espera peor escalado. Considera mantener ranks multi‑GPU en el mismo socket cuando sea posible,
o elegir un servidor con mejor interconexión entre GPUs.
Tarea 4: Confirma que el acceso P2P está habilitado (y no deshabilitado silenciosamente)
cr0x@server:~$ nvidia-smi topo -p2p n
GPU0 GPU1
GPU0 X OK
GPU1 OK X
Significado: P2P está permitido entre las GPUs. Si ves “NS” o “Disabled”, tus comunicaciones podrían estar rebotando por la memoria del host.
Decisión: Si P2P no está OK, revisa ajustes de IOMMU, modo de virtualización, toggles del BIOS y combinaciones driver/kernel.
Tarea 5: Comprueba relojes, potencia y térmicas (rendimiento que se derrite)
cr0x@server:~$ nvidia-smi --query-gpu=index,temperature.gpu,power.draw,power.limit,clocks.sm,clocks.mem,clocks.current.sm --format=csv
index, temperature.gpu, power.draw, power.limit, clocks.sm, clocks.mem, clocks.current.sm
0, 84, 147.23 W, 150.00 W, 1710 MHz, 5001 MHz, 1410 MHz
1, 72, 132.10 W, 150.00 W, 1710 MHz, 5001 MHz, 1680 MHz
Significado: GPU0 está cerca de límites térmicos y no mantiene los relojes SM objetivo (current menor que nominal). Eso por sí solo puede romper la eficiencia de sincronización multi‑GPU.
Decisión: Mejora el flujo de aire, ajusta curvas de ventilador, reduce límites de potencia con cuidado o recoloca GPUs para evitar que una asfixie a la otra.
Tarea 6: Busca errores ECC o de memoria (la comprobación de “está lento porque está enfermo”)
cr0x@server:~$ nvidia-smi -q -d ECC | sed -n '1,120p'
ECC Mode
Current ECC : Enabled
Pending ECC : Enabled
ECC Errors
Volatile
Single Bit
Device Memory : 0
Double Bit
Device Memory : 0
Aggregate
Single Bit
Device Memory : 2
Double Bit
Device Memory : 0
Significado: Existen errores single‑bit agregados. Eso puede no tumbarte, pero puede correlacionar con hardware marginal.
Decisión: Si los errores suben, programa mantenimiento y considera sacar la GPU de cargas sensibles a la latencia o entrenamientos largos.
Tarea 7: Busca errores Xid en logs del kernel (fallos de driver/GPU)
cr0x@server:~$ sudo dmesg -T | grep -i -E 'NVRM|Xid' | tail -n 20
[Mon Jan 13 09:41:02 2026] NVRM: Xid (PCI:0000:65:00): 31, Ch 0000000b, engmask 00000101, intr 10000000
[Mon Jan 13 09:41:02 2026] NVRM: GPU 0000:65:00.0: GPU has fallen off the bus.
Significado: “Fallen off the bus” no es un problema de ajuste. Es estabilidad: entrega de potencia, integridad PCIe, sobrecalentamiento o hardware fallando.
Decisión: Deja de perseguir rendimiento. Estabiliza el nodo: reasentar, intercambiar cables, validar margen de PSU, actualizaciones de firmware y considerar RMA.
Tarea 8: Confirma presión de CPU y memoria (data loaders y sobrecarga de lanzamiento)
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0 (server) 01/13/2026 _x86_64_ (64 CPU)
09:52:11 AM CPU %usr %nice %sys %iowait %irq %soft %idle
09:52:12 AM all 68.20 0.00 14.10 0.40 0.00 1.20 16.10
09:52:12 AM 0 98.00 0.00 2.00 0.00 0.00 0.00 0.00
09:52:12 AM 32 96.00 0.00 4.00 0.00 0.00 0.00 0.00
Significado: Algunas CPUs están fijadas y saturadas (probablemente workers del data‑loader o hilos del framework). La hambruna de GPU suele comenzar aquí.
Decisión: Incrementa la eficiencia del loader, usa memoria pinned con cuidado, ajusta conteos de workers y fija procesos al nodo NUMA correcto.
Tarea 9: Comprueba rendimiento de disco y iowait durante el entrenamiento
cr0x@server:~$ iostat -xz 1 3
Linux 6.5.0 (server) 01/13/2026 _x86_64_ (64 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
42.11 0.00 9.33 18.70 0.00 29.86
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
nvme0n1 320.0 86500.0 10.0 3.03 5.10 270.3 55.0 22000.0 7.80 2.10 92.0
Significado: Alto iowait y NVMe ~92% de utilización sugiere que el almacenamiento es el limitador. Dos GPUs simplemente hicieron la cola más profunda.
Decisión: Mueve el dataset local, prefetch, shardea, cachea o escala el ancho de banda de almacenamiento antes de añadir más GPUs.
Tarea 10: Comprueba tráfico de red si el dataset o checkpoints están remotos
cr0x@server:~$ sar -n DEV 1 3
Linux 6.5.0 (server) 01/13/2026 _x86_64_ (64 CPU)
09:55:21 AM IFACE rxpck/s txpck/s rxkB/s txkB/s rxcmp/s txcmp/s rxmcst/s
09:55:22 AM eth0 6200.00 5800.00 930000.00 210000.00 0.00 0.00 12.00
Significado: RX cerca de la tasa de línea en un enlace 10Gb/25Gb puede ser tu techo. Si tu job lee datos de forma remota, esto es un límite duro.
Decisión: Cachea localmente, comprime y shardea mejor o mejora la ruta de red/almacenamiento antes de esperar ganancias multi‑GPU.
Tarea 11: Verifica el mapeo proceso→GPU (podrías estar usando una GPU dos veces)
cr0x@server:~$ nvidia-smi pmon -c 1
# gpu pid type sm mem enc dec command
# Idx # C/G % % % % name
0 24819 C 72 61 0 0 python
0 24820 C 69 58 0 0 python
1 - - - - - - -
Significado: Dos procesos están en GPU0; GPU1 está sin usar. Esto es común cuando CUDA_VISIBLE_DEVICES está mal configurado o el lanzador es incorrecto.
Decisión: Arregla tu comando de lanzamiento, entorno o asignación del scheduler. No ajustes NCCL antes de usar la segunda GPU.
Tarea 12: Comprueba la visión de topología de NCCL (cuando las comunicaciones son el problema)
cr0x@server:~$ NCCL_DEBUG=INFO NCCL_TOPO_DUMP_FILE=/tmp/nccl-topo.xml python -c "import torch; import torch.distributed as dist; print('ok')"
NCCL INFO NET/Plugin: No plugin found (libnccl-net.so), using internal implementation
NCCL INFO CUDA Dev 0 [0] PCIe/Gen4 x8
NCCL INFO CUDA Dev 1 [1] PCIe/Gen4 x16
NCCL INFO Topo detection done
ok
Significado: NCCL informa anchuras de enlace y escribió un volcado de topología que puedes inspeccionar offline. El enlace x8 es un cigarrillo humeante.
Decisión: Arregla problemas de PCIe primero; luego vuelve a ejecutar pruebas de escalado. Ninguna sintonía de buckets sustituye a lanes faltantes.
Tarea 13: Comprueba uso de memoria GPU y presión por fragmentación
cr0x@server:~$ nvidia-smi --query-gpu=index,memory.total,memory.used,memory.free --format=csv
index, memory.total, memory.used, memory.free
0, 24564 MiB, 23890 MiB, 674 MiB
1, 24564 MiB, 1200 MiB, 23364 MiB
Significado: GPU0 está cerca de OOM mientras GPU1 está casi vacía. Eso apunta a desequilibrio: asignación de dispositivo incorrecta, modelo no shardeado o mismatch de ranks.
Decisión: Arregla asignación de dispositivos; verifica que cada rank use su GPU prevista; considera estrategia de sharding si la capacidad del modelo es la meta.
Tarea 14: Confirma localidad NUMA del proceso (evita tráfico de memoria remota)
cr0x@server:~$ numactl --show
policy: default
preferred node: current
physcpubind: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
membind: 0
Significado: El proceso está ligado a CPUs 0–15 y al nodo de memoria 0. Si este rank maneja GPU1 en el nodo NUMA 1, estás pagando costes de acceso remoto.
Decisión: Fija cada rank al socket local a su GPU (o al menos evita memoria cross‑socket).
Errores comunes: síntomas → causa raíz → solución
1) Síntoma: la utilización de GPU está “alta” pero el tiempo real empeora
- Causa raíz: Sobrecarga de sincronización (all‑reduce) domina; la utilización incluye tiempo bloqueado en comunicaciones o esperando barreras.
- Solución: Aumenta batch por GPU (o usa acumulación de gradientes), ajusta tamaños de bucket, superpone comunicaciones con cómputo y valida P2P/NVLink/topología.
2) Síntoma: una GPU está ocupada y la otra casi inactiva
- Causa raíz: Asignación de dispositivo incorrecta (CUDA_VISIBLE_DEVICES, lanzador, scheduler), o fallo de un rank dejando a un proceso en solitario.
- Solución: Valida el mapeo con
nvidia-smi pmon; aplica asignación rank↔device; falla rápido cuando cualquier rank sale.
3) Síntoma: el escalado es decente al principio y luego se degrada con el tiempo
- Causa raíz: Throttling térmico o comportamiento de límites de potencia; ocasionalmente fragmentación de memoria y comportamiento del allocator.
- Solución: Monitorea temperaturas/relojes; mejora flujo de aire; fija límites de potencia consistentes; estandariza fan/BIOS; reduce picos si hace falta.
4) Síntoma: el entrenamiento se vuelve inestable—cuelgues, deadlocks, “NCCL timeout”
- Causa raíz: Un rank sufre excepción/OOM y sale; otros esperan en colectivas para siempre. A veces jitter de red o fallos P2P contribuyen.
- Solución: Habilita manejo robusto de errores y timeouts; asegura que todos los ranks aborten juntos; captura logs por rank; reduce fragilidad simplificando la topología.
5) Síntoma: añadiste una GPU para caber un modelo más grande y aún falta memoria
- Causa raíz: Data‑parallel no agrupa VRAM; el modelo completo sigue necesitando caber por GPU.
- Solución: Usa sharding de modelo (tensor/pipeline/expert parallel), checkpointing de activaciones, cuantización o compra una GPU individual más grande.
6) Síntoma: el throughput de inferencia mejora pero la p95/p99 empeora
- Causa raíz: Comunicación cross‑GPU en la ruta crítica; batching/colado amplifica jitter; puntos de sincronización crean colas.
- Solución: Mantén endpoints sensibles a latencia en una sola GPU; reserva multi‑GPU para batch/offline; o rediseña batching y enrutamiento de peticiones.
7) Síntoma: mismo modelo, mismo código, pero el rendimiento varía entre servidores que parecen idénticos
- Causa raíz: Diferencias en topología PCIe, valores por defecto del BIOS, negociación de lanes (x8 vs x16) o P2P deshabilitado en algunos nodos.
- Solución: Establece baseline y aplica comprobaciones de topología en el aprovisionamiento; aísla nodos que no cumplen; estandariza firmware.
8) Síntoma: el sistema de ficheros y la red se ralentizan “aleatoriamente” cuando corren entrenamientos
- Causa raíz: Fanout del data‑loader y tormentas de checkpoints; presión de metadatos por archivos pequeños; contención en almacenamiento compartido.
- Solución: Shardea y cachea datasets; reduce archivos pequeños; escalona checkpoints; limita workers; mueve I/O pesado fuera de rutas compartidas.
Listas de verificación / plan paso a paso
Lista de decisión: ¿deberías comprar una segunda GPU o una GPU más grande?
- Si necesitas más VRAM para un único modelo, favorece una GPU más grande a menos que estés listo para implementar y operar paralelismo de modelo.
- Si necesitas más throughput para muchos trabajos independientes, dos GPUs suelen ser geniales—ejecuta dos procesos separados, evita sincronización.
- Si necesitas menor latencia, prefiere una GPU por ruta de petición. La latencia multi‑GPU es un problema de coordinación.
- Si tu plataforma está limitada por I/O, no añadas GPUs. Arregla almacenamiento/red primero o solo producirás inactividad cara.
- Si tus servidores son dual‑socket, valida la topología antes de comprar; “dos GPUs” puede significar “ruta SYS para siempre”.
Paso a paso: hacer que dos GPUs no sean terribles para entrenamiento
- Base con una GPU: mide tiempo por paso, throughput y relojes GPU en estado estable.
- Valida rutas de hardware: PCIe x16 donde esperas; P2P OK; afinidad NUMA conocida.
- Arregla el pipeline de entrada: cache local, datasets shardados, conteos de workers sensatos, evita archivos minúsculos.
- Escala batch responsablemente: aumenta batch global solo si no perjudica la convergencia; de lo contrario usa acumulación de gradientes.
- Reduce la sobrecarga de comunicación: fusiona tensores pequeños cuando sea posible; afina buckets DDP; superpone comunicaciones con cómputo.
- Estabiliza térmicas: límites de potencia y flujo de aire coherentes; verifica que los relojes no colapsen tras 10 minutos.
- Operativiza: timeouts, recolección de logs por rank, checks de salud para P2P y anchura de enlace PCIe.
Paso a paso: usar dos GPUs efectivamente (el patrón “trabajos separados”)
- Ejecuta procesos independientes fijados a una GPU cada uno (sin colectivas).
- Fija núcleos CPU y memoria por proceso al nodo NUMA de la GPU.
- Limita las escrituras de checkpoint para que ambos jobs no provoquen picos de I/O simultáneos.
- Monitorea throughput por job y relojes por dispositivo; aplica margen térmico obligatorio.
Preguntas frecuentes
1) ¿Dos GPUs son alguna vez mejores que una?
Sí—a menudo. Es mejor cuando puedes ejecutar dos cargas independientes, o cuando tu estrategia de paralelismo de modelo está madura y tu interconexión/topología lo soporta.
Es peor cuando te fuerzas a sincronizaciones frecuentes o cuando tu pipeline está limitado por I/O o CPU.
2) ¿Por qué la VRAM no se suma automáticamente entre GPUs?
Porque cada GPU es un dominio de memoria separado. La mayoría de modos de entrenamiento por defecto replican parámetros en cada dispositivo. Agrupar memoria requiere sharding explícito y
comunicación, lo que cambia el modelo de ejecución y los modos de fallo.
3) Si tengo NVLink, ¿aún tendré problemas multi‑GPU?
NVLink mejora ancho de banda y latencia entre GPUs, pero no arregla cuellos de botella de CPU, almacenamiento, mal dimensionamiento de batch, estrangulamiento térmico o rutas de software frágiles.
Reduce un impuesto; no elimina todos los impuestos.
4) ¿Por qué mi segunda GPU está infrautilizada en PyTorch?
Causas comunes: lanzador equivocado (no crea ranks), CUDA_VISIBLE_DEVICES mal configurado, afinidad de procesos fijando todo a una GPU o un crash en un rank.
Verifica con nvidia-smi pmon y asegúrate de que cada rank selecciona un dispositivo único.
5) ¿Pueden dos GPUs hacer que los juegos sean más fluidos?
Históricamente, multi‑GPU podía aumentar FPS promedio pero empeorar el pacing de frames (microstutter). El soporte moderno es limitado y a menudo no vale la pena.
Una sola GPU más potente suele ser la respuesta correcta para tiempos de frame consistentes.
6) ¿Por qué la inferencia multi‑GPU perjudica tanto la latencia?
Porque la comunicación entre GPUs entra en la ruta crítica de cada petición. Cualquier jitter—encolamiento, deriva térmica, planificación del SO—se convierte en latencia en cola.
El throughput puede mejorar mientras que el p99 empeora. Los usuarios de producción notan el p99.
7) ¿Cuál es el cuello de botella oculto más común al añadir GPUs?
El pipeline de entrada: almacenamiento y CPU. Dos GPUs pueden leer datos más rápido de lo que tu filesystem, object store o preprocesamiento pueden proveer. Entonces las GPUs “esperan eficientemente”.
8) ¿Cómo sé si estoy limitado por PCIe?
Los síntomas incluyen mal escalado a pesar de alta capacidad de cómputo, transferencias host‑device frecuentes y topología mostrando rutas SYS o anchura de enlace reducida.
Comprueba nvidia-smi -q -d PCI para Gen y width, y valida estado P2P con nvidia-smi topo.
9) ¿Debo activar cada perilla de tuning de NCCL que encuentre?
No. Primero valida topología, P2P, anchura PCIe y colocación NUMA. Luego afina. Si la tubería física está mal, los ajustes de NCCL son solo distintas formas de ir lento.
10) Si ya compré dos GPUs, ¿cuál es la mejor forma de usarlas?
Si no estás listo para paralelismo de modelo, el patrón con mayor ROI suele ser ejecutar dos jobs independientes—una por GPU—en lugar de forzar entrenamiento síncrono o inferencia dividida.
Siguientes pasos que puedes tomar
Si tu configuración de dos GPUs rinde menos de lo esperado, trátalo como un incidente SRE: identifica el recurso limitante, valida supuestos y solo entonces cambia la arquitectura.
Aquí está la secuencia práctica que funciona más a menudo de lo que tiene derecho:
- Mide lo que te importa: tiempo por paso, throughput y latencia de cola—elige uno y optimiza para ello.
- Prueba la topología: velocidad/anchura PCIe, P2P habilitado, afinidad NUMA correcta.
- Estabiliza relojes: límites de potencia, térmicas y cualquier indicio de throttling o errores Xid.
- Arregla el alimento: almacenamiento, red, preprocesado en CPU, sharding, cacheo, tormentas de checkpoints.
- Elige la estrategia multi‑GPU adecuada: trabajos independientes, data‑parallel o paralelismo real de modelo—no finjas que son intercambiables.
Si compras hardware: para la mayoría de equipos, el rendimiento por hora‑ingeniero más seguro proviene de una GPU más grande antes que dos más pequeñas—a menos que tu workload se divida naturalmente en tareas independientes.
La hoja de cálculo rara vez incluye “depurar un hang distribuido a las 3 a.m.” El calendario sí.