Radix Tree
逻辑索引 — key: token 序列, value: 每 token 对应一个 KV Pool slot
[1, 2, 3]
↓  ↓  ↓
value = [a, b, c]
├── [4, 5]
│     ↓  ↓
│    v = [d, e]
└── [6, 7]
      ↓  ↓
     v = [f, g]
1. match_prefix
──────▶
复制 slot 索引
到 ReqToTokenPool
的前缀部分
3. cache_finished_req
◀──────
完整 slot 索引
插入回 Radix Tree
供后续请求共享
ReqToTokenPool
请求视图 — 按请求组织,逐一展开
req[0] = [a, b, c, 0, 0]
token [1]→a, [2]→b, [3]→c (全部命中缓存)
req[1] = [a, b, c, d, e]
token [1]→a, [2]→b, [3]→c, [4]→d, [5]→e (前 3 个共享)

2. forward
attention kernel
按 ReqToTokenPool 索引
读写 KV Pool
KV Pool — GPU HBM (物理存储:只有一份)
shape: [num_slots, head_num, head_dim] × layer_num — 每个 slot 存一个 token 在所有 layer 和 head 上的 K/V
Slot 存储内容 被谁引用
0 padding — dummy write 占位
a K/V of token [1] (序列 [1,2,3] 第 1 个) ← [1,2,3].value[0], req[0][0], req[1][0]
b K/V of token [2] (序列 [1,2,3] 第 2 个) ← [1,2,3].value[1], req[0][1], req[1][1]
c K/V of token [3] (序列 [1,2,3] 第 3 个) ← [1,2,3].value[2], req[0][2], req[1][2]
d K/V of token [4] (序列 [4,5] 第 1 个) ← [4,5].value[0], req[1][3]
e K/V of token [5] (序列 [4,5] 第 2 个) ← [4,5].value[1], req[1][4]
f K/V of token [6] (序列 [6,7] 第 1 个) ← [6,7].value[0] (暂无请求匹配)
g K/V of token [7] (序列 [6,7] 第 2 个) ← [6,7].value[1] (暂无请求匹配)
暖金 = 共享前缀 (多个请求/节点引用同一 slot)
绿色 = req 独占 (只有该请求新增的部分)
灰色 = 未被活跃请求引用,可被逐出