Inferencia: cómo responde un modelo
¿Qué pasa, y cuánto cuesta, entre que escribes y que aparece la respuesta?
Lección completa
Si quieres:
Escribes una pregunta y pulsas Enter. Un instante después aparece la primera palabra, y luego las demás, una tras otra. ¿Qué hace el modelo en ese rato? ¿Y cuánto cuesta?
Sin voz: la lección avanza sola con subtítulos.
La voz de esta lección está en preparación: por ahora avanza sola con subtítulos.
Modo revisiónComentar este pasoTerminé la lección
Qué lograrás
- Explicar las dos fases de una respuesta: el llenado, que lee tu mensaje de una vez, y la decodificación, que escribe un token por vuelta.
- Describir qué guarda la caché KV, qué trabajo ahorra y por qué ocupa más memoria cuanto más larga es la conversación.
- Estimar el costo de una tarea con sus tokens de entrada y de salida, y reconocer qué la encarece o la hace esperar: contexto largo, salida larga, lote pequeño.
Ideas clave
- Una respuesta tiene dos fases. El llenado (prefill) procesa todo tu mensaje de una vez y fija la espera hasta el primer token; la decodificación (decode) escribe un token por vuelta y fija cuánto tarda el resto.
- La caché KV guarda las claves y los valores de los tokens anteriores, que nunca cambian, para no recalcularlos: en el ejemplo, 15 casillas en lugar de 105. A cambio ocupa memoria que crece con cada token y con cada conversación.
- En cada vuelta la GPU lee todos los pesos (y las cachés) de su memoria y hace muy poca aritmética: el ancho de banda marca el paso. Tokens por segundo ≤ ancho de banda ÷ bytes leídos por vuelta.
- Atender a varias personas en un lote reparte esa lectura: sube el rendimiento (throughput) y baja el costo por token, pero cada persona recibe menos tokens por segundo (más latencia).
- Costo de una tarea = entrada × su precio + salida × su precio, y la salida cuesta varias veces más. La mezcla de expertos ahorra cálculo por token, no memoria.
Lo que mucha gente cree
Creencia común Responder es «calcular»: con una GPU que haga el doble de operaciones por segundo, el modelo escribiría el doble de rápido.
Lo correcto Al escribir, la GPU espera datos, no cuentas: con una persona usa menos del uno por ciento de su cálculo. Manda el ancho de banda de memoria, junto con los bytes que hay que leer por vuelta (pesos y cachés), el largo del contexto y el tamaño del lote.
Compruébalo
Cuatro preguntas. Sin nota ni cuenta: sirven para ver si la idea quedó.
Por dentroPara quien quiere las fórmulas y el código. No hace falta para seguir el curso.
Dos fases, dos cuellos de botella
Un modelo denso con parámetros hace unas operaciones por cada token que procesa (una multiplicación y una suma por parámetro; Kaplan et al., 2020; Pope et al., 2022), más un término de atención que crece con el contexto.
Llenado (los tokens del mensaje a la vez; bloques, = cabezas × dimensión por cabeza):
Son multiplicaciones de matrices grandes: la GPU trabaja cerca de su pico. La lección supone el 40 % del pico (Llama 3 reporta entre 38 y 43 % al entrenar; Pope et al. llegan a 76 % en el llenado con lotes grandes). Con el modelo de 8 mil M y 2 000 tokens: FLOPs ÷ ≈ 84 ms.
Decodificación ( conversaciones de tokens de contexto cada una). Cada vuelta tiene un tiempo de memoria y un tiempo de cálculo (Pope et al., §2), y manda el mayor:
con los bytes de los pesos, los bytes de caché por token, BW el ancho de banda y el cálculo útil (la lección usa la mitad del pico). Con hay operaciones por cada bytes, es decir operaciones por byte: una, en FP16. La H100 puede hacer por byte, así que la decodificación de una persona usa cerca del 0.3 % del cálculo. Pope et al. lo dicen así: con lotes y secuencias cortas domina el tiempo de cargar los pesos; con lotes grandes y secuencias largas, el de cargar la caché.
La caché KV por dentro
El 2 es clave y valor; las cabezas de clave-valor; la dimensión por cabeza y los bytes por número. Llama 3 8B (Llama Team, 2024, tabla 3): bytes por token (en la escena, números por clave y por bloque). Con atención multicabeza completa (32 cabezas KV) serían : Llama 3 usa atención de consultas agrupadas (GQA, Ainslie et al., 2023), que comparte cada par entre cuatro cabezas de consulta, «para reducir el tamaño de las cachés de clave-valor durante la decodificación». La misma cuenta da el valor de Kwon et al. (2023) para OPT-13B: bytes, unos 800 KB por token.
Sin caché, generar tokens tras de entrada procesa posiciones; con caché, . Con y : frente a . El transformer de juguete de la escena (2 bloques, 2 cabezas, , pesos al azar con semilla fija; tiny.ts) recorre los dos caminos: cuenta 105 y 15 pasadas, 498 240 y 72 960 multiplicaciones-sumas, y sus logits coinciden con una diferencia máxima de 0.
Techo de velocidad, lotes y costo
Con el 8B en FP16 en una H100, 8 000 tokens de contexto y 2 USD por hora de GPU (supuesto): da 196 tokens/s y 2.84 USD por millón; , el máximo que cabe, da 42 tokens/s por persona, 2 545 en total y 0.22 USD por millón: unas trece veces más barato en la misma máquina. Con 128 000 tokens de contexto solo caben 3 conversaciones.
Lo que paga quien usa una API
En las listas consultadas el 12 de octubre de 2026, la salida cuesta cinco veces la entrada en todos los modelos de Anthropic, y de cinco a más de ocho veces en los de Google. Los precios de la escena (US$ 3 y 15 por millón) son un ejemplo con esa proporción. Si el inicio de tu mensaje se repite (instrucciones, un documento base), la caché de prompt lo cobra mucho más barato: en la lista de Anthropic, leer de ella cuesta 0.1 veces el precio de entrada (0.05 o 0.025 en algunos modelos) y escribir en ella, con vigencia de cinco minutos, 1.25 veces.
Las esperas de la escena son estimaciones con el modelo de 8 mil M en una H100 y una sola persona: llenado al 40 % del pico, y cada vuelta de escritura con el tiempo de memoria de arriba.
Mezcla de expertos
Cada bloque reemplaza su red por expertos y un enrutador que elige por token:
Mixtral 8x7B (Jiang et al., 2024, tabla 1): , , , , . Salen 46.7 mil millones en total y 12.9 activos. El artículo lo dice así: el cálculo es proporcional a los parámetros activos, pero «el costo de memoria para servir Mixtral es proporcional a su cantidad de parámetros dispersos, 47B». Si cada token eligiera sus dos expertos al azar (supuesto: en la práctica el reparto es desigual), un lote de tokens tocaría en cada bloque una fracción de los expertos: 25 % con , 90 % con , 99 % con .
En código
Caché, techo de velocidad y costo con la arquitectura de Llama 3 8B:
capas, cabezas_kv, dim_cabeza, bytes_num = 32, 8, 128, 2
kv_por_token = 2 * capas * cabezas_kv * dim_cabeza * bytes_num # 2 = clave y valor
print(kv_por_token) # bytes por token
pesos = 8.03e9 * 2 # FP16: 2 bytes por parámetro
print(round(kv_por_token * 128_000 / 1e9, 2)) # GB de una conversación de 128 000 tokens
ancho_banda = 3.35e12 # H100 SXM: 3.35 TB/s
print(round(ancho_banda / pesos, 1)) # techo de tokens/s con una persona
def servir(personas, contexto, usd_por_hora=2.0):
bytes_por_vuelta = pesos + personas * contexto * kv_por_token # pesos + una caché por persona
t = bytes_por_vuelta / ancho_banda # segundos por vuelta
rendimiento = personas / t # tokens/s de todo el sistema
return round(1 / t, 1), round(rendimiento), round(usd_por_hora / (3600 * rendimiento) * 1e6, 3)
print(servir(1, 8000)) # (tokens/s por persona, tokens/s totales, US$ por millón)
print(servir(60, 8000))
# 131072
# 16.78
# 208.6
# (195.8, 196, 2.837)
# (42.4, 2545, 0.218)
La caché no cambia el resultado: atención de una cabeza con y sin caché.
import numpy as np
rng = np.random.default_rng(0)
d = 8
Wq, Wk, Wv = (rng.normal(size=(d, d)) for _ in range(3))
x = rng.normal(size=(6, d)) # 6 tokens (ya convertidos en vectores)
def atencion_sin_cache(x): # recalcula K y V de todos los tokens
q, k, v = x @ Wq, x @ Wk, x @ Wv
s = q @ k.T / np.sqrt(d)
s = np.where(np.tril(np.ones_like(s)) == 1, s, -np.inf) # máscara causal
w = np.exp(s - s.max(1, keepdims=True)); w /= w.sum(1, keepdims=True)
return w @ v
K, V, salida = [], [], [] # con caché: un token por vuelta
for t in range(len(x)):
q = x[t] @ Wq
K.append(x[t] @ Wk); V.append(x[t] @ Wv) # solo el par nuevo entra a la caché
s = np.array(K) @ q / np.sqrt(d)
w = np.exp(s - s.max()); w /= w.sum()
salida.append(w @ np.array(V))
print(np.allclose(atencion_sin_cache(x), np.array(salida)))
# True
Lo que viene
Los sistemas reales añaden más piezas: PagedAttention reparte la caché en bloques para no desperdiciar memoria (vLLM: de 2 a 4 veces más rendimiento con la misma latencia que sistemas anteriores, Kwon et al., 2023); el batching continuo mete y saca conversaciones del lote en cada vuelta (Orca, Yu et al., 2022); y la decodificación especulativa dio de 2 a 3 veces más velocidad en T5-XXL «con salidas idénticas» (Leviathan et al., 2023) y de 2 a 2.5 veces en Chinchilla 70B (Chen et al., 2023). Todo esto sirve a un modelo base; convertirlo en asistente empieza con el ajuste fino, en la lección 27.
Lente de decisión
Qué significa esta idea si tu trabajo es decidir, no programar.
- Costo por tarea = tokens de entrada × precio de entrada + tokens de salida × precio de salida. Pide el desglose por tipo de tarea: resumir (entrada larga, salida corta) no se parece a redactar (al revés). Estima tu volumen real en tokens antes de presupuestar.
- La espera depende del largo del contexto: el primer token tarda más cuanto más texto envías, y cada token posterior sale más lento con contextos largos. Pide el tiempo hasta el primer token y los tokens por segundo medidos con textos del largo de los tuyos, no los de la ficha comercial.
- Pregunta por la caché de prompt. Si el inicio de tus mensajes se repite (instrucciones, un documento base), reutilizarlo baja el costo y la espera: en la lista de Anthropic, leer de esa caché cuesta una décima parte del precio de entrada o menos (escribir la primera vez cuesta algo más: 1.25 veces).
- Al comparar modelos o proveedores, mira más que los «parámetros»: parámetros activos (mezcla de expertos), largo del contexto, precio de entrada y de salida. Si alojas tú el modelo, el costo por token depende de cuánto llenes la GPU: con los supuestos de la lección, atender a una persona sola cuesta unas trece veces más por token que un lote lleno.
Términos de la lección
- Inferencia Usar un modelo ya entrenado para responder ante un caso nuevo, con los parámetros fijos.
- Parámetro Cada uno de los números que un modelo ajusta al entrenarse y en los que guarda lo aprendido.
- Peso (w) En un modelo lineal, el número que multiplica a la entrada: la pendiente de la recta. Indica cuánto sube la predicción por cada unidad que aumenta la entrada.
- Modelo de lenguaje Modelo que, dado un texto (el contexto), da una probabilidad a cada palabra o pieza que puede seguir. Escribe agregando una pieza a la vez.
- Token Pieza de texto (una palabra, un trozo de palabra, un signo o un código básico) tomada del vocabulario. Es la unidad que el modelo lee y genera, y por la que se cobra.
- Autorregresión Escribir una pieza a la vez usando como entrada lo ya escrito: cada palabra producida pasa a formar parte del contexto de la siguiente.
- Atención Mecanismo con el que cada token decide cuánto mirar a los demás: compara su consulta con las claves de todos, convierte las puntuaciones en pesos con softmax y arma su nuevo vector como la mezcla de los valores con esos pesos.
- Consulta, clave y valor (Q, K, V) Los tres vectores que produce cada token: la consulta dice qué busca, la clave cómo se le encuentra y el valor qué entrega. Salen de multiplicar su vector por tres matrices de pesos aprendidas.
- Máscara causal En la atención, cambia por menos infinito las puntuaciones hacia tokens futuros antes de softmax, que entonces les da peso cero. Así cada token solo mira a los anteriores y a sí mismo, y el modelo no puede copiar la respuesta al entrenar.
- Transformer Arquitectura de red neuronal formada por una pila de bloques con la misma forma. Cada bloque combina atención (entre tokens) y una red aplicada a cada token, con conexiones residuales y normalización. Se presentó en «Attention Is All You Need» (2017).
- GPU Unidad de procesamiento gráfico: un chip con cientos o miles de núcleos sencillos, creado para dibujar gráficos y muy eficiente para multiplicar matrices en paralelo, la operación central del entrenamiento.
- Lote Conjunto pequeño de ejemplos, tomado al azar, con el que se estima el gradiente en un paso de entrenamiento.
- FLOP, FLOPs Operación de punto flotante: una suma o una multiplicación con decimales. El cómputo de un entrenamiento se cuenta en FLOPs totales (≈ 6·N·D); la velocidad de un chip, en FLOPs por segundo.
- Ancho de banda (de memoria) Cuántos bytes por segundo pueden viajar de la memoria a los núcleos: 3 350 GB/s en una H100. Al generar texto token a token suele ser el límite de velocidad, porque cada token exige leer todos los parámetros.
- VRAM (memoria de la GPU) La memoria propia de una GPU, en la misma tarjeta que sus núcleos. Ahí deben estar los parámetros y los datos con los que calcula. Se mide en gigabytes: 80 en una H100, 12 en una RTX 3060. En las GPU de centro de datos es de un tipo muy rápido llamado HBM.
- FP16 (y FP32, INT8, INT4) Formatos para guardar cada número de un modelo. FP16 usa 2 bytes y guarda unas 3 cifras significativas; FP32, 4 bytes y unas 7. INT8 (1 byte) e INT4 (½ byte) guardan un entero que, multiplicado por una escala, aproxima el valor. BF16 es una variante de 2 bytes con el alcance de FP32.
- Cuantización Guardar los parámetros de un modelo ya entrenado con menos bits (8 o 4 en lugar de 16), redondeando cada uno a la marca más cercana de una escala propia de su grupo. Reduce la memoria y el tiempo de lectura, con una pérdida de calidad que hay que medir.
- Modelo base Modelo de lenguaje que solo pasó por el preentrenamiento: sabe continuar textos, pero no está ajustado para seguir instrucciones ni conversar como un asistente.
- Servir un modelo (servicio de inferencia) Tener un modelo ya entrenado funcionando para atender solicitudes reales: con los pesos fijos, a muchas personas a la vez y cuidando la espera y el costo.
- Caché KV (claves y valores) Memoria que guarda las claves y los valores ya calculados de los tokens anteriores para no recalcularlos en cada vuelta. Ahorra cálculo, pero ocupa memoria que crece con el contexto y con cada conversación.
- Llenado (prefill) Primera fase de la inferencia: todo el mensaje de entrada se procesa de una vez y se llena la caché KV. De ella depende la espera hasta el primer token.
- Decodificación (decode) Segunda fase: los tokens se generan de uno en uno, y cada uno exige una vuelta completa por el modelo que lee todos los pesos y la caché. Suele estar limitada por el ancho de banda de memoria.
- Rendimiento (throughput) Tokens por segundo que entrega el sistema completo, sumando a todas las personas atendidas. Sube con el tamaño del lote, a costa de la velocidad que recibe cada persona (la latencia).
- Mezcla de expertos (MoE) Arquitectura en la que cada bloque tiene varias redes (expertos) y un enrutador elige unas pocas para cada token. Hay muchos parámetros en total y pocos activos por token: ahorra cálculo, no memoria.
Transcripción completa
Fuentes
- Pope, R., Douglas, S., Chowdhery, A., Devlin, J., Bradbury, J., Levskaya, A., Heek, J., Xiao, K., Agrawal, S., Dean, J. (2022). Efficiently Scaling Transformer Inference
- Llama Team, AI @ Meta (2024). The Llama 3 Herd of Models (tabla 3: arquitectura de 8B; GQA con 8 cabezas de clave-valor; contexto de hasta 128K)
- NVIDIA (2023). NVIDIA H100 Tensor Core GPU (ficha: 80 GB, 3.35 TB/s; FLOPS «con dispersión»)
- Kwon, W., Li, Z., Zhuang, S., Sheng, Y., Zheng, L., Yu, C. H., Gonzalez, J. E., Zhang, H., Stoica, I. (2023). Efficient Memory Management for Large Language Model Serving with PagedAttention
- Jiang, A. Q., Sablayrolles, A., Roux, A., Mensch, A., Savary, B., et al. (2024). Mixtral of Experts
- Leviathan, Y., Kalman, M., Matias, Y. (2023). Fast Inference from Transformers via Speculative Decoding
- Chen, C., Borgeaud, S., Irving, G., Lespiau, J.-B., Sifre, L., Jumper, J. (2023). Accelerating Large Language Model Decoding with Speculative Sampling
- Kaplan, J., McCandlish, S., Henighan, T., Brown, T. B., Chess, B., Child, R., Gray, S., Radford, A., Wu, J., Amodei, D. (2020). Scaling Laws for Neural Language Models (2N operaciones por token en la pasada hacia delante)
- Chowdhery, A., et al. (2022). PaLM: Scaling Language Modeling with Pathways (apéndice B: FLOPs de la atención por token)
- Ainslie, J., Lee-Thorp, J., de Jong, M., Zemlyanskiy, Y., Lebrón, F., Sanghai, S. (2023). GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints
- Yu, G.-I., Jeong, J. S., Kim, G.-W., Kim, S., Chun, B.-G. (2022). Orca: A Distributed Serving System for Transformer-Based Generative Models
- Anthropic (2026). Pricing (lista de precios de la API, consultada el 12 de octubre de 2026)
- Google (2026). Gemini Developer API pricing (consultada el 12 de octubre de 2026)
ComentariosConversación pública de esta lección: dudas, datos por revisar, ideas.
Los comentarios viven en GitHub Discussions, en el repositorio público del curso; para escribir se necesita una cuenta de GitHub. Se cargan desde giscus.app al abrir esta sección. Las personas que revisan el curso los leen, y si un cambio se acepta, se aplica en los dos idiomas. Abrir el hilo en GitHub