GPUs con chiplets: por qué la idea tiene lógica — y es brutalmente difícil

¿Te fue útil?

Compras una “GPU más grande” y esperas una cosa: que tu trabajo termine más rápido. Luego tu entrenamiento se estanca, tus kernels parecen estar esperando un autobús y tu histograma de latencias desarrolla una segunda joroba. El proveedor dice “interconexión”, tu desarrollador dice “es el cargador de datos” y tu instinto de SRE dice “no es ninguno de los dos; es la topología”.

Las GPUs con chiplets son el siguiente paso obvio en un mundo donde los límites del retículo, las curvas de rendimiento y la densidad de potencia no se preocupan por tu hoja de ruta. También son un campo minado. La idea es elegante. La realidad es un sistema distribuido que accidentalmente ataste a una placa y llamaste “una GPU”.

Por qué las GPUs con chiplets tienen sentido (y por qué todos las quieren)

Si gestionas clústeres GPU en producción, ya convives con la economía del silicio. No el precio de etiqueta, sino la economía del silicio. Las GPUs monolíticas chocan contra varios muros a la vez: límites de tamaño de retícula, rendimiento por oblea, complejidad de empaquetado y entrega de potencia. Los chiplets prometen expandir esos muros.

La propuesta, en términos simples

Una GPU con chiplets divide un dado enorme en varios dados más pequeños (chiplets) y los une con una interconexión de alta velocidad. Obtienes:

  • Mejor rendimiento por oblea: los dados más pequeños tienen menos defectos por dado, así que hay más piezas utilizables por oblea.
  • Escalabilidad: construye una “GPU más grande” añadiendo chiplets en lugar de volver a diseñar un dado monstruoso.
  • Componentes reutilizables: combina tiles de cómputo, tiles de caché y tiles de E/S.
  • Flexibilidad de nodos de proceso: coloca la SRAM intensiva de caché en un nodo, el cómputo en otro y la E/S en uno más económico.

Para las CPU, esta estrategia ya es corriente. Para las GPUs, la lógica es la misma—hasta que recuerdas qué hacen realmente las GPUs: trabajo masivamente paralelo con un apetito brutal de ancho de banda, sincronizado a granularidad fina, donde pequeños aumentos de latencia pueden hundir la ocupación y el rendimiento.

Qué cambia cuando una GPU se vuelve “distribuida”

En una GPU monolítica, la interconexión en el dado es efectivamente “lo suficientemente barata” y coherente como para que los programadores puedan ignorarla en su mayor parte. En una GPU con chiplets, tu interconexión se convierte en una característica del producto. Tu jerarquía de caché se vuelve política. Tu modelo de memoria se convierte en una negociación.

Las GPUs con chiplets no son solo hardware. Son un contrato entre:

  • empaquetado (cómo conectas físicamente los dies),
  • la interconexión (ancho de banda/latencia/ordenamiento),
  • arquitectura de memoria (colocación de HBM, mapeo de direcciones, coherencia),
  • compilador/tiempo de ejecución (ubicación de kernels, distribución de trabajo),
  • controladores y SO (exposición de la topología),
  • y tu aplicación (patrones de acceso que quizá no habías visto como frágiles).

Broma #1: Los chiplets son geniales porque convierten “una GPU grande” en “varias GPUs más pequeñas”, y ahora puedes depurar sistemas distribuidos sin levantarte de la silla.

La parte difícil: fingir que varios dies son una sola GPU

La dificultad central no es “hacer que el ancho de banda sea rápido”. Es “hacer que todo se comporte como un único dispositivo bajo los peores patrones de acceso que tus usuarios sin duda golpearán por accidente”.

1) Interconexión: el ancho de banda es el titular; la latencia es la factura

Las interconexiones dentro de los paquetes pueden ser extremadamente anchas y rápidas. Pero siguen siendo más lentas que los cables en el dado, y la latencia no es un error de redondeo. En las GPUs eso importa porque:

  • muchos kernels son sensibles a la latencia a pesar del alto paralelismo,
  • la sincronización de granularidad fina amplifica la latencia en cola,
  • el planificador asume ciertas propiedades de localidad que dejan de ser válidas.

En producción, verás esto como “acantilados” de rendimiento misteriosos: el trabajo es rápido hasta que un tensor cruza un umbral, o cambia el tamaño del batch, o el asignador de memoria decide colocar un buffer “allí”.

2) Colocación de memoria: HBM es rápida; la HBM remota es “más o menos rápida”

Las GPUs con chiplets casi siempre mantienen memoria de alta ancho de banda (HBM) cerca de algunos dies. Si tu carga puede quedarse local, ganas. Si no puede, el acceso remoto a memoria se convierte en un impuesto.

El escenario más peligroso es cuando la arquitectura y el controlador presentan un espacio de direcciones unificado que parece plano, pero se comporta como NUMA. “Direcciones planas” no es lo mismo que “rendimiento plano”.

3) Coherencia y caché: el sutil asesino de rendimiento

La coherencia entre dies es cara. No implementar coherencia también es caro, pero en otra moneda: complejidad de software y riesgo de corrección.

Las GPUs ya juegan con la coherencia (diferentes niveles de caché, regiones no coherentes, atomics con reglas especiales). Los chiplets suben la apuesta. Si quieres semánticas de “una sola GPU”, necesitas:

  • reglas de ordenamiento bien definidas,
  • atomics eficientes a través de dies,
  • estrategias de invalidación de caché que no derritan el rendimiento,
  • comportamiento predecible bajo contención.

4) Planificación del trabajo: dónde ejecutas un kernel ahora importa

Con chiplets, no puedes tratar el dispositivo como un pool uniforme de unidades de cómputo. Debes responder:

  • ¿Qué chiplet ejecuta qué bloques?
  • ¿Dónde están los datos?
  • ¿Cuánto cuesta la comunicación entre chiplets?
  • ¿Qué pasa cuando varios kernels compiten por la misma interconexión?

El tiempo de ejecución puede intentar ser inteligente. A veces tendrá éxito. También a veces se sobrepasará a sí mismo de maneras que solo descubrirás a las 2 a. m., después de una actualización del controlador.

5) Confiabilidad: más componentes, más superficie de falla

Más dies y más enlaces significan más cosas que pueden degradarse. Un único enlace marginal puede manifestarse como:

  • picos intermitentes de ECC corregido,
  • reinicios del controlador tipo “Xid” bajo carga,
  • caídas silenciosas de rendimiento cuando el sistema retrena un enlace a una velocidad inferior,
  • resultados de benchmark irritantemente inconsistentes.

Aquí está la lente de confiabilidad que importa: cuando una GPU monolítica está enferma, suele estar evidentemente enferma. Cuando una GPU con chiplets está ligeramente enferma, puede parecer “el modelo se volvió más lento esta semana”. Esos son los incidentes caros.

Una idea parafraseada de una voz notable en confiabilidad (atribuida): Werner Vogels frecuentemente argumenta que “todo falla, así que diseña para la falla.” Las GPUs con chiplets son ese lema hecho silicio.

Hechos e historial interesantes que importan

Algunos puntos de contexto que realmente cambian cómo piensas sobre las GPUs con chiplets, no solo trivia para presentaciones:

  1. El límite del retículo fotolitográfico es un techo duro: no puedes imprimir dados monolíticos arbitrariamente grandes en una sola exposición, así que “simplemente hazlo más grande” deja de ser una opción.
  2. El rendimiento por oblea cae no linealmente con el área del dado: los dados grandes no solo cuestan más; fallan con más frecuencia, haciendo que las SKU de gama alta sean un ejercicio de binning y plegarias.
  3. Los módulos multi-die (MCM) no son nuevos: los proveedores de CPU han enviado paquetes multi-die por décadas, pero los patrones de acceso GPU son más duros porque el ancho de banda y la sincronización son presión constante.
  4. HBM cambió el juego de empaquetado: mover memoria a un interposer junto a la GPU empujó a la industria hacia empaquetados avanzados, lo cual es prerrequisito para chiplets.
  5. Las interconexiones son ahora productos: lo que antes era diseño de tejido interno se expone cada vez más como “ancho de banda de enlace” y “topología”, afectando la adquisición y planificación de capacidad.
  6. Las pilas de software GPU ya gestionan “múltiples dispositivos”: el entrenamiento multi-GPU y las comunicaciones colectivas existen, pero los chiplets intentan ocultar la complejidad multi-die bajo una abstracción de un solo dispositivo—más difícil que admitir que es multi-dispositivo.
  7. NUMA lleva años enseñando esta lección: la memoria unificada con acceso no uniforme funciona muy bien hasta que tu asignador y planificador discrepan sobre tus hot paths.
  8. Las consolas y SoC móviles han mezclado bloques heterogéneos desde hace tiempo: los chiplets extienden esa modularidad al cómputo de alto rendimiento, pero con requisitos de latencia y ancho de banda más estrictos.

Dónde fallan en producción: cuellos de botella reales y cómo se manifiestan

Acantilados de rendimiento que parecen “regresión aleatoria”

El síntoma clásico: el mismo código, mismo rango de entradas, diferente día, de repente 15–30% más lento. Sin caída obvia en la utilización de GPU. Sin cuello de botella evidente en CPU. El culpable suele ser la colocación: un buffer termina “remoto” respecto al chiplet que ejecuta el kernel caliente, o el planificador cambia la distribución de bloques.

Latencia de cola y jitter

Los chiplets añaden colas adicionales: arbitraje de tejido, control de flujo a nivel de enlace, tráfico de caché entre dies. El rendimiento medio puede verse bien mientras que el P99 explota. Si ejecutas inferencia o pasos de entrenamiento con tiempo acotado, lo notarás.

Contención en la interconexión: la “estrangulación invisible”

En una GPU monolítica, muchos caminos internos están sobreaprovisionados para cargas típicas. En una GPU con chiplets, la interconexión es un recurso compartido con nombre. Dos kernels que iban bien por separado pueden pelear cuando se programan juntos, y no lo verás en los habituales gráficos de “utilización de SM”.

Trampas de corrección (raras, pero costosas)

La mayoría de los problemas de GPU con chiplets son de rendimiento. Los peores son los de corrección que solo aparecen bajo condiciones específicas de sincronización y ordenamiento de memoria—normalmente cuando atomics cruzan límites de chiplet o cuando copias peer-to-peer se solapan con cómputo.

Broma #2: “Pasó las pruebas unitarias” es una frase hermosa, como “el paracaídas se abrió eventualmente.”

Tres mini-historias corporativas desde las trincheras

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

Un equipo desplegó una nueva SKU de GPU en un clúster mixto. La especificación de marketing decía “dispositivo único, espacio de direcciones de memoria unificado.” Los ingenieros asumieron que “dispositivo único” significaba “rendimiento uniforme”, así que mantuvieron su asignador ciego a la colocación y dejaron que el runtime lo manejara.

La carga era un modelo recomendador con tablas de embeddings que se actualizaban periódicamente y se leían constantemente. En las GPU monolíticas antiguas, el patrón era tolerable. En el nuevo hardware, algunos pasos de entrenamiento se alargaban, pero solo cuando los embeddings cruzaban un umbral de tamaño. El pico se correlacionaba con fases de comunicación colectiva, lo que llevó al on-call a culpar a la red.

Pasaron dos días mirando contadores de NIC y telemetría de switches. Nada. Entonces alguien ejecutó un microbenchmark que tocaba páginas de memoria con un patrón de stride y encontró latencia bimodal. El runtime estaba colocando los shards calientes de embedding “remotos” respecto al chiplet que ejecutaba con suficiente frecuencia para romper los SLOs de tiempo por paso.

La solución fue vergonzosamente simple: fijar los shards calientes en la memoria local al chiplet que ejecutaba los kernels intensivos en embeddings, y reestructurar la fase de actualización para agrupar el tráfico entre chiplets. La lección más profunda no fue “fija la memoria.” Fue “no trates un espacio de direcciones unificado como un modelo de costes uniforme.”

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

Otra organización intentó exprimir más rendimiento de los nodos GPU activando solapamiento agresivo: precargar el siguiente lote a memoria GPU mientras el lote actual calcula, ejecutar copias asíncronas, mantener ocupada la interconexión. En papel, perfecto.

En hardware chiplet, ese solapamiento se convirtió en un atasco de tráfico. El motor de prefetch y los kernels de cómputo comenzaron a contender en los mismos caminos cross-die. En lugar de ocultar la latencia, el solapamiento la amplificó: los fallos de caché desencadenaron fetches remotos, los fetches remotos compitieron con DMA asíncrono y el arbitraje de la interconexión penalizó a ambos. La utilización de GPU se mantuvo alta, pero el tiempo por paso empeoró y el jitter aumentó.

“Lo arreglaron” desactivando el prefetch, lo que mejoró la estabilidad pero dejó rendimiento sobre la mesa. La solución real llevó más tiempo: hacer que el prefetch conociera la topología, limitar las transferencias en vuelo y programar DMA para evitar ventanas de tráfico cross-die pico. Su mejor ganancia vino de una métrica aburrida: un tope a las lecturas remotas pendientes.

Conclusión: el solapamiento no es universalmente bueno. En chiplets, el solapamiento puede generar un colapso de congestión autoinfligido. Trata la interconexión como una red compartida, porque funcionalmente lo es.

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

Un equipo de plataforma tenía la costumbre que parecía paranoica: para cada nueva generación de GPU, ejecutaban una pequeña suite de “chequeos de sanidad de topología” cada noche. No benchmarks. Chequeos. Anchos de enlace, distancias NUMA reportadas, acceso peer, contadores ECC, microbenchmarks básicos de acceso local vs remoto.

Una mañana, la suite señaló que varios nodos tenían una velocidad de enlace entre chiplets menor de la esperada. Nadie se había quejado aún; los trabajos de entrenamiento todavía terminaban. Pero la varianza estaba aumentando y los nodos eran sutilmente más lentos.

Resultó que un lote de sistemas tenía una configuración de firmware que causaba retraining de enlaces bajo ciertas condiciones térmicas. El hardware no fallaba ruidosamente; se adaptaba discretamente reduciendo la velocidad. El equipo aisló los nodos, aplicó una actualización de firmware y los re-cualificó antes del siguiente gran lanzamiento de modelos.

Esa práctica aburrida previno un incidente en la semana de lanzamiento donde “el modelo a veces pierde la ventana de entrenamiento” habría sido culpado a todo menos la causa real. El trabajo de operaciones más valioso es lo que nadie nota porque funcionó.

Tareas prácticas: comandos, salidas, decisiones (12+)

Estas son las cosas que haces cuando sospechas del comportamiento de una GPU con chiplets. Las herramientas exactas varían por proveedor, pero el flujo de trabajo no: establece la topología, mide la localidad, valida la salud de los enlaces y luego correlaciona con las fases de carga.

Task 1: Identify GPU models and driver versions

cr0x@server:~$ nvidia-smi
Tue Jan 21 10:12:44 2026
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 550.54       Driver Version: 550.54       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. |
|-------------------------------+----------------------+----------------------+
|  0  H100 SXM5            On   | 00000000:41:00.0 Off |                    0 |
|  1  H100 SXM5            On   | 00000000:61:00.0 Off |                    0 |
+-----------------------------------------------------------------------------+

Qué significa: Establece la línea base: versión de controlador/CUDA y SKUs de GPU. Los cambios de rendimiento relacionados con chiplets a menudo siguen actualizaciones de controlador.

Decisión: Si la regresión coincide con un cambio de controlador, reproduce en el controlador anterior o fija versiones mientras investigas.

Task 2: Show GPU topology (links, NUMA affinity)

cr0x@server:~$ nvidia-smi topo -m
        GPU0    GPU1    CPU Affinity    NUMA Affinity
GPU0     X      NV4     0-31            0
GPU1    NV4      X      0-31            0

Qué significa: “NV4” indica una clase de enlace GPU-GPU de alta velocidad; afinidad CPU/NUMA te dice qué sockets están “cerca”.

Decisión: Si la afinidad CPU abarca sockets inesperadamente, enlaza tu trabajo al nodo NUMA más cercano y vuelve a medir.

Task 3: Confirm PCIe link width/speed for each GPU

cr0x@server:~$ sudo lspci -s 41:00.0 -vv | egrep -i "LnkCap|LnkSta"
LnkCap: Port #0, Speed 16GT/s, Width x16
LnkSta: Speed 16GT/s (ok), Width x16 (ok)

Qué significa: Si un enlace está entrenado a menor velocidad (x8, GT/s más bajo), las transferencias host-dispositivo y algunos caminos peer se ven afectados.

Decisión: Cualquier “(downgraded)” o ancho reducido: pon el nodo en cuarentena, revisa BIOS/firmware, vuelve a asentar risers/cables si aplica.

Task 4: Inspect NUMA topology from the OS

cr0x@server:~$ numactl -H
available: 2 nodes (0-1)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
node 0 size: 256000 MB
node 1 cpus: 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
node 1 size: 256000 MB

Qué significa: Confirma la localidad de CPU y memoria que puedes controlar.

Decisión: Fija hilos de CPU y asignaciones de memoria del host al nodo NUMA más cercano a la(s) GPU(s) usadas.

Task 5: Verify IOMMU status (can affect DMA behavior)

cr0x@server:~$ cat /proc/cmdline
BOOT_IMAGE=/vmlinuz root=/dev/nvme0n1p2 ro iommu=pt intel_iommu=on

Qué significa: “iommu=pt” suele reducir la sobrecarga de traducción para DMA de dispositivos.

Decisión: Si ves IOMMU estricto con cargas DMA intensas, prueba el modo passthrough en una ventana de mantenimiento.

Task 6: Watch GPU clocks, power, and throttling reasons

cr0x@server:~$ nvidia-smi -q -d CLOCK,POWER,PERFORMANCE | egrep -i "Clocks|Power Draw|Perf|Throttle"
Performance State                  : P0
Power Draw                         : 612.45 W
Clocks
    Graphics                        : 1410 MHz
    SM                              : 1410 MHz
    Memory                          : 1593 MHz
Clocks Throttle Reasons
    Thermal Slowdown                : Not Active
    Power Brake Slowdown            : Not Active

Qué significa: Si los chiplets están limitados térmicamente o por potencia, el comportamiento de la interconexión puede cambiar por downclocking.

Decisión: Si hay throttling activo, arregla la refrigeración/política de potencia antes de perseguir “regresiones de software” fantasma.

Task 7: Check ECC error counters (early signal of sick links/memory)

cr0x@server:~$ nvidia-smi -q -d ECC | egrep -i "Volatile|Uncorr|Corr"
Volatile Uncorr. ECC                    : 0
Volatile Corr. ECC                      : 12

Qué significa: Errores corregidos que aumentan bajo carga pueden significar memoria marginal o inestabilidad en la interconexión.

Decisión: Si ECC corregido aumenta constantemente, ejecuta diagnósticos del proveedor y considera sacar el nodo de producción.

Task 8: Confirm peer-to-peer access between GPUs

cr0x@server:~$ nvidia-smi topo -p2p r
GPU0 GPU1
GPU0  X   OK
GPU1 OK   X

Qué significa: “OK” indica que P2P está soportado/habilitado; si es “N/A” o “Disabled”, las transferencias entre dispositivos caen al host.

Decisión: Si P2P no está disponible inesperadamente, revisa ajustes BIOS (ACS), configuraciones del driver y privilegios de contenedor.

Task 9: Measure local vs remote access via microbenchmark timing (quick sanity)

cr0x@server:~$ /usr/bin/time -f "elapsed=%e" python3 -c 'import torch; a=torch.randn(8192,8192,device="cuda"); b=a.t().contiguous(); torch.cuda.synchronize()'
elapsed=0.41

Qué significa: Esto es tosca pero repetible. Si los tiempos son bimodales entre ejecuciones, probablemente tengas variación de colocación/topología.

Decisión: Si la varianza es alta, fija afinidad de proceso y controla el comportamiento del asignador; luego compara de nuevo.

Task 10: Capture GPU utilization and memory throughput over time

cr0x@server:~$ nvidia-smi dmon -s pucvmt -d 1 -c 5
# gpu  pwr  u  c  v  m  t
# Idx  W    %  %  %  %  C
0      610  85 99  0  72 68
0      612  83 99  0  73 69
0      608  40 98  0  70 69
0      611  86 99  0  72 68
0      613  84 99  0  73 69

Qué significa: Una caída de utilización con relojes constantes puede indicar stalls (a menudo memoria/interconexión).

Decisión: Correlaciona las caídas con la línea de tiempo del kernel; si % memoria sigue alto mientras cómputo baja, sospecha acceso remoto o contención.

Task 11: Validate container sees the expected devices and topology

cr0x@server:~$ nvidia-container-cli info | egrep -i "NVRM|CUDA|Device Index"
NVRM version:   550.54
CUDA version:   12.4
Device Index:   0
Device Index:   1

Qué significa: Confirma que el runtime de contenedores no ocultó dispositivos ni desajustó la pila de controladores.

Decisión: Si los dispositivos difieren entre host y contenedor, arregla la configuración del runtime antes de cualquier investigación de rendimiento.

Task 12: Check kernel and PCIe/AER logs for link instability

cr0x@server:~$ sudo journalctl -k -S -2h | egrep -i "AER|pcie|Xid|NVRM" | tail -n 8
Jan 21 09:12:01 server kernel: pcieport 0000:40:01.0: AER: Corrected error received: id=00e0
Jan 21 09:12:01 server kernel: pcieport 0000:40:01.0: PCIe Bus Error: severity=Corrected, type=Physical Layer, (Receiver ID)
Jan 21 09:12:02 server kernel: NVRM: Xid (PCI:0000:41:00): 48, pid=29133, errorString=Double Bit ECC Error

Qué significa: Spam de AER corregidos más Xids de GPU es una advertencia de confiabilidad. Los enlaces chiplet pueden agravar la sensibilidad.

Decisión: Cuarentena el nodo; ejecuta diagnósticos extendidos; no “simplemente reinicies” esperando que se arregle.

Task 13: Confirm CPU affinity of a running job

cr0x@server:~$ ps -o pid,psr,comm -p 29133
  PID PSR COMMAND
29133  27 python3

Qué significa: El proceso está programado actualmente en el núcleo CPU 27 (probablemente nodo NUMA 1 en el ejemplo anterior).

Decisión: Si la GPU está más cerca del nodo NUMA 0, fija el proceso/hilos al nodo 0 y vuelve a probar.

Task 14: Enforce NUMA binding for a benchmark run

cr0x@server:~$ numactl --cpunodebind=0 --membind=0 python3 -c 'import os; print("ok");'
ok

Qué significa: Puedes forzar la localidad para asignaciones de CPU y memoria del host.

Decisión: Si el tiempo por paso mejora y la varianza baja, tu cuello de botella incluye localidad del host (a menudo pasado por alto en debates “solo GPU”).

Guía rápida de diagnóstico

Cuando algo está lento en sistemas GPU de clase chiplet, no tienes tiempo para argumentos filosóficos sobre “el runtime debería manejarlo.” Necesitas un bucle cerrado: identifica si estás limitado por cómputo, memoria o tejido, y luego demuéstralo con evidencia de topología.

Primero: descarta los asesinos aburridos (potencia, térmica, retraining de enlaces)

  • Revisa relojes y razones de throttling (Task 6).
  • Revisa ancho/velocidad de enlace PCIe y logs AER (Tasks 3 y 12).
  • Revisa contadores ECC (Task 7).

Si cualquiera de estos está en rojo, arregla condiciones de hardware/firmware antes de perfilar kernels. Perfilar un nodo enfermo es cómo se escribe ficción.

Segundo: confirma supuestos de topología y localidad

  • Reporte de topología GPU (Task 2).
  • Distribución NUMA del SO (Task 4).
  • Disponibilidad P2P (Task 8).
  • Visibilidad en contenedor (Task 11).

Si ves una discrepancia de topología entre “lo que crees que compraste” y “lo que ve el SO”, para. Arregla esa discrepancia.

Tercero: correlaciona rendimiento con fases y contención

  • Ejecuta un microbenchmark simple repetidamente y busca bimodalidad (Task 9).
  • Captura patrones de utilización/memoria durante la ejecución lenta (Task 10).
  • Fija CPU/NUMA y compara (Tasks 13–14).

Si la misma carga cambia entre modos rápido y lento, probablemente tienes variación de colocación o retraining de enlaces. Si es consistentemente lento bajo concurrencia, probablemente tienes contención en el tejido.

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

1) Síntoma: tiempo por paso bimodal (ejecuciones rápidas/lentas alternan)

Causa raíz: la colocación de memoria o del planificador no es estable; los datos calientes a veces quedan “remotos” respecto al chiplet ejecutor.

Solución: aplica colocación determinista cuando sea posible (ajustes del asignador, fragmentación explícita), fija CPU/NUMA y evita migraciones implícitas durante el estado estable.

2) Síntoma: alta utilización de GPU, bajo rendimiento

Causa raíz: contención en la interconexión o stalls por memoria; los SMs parecen “ocupados” pero esperan fetches remotos o atomics.

Solución: reduce tráfico entre chiplets (reordena el layout de datos, fusiona kernels para mejorar localidad), limita DMA/prefetch concurrentes e aisla vecinos ruidosos.

3) Síntoma: regresión tras actualización de controlador, sin cambio de código

Causa raíz: cambiaron heurísticas de planificación; nuevo valor por defecto para P2P, comportamiento tipo MIG, o cambio en la política de asignación de memoria.

Solución: prueba A/B versiones de controlador; fija versiones conocidas buenas para producción; documenta qué versiones están validadas con tus patrones de carga.

4) Síntoma: errores Xid ocasionales bajo alta carga, desaparecen tras reboot

Causa raíz: enlace marginal o interconexión sensible térmicamente; el reboot retrena el enlace, pero el problema vuelve.

Solución: revisa tendencias AER y ECC; cuarentena del nodo; actualización de firmware; valida refrigeración y entrega de potencia; reemplaza componentes sospechosos.

5) Síntoma: el throughput multi-proceso colapsa al habilitar overlap/prefetch

Causa raíz: colapso de congestión autoinfligido en el tejido cross-die por demasiadas transferencias en vuelo.

Solución: limita transferencias pendientes, programa copias fuera de fases pico de cómputo y prueba con concurrencia realista—no benchmarks de trabajo único.

6) Síntoma: “P2P está soportado” pero transferencias siguen lentas

Causa raíz: P2P existe pero se enruta por un camino más lento (p. ej., diferente clase de enlace), o ajustes ACS/IOMMU fuerzan desvíos.

Solución: verifica la topología, revisa ajustes PCIe y mide ancho de banda efectivo; no asumas que “OK” significa “suficientemente rápido”.

7) Síntoma: spikes de latencia P99 en inferencia sin saturación de CPU

Causa raíz: jitter por arbitraje de tejido, thrashing de caché entre chiplets o contención de DMA en segundo plano.

Solución: prioriza localidad, reduce estado mutable compartido, aísla inferencia de entrenamiento/preprocesado y mantiene las transferencias en segundo plano controladas.

Listas de verificación / plan paso a paso

Lista de adquisición (antes de comprar una flota)

  1. Exige detalles de topología: cuántos tiles, cómo se conecta la HBM y si “un dispositivo” oculta comportamiento NUMA.
  2. Pide comportamiento de la interconexión bajo contención: qué pasa cuando múltiples motores compiten (cómputo, DMA, colectivas).
  3. Valida la madurez del driver: exige una versión que puedas fijar y una vía de soporte para regresiones de rendimiento.
  4. Prueba con tus kernels peores: no solo GEMM; incluye embeddings, scatter/gather, atomics y accesos irregulares.
  5. Exige telemetría: contadores para salud de enlaces, errores corregidos y cualquier comportamiento de auto-downshift.

Lista de puesta en marcha (hardware nuevo en tu centro de datos)

  1. Baseline de ancho/velocidad de enlace PCIe en cada nodo (Task 3) y guárdalo.
  2. Registra topología GPU (Task 2) y asegúrate de que coincida con la configuración SKU esperada.
  3. Revisa baseline de ECC en reposo y después de un burn-in (Task 7).
  4. Ejecuta una suite de microbenchmarks de localidad para detectar penalizaciones “remotas” (repite Task 9, además de tus propios tests).
  5. Verifica que el runtime de contenedores vea los dispositivos correctos (Task 11).
  6. Establece alertas sobre AER, Xid y tendencias de ECC corregido (Task 12 + ingestión de métricas).

Lista de triaje de rendimiento (cuando un trabajo está lento)

  1. Confirma salud del nodo: throttling, retraining de enlaces, ECC (Tasks 6, 3, 7).
  2. Captura topología y afinidad: topo GPU, NUMA, afinidad CPU (Tasks 2, 4, 13).
  3. Vuelve a ejecutar con binding NUMA y compara (Task 14).
  4. Captura series temporales de utilización (Task 10) durante la fase lenta.
  5. Reduce concurrencia: ejecuta solo en el nodo para ver si es por contención.
  6. Cambia una variable a la vez: tamaño de batch, ajustes de overlap, comportamiento del asignador, versión de driver.

Lista de diseño (para ingenieros que escriben kernels/modelos)

  1. Asume NUMA: mantén los datos calientes cerca del cómputo que los usa.
  2. Minimiza atomics y sincronizaciones finas entre chiplets.
  3. Prefiere transferencias por lotes en lugar de tráfico ping-pong.
  4. Mide explícitamente las penalizaciones de localidad; no confíes en el lenguaje de marketing de “memoria unificada”.
  5. Diseña para colocación predecible: el sharding estable supera a la migración dinámica ingeniosa en producción.

Preguntas frecuentes

1) ¿Las GPUs con chiplets son básicamente lo mismo que multi-GPU?

No. Multi-GPU es explícito: tienes varios dispositivos y los coordinas. Las GPUs con chiplets intentan parecer un solo dispositivo, lo cual es más difícil porque el runtime debe preservar las expectativas de “una sola GPU” mientras maneja costes tipo NUMA.

2) Si el proveedor presenta un espacio de direcciones unificado, ¿por qué debería importarme la localidad?

Porque un espacio de direcciones unificado es comodidad, no física. Si parte de la memoria está a un salto de interconexión, tu coste de acceso cambia. En kernels hambrientos de ancho de banda, “un salto” es la diferencia entre pico y meseta.

3) ¿Qué cargas sufren más en diseños chiplet?

Acceso de memoria irregular, embeddings, scatter/gather, cargas de grafo, sincronización fina, kernels intensivos en atomics y cualquier cosa con rebote frecuente de líneas de caché entre dies.

4) ¿Qué cargas se benefician más?

Álgebra lineal densa con buena localidad, kernels embarazosamente paralelos y cargas que pueden particionarse para que cada chiplet trabaje mayormente con sus propios datos. Si puedes mantener la HBM local, puedes ganar mucho.

5) ¿Es esto principalmente un problema de hardware o de software?

Ambos, pero sentirás el dolor primero en el software. El hardware define las restricciones; el software decide si las golpeas. El runtime y el controlador son efectivamente tu middleware de sistemas distribuidos.

6) ¿Cómo afectan los chiplets la depuración y la observabilidad?

Hacen que “una métrica” mienta más a menudo. Necesitas métricas conscientes de la topología: salud de enlaces, latencia sensible a localidad y contención por engine. La utilización agregada de GPU no es suficiente.

7) ¿Debería evitar las GPUs con chiplets en producción hoy?

Evita la primera generación de cualquier cosa si tu negocio no tolera sorpresas. Si necesitas rendimiento por dólar y puedes invertir en perfilado y ajuste consciente de topología, los chiplets son una apuesta razonable—solo que no los operes como monolitos.

8) ¿Cuál es el primer control operativo a implementar?

Programación consciente de la topología. Si tu scheduler de clúster no puede colocar trabajos con afinidad GPU/CPU y aislar vecinos ruidosos, pasarás la vida explicando el jitter.

9) ¿La “contención de tejido” es realmente medible?

A veces directamente vía contadores del proveedor, a menudo indirectamente vía análisis de línea de tiempo y experimentos controlados: ejecuta single-tenant vs multi-tenant, alterna overlap y observa cómo cambia el tiempo por paso con la concurrencia.

10) ¿Cuál es la creencia equivocada más común?

Que “un dispositivo GPU” implica “latencia y ancho de banda uniformes.” Esa creencia es cómo terminas con acantilados de rendimiento que parecen sobrenaturales.

Conclusión: próximos pasos prácticos

Las GPUs con chiplets tienen lógica porque la industria se quedó sin almuerzos gratis en la escala monolítica. Son brutalmente difíciles porque las GPUs son alérgicas a la latencia oculta y a la localidad impredecible. Si tratas a los chiplets como un monolito más grande, tendrás un incidente mayor.

Próximos pasos que realmente funcionan en producción:

  • Construye una línea base de topología para cada nodo: velocidades de enlace, afinidad NUMA, estado P2P, contadores ECC.
  • Haz que tu scheduler sea consciente de la topología: coloca los hilos CPU y la memoria junto a las GPUs que alimentan, e aísla cargas que compiten en el tejido.
  • Mide la sensibilidad a la localidad temprano: añade microbenchmarks y “detectores de bimodalidad” a la cualificación, no a los postmortems.
  • Controla concurrencia y solapamiento: limita transferencias en vuelo y no asumas que más solapamiento equivale a más rendimiento.
  • Fija y documenta versiones de controladores: trata el driver/runtime como parte del hardware, porque para chiplets básicamente lo es.

La ganancia es real: mejores rendimientos por oblea, mejor escalado y una vía hacia adelante cuando la física del dado único dice “no.” El coste también es real: estás operando un sistema distribuido a velocidades de terahercios. Compórtate como tal.

← Anterior
Ubuntu 24.04: sudo lento — correcciones DNS/hostname que eliminan la demora (caso #6)
Siguiente →
ZFS zfs hold: el pasador de seguridad que bloquea la eliminación accidental

Deja un comentario