1. 概述
1.1 简介
本方案面向AISBench建设Prefix Cache场景数据集生成及性能测评能力,覆盖Prefix Cache测试数据构造、真实业务流量模拟、理论命中率规划、推理服务指标采集及测评结果分析等完整流程。
用户可以根据业务请求长度特征、目标Prefix Cache命中率、Prefix组织方式、请求发送顺序及缓存部署形态,生成可控、可复现、可校验的Prefix Cache测试数据集,并通过AISBench执行性能测评,分析Prefix Cache对TTFT、吞吐、时延及KV Cache资源使用率的影响。
方案支持两类测试模式:
-
预热固定比例模式
通过Warmup请求预先建立公共Prefix缓存,正式测试请求按照固定公共Prefix比例复用缓存,适合验证推理框架Prefix Cache基础能力及不同Prefix比例下的性能收益。
-
0warmup逐步填充模式
不设置独立Warmup阶段,所有请求均纳入正式测评。每条请求相互独立,同一Prefix Group内的请求按照输入长度从短到长发送,前序请求逐步建立公共Prefix缓存水位,后续请求根据已建立的缓存水位产生理论命中,适合模拟真实业务中缓存从冷启动逐步增长的过程。
数据内容采用:
组级共享主Prefix+请求级唯一分叉Block+GSM8K多样本拼接Suffix+Block冲突检测。
其中:
- 组级共享主Prefix用于构造预期缓存复用;
- 唯一分叉Block用于保证请求在设计位置停止继续匹配;
- GSM8K多样本拼接Suffix用于增强文本自然性;
- Block冲突检测用于降低非公共区域偶然重复造成的额外缓存命中。
数据集生成完成后,AISBench输出数据Manifest和理论命中率校验报告,说明数据集是否达到目标理论命中率、偏差大小、最大可达命中率及偏差原因。
推理服务运行完成后,AISBench进一步采集服务端Prefix Cache指标,将目标命中率、数据集理论命中率和服务端实际命中率进行对比,区分数据构造偏差和服务端运行偏差。
1.2 动机
随着大模型上下文长度持续增长,以及RAG、长文档理解、代码生成和复杂Agent等应用的发展,Prefill阶段重复计算带来的时延和算力开销不断增加。
Prefix Cache通过复用请求之间相同Prefix对应的KV Cache,能够减少重复Prefill计算,降低TTFT并提升系统吞吐,是当前大模型推理系统的重要性能优化手段。
当前AISBench主要提供通用性能测评能力,在Prefix Cache专项测评方面存在以下不足:
- 主要支持固定输入长度,无法模拟真实业务中的变长请求及长尾分布;
- 缺少根据目标命中率自动规划Prefix长度的数据生成能力;
- 缺少统一的单Prefix、多Prefix和多租户流量建模;
- 缺少0warmup场景下缓存逐步建立过程的模拟能力;
- 静态公共Prefix比例无法准确表示考虑请求顺序后的理论命中率;
- 缺少多Prefix Group独立缓存水位和冷启动损失计算;
- 缺少自然文本Suffix及非预期Block重复检测;
- 缺少数据集生成结果的理论命中率校验;
- 缺少服务端Prefix Cache指标采集及多实例、DP域聚合;
- 缺少目标值、理论值和实际值之间的偏差分析。
vLLM相关Benchmark能够验证固定Prefix和多Prefix场景的基础性能,现有测试小工具能够基于GSM8K进行部分Prefix数据构造,但二者均缺少真实变长流量、顺序感知理论模型、可达性分析和理论与实际结果关联能力。
因此,需要在AISBench中建设完整的Prefix Cache场景数据集生成及性能测评能力,使AISBench不仅能够“运行Prefix Cache测试”,还能够解释:
- 数据集为什么能够达到目标命中率;
- 如果没有达到,理论偏差是多少;
- 服务端实际命中率为什么与理论值存在差异;
- 不同Prefix Group、实例和DP域分别表现如何。
1.3 目标
本方案目标包括:
- 支持固定长度、显式长度、截断正态分布、自定义区间分布及经验分布请求生成;
- 支持构造目标命中率为50%、60%、90%等不同场景的数据集;
- 支持单Prefix和多Prefix Group数据构造;
- 支持预热固定比例和0warmup逐步填充两类测试模式;
- 支持组内顺序、shuffle、interleave、weighted interleave等发送策略;
- 支持使用随机Token、GSM8K随机样本、指定样本及多样本拼接生成数据;
- 支持唯一分叉Block和
minimum_non_shared_length约束;
- 支持组内Suffix冲突和跨组主Prefix冲突检测;
- 支持顺序感知理论命中率计算;
- 支持多Prefix Group独立缓存水位和冷启动损失计算;
- 支持目标理论命中率可达性分析;
- 支持Block对齐和理论命中率残差校准;
- 支持输出数据Manifest和理论命中率校验报告;
- 支持采集Prefix Cache Query、Hit、Hit Rate及KV Cache使用率;
- 支持实例级、DP域级和全局指标统计;
- 支持分析目标命中率、理论命中率和实际命中率之间的偏差;
- 保证相同配置、Tokenizer和随机种子下数据生成结果可复现;
- 普通数据集构造场景下,目标命中率与数据集理论命中率偏差默认控制在1个百分点以内;
- 单实例、固定Prefix等受控场景下,理论命中率与服务端实测命中率偏差建议控制在5个百分点以内;
- 多Prefix、多实例和真实业务流量场景下,允许更高运行偏差,但必须输出明确的偏差分析。
2. 用例分析
2.1 固定长度单Prefix场景
用户配置固定输入长度和固定公共Prefix比例。
例如:
request_count: 1000
input_length: 4096
target_prefix_ratio: 0.5
prefix_mode: single_prefix
每条请求包含:
2048 Token共享Prefix
+
唯一分叉Block
+
剩余自然Suffix
该场景适合:
- 验证Prefix Cache是否生效;
- 对齐vLLM固定Prefix Benchmark;
- 对比0%、50%、60%、90%Prefix比例下的TTFT和吞吐;
- 验证不同推理框架的基础缓存收益。
2.2 固定长度多Prefix场景
用户配置多个Prefix Group,每个组拥有独立的主Prefix。
例如:
Group A:500条请求
Group B:300条请求
Group C:200条请求
支持:
- 分组连续发送;
- 组间轮转;
- 按权重交错;
- 全局shuffle。
该场景用于模拟多个租户、多个系统Prompt或多个业务模板共享同一推理服务。
2.3 变长请求场景
用户根据真实业务请求长度特征配置变长请求。
支持以下方式:
- 固定长度;
- 显式长度列表;
- 截断正态分布;
- 自定义区间分布;
- 真实长度样本抽样。
截断正态分布示例:
input_length:
mode: truncated_normal
min: 1024
max: 8192
mean: 4096
std: 1024
含义是:
- 请求长度集中在4096 Token附近;
- 长度波动受标准差控制;
- 所有请求必须落在1024~8192 Token范围内;
- 超出范围的样本重新采样或按配置处理。
区间分布示例:
input_length:
mode: histogram
bins:
- range: [0, 1000]
weight: 2
- range: [1000, 2000]
weight: 3
- range: [2000, 4000]
weight: 10
- range: [4000, 8000]
weight: 5
截断正态分布适合缺少真实业务数据时进行统计模拟;区间分布适合根据真实业务统计还原请求长度特征。
2.4 0warmup独立请求逐步填充场景
该场景中每条请求相互独立,不属于多轮对话,也不继承上一条请求的完整内容。
同一Prefix Group内的请求共享一条嵌套主Prefix,并按输入长度从短到长发送。
例如:
Request 1:1000 Token
Request 2:2000 Token
Request 3:3000 Token
Request 4:4000 Token
发送顺序:
Request 1→Request 2→Request 3→Request 4
每条请求结构:
MasterPrefix[0:planned_prefix_len]
+
UniqueDivergenceBlock
+
GSM8KSuffix
第一条请求发送前没有缓存,理论命中长度为0。
后续请求能够命中的长度,由该Prefix Group此前已建立的最长公共Prefix缓存水位决定。
该场景下,目标50%不能解释为每条请求都命中50%,而应解释为:
所有请求理论命中Token总数
÷
所有请求输入Token总数
=
50%
2.5 多Prefix 0warmup场景
多Prefix场景下,每个Prefix Group独立维护缓存水位。
例如:
Group A:A1→A2→A3
Group B:B1→B2→B3
Group C:C1→C2→C3
每个Group第一条请求均为冷启动请求,理论命中长度为0。
组间可以交错:
但必须保持每个组内部的顺序约束。
全局理论命中率必须按照Token总量加权计算,不能简单平均各组命中率。
2.6 真实文本数据场景
用户可以选择:
- 随机Token;
- 随机GSM8K样本;
- 指定GSM8K样本;
- 多条指定样本;
- 多样本确定性拼接;
- 用户自定义文本。
GSM8K数据既可以用于生成组级主Prefix,也可以用于生成自然Suffix。
当单条样本长度不足时,默认继续拼接其他样本,不建议无限重复同一条样本。
2.7 多实例和多DP场景
如果Prefix Cache为实例或DP本地缓存,则同一Prefix Group的请求进入不同实例或DP时,可能无法复用此前缓存。
支持两种缓存模型:
- 全局共享缓存:
- DP本地缓存:
watermark[dp_id][group_id]
需要支持:
- Prefix Group绑定实例或DP;
- Sticky Routing;
- 记录计划路由和实际路由;
- 分别统计实例、DP及全局命中率。
2.8 理论值与实测值对比场景
数据集生成后输出:
- 目标理论命中率;
- 数据集理论命中率;
- 数据构造偏差;
- 最大可达理论命中率;
- 校验状态。
服务端运行后输出:
- 服务端实际命中率;
- 理论与实际偏差;
- 性能指标变化;
- 多Prefix、实例和DP维度分析。
3. 方案设计
3.1 总体方案
总体架构分为六层。
3.1.1 场景配置层
负责接收用户配置,包括:
- 请求数量;
- 输入长度分布;
- 目标命中率;
- Prefix模式;
- Prefix Group数量及权重;
- Warmup模式;
- 请求顺序;
- 数据来源;
- Block Size;
- 最小非共享长度;
- 冲突检测策略;
- 指标采集地址。
3.1.2 Workload规划层
负责:
- 生成请求长度序列;
- 分配Prefix Group;
- 规划请求顺序;
- 计算目标命中Token预算;
- 规划Prefix长度;
- 执行可达性检查;
- 执行Block残差校准。
3.1.3 数据内容生成层
负责:
- 生成组级主Prefix;
- 生成请求级唯一分叉Block;
- 拼接GSM8K自然Suffix;
- 执行Token级截断和补齐;
- 执行Block冲突检测;
- 输出最终Prompt。
3.1.4 理论仿真与校验层
负责:
- 模拟单Prefix或多Prefix缓存水位;
- 计算请求级理论命中长度;
- 计算组级和全局理论命中率;
- 判断目标是否可达;
- 计算理论偏差;
- 输出校验报告。
3.1.5 测评执行与指标采集层
负责:
- 按最终顺序发送请求;
- 执行Cold、Warmup、Hot、Compare或Progressive Prefix Fill;
- 采集性能指标;
- 采集Prefix Cache服务端指标;
- 采集实例和DP维度指标。
3.1.6 结果分析层
负责:
- 关联数据Manifest和运行结果;
- 对比目标值、理论值和实际值;
- 计算数据构造偏差和运行实现偏差;
- 输出专项测评报告。
总体流程:
用户配置
↓
请求长度生成
↓
Prefix Group分配
↓
请求顺序规划
↓
目标可达性检查
↓
Prefix长度及缓存水位规划
↓
主Prefix/分叉Block/Suffix生成
↓
Block冲突检测
↓
数据Manifest和理论报告
↓
AISBench执行测评
↓
服务端Cache指标采集
↓
理论与实际偏差分析
↓
专项测评报告
3.2 技术选型
3.2.1 Token级数据生成
所有长度计算和数据截断均基于模型Tokenizer完成,不使用字符数估算。
原因包括:
- 不同Tokenizer下字符和Token映射不同;
- Prefix Cache按照Token及Block处理;
- 理论命中率需要与服务端Token统计口径一致。
生成流程:
原始文本
→Tokenizer Encode
→Token ID拼接
→Token级截断/补齐
→生成Prompt
→必要时重新Encode校验
3.2.2 长度分布模型
支持:
| 模式 |
用途 |
fixed |
固定长度基准测试 |
explicit |
用户指定每条请求长度 |
truncated_normal |
模拟均值集中、两侧减少的真实业务分布 |
histogram |
根据区间权重还原业务统计 |
empirical |
从真实业务长度样本抽样 |
截断正态分布优先采用拒绝采样,避免简单裁剪造成最小值和最大值处样本集中。
3.2.3 缓存粒度模型
数据规划需要基于服务端KV Cache Block Size。
优先级:
- 从服务端配置自动获取;
- 从服务启动参数获取;
- 用户显式配置;
- 使用框架默认值并输出告警。
所有规划Prefix长度原则上需要按照Block Size向下对齐:
aligned_prefix_len
=
floor(raw_prefix_len/block_size)×block_size
3.2.4 随机性与可复现
使用局部随机生成器。
随机种子由以下信息组合:
global_seed
+dataset_id
+target_ratio
+prefix_group_id
+request_id
+retry_count
相同配置、Tokenizer、数据源版本和随机种子应生成相同数据。
3.2.5 数据存储格式
建议输出:
dataset/
├──data.jsonl
├──manifest.json
├──request_metadata.jsonl
└──validation_report.json
其中:
data.jsonl:实际发送给模型的数据;
manifest.json:数据集配置及整体元数据;
request_metadata.jsonl:请求级Prefix、水位和理论命中信息;
validation_report.json:目标可达性和理论命中率校验结果。
3.2.6 指标采集方式
通过推理服务提供的/metrics或等价接口采集Prefix Cache指标。
对于累计Counter指标,采用运行前后快照差值:
metric_delta
=
metric_after-metric_before
多实例和多DP全局结果采用Counter增量加权,不直接平均命中率。
3.3 功能与性能设计
3.3.1 请求长度生成
支持固定、显式、截断正态、区间及经验分布。
生成后输出:
- 请求数量;
- 最小长度;
- 最大长度;
- 平均长度;
- P50、P90、P95、P99;
- 各长度区间请求数;
- 随机种子。
所有请求长度需要满足模型最大上下文约束:
input_len+output_len≤max_model_len
3.3.2 Prefix Group分配
支持:
- 单Prefix;
- 多Prefix平均分配;
- 按请求数量分配;
- 按请求权重分配;
- 用户显式指定请求所属Group。
每条请求必须具有唯一的prefix_group_id。
多Prefix Group之间的主Prefix相互独立,同一Group内请求从同一条主Prefix头部截取。
3.3.3 预热固定比例模式
对每条请求:
raw_prefix_len_i
=
input_len_i×target_prefix_ratio
执行Block对齐:
prefix_len_i
=
align_down(raw_prefix_len_i,block_size)
公共Prefix预先通过Warmup请求写入缓存。
正式请求的理论命中长度为规划公共Prefix长度。
该模式主要用于:
- 对齐vLLM固定Prefix测试;
- 验证框架Cache能力;
- 分析不同Prefix比例性能收益。
3.3.4 0warmup顺序感知模式
对第i条请求定义:
L_i:输入Token长度;
P_i:规划共享Prefix长度;
C_i:发送前所属Group缓存水位;
H_i:理论命中Token长度。
计算:
请求完成后:
若同组请求Prefix长度单调递增:
则:
H_1=0
H_2=P_1
H_3=P_2
...
H_n=P_(n-1)
全局理论命中率为:
order_aware_hit_ratio
=
sum(H_i)/sum(L_i)
用户配置的50%、60%、90%约束该指标,而不是单条请求的静态Prefix比例。
3.3.5 目标命中率反向规划
用户配置:
目标命中Token总量:
target_hit_tokens
=
T×sum(L_i)
系统需要规划每条请求的P_i,使:
sum(H_i)≈target_hit_tokens
规划过程:
- 根据请求长度和目标比例初始化基础规划比例;
- 对Prefix长度执行Block对齐;
- 按最终请求顺序仿真缓存水位;
- 计算当前理论命中率;
- 使用二分搜索调整基础规划比例;
- 使用Block级残差校准微调部分请求;
- 达到允许偏差或迭代上限。
3.3.6 目标可达性分析
每条请求需要保留最小非共享区域:
max_prefix_i
=
align_down(
input_len_i-minimum_non_shared_length,
block_size
)
将所有请求Prefix设置为最大允许值,并按最终请求顺序进行缓存水位仿真,得到最大可达理论命中率:
若:
target_hit_ratio>max_reachable_hit_ratio
则目标不可达。
系统需要输出:
- 目标命中率;
- 最大可达命中率;
- 不可达原因;
- 调整建议。
可调整方式包括:
- 增加请求数量;
- 减少Prefix Group数量;
- 增加每组请求数;
- 缩小最大请求与其他请求之间的长度差;
- 减少最小非共享区域;
- 改为预热模式。
3.3.7 多Prefix独立缓存水位
每个Prefix Group独立维护:
初始化:
请求理论命中:
hit_len_i
=
min(
planned_prefix_len_i,
watermark[group_id]
)
请求完成后:
watermark[group_id]
=
max(
watermark[group_id],
planned_prefix_len_i
)
不同Group水位互不影响。
每个Group第一条请求理论命中长度均为0。
如果每个Group只有一条请求,则全局理论命中率为0。
3.3.8 多Prefix全局目标分配
支持两种目标范围。
全局统一目标
只要求所有Group按Token加权后的全局理论命中率达到目标。
target:
scope: global
hit_ratio: 0.50
各组可以拥有不同理论命中率。
组级独立目标
为每个Group分别配置目标。
target:
scope: per_group
groups:
- id: group_a
hit_ratio: 0.50
- id: group_b
hit_ratio: 0.60
全局目标模式下,初始组级命中Token预算按输入Token权重分配:
target_hit_tokens_g
=
target_global_hit_tokens
×
group_input_tokens
/
global_input_tokens
然后根据各组冷启动损失和最大可达能力重新调整预算。
3.3.9 请求发送策略
支持:
| 策略 |
含义 |
sequential |
按数据生成顺序发送 |
shuffle |
全局随机打乱 |
grouped |
同组请求连续发送 |
interleave |
多组轮转交错 |
weighted_interleave |
按Group流量权重交错 |
input_len_asc |
按输入长度升序 |
input_len_desc |
按输入长度降序 |
prefix_len_asc |
按Prefix长度升序 |
prefix_len_desc |
按Prefix长度降序 |
0warmup模式下,组内顺序属于理论命中率的一部分。
数据生成完成后,如果重新排序或shuffle,原理论校验结果失效,必须重新执行仿真和校验。
3.3.10 组间发送与理论命中率
在以下理想条件下:
- 每个Group缓存独立;
- 缓存容量充足;
- 不发生淘汰;
- Group内顺序保持不变;
- 请求进入相同可见缓存域;
组间如何交错理论上不会改变总命中Token数。
但实际运行中,组间交错可能引入:
- Cache容量竞争;
- LRU淘汰;
- 多实例路由;
- 多DP路由;
- 请求处理时序变化。
因此,组间发送策略必须记录在Manifest中,并在运行报告中分析其对实际命中率的影响。
3.3.11 唯一分叉Block
每条请求在公共Prefix后插入请求级唯一分叉Block。
结构:
SharedPrefix
+
DivergenceBlock
+
NaturalSuffix
唯一分叉Block用于保证请求在规划位置立即发生差异。
生成种子包含:
prefix_group_id
+request_id
+global_seed
需要排除:
- BOS;
- EOS;
- PAD;
- Chat Template控制Token;
- 其他特殊Token。
同一Prefix Group内首个非公共Block必须唯一。
3.3.12 minimum_non_shared_length
minimum_non_shared_length表示:
每条请求在公共Prefix后必须保留的最小非共享Token长度。
主要作用:
- 保证公共Prefix后存在足够的差异区域;
- 限制单条请求最大可规划Prefix长度;
- 为唯一分叉Block和自然Suffix预留空间;
- 降低Suffix继续匹配造成额外缓存命中的风险。
约束:
planned_prefix_len_i
≤
input_len_i-minimum_non_shared_length
推荐默认:
minimum_non_shared_length=block_size
例如Block Size为16,则每条请求至少保留16 Token非共享区域。
需要说明:对于采用父链Hash的标准Prefix Cache,真正决定命中停止的是第一个不同Block及其父链上下文。因此,minimum_non_shared_length的主要价值是保证存在完整的非共享Block,而不是要求整个Suffix全部唯一。
3.3.13 GSM8K多样本拼接Suffix
自然Suffix生成流程:
选择GSM8K样本
→Tokenizer Encode
→插入样本分隔符
→继续选择其他样本
→达到目标长度
→Token级截断
支持:
- 确定性随机选择;
- 指定样本;
- 指定样本后拼接其他样本;
- 多指定样本循环;
- 自定义分隔符。
默认不建议重复同一条GSM8K样本补齐长Suffix,避免形成周期性重复。
3.3.14 Block冲突检测
Block冲突检测分为两类。
组内非共享区域检测
检查:
- 首个非共享Block是否唯一;
- 连续Block窗口是否重复;
- Suffix是否高度重复。
跨组主Prefix检测
检查不同Prefix Group主Prefix是否存在非预期长公共Prefix。
对于采用父链Hash的Prefix Cache:
- 首个非共享Block及父链不同后,后续相同原始Block通常不会形成Prefix Cache命中;
- 因此首个非共享Block唯一是强制约束;
- 后续Block窗口重复可作为风险诊断,不一定需要强制拒绝。
建议支持缓存匹配语义配置:
cache_match_semantics: chained_prefix
可选:
chained_prefix;
independent_block;
content_defined_chunk。
不同模式采用不同冲突检测强度。
3.3.15 冲突处理策略
按以下顺序处理:
- 重新生成唯一分叉Block;
- 更换GSM8K样本序列;
- 在样本边界加入自然请求标识;
- 达到最大重试次数后按配置处理。
支持:
error;
warn;
accept_with_warning。
冲突检测结果写入数据Manifest和请求级元数据。
3.3.16 数据Manifest
数据Manifest是数据集的元数据说明书,不是实际Prompt数据。
Manifest记录:
- 数据集ID;
- 生成器版本;
- Tokenizer;
- Block Size;
- 随机种子;
- 请求数量;
- 长度分布;
- Prefix模式;
- Prefix Group;
- 目标命中率;
- 请求发送顺序;
- Suffix数据来源;
- 最小非共享长度;
- 理论命中率;
- 最大可达命中率;
- 校验状态。
请求级元数据记录:
request_id;
prefix_group_id;
order_index;
input_len;
planned_prefix_len;
cached_watermark_before;
expected_hit_len;
expected_hit_ratio;
cached_watermark_after;
divergence_len;
suffix_len;
- 冲突检测状态。
Manifest用于:
- 数据复现;
- 理论命中率校验;
- 执行结果关联;
- 多Prefix分析;
- 问题定位。
3.3.17 理论命中率校验报告
数据集生成完成后必须输出理论校验报告。
核心指标:
designed_hit_ratio
=
sum(expected_hit_tokens)
/
sum(input_tokens)
signed_deviation
=
designed_hit_ratio-target_hit_ratio
absolute_deviation
=
abs(signed_deviation)
建议优先使用“百分点”表达偏差。
例如:
目标理论命中率:50.00%
数据集理论命中率:49.80%
有符号偏差:-0.20个百分点
绝对偏差:0.20个百分点
校验状态:
| 状态 |
默认条件 |
PASS |
偏差≤1个百分点 |
PASS_WITH_WARNING |
1~2个百分点 |
FAIL |
偏差>2个百分点或目标不可达 |
对于请求数量较多、长度较长的数据集,建议将构造偏差控制在0.5个百分点以内。
3.3.18 服务端指标采集
采集指标包括:
- Prefix Cache Query;
- Prefix Cache Hit;
- Prefix Cache Hit Rate;
- KV Cache Usage;
- Cache Eviction;
- 本地Cache命中;
- 外置KV Cache命中;
- 实例级Cache指标;
- DP域级Cache指标。
累计Counter采用前后差值。
例如:
queries_delta
=
queries_after-queries_before
hits_delta
=
hits_after-hits_before
actual_hit_rate
=
hits_delta/queries_delta
3.3.19 多实例和DP聚合
每个实例或DP独立计算:
dp_hit_rate
=
dp_hits_delta/dp_queries_delta
全局结果:
global_hit_rate
=
sum(dp_hits_delta)
/
sum(dp_queries_delta)
禁止直接对各DP命中率做算术平均。
若缓存为DP本地缓存,理论仿真需要维护:
watermark[dp_id][group_id]
若缓存为全局共享缓存,则维护:
3.3.20 性能指标
Prefix Cache性能测评需要至少输出:
- TTFT平均值;
- TTFT P50/P90/P95/P99;
- TPOT;
- E2E Latency;
- Request Throughput;
- Output Token Throughput;
- QPS;
- 请求成功率;
- 超时率;
- KV Cache使用率;
- Prefix Cache命中率。
支持对比:
- Cold vs Hot;
- 不同目标命中率;
- 单Prefix vs多Prefix;
- 不同发送顺序;
- 0warmup vs Warmup;
- 不同推理框架;
- 不同部署配置。
3.3.21 理论值与实测值偏差
需要区分两类偏差。
数据构造偏差
construction_deviation
=
designed_hit_ratio-target_hit_ratio
用于评价数据集生成准确性。
建议普通场景控制在1个百分点以内。
运行实现偏差
runtime_deviation
=
actual_hit_rate-designed_hit_ratio
用于评价服务端运行与理论模型的一致性。
参考范围:
| 场景 |
理论值与实测值建议偏差 |
| 固定长度、单Prefix、单实例 |
≤5个百分点 |
| 固定长度、多Prefix |
2~5个百分点 |
| 变长、短到长、0warmup |
3~5个百分点 |
| 多Prefix、多实例或多DP |
5~10个百分点 |
| 真实业务流量及容量压力 |
允许超过10个百分点,但需明确归因 |
以上范围为工程建议,不应直接作为所有推理框架的统一强约束。最终验收阈值需结合服务端指标语义和实际测试结果确定。
3.3.22 偏差归因
理论值与实际值不一致时,分析以下因素:
- Block Size配置不一致;
- 指标统计单位不同;
- 请求实际处理顺序与提交顺序不同;
- Prefix Group请求进入不同实例或DP;
- Cache容量不足或发生淘汰;
- 服务端存在历史缓存残留;
- Suffix发生非预期重复;
- 外置KV Cache与本地Cache统计重叠;
- Chat Template或特殊Token导致实际Token序列变化;
- 服务端只缓存完整Block;
- Counter采集区间不准确;
- 请求失败或超时未计入预期统计。
3.3.23 性能要求
数据生成性能建议满足:
- 支持至少10万条请求的流式生成;
- 大规模数据生成不要求将所有Prompt同时保存在内存;
- Block Hash采用增量注册;
- 支持分组并行Tokenize;
- 同一随机种子下生成结果稳定;
- 数据生成失败时能够保留错误上下文和部分Manifest;
- 理论仿真时间应明显低于实际测评时间;
- 指标采集不得显著影响请求发送性能。
3.4 安全隐私与DFX设计
3.4.1 数据安全
默认使用公开数据集,不包含用户私有业务数据。
用户导入自定义数据时支持:
- 原始文本不打印到普通日志;
- Manifest默认只记录样本ID和Hash;
- 可配置是否保存完整Prompt;
- 文件路径脱敏;
- 认证信息和服务地址脱敏;
- 报告中不展示敏感Header。
3.4.2 可复现性
保存以下信息:
- AISBench版本;
- 数据生成器版本;
- 配置文件;
- Tokenizer名称和版本;
- 数据集版本;
- Block Size;
- Random Seed;
- Prefix Group配置;
- 请求顺序;
- 路由策略;
- 冲突重试次数;
- 理论仿真结果。
3.4.3 可诊断性
日志分为:
- 配置校验日志;
- 长度生成日志;
- Prefix规划日志;
- 冲突检测日志;
- 理论仿真日志;
- 指标采集日志;
- 报告生成日志。
错误需要包含:
- 错误阶段;
- 数据集ID;
- Request ID;
- Prefix Group;
- 当前重试次数;
- 相关配置字段;
- 建议处理方式。
3.4.4 容错设计
需要处理:
- 长度范围非法;
- 平均值不在截断区间内;
- 请求数量为0;
- 目标命中率不在0~1;
- 目标命中率不可达;
- Prefix长度超过请求长度;
- 非共享长度不足;
- Tokenizer加载失败;
- GSM8K数据不足;
- Block冲突重试超限;
- Metrics地址不可访问;
- Counter重置;
- 服务实例重启;
- 部分请求失败;
- 多实例指标缺失。
3.4.5 兼容性
方案需要考虑:
- vLLM;
- vLLM-Ascend;
- MindIE;
- SGLang;
- OpenAI兼容推理服务;
- 外置KV Cache系统。
不同框架使用统一逻辑指标模型,通过Adapter映射框架原始指标。
3.4.6 可扩展性
后续可扩展:
- RAG Prefix Cache;
- 多级KV Cache;
- KV Cache Offload;
- PD分离Cache;
- Cache淘汰专项测试;
- Cache容量压力测试;
- Agent历史轨迹Cache;
- Code Repository Prefix;
- 用户真实流量回放。
3.5 编程与调用设计
3.5.1 编程模型基本设计
核心对象如下。
PrefixCacheDatasetConfig
描述完整数据生成配置。
字段包括:
dataset_id;
seed;
request_count;
block_size;
input_length;
target;
prefix;
suffix;
request_order;
execution;
routing;
validation。
RequestPlan
描述单条请求规划结果。
字段包括:
request_id;
prefix_group_id;
input_len;
planned_prefix_len;
divergence_len;
suffix_len;
order_index;
planned_dp_id。
PrefixGroupPlan
描述单个Prefix Group。
字段包括:
group_id;
request_count;
master_prefix_len;
target_hit_tokens;
max_reachable_hit_ratio;
cold_start_loss。
DatasetManifest
描述数据集整体元数据。
ValidationReport
描述目标可达性及理论校验结果。
RuntimeMetrics
描述服务端实际性能和Cache指标。
整体编程流程:
config = PrefixCacheDatasetConfig.load(config_path)
lengths = LengthGenerator.generate(
config.input_length,
config.request_count,
config.seed,
)
requests = RequestPlanner.create(lengths)
groups = PrefixGroupAllocator.allocate(
requests,
config.prefix,
)
RequestOrderPlanner.sort_within_groups(
groups,
config.request_order,
)
reachability = ReachabilityValidator.validate(
groups,
config,
)
PrefixPlanner.plan(
groups,
config.target,
config.block_size,
config.prefix.minimum_non_shared_length,
)
MasterPrefixGenerator.generate(groups, config)
RequestContentGenerator.generate(
groups,
config.suffix,
)
CollisionValidator.validate_and_repair(
groups,
config.suffix.collision_detection,
)
ordered_requests = RequestOrderPlanner.merge_groups(
groups,
config.request_order,
)
simulation = WatermarkSimulator.simulate(
ordered_requests,
config.routing.cache_scope,
)
validation = TheoreticalHitRateValidator.validate(
simulation,
config.target,
config.validation,
)
DatasetWriter.write(
ordered_requests,
groups,
simulation,
validation,
)
runtime_result = PrefixCacheBenchmarkRunner.run(
ordered_requests,
config.execution,
)
report = PrefixCacheReportBuilder.build(
manifest=DatasetManifest.load(),
validation=validation,
runtime_result=runtime_result,
)
3.5.2 接口定义与设计
数据集生成接口
def generate_prefix_cache_dataset(
config: PrefixCacheDatasetConfig,
) -> DatasetGenerationResult:
...
返回:
- 数据文件路径;
- Manifest路径;
- 请求级元数据路径;
- 理论校验报告路径。
长度生成接口
def generate_request_lengths(
config: LengthDistributionConfig,
request_count: int,
seed: int,
) -> list[int]:
...
Prefix Group分配接口
def allocate_prefix_groups(
requests: list[RequestPlan],
config: PrefixGroupConfig,
) -> dict[str, PrefixGroupPlan]:
...
目标可达性接口
def validate_target_reachability(
groups: dict[str, PrefixGroupPlan],
target: TargetHitRateConfig,
block_size: int,
minimum_non_shared_length: int,
) -> ReachabilityResult:
...
Prefix规划接口
def plan_prefix_lengths(
groups: dict[str, PrefixGroupPlan],
target: TargetHitRateConfig,
block_size: int,
minimum_non_shared_length: int,
) -> PrefixPlanningResult:
...
主Prefix生成接口
def generate_master_prefixes(
groups: dict[str, PrefixGroupPlan],
data_source: DataSourceConfig,
tokenizer: TokenizerProtocol,
) -> dict[str, list[int]]:
...
Suffix生成接口
def generate_request_suffix(
request: RequestPlan,
config: SuffixGenerationConfig,
tokenizer: TokenizerProtocol,
) -> SuffixGenerationResult:
...
冲突检测接口
def validate_block_collisions(
request_tokens: list[int],
group_registry: BlockRegistry,
config: CollisionDetectionConfig,
) -> CollisionValidationResult:
...
缓存水位仿真接口
def simulate_prefix_cache_watermarks(
requests: list[RequestPlan],
cache_scope: str,
) -> PrefixCacheSimulationResult:
...
理论命中率校验接口
def validate_theoretical_hit_rate(
simulation: PrefixCacheSimulationResult,
target_hit_ratio: float,
pass_tolerance: float,
warning_tolerance: float,
) -> ValidationReport:
...
指标采集接口
def collect_prefix_cache_metrics(
endpoints: list[str],
before_snapshot: MetricsSnapshot,
after_snapshot: MetricsSnapshot,
) -> PrefixCacheRuntimeMetrics:
...
报告生成接口
def build_prefix_cache_report(
manifest: DatasetManifest,
validation: ValidationReport,
runtime_metrics: PrefixCacheRuntimeMetrics,
performance_result: PerformanceResult,
) -> PrefixCacheReport:
...
3.5.3 编程手册设计
配置示例:固定长度单Prefix
prefix_cache_dataset:
dataset_id: fixed_single_prefix_50
seed: 42
request_count: 1000
block_size: 16
input_length:
mode: fixed
value: 4096
target:
scope: global
hit_ratio: 0.50
semantics: static_prefix_ratio
prefix:
mode: single_prefix
minimum_non_shared_length: 16
suffix:
source: gsm8k
mode: concat
divergence_block: true
request_order:
mode: sequential
execution:
mode: compare
warmup_rounds: 1
validation:
pass_tolerance: 0.01
warning_tolerance: 0.02
配置示例:0warmup变长单Prefix
prefix_cache_dataset:
dataset_id: progressive_single_prefix_50
seed: 42
request_count: 1000
block_size: 16
input_length:
mode: truncated_normal
min: 1024
max: 8192
mean: 4096
std: 1024
target:
scope: global
hit_ratio: 0.50
semantics: order_aware_global
prefix:
mode: single_prefix
nested_prefix: true
minimum_non_shared_length: 16
suffix:
source: gsm8k
mode: concat
divergence_block: true
collision_detection:
enabled: true
cache_match_semantics: chained_prefix
first_non_shared_block_unique: true
window_blocks: 2
request_order:
within_group: input_len_asc
execution:
mode: progressive_prefix_fill
warmup_rounds: 0
planning:
reachability_check: true
base_ratio_search: binary_search
block_residual_calibration: true
max_iterations: 1000
validation:
pass_tolerance: 0.01
warning_tolerance: 0.02
on_failure: error
配置示例:0warmup多Prefix
prefix_cache_dataset:
dataset_id: progressive_multi_prefix_50
seed: 42
request_count: 1000
block_size: 16
input_length:
mode: histogram
bins:
- range: [1024, 2048]
weight: 3
- range: [2048, 4096]
weight: 5
- range: [4096, 8192]
weight: 2
target:
scope: global
hit_ratio: 0.50
semantics: order_aware_global
prefix:
mode: multi_prefix
nested_prefix: true
minimum_non_shared_length: 16
groups:
- id: customer_a
request_weight: 0.50
- id: customer_b
request_weight: 0.30
- id: customer_c
request_weight: 0.20
request_order:
within_group: input_len_asc
across_group: weighted_interleave
preserve_group_dependency: true
execution:
mode: progressive_prefix_fill
warmup_rounds: 0
routing:
cache_scope: dp_local
sticky_routing: true
bind_prefix_group_to_dp: true
validation:
pass_tolerance: 0.01
warning_tolerance: 0.02
命令行示例
ais_bench prefix-cache generate \
--config prefix_cache.yaml \
--output ./prefix_cache_dataset
ais_bench prefix-cache validate \
--dataset ./prefix_cache_dataset
ais_bench prefix-cache run \
--dataset ./prefix_cache_dataset \
--url http://127.0.0.1:8000/v1/completions \
--metrics-url http://127.0.0.1:8000/metrics
ais_bench prefix-cache report \
--run-dir ./outputs/run_001
输出目录示例
outputs/run_001/
├──dataset/
│ ├──data.jsonl
│ ├──manifest.json
│ ├──request_metadata.jsonl
│ └──validation_report.json
├──runtime/
│ ├──request_results.jsonl
│ ├──performance_metrics.json
│ └──prefix_cache_metrics.json
└──report/
├──prefix_cache_report.json
└──prefix_cache_report.html
4. 缺点和风险
4.1 理论模型依赖服务端缓存语义
不同推理框架可能采用父链Hash、独立Block Hash或内容定义分块。
如果AISBench理论模型与服务端实际缓存匹配语义不一致,理论命中率可能产生系统性偏差。
4.2 Block Size获取不准确
若配置的Block Size与服务端不一致,会影响:
- Prefix对齐;
- 最大可达命中率;
- 唯一分叉Block;
- 理论命中率;
- 冲突检测。
4.3 提交顺序与实际处理顺序不一致
并发场景下,服务端可能改变Prefill执行顺序,导致实际缓存水位建立过程与理论提交顺序不一致。
4.4 多实例和多DP路由影响
同一Prefix Group请求被路由到不同实例或DP后,本地缓存可能无法复用。
若没有Sticky Routing,理论值可能明显高于实际值。
4.5 Cache容量和淘汰影响
理论模型默认缓存容量足够且不会淘汰。
多Prefix Group或长上下文场景中可能发生LRU淘汰,使实际命中率下降。
4.6 历史缓存污染
测试前服务端可能已有相同Prefix缓存,导致第一条请求产生非预期命中。
Cold场景需要支持服务重启、缓存清理或使用唯一Salt隔离。
4.7 自然文本无法完全代表真实业务
GSM8K多样本拼接能够提升文本自然性,但与真实RAG文档、代码上下文或业务Prompt仍存在差异。
4.8 高目标命中率可能不可达
以下情况可能导致90%等高命中目标不可达:
- 请求数量过少;
- Prefix Group数量过多;
- 每组请求过少;
- 最大请求占总Token比例过高;
- 最小非共享长度过大。
4.9 理论值与服务端指标口径不同
理论命中率可能按Token计算,服务端指标可能按Block、Query或Cache Entry统计,二者不能直接比较。
需要在Adapter中明确指标单位。
4.10 Block冲突检测存在额外开销
大规模长上下文数据集进行全量Block窗口Hash检测,会增加生成时间和内存消耗。
4.11 组级预算分配不唯一
相同全局目标可以通过多种组级命中率组合实现。
需要保存组级预算分配策略,保证结果可解释和可复现。
4.12 理论与实测误差无法完全消除
即使数据构造完全正确,实际运行仍会受到调度、路由、淘汰、Counter采样和请求失败等因素影响。
因此,运行一致性应采用合理误差阈值和偏差分析,而不是要求理论值与实测值完全相等。
5. 现有技术
5.1 vLLM Prefix Cache Benchmark
vLLM相关Benchmark能够支持:
- 固定Prefix长度;
- 固定输入长度;
- 随机Token生成;
- 多Prefix数量配置;
- 请求shuffle;
- 基础性能测评。
主要不足:
- 缺少真实变长分布;
- 缺少目标命中率自动构造;
- 缺少顺序感知理论模型;
- 缺少多Prefix独立缓存水位;
- 缺少理论命中率校验;
- 缺少理论值与实际值偏差分析。
5.2 现有测试小工具
测试小工具能够支持:
- GSM8K数据源;
- 基于数据集生成Prefix;
prefix_num多Prefix;
repeat_rate公共Prefix比例;
- 随机Token分叉;
- 请求shuffle;
- 多Pod指标采集。
主要不足:
- 固定随机分叉Token不足以保证完整Block分叉;
- 后缀可能重复单条GSM8K;
- 缺少Block冲突检测;
- 缺少变长区间分布;
- 缺少0warmup顺序感知命中率;
- 缺少目标可达性分析;
- 缺少数据Manifest和理论校验报告;
- 缺少多Prefix Group业务语义和组级分析。
5.3 AISBench现有性能评测能力
AISBench已有能力包括:
- OpenAI兼容接口请求发送;
- 请求并发控制;
- TTFT、TPOT、吞吐和时延统计;
- 数据集读取;
- 结果保存;
- 多类推理服务适配。
本方案主要复用AISBench已有执行和性能统计底座,新增Prefix Cache专项Workload生成、理论模型、指标采集和报告分析能力。
5.4 本方案新增能力
相较vLLM Benchmark和测试小工具,本方案新增核心能力包括:
- 变长请求长度分布生成;
- 目标命中率自动反向规划;
- 0warmup顺序感知理论命中率;
- 多Prefix Group独立缓存水位;
- 组级和全局可达性分析;
- 唯一分叉Block和最小非共享长度;
- GSM8K多样本自然Suffix;
- Block冲突检测;
- 数据Manifest;
- 理论命中率校验报告;
- 多实例、DP域指标聚合;
- 目标、理论和实测三层偏差分析。
6. 未解决问题
6.1 Block Size自动发现
不同框架暴露Block Size的方式不同,需要进一步设计统一发现机制。
6.2 服务端缓存匹配语义识别
需要明确vLLM、vLLM-Ascend、MindIE、SGLang和外置KV Cache的缓存Key及父链关系。
6.3 指标统计单位统一
需要建立统一指标语义:
- Token Hit;
- Block Hit;
- Query Hit;
- Cache Entry Hit。
6.4 并发场景理论模型
需要研究并发请求在Prefill开始、Block写入和Prefill完成不同时间点对缓存可见性的影响。
6.5 服务端实际处理顺序采集
需要评估是否能获取:
- Prefill开始时间;
- Prefill结束时间;
- Cache Block写入时间;
- 实际路由实例;
- 实际DP域。
6.6 Cache容量和淘汰仿真
当前理论模型主要计算缓存复用,不完整模拟Cache容量和LRU淘汰。
6.7 多级缓存模型
需要进一步支持:
- 本地GPU/NPU KV Cache;
- Host Cache;
- 外置KV Cache;
- 多级命中优先级。
6.8 真实业务数据接入
后续需要支持真实业务日志脱敏导入,并根据真实Prefix相似度构造测试数据。
6.9 高目标命中率最优规划算法
当前采用二分搜索和Block残差校准,复杂多Prefix场景可能需要整数规划或约束优化。
6.10 不同框架验收阈值
理论值与实测值偏差受框架指标口径影响,需要通过实际对比测试确定最终验收阈值。
附录
附录A:核心公式
A.1 预热固定比例
prefix_len_i
=
align_down(
input_len_i×target_ratio,
block_size
)
A.2 0warmup请求级理论命中
hit_len_i
=
min(
planned_prefix_len_i,
cached_watermark_before_i
)
A.3 缓存水位更新
cached_watermark_after_i
=
max(
cached_watermark_before_i,
planned_prefix_len_i
)
A.4 全局理论命中率
designed_hit_ratio
=
sum(expected_hit_tokens)
/
sum(input_tokens)
A.5 最大Prefix长度
max_prefix_len_i
=
align_down(
input_len_i-minimum_non_shared_length,
block_size
)
A.6 数据构造偏差
construction_deviation
=
designed_hit_ratio-target_hit_ratio
A.7 运行实现偏差
runtime_deviation
=
actual_hit_rate-designed_hit_ratio
A.8 多DP全局命中率
global_hit_rate
=
sum(dp_hits_delta)
/
sum(dp_queries_delta)
附录B:数据Manifest示例
{
"dataset_id": "progressive_multi_prefix_50",
"generator_version": "1.0",
"seed": 42,
"tokenizer": "Qwen",
"block_size": 16,
"request_count": 1000,
"execution_mode": "progressive_prefix_fill",
"target": {
"scope": "global",
"hit_ratio": 0.5,
"semantics": "order_aware_global"
},
"input_length": {
"mode": "truncated_normal",
"min": 1024,
"max": 8192,
"mean": 4096,
"std": 1024
},
"prefix": {
"mode": "multi_prefix",
"group_count": 3,
"minimum_non_shared_length": 16
},
"request_order": {
"within_group": "input_len_asc",
"across_group": "weighted_interleave"
},
"theoretical_result": {
"target_hit_ratio": 0.5,
"designed_hit_ratio": 0.4986,
"signed_deviation": -0.0014,
"absolute_deviation": 0.0014,
"max_reachable_hit_ratio": 0.724,
"validation_status": "PASS"
}
}
1. 概述
1.1 简介
本方案面向AISBench建设Prefix Cache场景数据集生成及性能测评能力,覆盖Prefix Cache测试数据构造、真实业务流量模拟、理论命中率规划、推理服务指标采集及测评结果分析等完整流程。
用户可以根据业务请求长度特征、目标Prefix Cache命中率、Prefix组织方式、请求发送顺序及缓存部署形态,生成可控、可复现、可校验的Prefix Cache测试数据集,并通过AISBench执行性能测评,分析Prefix Cache对TTFT、吞吐、时延及KV Cache资源使用率的影响。
方案支持两类测试模式:
预热固定比例模式
通过Warmup请求预先建立公共Prefix缓存,正式测试请求按照固定公共Prefix比例复用缓存,适合验证推理框架Prefix Cache基础能力及不同Prefix比例下的性能收益。
0warmup逐步填充模式
不设置独立Warmup阶段,所有请求均纳入正式测评。每条请求相互独立,同一Prefix Group内的请求按照输入长度从短到长发送,前序请求逐步建立公共Prefix缓存水位,后续请求根据已建立的缓存水位产生理论命中,适合模拟真实业务中缓存从冷启动逐步增长的过程。
数据内容采用:
其中:
数据集生成完成后,AISBench输出数据Manifest和理论命中率校验报告,说明数据集是否达到目标理论命中率、偏差大小、最大可达命中率及偏差原因。
推理服务运行完成后,AISBench进一步采集服务端Prefix Cache指标,将目标命中率、数据集理论命中率和服务端实际命中率进行对比,区分数据构造偏差和服务端运行偏差。
1.2 动机
随着大模型上下文长度持续增长,以及RAG、长文档理解、代码生成和复杂Agent等应用的发展,Prefill阶段重复计算带来的时延和算力开销不断增加。
Prefix Cache通过复用请求之间相同Prefix对应的KV Cache,能够减少重复Prefill计算,降低TTFT并提升系统吞吐,是当前大模型推理系统的重要性能优化手段。
当前AISBench主要提供通用性能测评能力,在Prefix Cache专项测评方面存在以下不足:
vLLM相关Benchmark能够验证固定Prefix和多Prefix场景的基础性能,现有测试小工具能够基于GSM8K进行部分Prefix数据构造,但二者均缺少真实变长流量、顺序感知理论模型、可达性分析和理论与实际结果关联能力。
因此,需要在AISBench中建设完整的Prefix Cache场景数据集生成及性能测评能力,使AISBench不仅能够“运行Prefix Cache测试”,还能够解释:
1.3 目标
本方案目标包括:
minimum_non_shared_length约束;2. 用例分析
2.1 固定长度单Prefix场景
用户配置固定输入长度和固定公共Prefix比例。
例如:
每条请求包含:
该场景适合:
2.2 固定长度多Prefix场景
用户配置多个Prefix Group,每个组拥有独立的主Prefix。
例如:
支持:
该场景用于模拟多个租户、多个系统Prompt或多个业务模板共享同一推理服务。
2.3 变长请求场景
用户根据真实业务请求长度特征配置变长请求。
支持以下方式:
截断正态分布示例:
含义是:
区间分布示例:
截断正态分布适合缺少真实业务数据时进行统计模拟;区间分布适合根据真实业务统计还原请求长度特征。
2.4 0warmup独立请求逐步填充场景
该场景中每条请求相互独立,不属于多轮对话,也不继承上一条请求的完整内容。
同一Prefix Group内的请求共享一条嵌套主Prefix,并按输入长度从短到长发送。
例如:
发送顺序:
每条请求结构:
第一条请求发送前没有缓存,理论命中长度为0。
后续请求能够命中的长度,由该Prefix Group此前已建立的最长公共Prefix缓存水位决定。
该场景下,目标50%不能解释为每条请求都命中50%,而应解释为:
2.5 多Prefix 0warmup场景
多Prefix场景下,每个Prefix Group独立维护缓存水位。
例如:
每个Group第一条请求均为冷启动请求,理论命中长度为0。
组间可以交错:
但必须保持每个组内部的顺序约束。
全局理论命中率必须按照Token总量加权计算,不能简单平均各组命中率。
2.6 真实文本数据场景
用户可以选择:
GSM8K数据既可以用于生成组级主Prefix,也可以用于生成自然Suffix。
当单条样本长度不足时,默认继续拼接其他样本,不建议无限重复同一条样本。
2.7 多实例和多DP场景
如果Prefix Cache为实例或DP本地缓存,则同一Prefix Group的请求进入不同实例或DP时,可能无法复用此前缓存。
支持两种缓存模型:
需要支持:
2.8 理论值与实测值对比场景
数据集生成后输出:
服务端运行后输出:
3. 方案设计
3.1 总体方案
总体架构分为六层。
3.1.1 场景配置层
负责接收用户配置,包括:
3.1.2 Workload规划层
负责:
3.1.3 数据内容生成层
负责:
3.1.4 理论仿真与校验层
负责:
3.1.5 测评执行与指标采集层
负责:
3.1.6 结果分析层
负责:
总体流程:
3.2 技术选型
3.2.1 Token级数据生成
所有长度计算和数据截断均基于模型Tokenizer完成,不使用字符数估算。
原因包括:
生成流程:
3.2.2 长度分布模型
支持:
fixedexplicittruncated_normalhistogramempirical截断正态分布优先采用拒绝采样,避免简单裁剪造成最小值和最大值处样本集中。
3.2.3 缓存粒度模型
数据规划需要基于服务端KV Cache Block Size。
优先级:
所有规划Prefix长度原则上需要按照Block Size向下对齐:
3.2.4 随机性与可复现
使用局部随机生成器。
随机种子由以下信息组合:
相同配置、Tokenizer、数据源版本和随机种子应生成相同数据。
3.2.5 数据存储格式
建议输出:
其中:
data.jsonl:实际发送给模型的数据;manifest.json:数据集配置及整体元数据;request_metadata.jsonl:请求级Prefix、水位和理论命中信息;validation_report.json:目标可达性和理论命中率校验结果。3.2.6 指标采集方式
通过推理服务提供的
/metrics或等价接口采集Prefix Cache指标。对于累计Counter指标,采用运行前后快照差值:
多实例和多DP全局结果采用Counter增量加权,不直接平均命中率。
3.3 功能与性能设计
3.3.1 请求长度生成
支持固定、显式、截断正态、区间及经验分布。
生成后输出:
所有请求长度需要满足模型最大上下文约束:
3.3.2 Prefix Group分配
支持:
每条请求必须具有唯一的
prefix_group_id。多Prefix Group之间的主Prefix相互独立,同一Group内请求从同一条主Prefix头部截取。
3.3.3 预热固定比例模式
对每条请求:
执行Block对齐:
公共Prefix预先通过Warmup请求写入缓存。
正式请求的理论命中长度为规划公共Prefix长度。
该模式主要用于:
3.3.4 0warmup顺序感知模式
对第
i条请求定义:L_i:输入Token长度;P_i:规划共享Prefix长度;C_i:发送前所属Group缓存水位;H_i:理论命中Token长度。计算:
请求完成后:
若同组请求Prefix长度单调递增:
则:
全局理论命中率为:
用户配置的50%、60%、90%约束该指标,而不是单条请求的静态Prefix比例。
3.3.5 目标命中率反向规划
用户配置:
目标命中Token总量:
系统需要规划每条请求的
P_i,使:规划过程:
3.3.6 目标可达性分析
每条请求需要保留最小非共享区域:
将所有请求Prefix设置为最大允许值,并按最终请求顺序进行缓存水位仿真,得到最大可达理论命中率:
若:
则目标不可达。
系统需要输出:
可调整方式包括:
3.3.7 多Prefix独立缓存水位
每个Prefix Group独立维护:
初始化:
请求理论命中:
请求完成后:
不同Group水位互不影响。
每个Group第一条请求理论命中长度均为0。
如果每个Group只有一条请求,则全局理论命中率为0。
3.3.8 多Prefix全局目标分配
支持两种目标范围。
全局统一目标
只要求所有Group按Token加权后的全局理论命中率达到目标。
各组可以拥有不同理论命中率。
组级独立目标
为每个Group分别配置目标。
全局目标模式下,初始组级命中Token预算按输入Token权重分配:
然后根据各组冷启动损失和最大可达能力重新调整预算。
3.3.9 请求发送策略
支持:
sequentialshufflegroupedinterleaveweighted_interleaveinput_len_ascinput_len_descprefix_len_ascprefix_len_desc0warmup模式下,组内顺序属于理论命中率的一部分。
数据生成完成后,如果重新排序或shuffle,原理论校验结果失效,必须重新执行仿真和校验。
3.3.10 组间发送与理论命中率
在以下理想条件下:
组间如何交错理论上不会改变总命中Token数。
但实际运行中,组间交错可能引入:
因此,组间发送策略必须记录在Manifest中,并在运行报告中分析其对实际命中率的影响。
3.3.11 唯一分叉Block
每条请求在公共Prefix后插入请求级唯一分叉Block。
结构:
唯一分叉Block用于保证请求在规划位置立即发生差异。
生成种子包含:
需要排除:
同一Prefix Group内首个非公共Block必须唯一。
3.3.12 minimum_non_shared_length
minimum_non_shared_length表示:主要作用:
约束:
推荐默认:
例如Block Size为16,则每条请求至少保留16 Token非共享区域。
需要说明:对于采用父链Hash的标准Prefix Cache,真正决定命中停止的是第一个不同Block及其父链上下文。因此,
minimum_non_shared_length的主要价值是保证存在完整的非共享Block,而不是要求整个Suffix全部唯一。3.3.13 GSM8K多样本拼接Suffix
自然Suffix生成流程:
支持:
默认不建议重复同一条GSM8K样本补齐长Suffix,避免形成周期性重复。
3.3.14 Block冲突检测
Block冲突检测分为两类。
组内非共享区域检测
检查:
跨组主Prefix检测
检查不同Prefix Group主Prefix是否存在非预期长公共Prefix。
对于采用父链Hash的Prefix Cache:
建议支持缓存匹配语义配置:
可选:
chained_prefix;independent_block;content_defined_chunk。不同模式采用不同冲突检测强度。
3.3.15 冲突处理策略
按以下顺序处理:
支持:
error;warn;accept_with_warning。冲突检测结果写入数据Manifest和请求级元数据。
3.3.16 数据Manifest
数据Manifest是数据集的元数据说明书,不是实际Prompt数据。
Manifest记录:
请求级元数据记录:
request_id;prefix_group_id;order_index;input_len;planned_prefix_len;cached_watermark_before;expected_hit_len;expected_hit_ratio;cached_watermark_after;divergence_len;suffix_len;Manifest用于:
3.3.17 理论命中率校验报告
数据集生成完成后必须输出理论校验报告。
核心指标:
建议优先使用“百分点”表达偏差。
例如:
校验状态:
PASSPASS_WITH_WARNINGFAIL对于请求数量较多、长度较长的数据集,建议将构造偏差控制在0.5个百分点以内。
3.3.18 服务端指标采集
采集指标包括:
累计Counter采用前后差值。
例如:
3.3.19 多实例和DP聚合
每个实例或DP独立计算:
全局结果:
禁止直接对各DP命中率做算术平均。
若缓存为DP本地缓存,理论仿真需要维护:
若缓存为全局共享缓存,则维护:
3.3.20 性能指标
Prefix Cache性能测评需要至少输出:
支持对比:
3.3.21 理论值与实测值偏差
需要区分两类偏差。
数据构造偏差
用于评价数据集生成准确性。
建议普通场景控制在1个百分点以内。
运行实现偏差
用于评价服务端运行与理论模型的一致性。
参考范围:
以上范围为工程建议,不应直接作为所有推理框架的统一强约束。最终验收阈值需结合服务端指标语义和实际测试结果确定。
3.3.22 偏差归因
理论值与实际值不一致时,分析以下因素:
3.3.23 性能要求
数据生成性能建议满足:
3.4 安全隐私与DFX设计
3.4.1 数据安全
默认使用公开数据集,不包含用户私有业务数据。
用户导入自定义数据时支持:
3.4.2 可复现性
保存以下信息:
3.4.3 可诊断性
日志分为:
错误需要包含:
3.4.4 容错设计
需要处理:
3.4.5 兼容性
方案需要考虑:
不同框架使用统一逻辑指标模型,通过Adapter映射框架原始指标。
3.4.6 可扩展性
后续可扩展:
3.5 编程与调用设计
3.5.1 编程模型基本设计
核心对象如下。
PrefixCacheDatasetConfig
描述完整数据生成配置。
字段包括:
dataset_id;seed;request_count;block_size;input_length;target;prefix;suffix;request_order;execution;routing;validation。RequestPlan
描述单条请求规划结果。
字段包括:
request_id;prefix_group_id;input_len;planned_prefix_len;divergence_len;suffix_len;order_index;planned_dp_id。PrefixGroupPlan
描述单个Prefix Group。
字段包括:
group_id;request_count;master_prefix_len;target_hit_tokens;max_reachable_hit_ratio;cold_start_loss。DatasetManifest
描述数据集整体元数据。
ValidationReport
描述目标可达性及理论校验结果。
RuntimeMetrics
描述服务端实际性能和Cache指标。
整体编程流程:
3.5.2 接口定义与设计
数据集生成接口
返回:
长度生成接口
Prefix Group分配接口
目标可达性接口
Prefix规划接口
主Prefix生成接口
Suffix生成接口
冲突检测接口
缓存水位仿真接口
理论命中率校验接口
指标采集接口
报告生成接口
3.5.3 编程手册设计
配置示例:固定长度单Prefix
配置示例:0warmup变长单Prefix
配置示例:0warmup多Prefix
命令行示例
输出目录示例
4. 缺点和风险
4.1 理论模型依赖服务端缓存语义
不同推理框架可能采用父链Hash、独立Block Hash或内容定义分块。
如果AISBench理论模型与服务端实际缓存匹配语义不一致,理论命中率可能产生系统性偏差。
4.2 Block Size获取不准确
若配置的Block Size与服务端不一致,会影响:
4.3 提交顺序与实际处理顺序不一致
并发场景下,服务端可能改变Prefill执行顺序,导致实际缓存水位建立过程与理论提交顺序不一致。
4.4 多实例和多DP路由影响
同一Prefix Group请求被路由到不同实例或DP后,本地缓存可能无法复用。
若没有Sticky Routing,理论值可能明显高于实际值。
4.5 Cache容量和淘汰影响
理论模型默认缓存容量足够且不会淘汰。
多Prefix Group或长上下文场景中可能发生LRU淘汰,使实际命中率下降。
4.6 历史缓存污染
测试前服务端可能已有相同Prefix缓存,导致第一条请求产生非预期命中。
Cold场景需要支持服务重启、缓存清理或使用唯一Salt隔离。
4.7 自然文本无法完全代表真实业务
GSM8K多样本拼接能够提升文本自然性,但与真实RAG文档、代码上下文或业务Prompt仍存在差异。
4.8 高目标命中率可能不可达
以下情况可能导致90%等高命中目标不可达:
4.9 理论值与服务端指标口径不同
理论命中率可能按Token计算,服务端指标可能按Block、Query或Cache Entry统计,二者不能直接比较。
需要在Adapter中明确指标单位。
4.10 Block冲突检测存在额外开销
大规模长上下文数据集进行全量Block窗口Hash检测,会增加生成时间和内存消耗。
4.11 组级预算分配不唯一
相同全局目标可以通过多种组级命中率组合实现。
需要保存组级预算分配策略,保证结果可解释和可复现。
4.12 理论与实测误差无法完全消除
即使数据构造完全正确,实际运行仍会受到调度、路由、淘汰、Counter采样和请求失败等因素影响。
因此,运行一致性应采用合理误差阈值和偏差分析,而不是要求理论值与实测值完全相等。
5. 现有技术
5.1 vLLM Prefix Cache Benchmark
vLLM相关Benchmark能够支持:
主要不足:
5.2 现有测试小工具
测试小工具能够支持:
prefix_num多Prefix;repeat_rate公共Prefix比例;主要不足:
5.3 AISBench现有性能评测能力
AISBench已有能力包括:
本方案主要复用AISBench已有执行和性能统计底座,新增Prefix Cache专项Workload生成、理论模型、指标采集和报告分析能力。
5.4 本方案新增能力
相较vLLM Benchmark和测试小工具,本方案新增核心能力包括:
6. 未解决问题
6.1 Block Size自动发现
不同框架暴露Block Size的方式不同,需要进一步设计统一发现机制。
6.2 服务端缓存匹配语义识别
需要明确vLLM、vLLM-Ascend、MindIE、SGLang和外置KV Cache的缓存Key及父链关系。
6.3 指标统计单位统一
需要建立统一指标语义:
6.4 并发场景理论模型
需要研究并发请求在Prefill开始、Block写入和Prefill完成不同时间点对缓存可见性的影响。
6.5 服务端实际处理顺序采集
需要评估是否能获取:
6.6 Cache容量和淘汰仿真
当前理论模型主要计算缓存复用,不完整模拟Cache容量和LRU淘汰。
6.7 多级缓存模型
需要进一步支持:
6.8 真实业务数据接入
后续需要支持真实业务日志脱敏导入,并根据真实Prefix相似度构造测试数据。
6.9 高目标命中率最优规划算法
当前采用二分搜索和Block残差校准,复杂多Prefix场景可能需要整数规划或约束优化。
6.10 不同框架验收阈值
理论值与实测值偏差受框架指标口径影响,需要通过实际对比测试确定最终验收阈值。
附录
附录A:核心公式
A.1 预热固定比例
A.2 0warmup请求级理论命中
A.3 缓存水位更新
A.4 全局理论命中率
A.5 最大Prefix长度
A.6 数据构造偏差
A.7 运行实现偏差
A.8 多DP全局命中率
附录B:数据Manifest示例
{ "dataset_id": "progressive_multi_prefix_50", "generator_version": "1.0", "seed": 42, "tokenizer": "Qwen", "block_size": 16, "request_count": 1000, "execution_mode": "progressive_prefix_fill", "target": { "scope": "global", "hit_ratio": 0.5, "semantics": "order_aware_global" }, "input_length": { "mode": "truncated_normal", "min": 1024, "max": 8192, "mean": 4096, "std": 1024 }, "prefix": { "mode": "multi_prefix", "group_count": 3, "minimum_non_shared_length": 16 }, "request_order": { "within_group": "input_len_asc", "across_group": "weighted_interleave" }, "theoretical_result": { "target_hit_ratio": 0.5, "designed_hit_ratio": 0.4986, "signed_deviation": -0.0014, "absolute_deviation": 0.0014, "max_reachable_hit_ratio": 0.724, "validation_status": "PASS" } }