AI engineering and inferenceLoading progress…

Preemption

Trace static and iteration-level schedules and explain chunked prefill, preemption and latency tradeoffs.

When memory runs out: preemption

If memory is short, a scheduler can preempt a request: pause it and take its cache memory for others. To resume later it must either recompute the cache (prefill the tokens again) or swap it to slower memory and back. Both cost time, and the cost grows with the number of cached tokens, so a good policy considers it when picking the victim.

cached tokens of the victim1,000link bandwidth (GB/s)25
optionhowcost (ms)
drop and recomputeprefill the tokens again at 0.1 ms each100
swap out and back131.1 MB each way at 25 GB/s10.49
cheaper here: swap Either way the resumed request pays; eviction is never free, and the policy must include that cost.
With the toy numbers swapping is cheaper. Slow the link and see the choice flip.

Predict first. Is evicting a cache free if the sequence later resumes?

Chapter context

Requests arrive at different times and finish after different output lengths. Scheduling decides which work enters each iteration and how waiting prompts compete with ongoing generation.

Chapter reference: math, worked example & code

This section belongs to the whole chapter, so it is the same on every lesson in it and may cover a different lesson's topic. The code for the experiment you just ran is inside the experiment itself.

Math and notation

In a simplified equal-cost decode schedule, utilization = active sequence-iterations / available sequence-iterations. This omits prefill costs and assumes uniform iteration time. A real scheduler needs measured compute, memory and latency constraints.

Worked example

Two slots serve requests A,B,C with output lengths 2,1,2. Static groups run A+B for two iterations, then C alone for two: 5 active slots out of 8 available. Continuous admission runs A+B, then A+C, then C: 5 active slots out of 6. Utilization rises from 62.5% to about 83.33% in this toy schedule; real token costs are not equal.

Reference code

The following example uses the Python standard library and does not call a remote service.

from math import isclose
static=[['A','B'],['A',None],['C',None],['C',None]]
continuous=[['A','B'],['A','C'],['C',None]]
util=lambda rows: sum(x is not None for row in rows for x in row)/(2*len(rows))
assert util(static) == .625
assert isclose(util(continuous),5/6)

Python examples are provided for study and local execution; this page does not execute Python.

Common mistakes

Continuous batching does not guarantee a fixed improvement. Chunked prefill changes scheduling granularity, not the model's context dependencies. Include cache movement or recomputation costs when comparing preemption policies.