🔌 Hardware: la realidad física
Todo lo que hace un LLM —cada multiplicación, cada token— se traduce al final en señales eléctricas viajando por cables de silicio a velocidades finitas. Esta página explica qué hay físicamente dentro de la GPU y por qué los datos tardan lo que tardan.
⏱️ El ciclo de reloj: el latido de la GPU
1. ¿Qué es un ciclo de reloj?
Imagina un metrónomo dando 2.23 mil millones de pulsos por segundo. Eso es el reloj de la GPU. Cada pulso es un ciclo. En cada ciclo pueden ocurrir cosas:
- Una señal eléctrica avanza por un cable
- Un núcleo empieza una multiplicación
- Un dato se lee de la caché
💡 RTX 4090: 2.23 GHz → 1 ciclo = 0.45 nanosegundos (ns).
En 0.45 ns, la luz recorre 13.5 centímetros. La señal eléctrica en un cable de cobre es más lenta (~70% de la velocidad de la luz), así que recorre ~9 centímetros por ciclo.
El chip de la GPU mide ~3 cm. La señal lo cruza en ~0.3 ciclos.
Pero la VRAM está a ~2 cm del chip. Ida + vuelta = 4 cm ≈ medio ciclo si fuera en línea recta... pero no lo es.
2. El mapa físico de la GPU
Una GPU tiene una jerarquía física muy clara. Visualmente:
🔲 Chip GPU (3×3 cm) — aquí están los núcleos que multiplican
├─ 128 SM (Streaming Multiprocessors)
├─ 16,384 CUDA Cores (matemáticas generales)
├─ 512 Tensor Cores (matemáticas matriciales → las que usa el LLM)
├─ L1 Cache: 16 MB (SRAM, dentro del chip)
├─ L2 Cache: 72 MB (SRAM, también en el chip)
🔌 Bus de memoria (384 bits) — cables que conectan chip con VRAM
├─ 12 pares de cables de 32 bits cada uno
├─ ~2 cm de longitud por cable
💾 VRAM (24 GB) — 12 chips GDDR6X alrededor del chip
├─ Cada chip: 2 GB, ~5×5 mm
├─ Colocados en anillo alrededor del chip GPU
├─ Comunicación a través del bus de 384 bits
3. ¿Por qué 200 ciclos para leer de VRAM?
Cuando un núcleo necesita un peso que está en VRAM, pasa esto:
- ~10 ciclos: la dirección de memoria viaja desde el núcleo hasta la VRAM por el bus de direcciones (~2 cm de ida, señal a 9 cm/ciclo)
- ~80 ciclos: la VRAM busca el dato en su interior (CAS latency — es el tiempo que tarda en encontrar la fila y columna correcta dentro del chip de memoria, como buscar un libro en una estantería)
- ~50 ciclos: el dato (4 bytes) viaja de vuelta por el bus de datos (~2 cm de vuelta, más el tiempo de sincronización entre relojes distintos)
- ~60 ciclos: el dato pasa por L2 Cache, L1 Cache, y llega a los registros del núcleo (atravesando el chip)
⚠️ ¿Por qué 200 ciclos para 2 cm? Porque no es solo la distancia. La VRAM es un chip separado con su propio reloj, más lento que el de la GPU (la GDDR6X corre a ~2.6 GHz, la GPU a 2.23 GHz — pero no están sincronizados). Además, la VRAM está optimizada para capacidad (24 GB) y ancho de banda, no para velocidad de acceso individual. Cada petición tiene que negociar el bus, esperar su turno, y luego buscar físicamente los datos dentro del chip de memoria.
Es como pedir un libro en una biblioteca enorme: aunque estés a 2 metros de la estantería, el bibliotecario tiene que mirar el catálogo, ir a la estantería, encontrar la sección, buscar el libro, y traerlo.
Tiempos de acceso en detalle
| Operación | Ciclos | Tiempo real | Distancia equivalente |
|---|---|---|---|
| 1 ciclo de reloj | 1 | 0.45 ns | 13.5 cm (luz) / 9 cm (señal) |
| Suma de enteros | 1 | 0.45 ns | — |
| Multiplicación FP32 | ~4 | 1.8 ns | — |
| Tensor Core matmul 4×4 | 1 | 0.45 ns | — |
| Leer de L1 Cache | ~10 | 4.5 ns | 0.4 mm (señal dentro del chip) |
| Leer de L2 Cache | ~50 | 22.5 ns | 2 mm (a través del chip) |
| Leer de VRAM (GDDR6X) | ~200 | 90 ns | ~2 cm (ida+vuelta + latencia chip) |
| Leer de RAM CPU (DDR5) | ~500 | 225 ns | ida+vuelta PCIe + RAM latencia |
| Leer de SSD NVMe | ~1,000,000 | 0.45 ms | controlador + bus PCIe + flash |
Leer de VRAM cuesta ~200× más que una multiplicación. Por eso mover datos es el cuello de botella.
Física de la señal en el chip
Una señal eléctrica en un conductor de cobre viaja a aproximadamente el 70% de la velocidad de la luz en el vacío (la velocidad real depende de la permitividad del material dieléctrico alrededor del conductor):
Velocidad de la luz: 299,792,458 m/s ≈ 30 cm/ns
Velocidad en PCB (cobre): ~70% ≈ 21 cm/ns
Velocidad en silicio (chip): ~50% ≈ 15 cm/ns
Reloj GPU (2.23 GHz):
1 ciclo = 0.45 ns
Distancia recorrida en 1 ciclo:
- En PCB: 21 cm/ns × 0.45 ns ≈ 9.5 cm
- En silicio: 15 cm/ns × 0.45 ns ≈ 6.8 cm
Esto significa:
- Señal cruzando el chip (3 cm) ≈ 0.2 ns ≈ 0.4 ciclos
- Señal chip→VRAM (2 cm) ≈ 0.1 ns ≈ 0.2 ciclos
- Pero la VRAM tarda ~90 ns por su latencia interna (no por distancia) 💡 Mito: "la velocidad de la luz es el límite" — Es cierto, pero en una GPU el límite no es la distancia física (2 cm) sino la latencia de los chips de memoria. Cada chip GDDR6X tiene su propia lógica interna: decodificar direcciones, activar filas en la matriz de celdas, leer los condensadores, amplificar la señal, y enviarla de vuelta. Eso lleva ~80 ciclos. Es como un camión que tarda 10 minutos en cargarse aunque el viaje sean 2 minutos.
🔧 Componentes de la GPU (diagrama interactivo)
Aquí tienes todos los componentes físicos explicados: el chip, los núcleos, la VRAM, el bus. Haz clic en cada tarjeta para ver los detalles.
Arquitectura física de una GPU (RTX 4090)
Aquí se hacen las cuentas. Contiene 128 SM con CUDA Cores y Tensor Cores.
Aquí viven los pesos del modelo. 12 chips alrededor del chip GPU.
Los cables que conectan VRAM con chip. Por aquí viajan los pesos.
⏱️ Línea de tiempo: cargar 4 bytes desde VRAM
Total: ~202 ciclos ≈ 91 ns. Solo 2 ciclos (~1%) se usan realmente para multiplicar.
🟢 Resumen visual de la jerarquía:
Registros (32 MB) → están DENTRO de cada SM, son la memoria más rápida (~1 ciclo). Aquí se ponen los números justo antes de multiplicarse.
L1 Cache (16 MB) → está DENTRO del chip, compartida entre unos pocos SM. Si los datos están aquí, se leen en ~10 ciclos.
L2 Cache (72 MB) → está DENTRO del chip, compartida globalmente. Trampolín antes de ir a VRAM. ~50 ciclos.
VRAM (24 GB) → está FUERA del chip, conectada por el bus. Aquí viven los pesos. ~200 ciclos.
Los pesos del modelo NO CABEN ni en registros, ni en L1, ni en L2. Solo caben en VRAM. Por eso cada multiplicación requiere leer de VRAM, y eso cuesta ~200 ciclos.
🚛 El viaje: de VRAM a los núcleos
¿Qué es lo que viaja exactamente?
Lo que viaja desde VRAM a los núcleos son los pesos (parámetros). Los pesos son números que se multiplican. El modelo tiene miles de millones de ellos.
❓ Pregunta clave: "¿Por qué los pesos tienen que viajar si solo se van a multiplicar?"
✅ Respuesta: Porque la multiplicación no ocurre donde están guardados los pesos. El Tensor Core que hace la multiplicación está dentro del chip GPU. El peso está en VRAM, fuera del chip.
Es como tener los números en una libreta y la calculadora en la mesa. No puedes multiplicar dentro de la libreta. Tienes que leer el número de la libreta, teclearlo en la calculadora, y entonces obtienes el resultado.
La "libreta" es la VRAM. La "calculadora" es el Tensor Core. El "movimiento de tus ojos y manos" es el bus de memoria.
El flujo, paso a paso
El prompt se tokeniza y se carga en VRAM
"La capital de Francia es" → [123, 456, 789, 101] → 4 vectores de 4096 números
Se lee W_Q desde VRAM → a los núcleos
33 MB de pesos viajan por el bus. Tarda ~0.03 ms.
Se multiplica: activaciones × W_Q = Q
Esto ocurre en los Tensor Cores. Tarda ~0.001 ms. Los pesos se descartan de la caché.
Se lee W_K desde VRAM
Hay que volver a VRAM a por la siguiente matriz. No se guardó porque no cabía en caché.
Esto se repite para W_K, W_V, W_O, W_gate, W_up, W_down
Cada una requiere leer ~33-100 MB de pesos desde VRAM. 7 matrices por capa. 32 capas. Luego otra vez para el siguiente token.
💡 ¿Cuántos datos viajan en total por el bus?
Para generar 1 token con un modelo 7B en FP16:
• 32 capas × 7 matrices × ~33 MB = ~7.4 GB leídos desde VRAM
• A 1008 GB/s: ~7.4 ms de ida y vuelta constante de datos
Para 100 tokens de respuesta: ~740 GB de datos viajando por el bus
Pero la VRAM sigue teniendo los mismos 14 GB de pesos. No se gastan. Solo se leen.
Cálculo detallado: datos por capa
| Operación | Matriz | Params | Bytes (FP16) | Lecturas |
|---|---|---|---|---|
| Attention Q | d_model × d_model | 16.7M | 33.5 MB | 1× |
| Attention K | d_model × d_model | 16.7M | 33.5 MB | 1× |
| Attention V | d_model × d_model | 16.7M | 33.5 MB | 1× |
| Attention O | d_model × d_model | 16.7M | 33.5 MB | 1× |
| FFN gate | d_model × d_ff | 45.1M | 90.2 MB | 1× |
| FFN up | d_model × d_ff | 45.1M | 90.2 MB | 1× |
| FFN down | d_ff × d_model | 45.1M | 90.2 MB | 1× |
| Total por capa | 202M | 404 MB | 7 lecturas | |
| Total 32 capas | 6.5B | 12.9 GB | 224 lecturas | |
Pero espera — hay 6.5B parámetros, no 14 GB
En el modelo de 7B hay ~6.7B parámetros (no 7B exactos). En FP16, 6.7B × 2 bytes = 13.4 GB. La tabla de arriba suma ~12.9 GB, que son los pesos de las capas. El resto (~0.5 GB) es embedding y LM head, que solo se leen una vez al principio y al final.
💡 Por cada token generado, el bus mueve ~13 GB de pesos.
Pero no todos a la vez. Son 224 viajes individuales (7 matrices × 32 capas), cada uno moviendo 33-90 MB. El bus es una autopista por la que viajan constantemente estos datos, como una cinta transportadora de números.
Es como tener que leer 224 capítulos de un libro, y cada capítulo requiere ir a la estantería a buscar el libro (VRAM), abrirlo por la página correcta, leerla, y dejarlo.
Ancho de banda efectivo vs. teórico
El ancho de banda teórico de 1008 GB/s es el límite máximo, pero en la práctica no se alcanza porque:
- Overhead de dirección: cada lectura de VRAM requiere enviar una dirección de memoria antes de recibir los datos
- Row activation: la VRAM organiza los datos en filas y columnas. Cambiar de fila cuesta tiempo extra
- Bank conflicts: múltiples peticiones a la misma partición de VRAM se serializan
- Protocol overhead: la señal tiene que ser codificada/decodificada (GDDR6X usa PAM4, que codifica 2 bits por símbolo)
En benchmarks reales (como llama.cpp), una RTX 4090 suele alcanzar ~80-85% del ancho de banda teórico, es decir, ~800-850 GB/s efectivos.
🐢 El cuello de botella: memory-bound
La inferencia es mover datos, no calcular
Ahora que sabemos qué viaja (pesos), dónde (bus), y por qué tarda (~200 ciclos por viaje), podemos entender por qué la inferencia está limitada por la memoria, no por la potencia de cálculo.
🧮 Capacidad de cálculo (TFLOPS)
82 TFLOPS = 82 billones de multiplicaciones por segundo
Pero cada multiplicación necesita sus operandos. Si los operandos tardan 200 ciclos en llegar, el núcleo se para y espera.
🚛 Capacidad de transporte (BW)
1008 GB/s = 1 terabyte de datos por segundo pueden viajar por el bus
El modelo 7B pesa 14 GB. Cada token requiere leer ~13 GB. 1008 / 13 ≈ 77 tokens/s. Ese es el límite.
🔴 El dato que lo explica todo:
De cada 200 ciclos que tarda en leerse un peso de VRAM, solo ~2 ciclos se usan para multiplicar. El 99% del tiempo la GPU está esperando a que lleguen datos desde la VRAM.
Es como un chef superrápido (puede cortar una cebolla en 0.1 segundos) pero que tiene que ir a la despensa a buscar cada ingrediente, y la despensa está al otro lado de la cocina. Pasa el 99% del tiempo caminando y el 1% cortando.
Cálculo exacto: tiempo de inferencia
Modelo 7B FP16 en RTX 4090 (1008 GB/s, 82 TFLOPS)
PESOS A LEER POR TOKEN:
Attention (Q,K,V,O): 4 × 33.5 MB = 134 MB
FFN (gate,up,down): 3 × 90.2 MB = 270 MB
Total por capa: 404 MB
32 capas: 12.9 GB
+ Embedding + LM Head: ~0.5 GB
------------------------------------------
Total leído por token: 13.4 GB
TIEMPO DE CARGA (1008 GB/s):
13.4 GB / 1008 GB/s = 13.3 ms
TIEMPO DE CÓMPUTO (82 TFLOPS):
FLOPs por token (7B): ~14 GFLOP
14 GFLOP / 82 TFLOP/s = 0.17 ms
TIEMPO TOTAL ESTIMADO:
13.3 + 0.17 ≈ 13.5 ms/token
→ ~74 tokens/s
En realidad con overheads y KV cache: ~60-70 tokens/s ¿Y si cuantizamos?
Modelo 7B Q4_K_M en RTX 4090 (1008 GB/s)
Pesos a leer: 6.7B × 0.5 bytes = 3.4 GB
Tiempo de carga: 3.4 / 1008 = 3.4 ms
Tiempo de cómputo: ~0.05 ms (matmuls más pequeñas)
Total: ~3.5 ms/token → ~290 tokens/s
En la práctica: ~200-250 t/s (algo de overhead de de-cuantización) 🟢 Moraleja: La cuantización acelera 4× porque reduces los datos que viajan por el bus en 4×. No porque las multiplicaciones sean más rápidas (de hecho, multiplicar INT4 puede ser más lento que FP16 en Tensor Cores). El cuello de botella siempre es el bus.
Roofline Model
El modelo Roofline clasifica cualquier operación según su intensidad aritmética (FLOPs por byte movido):
Intensidad aritmética = FLOPs / Bytes desde VRAM
Para inferencia de 1 token en 7B FP16:
Intensidad = 14 GFLOP / 13.4 GB ≈ 1.0 FLOP/byte
Límites de la RTX 4090:
Techo de cómputo: 82 TFLOPS
Techo de memoria: 1008 GB/s
Rendimiento real = min(82 TFLOP, 1008 GB/s × 1.0 FLOP/byte)
= min(82 TFLOP, 1.0 TFLOP)
= 1.0 TFLOP ← memory bound!
La GPU solo usa el 1.2% de su capacidad de cómputo. ¿Cómo escapar del memory-bound?
- Batching: procesas N prompts a la vez. Los pesos se leen 1 vez y se reutilizan para N prompts. La intensidad aritmética sube a N × 1.0 FLOP/byte. Con batch=512, pasas a 512 FLOP/byte → compute-bound.
- Cuantizar: reduces los bytes/peso. Mueves menos datos por el mismo bus.
- Speculative Decoding: generas K tokens baratos con un modelo pequeño, verificas con el grande en paralelo.
- Prompt Caching: reutilizas la KV Cache de prompts repetidos sin tener que reprocesarlos.
📋 Resumen: respuestas a tus preguntas
❓ "¿Los pesos caben en los núcleos de cálculo?"
No. Los núcleos tienen registros (32 MB en total). Los pesos de una capa son ~400 MB. Los pesos viven en VRAM (24 GB).
❓ "¿Si el modelo pesa 24 GB, esos 24 GB se mueven por el bus?"
No se mueven de golpe. Viajan por el bus en fragmentos, capa por capa, matriz por matriz. Por cada token se mueven ~13 GB (el modelo completo), pero en 224 viajes individuales a lo largo de ~13 ms.
❓ "¿Por qué 200 ciclos si la distancia son 2 cm?"
Porque la VRAM tiene su propia latencia interna (~80 ciclos para buscar el dato dentro del chip). La distancia física solo explica ~10-20 ciclos. El resto es burocracia del protocolo de memoria.
❓ "¿Qué es lo que se mueve por la autopista?"
Los pesos (parámetros del modelo). Son números que viajan desde VRAM a los Tensor Cores para ser multiplicados. ~13 GB por token en FP16, ~3.5 GB por token en Q4.
🚀 Conclusión final
La inferencia de LLMs no es un problema de potencia de cálculo (tenemos de sobra). Es un problema de transporte de datos. La GPU pasa el 99% del tiempo esperando a que los pesos lleguen desde la VRAM. Cuantizar = reducir la carga a transportar = 4× más rápido.