Capítulo 7 — Estrategias de batching avanzadas

Publicado el: 2026-04-29 Última actualización el: 2026-07-07 Versión: 1
Capítulo 7 — Estrategias de batching avanzadas

Capítulo 7 — Estrategias de batching avanzadas

Séptima entrega del recorrido capítulo por capítulo de LLM Primer VI: Scaling AI Systems. El capítulo que muestra que el batching no es una optimización sino el movimiento que sostiene la carga, el que hace tratable el decoding limitado por ancho de banda — y por qué el batch es un verbo, no un sustantivo.


Por qué existe este capítulo

Un único paso de decoding lee decenas de gigabytes de pesos desde HBM para producir un token. Si la GPU está haciendo fluir esos pesos de todos modos, puede producir un token para muchas peticiones en el mismo paso a coste marginal casi cero. Por tanto, el batching no es una optimización en el sentido habitual — es el único modo de hacer que el decoding sea económicamente tratable sobre hardware limitado por ancho de banda de memoria. Pero la forma obvia de batchear colapsa al contacto con el mundo real, porque las peticiones tienen longitudes distintas y terminan en momentos distintos. El Capítulo 7 recorre desde el esquema ingenuo que casi funciona hasta el scheduler a nivel de iteración que los motores de producción realmente corren, y nombra la deuda que ese scheduler crea para que el Capítulo 8 la pague.

En una línea: el batching continuo convierte el batch de sustantivo en verbo — las secuencias entran y salen en cada iteración — y al hacerlo expone la caché KV como la nueva restricción vinculante.

7.1 El batching estático es derrotado por el problema del que termina primero

El batching estático es lo que todo el mundo escribe primero: reúne peticiones hasta un tamaño de batch B o un timeout, ejecuta el prefill sobre todo el batch a longitud S_max, ejecuta un bucle de decode hasta que cada secuencia del batch haya emitido EOS. Los dos costes son catastróficos en combinación. Padding — el prompt de 50 tokens en el mismo batch que el prompt de 4.000 tokens paga 80 veces el trabajo de prefill que necesita. El que termina primero — el bucle de decode corre hasta que cada secuencia termina, así que un batch con una petición de 20 tokens y una de 2.000 tokens pasa el 99 por ciento de su tiempo con 31 slots produciendo tokens que serán descartados. El throughput medio parece aceptable y la latencia de cola queda dominada por la petición larga que el batch resultase contener. El batching dinámico (timeout variable, permitir llegadas tardías al batch pendiente) suaviza la espera pero no cambia el esquema fundamental; hereda el mismo problema del que termina primero una vez empieza el decode.

7.2 El batching continuo planifica por iteración, no por petición

El batching continuo — el scheduling a nivel de iteración de Orca, el in-flight batching de NVIDIA, "el truco central" de vLLM y TGI — es el cambio de variable. En lugar de comprometer un batch para toda la duración de la generación, el scheduler revisita la composición del batch en cada paso de decode. Tras cada paso: las secuencias terminadas dejan su slot y liberan su KV; secuencias nuevas de la cola entran en los slots liberados; el paso conjunto de decode corre sobre el nuevo conjunto activo. Dos propiedades del decoding de LLMs lo permiten. Cada paso de decode es estructuralmente la misma operación — al kernel no le importa qué secuencia está en el slot 7 frente al 11. Y cada secuencia lleva su propia caché KV de forma independiente, así que su memoria simplemente queda disponible cuando se va. La unidad de justicia se vuelve la iteración, no la petición: una petición de 20 tokens termina tras unas 20 iteraciones al margen de quién más esté en el batch, y una de 2.000 tokens ocupa un slot todo el tiempo que necesita sin retener a las demás. Sobre tráfico real de cola larga — mezclas de turnos cortos de chat y completaciones largas de RAG — la utilización de GPU en un modelo de 70B sube del rango 10–20 por ciento típico del batching estático al 60–80 por ciento, y la latencia p99 se aprieta drásticamente.

7.3 El chunked prefill unifica prefill con decode en el mismo chip

El batching continuo aún deja una tensión. Las llegadas nuevas necesitan prefill, que está limitado por cómputo y prefiere secuencias largas por pasada. Las secuencias en curso necesitan decode, que está limitado por ancho de banda de memoria y prefiere batches anchos. Ejecutar un prefill completo sobre un prompt fresco de 4.000 tokens en el mismo forward pass que el paso de decode de treinta secuencias en curso o bien retrasa los decodes en curso (mal TTFT para los usuarios existentes) o bien retrasa el prefill del nuevo (mal TTFT para el nuevo). El chunked prefill parte el prefill en trozos — digamos 512 tokens cada vez — e intercala esos trozos con los pasos de decode de las secuencias activas. El único forward pass lleva ahora algo de trabajo de prefill de prompt nuevo y algo de trabajo de decode en curso simultáneamente, y las dos fases comparten los mismos flujos de pesos. El carácter limitado por cómputo del prefill absorbe la aritmética; la demanda de ancho de banda del decode se amortiza sobre más trabajo útil por byte. Las dos fases dejan de ser antagónicas en un mismo chip. El caso restante — tráfico suficiente para que aún peleen — es la preparación del serving desagregado del Capítulo 12.

Vale la pena recordar: la ganancia de throughput del batching continuo es real, y replantea el problema de memoria. Las secuencias entran y salen en cada paso, así que el motor no puede pre-asignar una losa por slot. El esquema de memoria que sustituya a la losa tiene que sobrevivir a admisiones y expulsiones constantes — por eso paginación.

Lo que prepara el Capítulo 7

El batching continuo hace su trabajo y al hacerlo expone la caché KV como restricción vinculante sobre la concurrencia. Cada secuencia activa lleva su propia KV, dimensionada en proporción a su longitud actual; las secuencias entran y salen en cada paso; el motor no puede saber por adelantado cuán largas serán. Una disposición ingenua de una-losa-por-slot devuelve la mayor parte de la ganancia del batching. El Capítulo 8 trae la solución del sistema operativo: parte la caché en pequeños bloques físicos, desacóplalos de las posiciones lógicas de token con una tabla de páginas, y deja que una política de eviction reclame o comparta bloques entre secuencias. PagedAttention es el movimiento que hace tratable el problema de KV del batching continuo.


Próximamente — Capítulo 8: Gestión de caché KV de nueva generación. PagedAttention, eviction H2O, InfiniGen y la economía del caché de prefijos.

¿Quieres el panorama completo? El capítulo del libro incluye la implementación ejecutable de batching estático, el scheduler completo de batching continuo en el espíritu de vLLM/TGI, la traza paso a paso trabajada de seis peticiones a través de un motor de cuatro slots, y la discusión de preempción/eviction/control de admisión para la que este artículo no tiene sitio. Consulta LLM Primer VI en Amazon →

SHO
SHO
CTO y Fundador de RECEIPTROLLER. Enfocado en datos, impulsado por la innovación, siempre curioso.