Batching en LLM: estático, dinámico y continuo explicado para decisores
El batching agrupa solicitudes para mejorar la utilización de GPUs en inferencia de LLMs. Aquí explicamos las diferencias entre batching estático, dinámico y continuo, y cuándo conviene cada uno.
Introducción
Imaginen cuatro personas pidiendo viaje hacia el mismo destino. Si cada una toma un taxi, hay cuatro viajes iguales; si viajan en un solo autobús, el recurso se aprovecha mejor. Batching en IA funciona parecido: en lugar de procesar solicitudes una por una, el servidor las agrupa para que la GPU ejecute más trabajo útil en cada lectura de memoria. Pero la forma de agrupar y programar esas solicitudes impacta directamente en la latencia percibida por el usuario y el costo por token generado.
En este artículo desglosamos qué es batching en LLMs, por qué es crítico, y explicamos las tres estrategias principales —estático, dinámico y continuo— con sus ventajas y limitaciones, pensando en equipos y tomadores de decisión en América Latina.
¿Qué es batching?
Batching es ejecutar múltiples entradas a través de un modelo en una sola pasada (forward pass) en vez de procesarlas individualmente. En un LLM, cada entrada es una secuencia de tokens; en vez de alimentar al modelo con una forma [1, seq_len], se le entrega un tensor [batch_size, seq_len]. Esto permite que la GPU realice operaciones en paralelo sobre varias solicitudes y aumente el rendimiento.
Sin embargo, la generación en LLMs ocurre token a token y distintas solicitudes pueden tener longitudes de salida muy diferentes. Cómo agrupe el servidor las solicitudes, qué hace con las que llegan en tiempo real y cómo libera recursos cuando algunas terminan influyen en qué estrategia de batching es la más adecuada.
¿Por qué los LLMs necesitan batching?
La razón técnica es sencilla: durante la decodificación la GPU está limitada por la velocidad de lectura de memoria, no por la capacidad de cálculo bruto. El proceso de inferencia tiene dos fases:
- Prefill: el modelo consume el prompt completo en una pasada; todos los tokens del prompt se procesan en paralelo y mantienen ocupadas las unidades de cómputo.
- Decode: el modelo genera token por token. Cada token requiere otra pasada que conlleva leer todos los pesos desde la memoria GPU.
En el ejemplo de la fuente para un modelo de 7B en FP16 sobre una H100, los pesos ocupan alrededor de 14 GB; con un ancho de banda de memoria de 3.35 TB/s, leer esos 14 GB toma aproximadamente 4 ms. Eso limita una sola solicitud a cerca de 240 tokens por segundo. Cada token requiere unas 14 GFLOPs, lo que implicaría cerca de 3.5 TFLOPS por paso; sin embargo, la H100 puede ofrecer en torno a 1,000 TFLOPS de dense BF16. En batch size 1, la GPU está más del 99% del tiempo ociosa en términos de cómputo porque pasa la mayor parte del tiempo cargando pesos.
Si se ejecutan 32 secuencias en el mismo paso, los pesos se cargan una sola vez y se generan 32 tokens por paso, obteniendo un salto enorme en rendimiento y en costo por token. El límite viene por la memoria: cada secuencia en el batch mantiene su propio KV cache en GPU y ese cache crece con cada token generado, lo que acota el tamaño máximo de batch.
Batching estático
El batching estático agrupa un conjunto fijo de solicitudes, las ejecuta juntas y devuelve resultados solo cuando todas las solicitudes del grupo han terminado. Nada nuevo se puede unir hasta que el batch completo finaliza.
Ventajas:
- Implementación simple y reproducible.
- Bueno para trabajos por lotes (offline) y flujos con salidas uniformes (por ejemplo, resumir muchos documentos con un límite fijo de salida).
Desventajas:
- Mala tolerancia a la variabilidad en las longitudes de salida. Si un batch contiene respuestas de 20, 50, 100 y 500 tokens, el batch tendrá que ejecutarse durante 500 pasos y las solicitudes cortas estarán inactivas o haciendo padding durante la mayor parte del tiempo (head-of-line blocking).
- Baja utilización en presencia de alta variabilidad en longitudes.
El comportamiento por defecto de muchas loops de inferencia es estático: se llena el batch y se espera hasta que todo termina.
Batching dinámico
El batching dinámico intenta reducir la espera de solicitudes cortas y mejorar la latencia promedio sin sacrificar mucho la eficiencia. En esencia, el sistema reúne solicitudes que llegan en un pequeño intervalo de tiempo o hasta completar cierto tamaño de batch, y lanza una ejecución cuando se cumple una condición (por ejemplo, se alcanza el tamaño máximo o se supera un tiempo de espera).
Ventajas:
- Reduce el head-of-line blocking comparado con batching estático.
- Mejor equilibrio entre latencia y throughput en escenarios de tráfico variable.
Desventajas:
- Introduce complejidad en el encolado y en la lógica de timeouts.
- Aun puede desperdiciar capacidad cuando hay solicitudes muy largas que prolongan el paso si se priorizan completarlas dentro de un mismo batch.
Batching continuo
El batching continuo busca mantener la GPU ocupada ejecutando secuencias todo el tiempo, permitiendo que nuevas solicitudes entren en los “huecos” que dejan otras cuando terminan. En lugar de esperar a que un lote entero finalice, las ranuras de ejecución se rellenan continuamente con nuevas secuencias que llegan o que han quedado pendientes.
Ventajas:
- Muy alta utilización de la GPU en cargas de trabajo con tráfico sostenido y variabilidad en longitudes.
- Reduce la latencia tail al aprovechar ranuras libres al vuelo.
Desventajas:
- Gestión compleja del KV cache y de la memoria GPU, porque cada secuencia activa mantiene su propio estado.
- Riesgo de consumir más memoria si muchas secuencias largas coexisten.
Comparación y recomendaciones prácticas
-
Cuándo preferir batching estático: procesos offline, previsibles y uniformes (p. ej. tareas de inferencia por lotes con cap fijo). Su sencillez lo hace atractivo para pipelines controlados.
-
Cuándo preferir batching dinámico: servicios en tiempo real con tráfico variable que necesitan un equilibrio entre latencia y costo. Es una buena opción para APIs que atienden picos y requieren menores latencias promedio.
-
Cuándo preferir batching continuo: plataformas que sirven mucho tráfico sostenido y donde la prioridad es maximizar throughput por GPU, siempre que se tenga control de la memoria y herramientas para manejar KV caches.
Aspectos operativos a vigilar (relevantes para equipos en LATAM con presupuestos ajustados):
- Monitorizar porcentaje de utilización de GPU, latencias percentil 95/99 y consumo de memoria por proceso.
- Considerar límites de batch para evitar OOM por KV cache.
- Evaluar costos: una mayor eficiencia de GPU reduce el gasto por token, crucial si se usan instancias on-premise o nube con presupuesto restringido.
Conclusión
Batching no es una sola técnica, sino un conjunto de estrategias de programación que afectan directamente el rendimiento, la latencia y el costo de desplegar LLMs. La elección entre estático, dinámico y continuo depende del patrón de tráfico, las expectativas de latencia y las restricciones de memoria. Para equipos y empresas en América Latina, optimizar el uso de GPU mediante el enfoque adecuado puede traducirse en ahorros significativos y en una mejor experiencia para los usuarios sin necesidad de escalar verticalmente la infraestructura.
Para avanzar, recomendamos probar en laboratorio cada estrategia con trazas reales de tráfico, medir latencia y utilización, y entonces elegir la mezcla (o combinación híbrida) que mejor se ajuste a sus objetivos operativos y financieros.
Fuente original: Analytics Vidhya