Servicio de los motores internos PagedAttención, Batch continuo, preempleo en pedazos
code/main.pyque los horarios preemplen y decodan de la manera que vLLM hace.Type: Learn
Languages: Python (stdlib, toy continuous batching scheduler)
Prerequisites: Phase 17 · 01 (Model Serving), Phase 11 (LLM Engineering)
Time: ~75 minutes
Objetivos de aprendizaje
- Explica PagedAttention como un alocador de caché KV: bloques, tablas de bloques y por qué la fragmentación se mantiene por debajo del 4% en la carga de producción.
- Diagrama de la partición continua a nivel de iteración: cómo las secuencias terminadas salen del lote y las nuevas se unen sin drenar.
- Describa el preempleo en pedazos en una frase y nombre qué métrica de latencia protege (indicación: es cola TTFT, no es el promedio de rendimiento).
- Compruebe una combinación de funciones vLLM con la matriz de compatibilidad de su versión antes de habilitar cada optimización a la vez.
El problema
Un ciclo de servicio PyTorch ingenuo ejecuta una solicitud a la vez: tokenizar, preemplir, decodificar hasta EOS, devolver. En un usuario esto funciona. A cien, es una cola de pacientes. La solución obvia lotamiento estático empapa cada solicitud al prompt más largo de la ventana, empapa cada decodificación a la salida esperada más larga, y detiene todo el lote en la secuencia más lenta. Pagas por relleno que nunca usas, y las solicitudes rápidas esperan las lentas.
VLLM resuelve tres problemas a la vez. PagedAttention detiene la fragmentación de la caché de KV de consumir 60-80% de la memoria de la GPU de la manera que lo hace la asignación contiguosa clásica. El batch continuo permite que las solicitudes se unan y salgan del lote entre cada iteración de decodificación, por lo que el lote siempre está lleno de trabajo real. El preempleo en pedazos rompe una señal de 32k en 512 tokens que se interponen con el decodificación, por lo que una señal larga no congela cada token de decodificación en la GPU.
El modelo de producción 2026 está activado por defecto. Necesitas entender lo que cada uno hace porque los modos de falla están todos en el programador, no en el modelo.
El concepto
PagedAttention como un sistema de memoria virtual
Un caché KV esnum_layers × 2 × num_heads × head_dim × seq_len × bytes_per_elementPara Llama 3.3 70B a 8192 tokens, es aproximadamente 1.25 GB por secuencia en BF16. Si reservas 8192 ranuras por adelantado para cada solicitud pero la solicitud promedio solo utiliza 1500 tokens, desperdicias aproximadamente el 82% del HBM reservado.
PagedAttention toma la idea de la memoria virtual del sistema operativo. El caché KV no es contiguo por secuencia. Se asigna en bloques de tamaño fijo (tokens predeterminados 16). Cada secuencia tiene una tabla de bloques que mapea sus posiciones lógicas de tokens a los ID de bloques físicos. Cuando una secuencia se expande más allá de sus bloques asignados, se agrega un bloque más. Cuando termina, sus bloques regresan al grupo.
La fragmentación cae del 60-80% (clásico) a menos del 4% (Attención pagada).--gpu-memory-utilization(default 0.9), que indica a vLLM cuánto HBM debe reservar para los bloques KV después de cargar pesos y activaciones.
Participación continua en el nivel de iteración
El antiguo "batch dinámico" esperaba una ventana (digamos 10 ms) para llenar un lote, luego ejecuta prefill + decode + decode + decode hasta que cada secuencia terminara.
El batch continuo se opera entre cada paso de decodificación.RUNNINGEn cada iteración:
- Cualquier secuencia en
RUNNINGque acaba de golpear EOS o max_tokens se elimina. - El programador mira la cola de espera. Si hay bloques KV libres, admite nuevas secuencias (preencher o reanudar).
- El pase hacia adelante se ejecuta en lo que sea que ahora está en .
RUNNING, emitiendo un nuevo token por secuencia.
El tamaño del lote nunca se empolga a un número fijo. Secuencias en diferentes posiciones en su salida comparten una fusionada hacia adelante.V1 scheduler. La invariante clave: el programador se ejecuta una vez por iteración de decodificación, no una vez por solicitud.
El preempleo en pedazos protege la cola de TTFT
Prefill es computacional. Una solicitud de 32k-token en Llama 3.3 70B toma ~800 ms de prefill puro en un H100. Mientras que la solicitud de prefill se ejecuta, decodifica las fichas para cada otra secuencia en el lote de espera. En un bucle de servicio, la latencia de primer token (TTFT) de un pedido largo se convierte en la latencia de intertoken (ITL) para docenas de otros usuarios.
El preenrollo en piezas se divide en piezas de tamaño fijo (tokens predeterminados 512) y se programa cada pieza como una unidad. Entre los trozos el programador puede avanzar las secuencias de decodificación por un token.
Las tres configuraciones interactúan
Las tres características se asumen mutuamente. PagedAttention le da al programador un recurso de KV de granos finos para negociar con.RUNNINGEn el caso de los Estados miembros, el sistema de programación de programas de programación es un sistema de programación más, no un sistema separado.
No es necesario conocer cada bandera, es necesario saber lo que el programador optimiza: un buen rendimiento bajo el presupuesto del bloque KV, sujeto a la recorte de preempleo en pedazos.
Verifique la matriz de compatibilidad
Compruebe cada combinación de características contra la matriz de compatibilidad para su versión exacta de vLLM antes de habilitarlas todas a la vez, porque lo que compone cambia entre las versiones. En la matriz de características de v0.18.0 marca la descodificación especulativa como compatible con el preempleo y el caching de prefijos en pedazos, y la página de descodificación especulativa enumera dos incompatibilidades conocidas: paralelismo de tubería a través de v0.15.0, y especulación de modelo de proyecto a través de v0.10.0. Para el proyecto de método en sí, el estándar de 2026 es a menudo EAGLE-3 ("method": "eagle3"), incluida en la fase 17 · 05.
Números que debes recordar
- Llama 3.3 70B FP8, H100 SXM5, 128 simultáneos, todos los tres en: 2.200-2.400 tok/s.
- El mismo modelo, VLLM predeterminado (sin precarga en pedazos): ~1.800 tok/s.
- El mismo modelo, el ciclo PyTorch hacia adelante ingenuo: ~600 tok/s.
- Residuos de fragmentación de KV bajo PagedAttention a carga de producción: < 4%.
- P99 ITL bajo carga mixta: ~ 15 ms con precarga en pedazos, ~ 50 ms sin.
Cómo se ve el programador
while True:
finished = [s for s in RUNNING if s.is_done()]
for s in finished: release_blocks(s); RUNNING.remove(s)
while WAITING and have_free_blocks_for(WAITING[0]):
s = WAITING.pop(0)
allocate_initial_blocks(s)
RUNNING.append(s)
# schedule prefill chunks + decode in one batch
batch = []
for s in RUNNING:
if s.in_prefill:
batch.append(next_prefill_chunk(s)) # e.g. 512 tokens
else:
batch.append(decode_one_token(s)) # 1 token
run_forward(batch) # one fused GPU callcode/main.pyEs exactamente este bucle en stdlib Python con recuentos falsos de tokens y latencia avanzada falsa. ejecutándolo muestra cómo el preempleo en pedazos mantiene las secuencias de decodificación vivas durante un largo preempleo.
Usalo
code/main.pysimula un programador de estilo vLLM con características alternativas. ejecuta para ver:
NAIVEmodo: una solicitud a la vez, sin lotes.STATICmodo: pad y espera, batch clásico.CONTINUOUSmodo: admisión y liberación a nivel de iteración.CONTINUOUS + CHUNKEDmodo: preemplar las recetas entrelazadas con decodificación.
La salida muestra el rendimiento total (tokens por segundo virtual), el TTFT medio y P99 ITL.CONTINUOUS + CHUNKEDLa fila debe ser la principal en el tráfico mixto.
Envío
Esta lección produceoutputs/skill-vllm-scheduler-reader.md. Dado un formato de servicio (tamaño de lote, utilización de memoria KV, tamaño de preenrollo en pedazos, configuración especulativa), produce un diagnóstico de cronometrista que nombra cuál de las tres anomalías es el cuello de botella y qué sintonizar.
Los ejercicios
- - ¿ Qué ?
code/main.py- Comparar .STATIC¿ Qué ?CONTINUOUS¿De dónde viene la brecha de rendimiento de la eficiencia de preempleo, la eficiencia de decodificación o la latencia de cola? - Modificar el programador de juguetes para agregar
--max-num-batched-tokens. ¿Cuál es el valor correcto para un H100 con Llama 3.3 70B FP8? (Intención: es una función del tamaño de bloque KV y el número de bloques libres, no HBM crudo). - Re-leer las notas de vLLM v0.18.0. ¿Qué combinaciones de banderas son mutuamente excluyentes?
- Calcule el desperdicio de fragmentación de la caché KV para un rastro de 1.000 solicitudes con promedio de 1.500 tokens de salida, std 600 tokens, bajo (a) asignación contiguosa por solicitud a 8192 max, (b) PagedAttention con bloques de 16 tokens.
- Explique en un párrafo por qué el precarga en piezas ayuda a la P99 ITL pero no a la capacidad de producción en forma aislada.
Términos clave
| Term | What people say | What it actually means |
|---|---|---|
| PagedAttention | "the KV trick" | Fixed-size block allocator for KV cache; fragmentation <4% |
| Block table | "the page table" | Per-sequence map from logical token position to physical KV block |
| Continuous batching | "dynamic batching, but right" | Admit/release decisions made every decode iteration |
| Chunked prefill | "prefill splitting" | Break long prefill into 512-token slices interleaved with decode |
| TTFT | "first token time" | Prefill + queue + network; dominated by prefill at long prompts |
| ITL | "inter-token latency" | Time between consecutive decode tokens; dominated by batch size |
| Goodput | "throughput that meets SLO" | Tokens/sec where every request still hit TTFT and ITL targets |
| V1 scheduler | "the new scheduler" | vLLM's 2026 scheduler; runs continuous batching with chunked prefill |
--gpu-memory-utilization | "the memory knob" | Fraction of HBM reserved for KV blocks after weights and activations |
Leer más
- vLLM documentation — Speculative Decoding fuente oficial sobre compatibilidad entre preemplazos en pedazos y decodificación especulativa.
- vLLM Release Notes (NVIDIA) 2026 libera cadencia y comportamiento específico de la versión.
- vLLM Blog — PagedAttention la redacción original que todavía define cómo pensar sobre el asignador.
- PagedAttention paper (arXiv:2309.06180) análisis de fragmentación y diseño de los programadores.
- Aleksa Gordic — Inside vLLM detallado V1 programador paseo con gráficos de llama.
This free lesson is part of the AI Engineering from Scratch curriculum. Read the full explanation, run the lesson code, and verify the result in the interactive reader or from the repository source.
Browse the complete course catalog or open this lesson on GitHub.