Prefill:先向上取整,再做一次完整容量检查
🎯 先猜一猜
prompt_len=5、block_size=4,空闲池只有 1 个块。
allocate_for_prefill 应怎样处理?
先补的知识
- physical_kv_cache 已在当前练习的 __init__ 中给出,shape 是 [num_blocks, block_size, head_dim];不要重复实现参考解析里的初始化 TODO。
- req.seq_len 是 prompt token 数,req.block_table 是 List[int],按逻辑顺序记录物理 block_id。
- free_blocks 是可用物理块编号列表;pop(0) 会返回队首编号并从列表移除。
- 最后一块即使只使用一个 token,也必须占用完整物理块,因此需要整数向上取整。
图解原理
把物理块当成固定容量的箱子。Prompt 要一次性装完:先算需要几个箱子,再确认库存足够,最后才逐个拿走。先检查完整容量能避免分到一半才 OOM,留下 block_table 和 free_blocks 不一致的半更新状态。
长度 6、block_size 4
6 // 4 只得到 1,会漏掉尾部两个 token;向上取整得到 2。
块表只记录地址
物理 ID 可以不连续,列表顺序负责表达逻辑顺序。
语法热身:给订单分配固定容量的货箱
item_count = 11
box_capacity = 5
boxes_needed = (item_count + box_capacity - 1) // box_capacity
available = [20, 7, 31, 9]
assigned = []
if len(available) < boxes_needed:
raise RuntimeError('FULL')
for _ in range(boxes_needed):
assigned.append(available.pop(0))从语法例子迁移到当前练习
item_count:对应 req.seq_lenbox_capacity:对应 self.block_sizeboxes_needed:对应 TODO 1 的 needed_blocksavailable:对应 self.free_blocksassigned:对应 req.block_table;异常文本要按 Notebook 写成 OOM
巩固一下
为什么应在 for 循环 pop 之前检查 len(free_blocks)?
学完这一段,试着做
用一个小动作确认自己理解了;最后再进入官方题目。