NVIDIA vs AMD vs Intel: lo que la competencia debe ofrecer para mantener la cordura

¿Te fue útil?

A las 02:17 suena el pager porque “los nodos GPU están lentos”. Eso no es un mensaje de error. Es un estilo de vida. En la producción moderna, la diferencia entre un clúster sano y un caro calefactor de espacio suele ser una revisión de controlador, un enlace PCIe funcionando con el ancho equivocado o un equipo que cree en diapositivas de marketing en lugar de en contadores reales.

El mercado de GPUs no es solo una pelea de tres logotipos. Es una cadena de suministro, un ecosistema de software y un perfil de riesgo operativo. Si compras aceleración a escala—entrenamiento de IA, inferencia, HPC, vídeo, analítica—la competencia no es un lujo. Es lo único que evita que los precios, la energía y el lock-in conviertan tu hoja de ruta en una nota de rehenes.

Qué debe entregar la competencia (y qué debe dejar de hacer)

“NVIDIA vs AMD vs Intel” suele enmarcarse en términos de rendimiento, y el rendimiento es real. Pero en producción, el rendimiento es la tercera pregunta. La primera es ¿podemos ejecutarlo de forma fiable? La segunda es ¿podemos comprarlo de forma predecible? La tercera es ¿podemos cambiar de opinión después?

1) La competencia debe mantener honestos a los ecosistemas de software

Si el stack propietario de un proveedor se convierte en la API de facto de una industria, ese proveedor deja de preocuparse por tus costes de migración. La válvula de seguridad son alternativas creíbles: no solo “compila”, sino “se entrega”. La competencia fuerza:

  • Controladores y kernels estables y documentados que no rompan el userland con una versión puntual.
  • Paridad de herramientas (profilers, depuradores, telemetría) para que los SRE puedan diagnosticar problemas sin un doctorado en la mitología del proveedor.
  • Mejores estándares (IRs de compilador, APIs de runtime, patrones de distribución de contenedores) porque los clientes exigen portabilidad cuando tienen opciones.

2) La competencia debe hacer las cadenas de suministro menos ridículas

Las hojas de ruta de hardware son ahora hojas de ruta de negocio. Si tu ejecución de entrenamiento depende de una sola SKU que un solo proveedor puede entregar, no tienes un plan de infraestructura. Tienes un pronóstico del tiempo.

3) La competencia debe impulsar la eficiencia energética como métrica de primera clase

En 2026, el “coste” del cómputo está dominado por la energía, la refrigeración, los límites de densidad en rack y las personas que mantienen todo en pie. El mejor acelerador es el que alcanza tus objetivos de latencia/throughput sin obligarte a rediseñar el centro de datos alrededor suyo.

Una cita para graparla al dossier de procurement: “La esperanza no es una estrategia.” — General Gordon R. Sullivan. En ops, es prácticamente una filosofía de monitoreo.

Broma corta #1: El mercado de GPUs es el único lugar donde “disponible” se considera una característica avanzada.

Algunos hechos e historia que aún importan

Seis a diez hechos concretos no resolverán tu arquitectura, pero te inmunizan contra el pensamiento de “esto es totalmente nuevo”. Aquí hay nueve que aún aparecen en la toma de decisiones de hoy:

  1. CUDA (introducido en 2006) convirtió a las GPUs en una plataforma de cómputo de propósito general mainstream, no solo hardware gráfico. Esto creó un pozo gravitatorio de librerías y hábitos de desarrollador.
  2. AMD compró ATI en 2006, heredando talento y líneas de producto GPU, y luego pasó años conciliando prioridades centradas en gráficos y en cómputo.
  3. OpenCL (Khronos, 2009) prometía cómputo GPU entre proveedores. Entregó portabilidad en teoría y “dolor de rendimiento portátil” en la práctica para muchas cargas.
  4. HBM (High Bandwidth Memory) se convirtió en una ventaja definitoria para aceleradores paralelos: no son solo FLOPS, es alimentar los núcleos sin dejarlos hambrientos.
  5. PCIe ha sido el cuello de botella perenne para el movimiento de datos GPU→CPU; los saltos de generación ayudan, pero una topología descuidada sigue matando el rendimiento.
  6. NVLink promovió la comunicación GPU↔GPU de alto ancho de banda como diferenciador de producto, especialmente para entrenamiento que necesita all-reduce rápido.
  7. ROCm maduró de forma desigual entre generaciones de GPU y distros Linux; la historia ha mejorado, pero la “matriz de soporte” sigue siendo una restricción operacional real.
  8. oneAPI de Intel es un intento estratégico de unificar la programación entre CPUs, GPUs y aceleradores—útil cuando funciona, frustrante cuando el ecosistema que lo rodea no está maduro.
  9. La inferencia cambió la economía: el entrenamiento hace titulares, pero la inferencia en estado estable a escala es donde el coste por token, la energía y la simplicidad operativa deciden ganadores.

Estos hechos no son trivia. Explican por qué existe el foso de software de NVIDIA, por qué la oportunidad de AMD reaparece, y por qué la historia de Intel está inseparablemente ligada a la plataforma CPU y las relaciones empresariales.

Cómo pensar en NVIDIA vs AMD vs Intel sin engañarte

La mayoría de comparaciones son o guerras de fans o teatro de procurement. Aquí está la vista de producción: trata a cada proveedor como un paquete de silicio + controlador + runtime + librerías + herramientas + comportamiento de soporte + cadena de suministro. La GPU es lo menos importante.

NVIDIA: la predeterminada, por razones que no son puramente técnicas

La mayor ventaja de NVIDIA no es el rendimiento bruto. Es que CUDA se volvió el centro de gravedad para las herramientas de ML, además de un historial largo de entregar experiencia de desarrollador que funciona “out of the box” más a menudo que no. En producción, eso se traduce en:

  • Tiempo a primer éxito más rápido para equipos sin profunda experiencia en compiladores/runtime.
  • Mejor cobertura del ecosistema: kernels, implementaciones de attention, runtimes de inferencia, herramientas de cuantización, profilers.
  • Soporte más predecible en entornos Linux comunes (aún no perfecto; nada lo es).

El riesgo también es claro: cuanto más dependa tu negocio de rutas de código exclusivas de CUDA, menos poder de negociación tendrás sobre precios, plazos de entrega y restricciones de hoja de ruta.

AMD: silicio creíble, madurez del software como determinante

La propuesta de valor central de AMD es simple: potencial de alto rendimiento y la oportunidad de romper la monocultura. Pero en producción, ROCm no se juzga por diapositivas; se juzga por:

  • Si tu combinación exacta de distro/kernel está soportada y es estable.
  • Si tus frameworks y kernels clave alcanzan el rendimiento esperado sin ajustes heroicos.
  • Si tu equipo puede depurar y perfilar problemas con la misma velocidad que en CUDA.

AMD puede ganar mucho donde los clientes estén dispuestos a estandarizar su entorno, validar cuidadosamente y exigir responsabilidad al proveedor. Pierde donde los equipos esperan “instalar y rezar”.

Intel: el caballo oscuro que importa porque existen empresas

La posición de Intel es única: ya posee gran parte de la plataforma CPU, las relaciones de procurement y los canales empresariales “aburridos pero críticos”. La apuesta es que oneAPI y las GPUs de Intel pueden ofrecer un camino de aceleración que encaje en flotas existentes.

En la práctica, Intel suele ser más interesante cuando:

  • Tus cargas ya se benefician de CPUs Intel y quieres una integración más estrecha.
  • Te importa la estabilidad a largo plazo del proveedor y los modelos de soporte empresarial.
  • Puedes aceptar que algunas partes del ecosistema serán menos maduras que las rutas centradas en CUDA.

Cómo es una competencia sensata

No es “tres proveedores iguales en todo”. Eso nunca ocurre. La competencia sensata es:

  • Al menos dos opciones viables para tus cargas principales.
  • Arquitecturas portables donde la lógica de negocio no se case con la API de un proveedor.
  • Benchmarks que ejecutes tú mismo, ligados a tus datos, tus tamaños de batch y tus SLOs de latencia.

Pilas de software: CUDA, ROCm, oneAPI y el coste real de “portable”

La portabilidad no es una casilla para marcar. La portabilidad es un presupuesto de ingeniería. La pregunta correcta no es “¿puede ejecutarse en varios proveedores?” sino “¿cuánto cuesta mantenerlo funcionando en varios proveedores a lo largo del tiempo?”

Las tres capas que deberías separar

Si quieres opcionalidad, diseña como si esperaras cambiar. Separa:

  • Capa de framework: PyTorch, TensorFlow, JAX, XGBoost, pilas de serving estilo Triton Inference Server.
  • Capa de kernels/librerías: análogos a cuDNN/hipDNN, BLAS, kernels de attention, cuantización, comunicación colectiva.
  • Capa de runtime/controlador: runtime/controlador CUDA, stack ROCm, runtimes Level Zero/oneAPI.

Tu portabilidad vive y muere en la capa intermedia. Ahí se esconden los kernels críticos de rendimiento. Puedes escribir código de modelo neutral al proveedor y aun así quedar efectivamente bloqueado por las implementaciones de kernels que tu framework elija en tiempo de ejecución.

Qué hacer en producción

  • Prefiere frameworks que ya soporten múltiples backends para tu clase de carga, incluso si hoy despliegas en un proveedor.
  • Evita extensiones CUDA personalizadas salvo que sea imprescindible. Si debes usarlas, enciérralas detrás de una interfaz limpia y mantén una alternativa en CPU para pruebas de corrección.
  • Construye una “línea CI de portabilidad”: ejecuta un job semanal en un proveedor no primario para mantener la opción viva.

Broma corta #2: “Lo haremos portable después” es la versión de software de “empezaré a hacer backups después de este deploy”.

Realidad operativa: los controladores son parte de tu app

En el mundo GPU, “la app” incluye:

  • Versión del kernel
  • Versión del controlador GPU
  • Firmware (GPU, NIC, a veces placa base)
  • Versión del runtime de contenedor y del device plugin
  • Opciones de compilación del framework

Si no fijas y validas estos como fijas y validas cambios de esquema de base de datos, estás eligiendo outages aleatorios.

Realidades de hardware: memoria, interconexiones y por qué PCIe siempre es sospechoso

Cuando el rendimiento es malo, la gente culpa “la GPU”. En la práctica, a menudo es el ancho de banda de memoria, la topología o la inanición por parte del CPU. Aquí están los controles que realmente mueven la aguja.

Capacidad y ancho de banda de HBM: la restricción silenciosa

Para entrenamiento y inferencia con batches grandes, la capacidad de HBM determina si puedes mantener activaciones y caché KV en memoria. El ancho de banda de HBM determina si tus unidades de cómputo pasan la vida esperando.

Regla de decisión: si ves baja utilización de cómputo pero alta presión en el controlador de memoria, no necesitas “más TFLOPS”. Necesitas mejor comportamiento de memoria: kernels fusionados, ajuste de batch, cuantización o una SKU diferente con más ancho de banda.

Enlaces GPU↔GPU y GPU↔CPU: la topología importa más que la marca

La interconexión es donde la formación multi-GPU vive o muere. Si tu all-reduce es lento, puedes tener la mejor GPU en papel y aun así perder frente a una caja más barata con mejor topología. Necesitas saber:

  • ¿El tráfico GPU-GPU va por telas tipo NVLink o está rebotando por PCIe?
  • ¿Están las GPUs divididas entre sockets CPU con mala alineación NUMA?
  • ¿Está la NIC colocada en el “root complex” equivocado, forzando saltos cross-socket?

Energía y térmicas: acantilados de rendimiento que no ves en benchmarks

El throttling térmico es un asesino silencioso en racks densos. Puedes estar “sano” y aun así incumplir SLOs porque los relojes colapsan bajo carga sostenida. Tu monitoreo debe tratar los relojes GPU y el consumo como métricas de primera clase, no trivia.

Procurement para SREs: las preguntas que tu proveedor no te hará

Las conversaciones de procurement suelen estar dominadas por precio y throughput pico. En ops, deberías preocuparte por: tiempo medio de recuperación, gestión de cambios y heterogeneidad de la flota.

Qué deberías exigir antes de comprar

  • Una matriz de software soportada: versiones exactas de OS, rangos de kernel, versiones de controladores y expectativas de runtime de contenedor.
  • Una historia de actualizaciones de firmware: ¿cómo parchean a escala, con qué frecuencia y qué se rompe?
  • Expectativas de RMA y sparing: plazos, cross-ship y qué significa “falla” en sus logs.
  • Compatibilidad de telemetría: ¿puedes extraer las métricas que necesitas sin agentes propietarios que choquen con tu entorno?
  • Documentos claros de topología de interconexión para la SKU de servidor que realmente estás comprando, no un diseño de referencia.

Qué deberías construir internamente

  • Una imagen golden por stack de proveedor con versiones fijadas.
  • Una vía de canary para upgrades que ejecute cargas representativas de entrenamiento e inferencia.
  • Un harness de benchmark que mida no solo throughput, sino latencia cola, comportamiento de warmup y recuperación ante fallos.

Guión de diagnóstico rápido: qué revisar primero/segundo/tercero para encontrar el cuello de botella rápidamente

Esta es la secuencia de “dejar de discutir, empezar a medir”. Funciona entre proveedores porque se basa en física y sistemas operativos, no en identidad de marca.

Primero: ¿la GPU se está usando realmente?

  • Revisa utilización, relojes, consumo y uso de memoria.
  • Si la utilización es baja pero el job está “lento”, probablemente estás limitado por CPU, I/O o bloqueado en sincronización.

Segundo: ¿el movimiento de datos es el verdadero cuello de botella?

  • Busca alto PCIe RX/TX con cómputo bajo.
  • Chequea velocidad/ancho de enlace PCIe (x16 vs x8; Gen5 vs Gen4) y la localidad NUMA.
  • Para multi-GPU, valida peer-to-peer y ancho de banda colectivo.

Tercero: ¿el framework está cayendo a una ruta lenta?

  • Confirma que el backend previsto esté activo (CUDA/ROCm/oneAPI) y que las ops clave usen kernels acelerados.
  • Observa logs por advertencias de “fallback” y ubicaciones de dispositivo inesperadas.

Cuarto: ¿el nodo es estable bajo carga sostenida?

  • Chequea throttling (térmico/energía), errores ECC y resets de controlador.
  • Revisa logs del kernel por errores PCIe/AER y eventos estilo Xid de GPU.

Quinto: ¿te está mintiendo el scheduler del clúster?

  • Valida la salud del device plugin, restricciones cgroup, configuración MIG/particionamiento e integración del runtime de contenedor.
  • Confirma que no estés sobrereservando CPU/memoria para jobs GPU (común en Kubernetes).

Tareas prácticas: comandos, qué significa la salida y qué decisión tomar

Estos son chequeos reales ejecutables. Úsalos durante incidentes, planificación de capacidad y pruebas de proveedores. El objetivo no es coleccionar trivia; es tomar decisiones.

Tarea 1: Identificar GPUs y el controlador en uso

cr0x@server:~$ lspci -nn | egrep -i 'vga|3d|display'
01:00.0 3D controller [0302]: NVIDIA Corporation Device [10de:2330] (rev a1)
21:00.0 Display controller [0380]: Advanced Micro Devices, Inc. [AMD/ATI] Device [1002:74a1] (rev c1)

Qué significa: Ves qué dispositivos de proveedor están presentes y sus IDs PCI. Flotas mixtas son normales; drivers mixtos en un mismo nodo suelen no serlo.

Decisión: Si el dispositivo no coincide con lo que creías desplegar, para. Arregla inventario y scheduling antes de afinar otra cosa.

Tarea 2: Comprobar detalles del kernel y OS (la compatibilidad de drivers empieza aquí)

cr0x@server:~$ uname -r
6.5.0-17-generic

Qué significa: La versión del kernel afecta módulos DKMS, comportamiento IOMMU y matrices de soporte del proveedor.

Decisión: Si estás fuera del rango de kernel soportado por el proveedor, estás depurando un proyecto de investigación. Pasa a un kernel soportado.

Tarea 3: Vista rápida de salud NVIDIA (utilización, energía, relojes)

cr0x@server:~$ nvidia-smi
Tue Jan 21 02:31:09 2026
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14    Driver Version: 550.54.14    CUDA Version: 12.4               |
|-----------------------------------------+----------------------+----------------------+
| GPU  Name                 Persistence-M | Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp   Perf          Pwr:Usage/Cap |         Memory-Usage | GPU-Util  Compute M. |
|                                         |                      |               MIG M. |
|=========================================+======================+======================|
|  0  NVIDIA H100 PCIe                 On | 00000000:01:00.0 Off |                    0 |
| N/A   61C    P0              280W / 350W|  62480MiB / 81559MiB |     92%      Default |
+-----------------------------------------+----------------------+----------------------+

Qué significa: Alta GPU-Util con alto consumo y estado P0 estable sugiere que la GPU está trabajando. Baja utilización con alto uso de memoria suele significar memoria residente pero cómputo inactivo (pipeline de datos, sincronización o ineficiencia de kernel).

Decisión: Si GPU-Util es baja, enfoca en CPU/I/O/scheduling y en fallbacks del framework.

Tarea 4: Vista de salud AMD ROCm (si ROCm está instalado)

cr0x@server:~$ rocm-smi
========================ROCm System Management Interface========================
GPU[0]          : GPU ID: 0x74a1
GPU[0]          : Temp (Sensor edge) (C): 58.0
GPU[0]          : Average Graphics Package Power (W): 240.0
GPU[0]          : VRAM Total (B): 68719476736
GPU[0]          : VRAM Used (B): 42949672960
GPU[0]          : GPU use (%): 88

Qué significa: Misma lógica que NVIDIA: utilización/consumo/temp te dicen si el acelerador está comprometido y si está térmicamente estresado.

Decisión: Si la utilización es alta pero el throughput es bajo, sospecha ancho de banda de memoria o elección de kernel; pasa al profiler y logs del framework.

Tarea 5: Enumeración GPU Intel (Level Zero)

cr0x@server:~$ /usr/bin/zeinfo | head
Level Zero API version: 1.13
Driver version: 1.3.29735
Devices:
  Device 0: Intel(R) Data Center GPU

Qué significa: Confirma que el runtime Level Zero ve el dispositivo y que se cargó un driver.

Decisión: Si el runtime no enumera dispositivos, arregla instalación de driver/runtime antes de tocar configuraciones de la app.

Tarea 6: Comprobar velocidad/ancho de enlace PCIe (falla silenciosa común)

cr0x@server:~$ sudo lspci -s 01:00.0 -vv | egrep -i 'LnkCap|LnkSta'
LnkCap: Port #0, Speed 32GT/s, Width x16
LnkSta: Speed 16GT/s (downgraded), Width x8 (downgraded)

Qué significa: La tarjeta puede hacer PCIe Gen5 x16, pero actualmente está funcionando Gen4 x8. Eso es un impuesto de rendimiento, a veces un desastre.

Decisión: Trata esto como un incidente de hardware/BIOS/topología: reseat, revisa risers, configuraciones BIOS, compartición de lanes y layout de la placa base.

Tarea 7: Comprobar topología NUMA (GPU colocada lejos de tus hilos CPU)

cr0x@server:~$ numactl --hardware
available: 2 nodes (0-1)
node 0 cpus: 0-31
node 1 cpus: 32-63
node 0 size: 256000 MB
node 1 size: 256000 MB

Qué significa: Sistema dual-socket. Si tu GPU está conectada al nodo 1 pero tu dataloader corre en el nodo 0, pagas latencia y coste de ancho de banda cross-socket.

Decisión: Pinnea hilos CPU y asignación de memoria al nodo NUMA local a la GPU para throughput y estabilidad de latencia tail.

Tarea 8: Mapear dispositivos PCI a nodos NUMA

cr0x@server:~$ cat /sys/bus/pci/devices/0000:01:00.0/numa_node
1

Qué significa: Esta GPU es local al nodo NUMA 1.

Decisión: Ejecuta tu pipeline de entrada y preprocesado en CPU en el nodo 1 (o acepta el coste conscientemente).

Tarea 9: Comprobar ajustes IOMMU (puede perjudicar latencia y P2P)

cr0x@server:~$ dmesg | egrep -i 'iommu|dmari' | head
[    0.112345] DMAR: IOMMU enabled
[    0.112900] DMAR: Intel(R) Virtualization Technology for Directed I/O

Qué significa: IOMMU está habilitado. Eso suele ser requerido para virtualización e aislamiento, pero configuraciones erróneas pueden romper P2P o reducir rendimiento.

Decisión: Si necesitas GPU peer-to-peer o máximo throughput, valida el modo IOMMU recomendado por el proveedor (enabled, passthrough o parámetros de kernel específicos) y prueba.

Tarea 10: Encontrar errores del kernel relacionados con GPU (AER, resets, eventos tipo Xid)

cr0x@server:~$ sudo journalctl -k -S -2h | egrep -i 'nvrm|xid|amdgpu|pcie|aer|gpu reset' | tail
Jan 21 01:44:10 server kernel: pcieport 0000:00:01.0: AER: Corrected error received: id=00e0
Jan 21 01:44:10 server kernel: amdgpu 0000:21:00.0: GPU reset begin!
Jan 21 01:44:14 server kernel: amdgpu 0000:21:00.0: GPU reset succeeded

Qué significa: Errores PCIe corregidos y un reset de GPU. Incluso los errores “corregidos” se correlacionan con risers defectuosos, alimentación marginal o lanes malas.

Decisión: Si ves resets bajo carga, deja de culpar al modelo. Cuarentena el nodo, ejecuta diagnósticos de hardware y contacta al proveedor.

Tarea 11: Confirmar que el runtime de contenedores ve las GPUs (Kubernetes o standalone)

cr0x@server:~$ docker run --rm --gpus all nvidia/cuda:12.4.1-base-ubuntu22.04 nvidia-smi
+---------------------------------------------------------------------------------------+
| NVIDIA-SMI 550.54.14    Driver Version: 550.54.14    CUDA Version: 12.4               |
+---------------------------------------------------------------------------------------+

Qué significa: El contenedor puede acceder a la GPU y la pila de controladores está conectada correctamente a través del runtime.

Decisión: Si esto falla, arregla runtime de contenedor/device plugin/permisos antes de tocar el código de la aplicación.

Tarea 12: Comprobar asignación GPU en Kubernetes (¿estás realmente programado en una GPU?)

cr0x@server:~$ kubectl describe pod infer-7c9b6d6c6f-2kqnx | egrep -i 'node:|nvidia.com/gpu|amd.com/gpu|intel.com/gpu|limits|requests'
Node:           gpu-node-12/10.10.12.34
Limits:
  nvidia.com/gpu:  1
Requests:
  nvidia.com/gpu:  1

Qué significa: El pod está programado con un límite/solicitud de GPU, y puedes ver en qué nodo está.

Decisión: Si faltan requests/limits, estás en CPU y tu “ralentización GPU” es en realidad “sin GPU”. Arregla el manifiesto y los controles de admisión.

Tarea 13: Comprobar throttling de CPU y tiempo steal (los jobs GPU pueden quedarse sin CPU)

cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.5.0-17-generic (server)  01/21/2026  _x86_64_  (64 CPU)

02:32:01 AM  CPU   %usr  %sys  %iowait  %steal  %idle
02:32:02 AM  all   85.1   8.2     1.3     0.0    5.4
02:32:03 AM  all   88.0   9.1     0.7     0.0    2.2

Qué significa: CPU está muy cargada; si tu dataloader y networking corren en CPU, la utilización GPU puede bajar esperando input.

Decisión: Aumenta asignación CPU para pods GPU, ajusta workers del dataloader o mueve preprocesado fuera de nodos críticos.

Tarea 14: Comprobar saturación I/O de disco (pipeline de entrada de entrenamiento)

cr0x@server:~$ iostat -xz 1 3
Device            r/s     rkB/s   await  %util
nvme0n1         120.0   98000.0   18.2   99.5

Qué significa: NVMe está al ~100% de utilización y await alto. Tu GPU probablemente está esperando datos.

Decisión: Cachea datasets localmente, usa mejor sharding, aumenta read-ahead o mueve a almacenamiento de mayor throughput. No compres más GPUs para arreglar un cuello de botella de disco.

Tarea 15: Comprobar salud de la red (all-reduce distribuido, almacenamiento remoto)

cr0x@server:~$ ip -s link show dev eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    RX: bytes  packets  errors  dropped  missed  mcast
    9834212345  8123456  0       0        0       0
    TX: bytes  packets  errors  dropped  carrier collsns
    11233455667  9234567  0       0        0       0

Qué significa: Errores y drops son cero (bien). Si ves errores/drops en aumento, el entrenamiento distribuido parecerá “lentitud GPU” pero son retransmisiones y congestión.

Decisión: Arregla firmware NIC, cableado, configuración de switch o mueve collectives a una red dedicada.

Tarea 16: Verificar hugepages y presión de memoria (fallos de página dañan)

cr0x@server:~$ grep -E 'HugePages_Total|HugePages_Free|MemAvailable' /proc/meminfo
MemAvailable:   182345672 kB
HugePages_Total:    4096
HugePages_Free:     3900

Qué significa: Hugepages están mayormente libres y la memoria disponible; buen baseline. Si MemAvailable es bajo, el paginado en CPU puede detener pipelines de datos y aumentar latencia.

Decisión: Evita overcommit de memoria en nodos GPU; ajusta límites de pods; aísla nodos para cargas GPU.

Tres mini-historias corporativas (cómo esto falla en empresas reales)

Mini-historia 1: El incidente causado por una suposición errónea

La empresa tenía un flamante clúster de inferencia. Mismo modelo, misma imagen de contenedor, mismos manifiestos de Kubernetes. El plan de rollout era limpio: añadir nodos gradualmente, dejar que el autoscaler haga el resto. El dashboard se veía bien—los pods estaban corriendo, las GPUs “asignadas” y el servicio devolvía respuestas.

Entonces la latencia tail se duplicó. Nada estaba obviamente roto. La utilización GPU era baja, la CPU alta y los logs de la aplicación estaban llenos de advertencias inocuas que nadie había leído jamás.

La suposición errónea: “Si el pod solicita una GPU, la usará”. En realidad, el runtime del modelo dentro del contenedor no coincidía con la pila de controladores en los nuevos nodos. El framework detectó una incompatibilidad y silenciosamente cayó a CPU para varias ops clave. No todas las ops—las suficientes para mantener el servicio “funcionando”, lo suficientemente lento para que los SLOs lloraran.

La solución fue aburrida: alinear la versión del controlador con el runtime esperado por el contenedor, añadir un chequeo de arranque que falle el pod si el backend no está activo y forzar etiquetado de nodos para que nodos incompatibles no puedan ser seleccionados. El postmortem fue aún más aburrido: “Deberíamos haber probado la imagen de nodo exacta en canary.” Correcto. También doloroso.

Mini-historia 2: La optimización que salió mal

Un equipo de entrenamiento quería épocas más rápidas. Tenían una nueva caja multi-GPU con interconexión rápida y decidieron subir workers del dataloader y aumentar prefetch. Funcionó en una prueba pequeña: la utilización GPU subió y los pasos se volvieron más rápidos.

En la corrida completa, el rendimiento se degradó durante horas. No inmediatamente, lo que lo convirtió en un gran misterio y un mejor sumidero de tiempo. Las GPUs empezaron a oscilar: picos de alta utilización seguidos por huecos inactivos. Eventualmente, los nodos comenzaron a reportar errores PCIe corregidos y luego resets ocasionales de GPU.

La “optimización” incrementó la carga CPU y la churn de memoria, lo que elevó las temperaturas del chasis y empujó la plataforma a una estabilidad marginal. Las GPUs estaban bien; el servidor no. Bajo carga sostenida, una combinación de térmicas e integridad de señal PCIe al límite causó resets. El clúster parecía un problema de software porque el job se reiniciaba y continuaba—solo más lento, más ruidoso y con backlog creciente.

El retroceso se resolvió reduciendo la presión en CPU, mejorando la gestión del flujo de aire y estableciendo límites de potencia/reloj para evitar acantilados térmicos. La lección fue clara: si un tweak de rendimiento cambia el consumo, también cambiaste la fiabilidad. Trátalo como un cambio de producción, no como un experimento en notebook.

Mini-historia 3: La práctica aburrida pero correcta que salvó el día

Un equipo de infra corría una flota de proveedores mixtos: algunos nodos en un proveedor para entrenamiento, otros en otro para experimentos de inferencia. Constantemente se sentían tentados a “estandarizar más adelante”, pero hacían una cosa consistentemente: fijaban una imagen golden por clase de nodo, con driver/kernel/container validados. Sin máquinas especiales, sin hotfixes manuales.

Durante un ciclo de parches de seguridad, una actualización de kernel se desplegó en la flota de cómputo general. Los nodos GPU fueron excluidos por política. Alguien se quejó—“¿por qué los nodos GPU son especiales?”—y la respuesta fue la misma de siempre: porque desajustes kernel/driver no son una forma divertida de pasar los fines de semana.

Dos semanas después, un update de driver del proveedor solucionó estabilidad bajo cierto patrón de carga. El equipo lo desplegó en una pequeña pool canary, corrió un conjunto completo de benchmarks de entrenamiento e inferencia y observó logs por errores PCIe corregidos y throttling. Solo entonces lo desplegaron ampliamente.

El pago llegó silenciosamente: mientras otros equipos apagaban incendios con regresiones misteriosas después de la actualización del kernel, este equipo tenía baselines limpias y una vía controlada de upgrades. El incidente nunca les ocurrió. Ese es el objetivo de la corrección aburrida—evitar que las historias existan en primer lugar.

Errores comunes: síntoma → causa raíz → solución

1) Síntoma: baja utilización de GPU, pero el job es lento

Causa raíz: pipeline de entrada limitado por CPU, cuello de botella de almacenamiento o fallback del framework a CPU para ops clave.

Solución: Revisa CPU (mpstat), disco (iostat) y logs de activación del backend. Falla rápido si el backend no está activo. Pinnea CPU/memoria al nodo NUMA local a la GPU.

2) Síntoma: el entrenamiento multi-GPU es más lento que la escala de una sola GPU

Causa raíz: cuello de botella de comunicación colectiva (ubicación de NIC, topología, mala utilización de interconexión) o tamaños de batch pequeños que hacen que la sincronización domine.

Solución: Verifica topología (PCIe/enlaces tipo NVLink), asegura localidad de la NIC, ajusta tamaños de batch y acumulación de gradientes, y aísla la red para collectives.

3) Síntoma: gran rendimiento en benchmark, mediocre en producción

Causa raíz: el benchmark cabe en cache/HBM y no modela I/O real, patrones de request o latencia tail. Throttling térmico bajo carga sostenida.

Solución: Haz benchmarks con secuencias realistas, concurrencia y duraciones. Monitorea relojes y consumo bajo carga sostenida. Establece power caps estables si hace falta.

4) Síntoma: “device disappeared” aleatorio / resets GPU

Causa raíz: errores PCIe/AER, risers marginales, problemas de alimentación o bugs de driver/firmware que se disparan bajo carga.

Solución: Cuarentena el nodo. Revisa journalctl -k por logs AER/reset GPU. Valida ancho de enlace/velocidad PCIe. Actualiza firmware/driver en canary y luego despliega.

5) Síntoma: picos de latencia en inferencia cada pocos minutos

Causa raíz: compactación en background, lecturas de dataset, churn del autoscaler, recolección de basura en CPU o cambios de reloj GPU por gestión de energía.

Solución: Calienta modelos, preasigna pools de memoria, fija relojes/potencia cuando proceda y elimina vecinos ruidosos (aislamiento de CPU e I/O).

6) Síntoma: portar de CUDA a backend “portable” compila pero es mucho más lento

Causa raíz: falta de kernels optimizados (attention, layernorm, variantes GEMM), diferente comportamiento de fusión o fallback a implementaciones genéricas.

Solución: Perfila e identifica ops calientes, luego elige librerías que provean kernels optimizados para el backend objetivo. Mantén la arquitectura del modelo flexible cuando sea posible.

7) Síntoma: Kubernetes muestra GPUs asignadas, pero dentro del contenedor no hay GPU visible

Causa raíz: mismatch del device plugin, mala configuración del runtime de contenedores, permisos insuficientes o hooks de contenedor del proveedor faltantes.

Solución: Valida con un test mínimo de contenedor GPU, revisa logs del device plugin y estandariza la configuración del runtime entre pools de nodos.

Listas de verificación / plan paso a paso

Paso a paso: seleccionar un proveedor (o mezclar proveedores) sin remordimientos

  1. Escribe tu mezcla real de cargas. Entrenamiento vs inferencia, tamaños de batch, modos de precisión, longitudes de secuencia, huella de memoria y patrones de comunicación.
  2. Define dos métricas por carga: una de rendimiento (throughput o tiempo a entrenar) y una métrica de negocio (coste por token, coste por época, energía por request).
  3. Elige tres pruebas representativas que puedas ejecutar en cada plataforma candidata: (a) inferencia en estado estable, (b) corrida larga de entrenamiento, (c) prueba de recuperación ante fallo (drain de nodo + reschedule).
  4. Construye una imagen golden por plataforma con kernel/driver/runtime fijados y una pipeline de build reproducible.
  5. Valida la topología (velocidad/ancho PCIe, localidad NUMA, colocación de NIC) antes de correr cualquier benchmark. Si no, estarás midiendo tus errores.
  6. Corre tests sostenidos (horas, no minutos). Observa relojes, temps, errores PCIe corregidos y resets.
  7. Decide tu postura sobre portabilidad explícitamente: “CUDA-first pero arquitectura portable”, o “CI multi-backend”, o “un proveedor por ahora”. Pretender hacerlo todo es cómo mueren los presupuestos.
  8. Operacionaliza upgrades: vía canary, plan de rollback y checks de salud automáticos que validen que el backend está activo.
  9. Negocia soporte como un SRE: exige rutas claras de escalado para problemas de drivers y define qué logs/telemetría son necesarios para abrir un caso.

Checklist: antes de culpar al proveedor de GPU

  • El enlace PCIe no está degradado (velocidad y ancho coinciden con expectativas).
  • La alineación NUMA es correcta para hilos CPU y asignaciones de memoria.
  • No hay errores PCIe corregidos en logs del kernel bajo carga.
  • El pipeline de almacenamiento no está saturado.
  • Los errores/drops de red son cero para jobs distribuidos.
  • El framework está usando el backend previsto y no cae silenciosamente.
  • Térmicas y energía estables; sin throttling sostenido.

Checklist: cómo mantener viva la competencia dentro de tu organización

  • Mantén al menos una pool de nodos de un proveedor no primario, aunque pequeña.
  • Ejecuta un job de portabilidad semanal: compila, ejecuta comprobaciones de corrección y registra deltas de rendimiento.
  • Prohíbe extensiones específicas del proveedor a menos que haya un ROI medido y un plan de salida.
  • Rastrea “bloqueadores de migración” como deuda técnica: asigna dueños y presupuestos.

Preguntas frecuentes

1) ¿Deberíamos estandarizar en un proveedor para reducir la complejidad operativa?

Estandariza tu proceso, no tu proveedor. Una flota de proveedor único es más simple hasta que deja de serlo—precios, plazos y sorpresas de hoja de ruta son complejidad operativa también. Si puedes pagarlo, mantén una pequeña pool de un segundo proveedor para preservar apalancamiento y músculo de portabilidad.

2) ¿El lock-in en CUDA siempre es malo?

No. CUDA puede ser la vía más rápida a producción y a menudo la mejor soportada. El lock-in se vuelve malo cuando construyes kernels personalizados sólo en CUDA en todas partes y no puedes negociar precios o pivotar cuando la oferta se seca. Usa CUDA, pero diseña para opcionalidad.

3) ¿Cuál es el asesino de rendimiento oculto número uno?

PCIe y problemas de topología. Un enlace degradado (Gen5 x16 funcionando como Gen4 x8) o tráfico cross-socket puede borrar la ventaja de una GPU más cara.

4) Para inferencia, ¿qué importa más: cómputo o memoria?

A menudo la memoria—capacidad y ancho de banda—porque la caché KV y las activaciones dominan. El cómputo también importa, pero muchas cargas de inferencia están limitadas por mover datos, no por hacer operaciones.

5) ¿Podemos confiar en APIs “portables” y esperar rendimiento casi igual?

Espera portabilidad funcional, no paridad de rendimiento. El rendimiento viene de kernels ajustados, estrategias de fusión y librerías maduras. La portabilidad sigue valiendo la pena; solo presupuestea tuning específico por backend.

6) ¿Cómo prevenimos fallback silencioso a CPU?

Añade chequeos explícitos de arranque en tu servicio/job que verifiquen que el backend está activo y que una pequeña operación tensorial se ejecute en el dispositivo. Si no, falla rápido y ruidoso. “Funcionando pero lento” es el peor modo de fallo.

7) ¿Necesitamos imágenes golden separadas por proveedor?

Sí, si quieres cordura. Trata la combinación driver/runtime/kernel como parte de la aplicación. Fíjalo, pruébalo y desplégalo como despliegas migraciones de base de datos.

8) ¿Cuál es una forma sensata de benchmarkear proveedores?

Usa tus modelos reales y patrones de request reales. Ejecuta pruebas sostenidas. Mide latencia tail, estabilidad (resets, errores corregidos) y fricción operativa (herramientas, facilidad de upgrade). Si solo mides throughput pico por cinco minutos, estás midiendo optimismo.

9) ¿Los power caps son un truco o una buena práctica?

Son una buena práctica cuando alcanzas acantilados térmicos o de suministro de energía. Un reloj pico ligeramente inferior con rendimiento sostenido estable vence a un nodo inestable que se resetea bajo carga.

10) ¿Cuál es la forma más simple de mantener la opcionalidad multi-proveedor?

Mantén tu código de modelo libre de extensiones específicas del proveedor, ejecuta un job periódico en un segundo backend y evita construir tu stack de serving alrededor de características propietarias de un proveedor a menos que tengas una necesidad de negocio medida.

Próximos pasos que realmente puedes ejecutar

Si quieres que la competencia mantenga el mercado sensato, tienes que mantener tu propia arquitectura sensata. Eso significa que puedas cambiar, o al menos amenazar creíblemente con hacerlo. Aquí está la ruta práctica:

  1. Instrumenta primero: añade utilización GPU, relojes, potencia, memoria, errores PCIe y señales de selección de backend a tu monitoreo. Si no lo puedes ver, no puedes negociarlo.
  2. Construye una vía de portabilidad: una corrida CI semanal en un nodo de proveedor no primario. No necesita ser rápida. Necesita ser real.
  3. Endurece tu flota: imágenes golden, versiones fijadas, rollouts canary y checks de salud automáticos que fallen rápido en rutas de fallback.
  4. Haz benchmarks como operador: corridas sostenidas, datos reales, concurrencia real y una inyección de fallo (drain de nodo, restart, reschedule) para medir comportamiento de recuperación.
  5. Compra como un SRE: documentos de topología, matrices soportadas, estrategia de firmware y rutas de escalado de soporte no son “bonos”. Son la diferencia entre enviar y apagar incendios.

El mercado seguirá haciendo lo que hacen los mercados: concentrarse, extraer rentas y llamarlo “innovación”. Tu trabajo es mantener opciones vivas—técnica y comercialmente—para que tus sistemas de producción no se conviertan en un monumento a los márgenes de otro.

← Anterior
Mejor tipografía para documentación que los ingenieros sí leen
Siguiente →
Spectre y Meltdown: cuando la seguridad empezó a costar rendimiento

Deja un comentario