## Continuous batching

*Model na produkcji*

*Ostatnia zmiana: 28 września 2026*

Serwer składa rozmowy w batch, żeby jedno czytanie wag obsłużyło wielu użytkowników naraz. Continuous batching wymienia rozmowy w batchu co krok, a PagedAttention przydziela im pamięć na KV cache małymi blokami, więc na tej samej karcie mieści się ich kilka razy więcej.

**Po ludzku:** Autobus, który nie czeka, aż wszyscy dojadą do pętli: kto wysiada, zwalnia miejsce następnemu na najbliższym przystanku. Do tego nikt nie rezerwuje miejsca na całą trasę z góry, tylko siada, gdy wsiada.

*Interaktywny widżet na stronie: Odtwórz oba tryby i porównaj: ile kratek stoi pustych i w którym kroku kończy się ostatnia rozmowa.*

### Jak działa continuous batching

- Batch statyczny ustala skład raz: wszyscy czekają na najdłuższą odpowiedź, a nowe żądania na koniec całej grupy. Długości odpowiedzi nie znasz z góry, więc puste miejsca są regułą, nie wyjątkiem.
- Continuous batching (w literaturze iteration-level scheduling, system Orca, OSDI 2022) decyduje o składzie co krok decode. Skończona rozmowa zwalnia miejsce od razu, a czekająca dołącza w następnym kroku. Działa, bo każdy krok to osobny przebieg modelu, a warstwy poza attention nie zależą od długości sekwencji.
- Nowa rozmowa zaczyna od prefillu swojego promptu, który na chwilę zabiera kartę rozmowom w trakcie generowania. Chunked prefill tnie długi prompt na kawałki mieszczące się w budżecie tokenów na krok. vLLM V1 włącza go domyślnie i w każdym kroku najpierw obsługuje rozmowy w fazie decode, a prefill dokłada w wolne miejsce.

*Interaktywny widżet na stronie: Przełącz sposób przydziału pamięci i policz, ile rozmów mieści się w tych samych 32 blokach.*

### PagedAttention: pamięć na KV cache

- Rezerwacja ciągłego obszaru na maksymalną długość odpowiedzi marnuje pamięć na zapas i fragmentację. Autorzy vLLM zmierzyli w ówczesnych systemach 60–80% straty pamięci na KV cache.
- PagedAttention dzieli KV cache na bloki po kilkanaście tokenów (zwykle 16), przydzielane w miarę generowania i adresowane przez tablicę bloków, jak strony pamięci wirtualnej w systemie operacyjnym. Pusta zostaje tylko końcówka ostatniego bloku, a strata spada poniżej 4%. Więcej rozmów w pamięci to większy batch i niższy koszt na token.
- Bloki można współdzielić z kopiowaniem przy zapisie (copy-on-write). Wspólny prefiks, na przykład system prompt albo prompt kilku próbek tej samej odpowiedzi, leży w pamięci raz. Na tym opiera się prefix caching w serwerze (zobacz „Prompt caching”). Przy wielu replikach działa tylko wtedy, gdy router kieruje żądania z tym samym prefiksem do repliki, która już go ma (routing świadomy prefiksu, np. w llm-d albo NVIDIA Dynamo).
- Ceną przydziału na żądanie jest to, że pamięć może się skończyć w trakcie generowania. Serwer wtedy wywłaszcza rozmowę, a później liczy jej KV cache od nowa. W vLLM V1 to domyślny tryb, a nie przenoszenie cache’u do pamięci CPU. Użytkownik widzi to jako nagły przestój strumienia.

### Przepustowość a opóźnienie na produkcji

- Rozmiar batcha ograniczają pamięć na KV cache (liczba rozmów × długość kontekstu) i budżet opóźnienia między tokenami. Parametry serwera, takie jak `max_num_seqs` i `max_num_batched_tokens` w vLLM, ustawiają wprost ten kompromis.
- Przepustowość rośnie kosztem opóźnienia. Pod obciążeniem czas do pierwszego tokena rośnie przez kolejkę i prefille, a czas między tokenami przez większe batche. Oba mierzysz osobno, w percentylach p50 i p99 (zobacz „LLM na produkcji”).
- Batch API dostawców sprzedaje luźne SLO: u Anthropic 50% taniej, większość paczek kończy się w ciągu godziny, limit to 24 godziny. Dostawca może takim ruchem wypełniać wolne miejsca w batchach i doliny ruchu. Do ewaluacji i przetwarzania wsadowego to najprostsza oszczędność.

### Sprawdź się

**Pytanie:** Jak serwer LLM obsługuje wielu użytkowników naraz i co dają continuous batching oraz PagedAttention?

**Krótka odpowiedź:** Batch dzieli koszt czytania wag, więc serwer chce go mieć jak największy. Continuous batching ustala skład batcha co krok decode, a nie co żądanie: skończona rozmowa od razu zwalnia miejsce, nowa dołącza w następnym kroku, więc karta nie czeka na najdłuższą odpowiedź. PagedAttention przydziela KV cache blokami na żądanie, zamiast rezerwować maksimum z góry: strata pamięci spada z 60–80% do kilku procent, mieści się więcej rozmów, a wspólne prefiksy leżą w pamięci raz. Ceną są wywłaszczenia, gdy pamięć się skończy.

### Pytania pogłębiające

- **Co ogranicza rozmiar batcha?** Pamięć na KV cache wszystkich rozmów i budżet opóźnienia między tokenami. Przy długich kontekstach najpierw kończy się pamięć, przy krótkich budżet opóźnienia.
- **Użytkownicy zgłaszają rzadkie, kilkusekundowe przestoje w strumieniu tokenów. Co sprawdzasz?** Wywłaszczenia z braku pamięci na KV cache (licznik w metrykach serwera) i długie prefille nowych żądań bez chunked prefill. Pomaga niższy limit równoległych rozmów, więcej pamięci na cache albo osobne repliki dla bardzo długich promptów.
- **Co daje PagedAttention poza ciaśniejszym upakowaniem?** Współdzielenie bloków z copy-on-write. Wspólny prefiks wielu rozmów leży w pamięci raz, a kilka próbek tej samej odpowiedzi (n > 1, beam search) dzieli bloki promptu. Autorzy vLLM podają do 55% mniej pamięci przy takim samplowaniu.
- **Czemu przy temperaturze 0 ten sam prompt daje czasem inny tekst?** Wynik kernela zależy od rozmiaru batcha, bo zmienia się kolejność sumowania liczb zmiennoprzecinkowych. Rozmiar batcha zależy od obciążenia serwera, więc drobne różnice w logitach zmieniają czasem wybrany token. Thinking Machines (2025) wskazuje to jako główną przyczynę niedeterminizmu endpointów. Lekarstwem są kernele niezależne od batcha: vLLM ma tryb Batch Invariance (beta, stan na wrzesień 2026), w którym wynik nie zależy od rozmiaru batcha ani kolejności żądań, co może kosztować część szybkości. Przydaje się w ewaluacjach, debugowaniu i rolloutach RL.

### Źródła

- [Kwon i in.: Efficient Memory Management for LLM Serving with PagedAttention (SOSP 2023)](https://arxiv.org/abs/2309.06180)
- [vLLM: Easy, Fast, and Cheap LLM Serving with PagedAttention](https://vllm.ai/blog/2023-06-20-vllm)
- [vLLM: Optimization and Tuning (preemption, chunked prefill)](https://docs.vllm.ai/en/latest/configuration/optimization.html)
- [Agrawal i in.: Sarathi-Serve, chunked prefill (OSDI 2024)](https://arxiv.org/abs/2403.02310)

Strona interaktywna: https://howaiworks.dev/pl/batching/
