03 · Sequence:请求的状态机
Sequence 不只是 token 列表
在推理引擎里,一个请求需要同时回答:
- 原始 prompt 有多少 token?
- 已经生成了多少 completion token?
- 其中多少 token 已经存在 KV Cache?
- 本轮计划处理多少 token?
- 它占用了哪些 block?
- 是否已经遇到 EOS 或达到
max_tokens?
这些信息集中在 engine/sequence.py 的 Sequence 对象中。
三个状态
text
WAITING → RUNNING → FINISHEDWAITING:尚未获得本轮执行资格,通常也还没有完整的 block table。RUNNING:已分配缓存资源,参与 Prefill 或 Decode。FINISHED:遇到 EOS 或生成长度上限,随后释放 block。
四种长度不要混淆
| 字段 / 属性 | 含义 |
|---|---|
num_tokens | 当前总 token 数,prompt + completion |
num_prompt_tokens | 初始 prompt 长度,创建后不变 |
num_cached_tokens | 已经写入 KV Cache 的 token 数 |
num_scheduled_tokens | 本轮被 Scheduler 选中的 token 数 |
特别注意:scheduled 不等于 cached。Scheduler 先计划,ModelRunner 执行成功后,postprocess 才更新 cached 数量。
为什么实现 __getstate__ / __setstate__
多 GPU worker 之间需要传递 Sequence 的必要状态。Prefill 时需要完整 token 列表;Decode 时通常只需要最后一个 token 和缓存元数据。自定义序列化能减少进程通信数据量。
block table 是逻辑地址表
Sequence.block_table 保存该请求使用的物理 KV block id。token 的逻辑位置通过:
text
logical_block = token_position // block_size
physical_block = block_table[logical_block]
slot = physical_block * block_size + offset映射到 KV Cache 的具体槽位。下一章 Scheduler 和后续 BlockManager 都依赖这张表。
HTML INTERACTIVE LAB03 · Sequence:请求的状态机
单独打开 ↗课后习题等待完成
`num_scheduled_tokens` 与 `num_cached_tokens` 的正确关系是什么?
动手任务
为一个 10-token prompt、block_size=4 的请求画出逻辑 block 0、1、2,并假设 block_table=[7,2,9],计算 token 位置 6 对应的物理 slot。
下一节:Scheduler