Chunked Prefill 过程
stateDiagram-v2
[*] --> 到达 : Request 到达
到达 --> 匹配 : init_next_round_input()
匹配 --> 一次完成 : extend_input_len ≤ chunk_size
匹配 --> 截断 : extend_input_len > chunk_size, is_chunked += 1
截断 --> Prefill_chunk : EXTEND forward
Prefill_chunk --> Stash : 写回 radix tree
Stash --> 匹配 : is_chunked > 0 (续 chunk)
一次完成 --> [*] : 进入 decode
Stash --> 一次完成 : is_chunked == 0
长 prompt 超过 chunked_prefill_size 时被截断。每个 chunk 的中间结果 stash 回 radix tree,下一 chunk 可命中为前缀缓存。
chunked 状态下请求不输出 token,只有最后一个 chunk 完成后才进入 decode。
注意:续 chunk 时,请求作为 self.chunked_req 保留在调度器中(不进入 waiting_queue),通过 add_chunked_req() 直接加入下一轮 prefill batch 的 can_run_list。这确保了 chunk 之间不穿插 decode。
Request 生命周期
stateDiagram-v2
[*] --> waiting_queue : Tokenizer 发来请求
note right of waiting_queue : #queue-req 统计这里
waiting_queue --> Prefill_Batch : PrefillAdder 选中 (admit)
note right of Prefill_Batch : #running-req 统计这里
Prefill_Batch --> waiting_queue : is_chunked > 0 (下一个 chunk)
Prefill_Batch --> Decode_Batch : is_chunked == 0 (prefill 完成)
note right of Decode_Batch : #running-req 统计这里
Decode_Batch --> Decode_Batch : 未完 (每步 1 token)
Decode_Batch --> [*] : finished
Decode_Batch --> waiting_queue : retract_decode (L1 满了)
一个 Request 依次穿过 waiting_queue → Prefill Batch(可能多个,chunking) → Decode Batch(持续)。
#queue-req = waiting_queue 中的排队数。#running-req = Prefill/Decode batch 中正在处理的请求数(同名、不同义)。