Serving in production: batching, concurrency and autoscaling
Mi servidor respondía perfecto con un usuario y se arrastraba con diez. La culpa no era del modelo ni de la GPU: era que atendía las peticiones de a una. El mismo modelo, la misma máquina, con la configuración correcta, atiende muchas más.
Esta pieza es lo que cambia cuando pasas de "funciona" a "sirve": batching, caché de contexto, la separación entre leer y generar, y cómo pagar solo por lo que usas.
Batching: la diferencia está en cómo agrupas
Un servidor naïve procesa una petición, la termina y recién ahí empieza la siguiente. Eso deja la GPU ociosa casi todo el tiempo: mientras esperas el primer token de una respuesta, podrías estar generando tokens de otras cinco.
El batching continuo mezcla tokens de varias peticiones en el mismo paso de GPU y libera a las que terminan. vLLM se presenta como "un motor de batching continuo completo" y reporta hasta 1.7x más throughput que su arquitectura anterior, medido con Llama 3.1 8B y Llama 3.3 70B. - Source: vLLM V1 - vLLM Team
El trade-off que vas a medir
Batching sube throughput (tokens por segundo totales) y puede subir latencia p95 (cuánto espera el peor usuario). No hay almuerzo gratis:
| Configuración | Throughput | p95 |
|---|---|---|
| Sin batching | Bajo | Bueno con poca carga, malo con mucha |
| Batching agresivo | Alto | Puede empeorar por espera de cola |
Lo correcto no es maximizar uno, sino elegir el punto para tu producto. Y para eso hay que medir: → Medir inferencia sin engañarte
Prefix caching: pagar el prompt una sola vez
Si muchas peticiones comparten un prefijo (tu system prompt, un documento largo, una conversación anterior), la caché lo calcula una vez y lo reutiliza. vLLM reporta que su implementación introduce menos de 1% de pérdida de throughput con 0% de aciertos, y varias veces más rendimiento con aciertos altos, por eso lo activa por defecto. - Source: vLLM V1 - vLLM Team
Implicación de diseño: ordena tus prompts para que el prefijo estable vaya primero. Es gratis y multiplica el acierto de caché.
Leer y generar son dos fases distintas
El prompt se "lee" (prefill) y la respuesta se "genera" (decode), y tienen perfiles opuestos: el prefill es intensivo en cómputo y el decode, en memoria. Separarlos en máquinas (o GPUs) distintas se llama PD serving, y es una de las palancas que usan los despliegues grandes para exprimir el hardware.
No necesitas empezar ahí. Pero sí entender que un prompt de 100.000 tokens y una respuesta de 200 no son el mismo problema.
Autoscaling: pagar por lo que usas
En GPU dedicada pagas por hora encendida, con o sin tráfico. En serverless pagas por trabajador activo: RunPod describe su modelo serverless como "factura los trabajadores de inferencia según el uso", con tarifas por hora que van desde $0.58/hora (GPU de 16 GB) hasta $9.98/hora (B300 de 280 GB). - Source: GPU Cloud Pricing - RunPod
La pregunta de arquitectura es cuál te conviene:
- Tráfico constante → instancia dedicada (más barata por hora, busca el mejor precio).
- Tráfico en picos → serverless (pagas el pico solo cuando ocurre).
- Tráfico constante + picos → dedicada para la base, serverless para el excedente.
El cuello de botella que no es la GPU
Recuerda la pieza anterior: con Llama-8B en una H100, el tiempo en GPU puede ser de ~5 ms y el resto se va en CPU (tokenizar, preparar inputs, des-tokenizar, streaming). - Source: vLLM V1 - vLLM Team
Si tu p95 es malo con una GPU sobrada, mira la CPU y el loop del API antes de comprar hardware.
Cómo configurarlo (5 pasos)
- Corre con batching continuo (vLLM o un servicio gestionado que lo use) desde que tengas más de un usuario.
- Activa prefix caching y ordena los prompts con el prefijo estable primero.
- Mide throughput y p95 con carga realista; no con una petición.
- Elige el punto de batching según tu producto (un chat prioriza p95; un proceso por lotes prioriza throughput).
- Decide el modelo de facturación según tu patrón de tráfico (dedicado vs serverless).
Lo que sigue es el dinero: El costo real de tu feature de AI. Y el marco completo, en la guía Inference Engineering.
¿Cómo sirves tus modelos hoy: una petición a la vez o con batching? Cuéntame en los comentarios qué métrica te delató el problema.