- 大模型
- 人工智能
- 缓存
【免费下载链接】unified-cache-management
Unified Cache Manager(推理记忆数据管理器),是一款以KV Cache为中心的推理加速套件,其融合了多类型缓存加速算法工具,分级管理并持久化推理过程中产生的KV Cache记忆数据,扩大推理上下文窗口,以实现高吞吐、低时延的推理体验,降低每Token推理成本。
本文聚焦于 unified-cache-management 仓库中
test/common/llmperf目录下的 LLM 性能测试框架(即LLMPerf.md文档所描述的测试套件),系统讲解其在多样负载下如何量化推理服务的延迟分布(TTFT/TBT/端到端)、吞吐上限、并发稳定性与Prefix Cache 命中效果。读者阅读后可掌握该框架的配置体系、三大引擎(vLLM/SGLang/MindIE)下缓存命中率的差异处理逻辑、pytest 执行方式、结果指标含义与质量门禁规则,并可直接在仓库的 test/ 目录下复现整套性能基准测试流程。
功能概述:该测试套件能测什么
该测试框架专为LLM 推理服务设计,用于在多样化负载条件下对推理服务进行自动化、可量化的性能评估,覆盖以下四个关键维度:
| 测试维度 | 评估重点 | 适用场景 |
|---|---|---|
| ⏱️延迟分析 | TTFT(首 Token 延迟)、TBT(Token 间隔延迟)、端到端延迟 | 实时交互应用(Chatbot) |
| 🚀吞吐能力 | Total / Incremental Throughput | 高并发批量处理 |
| 🔄并发稳定性 | 不同并发度下的性能衰减曲线 | 容量规划与限流策略 |
| 💾缓存效能 | Prefix Cache Hit Rate(Prefill 复用率) | 长上下文重复查询优化 |
从源码结构看,测试套件的核心调用链可概括为:
pytest 入口(test/suites/E2E/test_uc_performance.py) └─ inference_results()(test/common/llmperf/run_inference.py) └─ run_test_cases():按引擎类型分派 prefill 预埋策略 └─ run_token_benchmark()(test/common/llmperf/utils/token_benchmark.py) └─ get_token_throughput_latencies():生成 Prompt、线程池并发发压 └─ OpenAIChatCompletionsClient.llm_request() (test/common/llmperf/utils/openai_chat_completions_client.py)其中负载发压与指标采集的核心实现位于 token_benchmark.py,它通过ThreadPoolExecutor(max_workers=concurrent_requests)提交请求、以as_completed(futures, timeout=test_timeout_s)控制总超时;指标名称常量统一定义在 common_metrics.py。
配置体系
测试套件采用双层配置结构:环境级配置写在 config.yaml,负载矩阵则内嵌于测试文件 test_uc_performance.py。所有配置通过 config_utils.py 中的单例config_utils读取(支持get_config取顶层键、get_nested_config取a.b.c嵌套键)。
基础环境配置(config.yaml)
llm_connection段定义模型、服务端点与环境参数:
| 参数 | 类型 | 必填 | 说明 | 示例值 |
|---|---|---|---|---|
model | string | ✅ | 模型标识名称 | Qwen3-32B |
server_url | string | ✅ | 推理服务 HTTP 端点 | http://141.111.32.70:8244 |
tokenizer_path | string | ✅ | Tokenizer 本地路径 | /mnt/model/Qwen3-32B |
llm_type | enum | ✅ | 推理引擎类型 | vllm/sglang/mindie |
enable_clear_hbm | bool | ✅ | 测试前清除显存/前缀缓存 | true(默认) |
timeout | int | ✅ | 单请求超时时间(秒) | 180(默认) |
仓库中 config.yaml 还给出了若干补充参数,实际运行时同样生效:
| 补充参数 | 类型 | 说明 | 仓库默认值 |
|---|---|---|---|
stream | bool | 是否流式输出(SSE),影响 TTFT/TBT 的测量方式 | true |
ignore_eos | bool | 是否忽略返回的结束符,避免提前截断影响吞吐统计 | true |
extra_info | string | 附加说明,用于标记不同的服务拉起参数(如vllm_qwen3-32b_pc-gsa),会写入结果元数据 | — |
stddev_input_tokens | int | 输入 Token 数标准差,控制 Prompt 长度波动(见inference_results读取逻辑) | 0 |
stddev_output_tokens | int | 输出 Token 数标准差 | 0 |
这些参数在 openai_chat_completions_client.py 中被读取并拼入请求体(stream、ignore_eos、timeout),extra_info则经 test_uc_performance.py 写入最终的扁平化指标字典。
引擎特性差异:Hit Rate 处理逻辑
不同推理引擎对Prefix Caching(hit_rate)的实现机制差异显著,测试框架据此采用不同的 prefill 预埋策略:
| 引擎 | Prefill 策略 | 实际输入计算 | 备注 |
|---|---|---|---|
| vLLM | 1 次预埋 | input_tokens(不变) | 利用 vLLM 的 Automatic Prefix Caching |
| SGLang | 2 次预埋 | input_tokens(不变) | 双重预热确保 KV Cache 稳定 |
| MindIE | 跳过 | input_tokens × hit_rate | 直接缩短输入长度模拟命中效果 |
这段逻辑在 run_inference.py 中有完整源码实现,可逐一对应:
- 预埋长度计算:
prefill_mean_input = int(mean_input * hit_rate_val / 100)(run_inference.py),即按命中率百分比截取输入前缀作为缓存预埋内容。 - vLLM 路径:
run_vllm()先执行一轮mean_output=2的 prefill 请求(仅发送前缀、几乎不生成 Token),随后进入正常推理(run_inference.py)。 - SGLang 路径:
run_sglang()连续执行prefill_1、prefill_2两轮预埋(每轮之间time.sleep(2)),再切换正常模式(run_inference.py)。 - MindIE 路径:
run_mindie()不做预埋,直接将正常请求的mean_input替换为prefill_mean_input,用缩短后的实际输入模拟缓存命中效果(run_inference.py)。 - 缓存清理:每个阶段之间调用
reset_prefill_cache()(实现在 utils.py),当enable_clear_hbm=true时,vLLM 走POST {server_url}/reset_prefix_cache,SGLang 走POST {server_url}/flush_cache,确保每轮测试从干净的缓存状态开始。 - 阶段分派:
run_test_cases()通过zip(mean_input_tokens, mean_output_tokens, max_num_completed_requests, concurrent_requests, random_seed, hit_rate)逐组消费负载矩阵,并按llm_type路由到对应分支(run_inference.py),不支持的引擎会抛出ValueError。
此外,每轮 prefill 请求的user_metadata中会记录phase(prefill/prefill_1/prefill_2/normal)与case_idx,便于事后区分结果归属。
负载参数配置(test_uc_performance.py)
测试用例负载矩阵定义在 test_uc_performance.py 中,测试用例为每组 list 相同对应位置(即索引对齐后构成一组完整场景):
| 参数 | 类型 | 说明 | 示例 |
|---|---|---|---|
mean_input_tokens | list[int] | 平均输入长度分布 | [512, 2048, 4096] |
mean_output_tokens | list[int] | 平均输出长度分布 | [128, 512, 1024] |
concurrent_requests | list[int] | 并发请求数梯度 | [1, 4, 8] |
max_num_completed_requests | list[int] | 单轮最大完成数 | [100, 50, 50] |
hit_rate | list[int] | 缓存命中率(%) | [0, 50, 90] |
random_seed | list[int] | 随机种子 | [42, 0, 0] |
实际测试文件中的默认场景为perf_scenarios = [(1000, 1024, 8, 8, 0, 0), (4000, 500, 1, 1, 0, 0)](test_uc_performance.py),每组元素依次对应(mean_in, mean_out, max_req, concurrent, random_seed, hit_rate)。
随机种子(Random Seed)策略
| 取值 | 行为 | 适用场景 |
|---|---|---|
0 | 每轮生成随机 Prompt | 模拟真实流量分布 |
≠0 | 多轮固定相同 Prompt | 回归测试、A/B 对比 |
源码实现中有两点值得注意:
- 在 run_inference.py 中,当
seed == 0时会被替换为random.randint(1, 100000)的真实随机种子,随后random.seed(random_seed)会锁住该轮的 Prompt 生成序列; - 固定种子的 Prompt 通过
generate_fixed_token_prompt()基于Token ID 采样生成(而非文本拼接),并用hashlib.sha256打印摘要以校验一致性,见 token_benchmark.py。输入长度服从高斯分布,且采样到非正数时会循环重采(sample_random_positive_int,实现在 utils.py)。
测试执行
前置依赖
# 安装测试框架依赖 pip install -r requirements.txt # 验证推理服务端点可达 curl http://<server_url>/health依赖清单见 requirements.txt,除 pytest、requests、pandas、transformers 外,还包含nvidia-ml-py(用于 conftest.py 中的 GPU 显存探测与分配)、peewee/psycopg2-binary/pymongo(结果可选入库)等。执行前应确保:
- 推理服务已拉起且
server_url可访问(vLLM/SGLang 等通常暴露 OpenAI 兼容的/v1/chat/completions端点,测试客户端会自动拼接); tokenizer_path指向本地 HuggingFace 模型目录,用于精确统计 Prompt/输出 Token 数;- 若
enable_clear_hbm=true,服务需提供reset_prefix_cache(vLLM)或flush_cache(SGLang)接口用于清缓存。
运行方式
cd test/ # 方式1:运行完整测试文件 pytest test_uc_performance.py -v # 方式2:按阶段执行(如阶段0:基准测试) pytest --stage=0 # 方式3:按特性标签执行 pytest --feature=uc_performance_test这三种方式与 pytest.ini 中注册的 markers 一一对应:stage(0=Unit 1=Smoke 2=Regression 3=Release)、feature(特性标签)、platform(gpu/npu)等;筛选逻辑实现在 conftest.py 的pytest_collection_modifyitems中,支持--stage=2+这类“大于等于某阶段”的写法。性能用例test_performance被标记为@pytest.mark.stage(2)与@pytest.mark.feature("uc_performance_test")(test_uc_performance.py),并经pytest.mark.parametrize展开为多组场景。
实时监控
运行时可观察以下实时输出:
[ RUNNING ] Qwen3-32B | input=2048 | output=512 | concurrency=8 | hit_rate=50% [ PROGRESS ] 45/100 requests completed (45%) | TTFT: 125ms | TBT: 18ms [ COMPLETE ] Throughput: 156.3 tok/s | P99 Latency: 8.4s此外,测试进程启动时会打印加载到的完整 LLM 配置(模型、端点、超时、结果目录等),并在每个用例开始前输出>>> Executing test case N <<<与hit_rate=N%, prefill_mean_input=M等日志(见 run_inference.py),便于现场核对参数。
进阶:通过环境变量注入测试场景
负载矩阵不仅可改代码,也可通过环境变量PERF_TEST_CASE动态注入:其值需为 JSON 格式的六元组列表(每组(mean_in, mean_out, max_req, concurrent, random_seed, hit_rate)),解析成功后覆盖默认perf_scenarios,格式非法时回退默认值(test_uc_performance.py)。另外设置ENABLE_PROFILING=true时,用例会在压测前后向服务发送POST {server_url}/start_profile与stop_profile请求(test_uc_performance.py),方便同步采集 Profiler 数据。
结果解读
核心指标定义
延迟维度(Latency)
| 指标 | 说明 | 关注重点 |
|---|---|---|
ttft_s | Time To First Token | 首字响应速度,影响用户感知延迟 |
inter_token_latency_s | Time Between Tokens | 流式输出流畅度 |
end_to_end_latency_s | 总耗时 | 完整请求处理时间 |
统计分位:每项指标输出P50 / P90 / P99 / Mean(此外还包含 Min / Max / Stddev 以及 P25 / P75 / P95)。
这些指标的采集逻辑如下:
- TTFT 在客户端收到首个
content内容块时以time.monotonic() - start_time计算(openai_chat_completions_client.py),同时兼容reasoning_content(如带思维链的模型); - 相邻 Token 到达时间差累计为
inter_token_latency_s,随后在 token_benchmark.py 中按(输出Token数 - 1)归一化得到平均 Token 间隔,并进一步推导tpot_s(Time Per Output Token,即(e2e - ttft) / (n_out - 1)); - 指标常量定义可参考 common_metrics.py,其中还包含
number_input_tokens、number_output_tokens、request_output_throughput_token_per_s等明细字段。
吞吐维度(Throughput)
| 指标 | 计算方式 | 用途 |
|---|---|---|
total_throughput | Total Tokens / Total Time | 综合吞吐能力 |
incremental_throughput | Output Tokens / Generation Time | 解码阶段纯效率 |
具体实现在compute_throughput()(token_benchmark.py):
total_throughput = (mean_output_tokens × 完成请求数) / 总耗时(elapsed_time);incremental_throughput = (mean_output_tokens × 完成请求数) / 增量时间开销(incremental_time_delay),其中incremental_time_delay为所有请求inter_token_latency之和,即纯解码阶段的累计时间。
其他关键指标
num_completed_requests:成功完成请求数(对比期望值验证成功率)elapsed_time:单轮测试 wall-clock 时间incremental_time_delay:解码阶段时间开销- 此外
metrics_summary()(token_benchmark.py)还会输出error_rate、num_completed_requests_per_min、mean_output_throughput_token_per_s等汇总值,并以 Pandas DataFrame 计算分位数与均值。
输出格式示例
测试结果以结构化字典返回,便于存储数据库或看板展示:
{ "_name": "llmperf", "_metadata": { "model": "Qwen3-32B", "timestamp": "2026-01-31T14:30:00Z", "config": { ... } }, "_data": { # 延迟分布 (秒) "results_ttft_s_mean": 0.125, "results_ttft_s_quantiles_p50": 0.118, "results_ttft_s_quantiles_p99": 0.245, "results_inter_token_latency_s_mean": 0.018, "results_end_to_end_latency_s_mean": 4.567, # 吞吐指标 (tokens/s) "results_total_throughput": 245.8, "results_incremental_throughput": 198.3, # 请求统计 "results_num_completed_requests": 100, "results_elapsed_time": 45.2 } }在仓库实际实现中:
inference_results()返回的summary字典包含total_throughput、incremental_throughput、num_completed_requests、elapsed_time等字段,且run_token_benchmark()会为每轮测试在results/llmperf/目录下落盘一份{model}_{input}_{output}_{timestamp}_summary.json(token_benchmark.py),文件内容经LLMPerfResults.to_dict()展平,便于 JSON 存储;- test_uc_performance.py 会把各指标再次展平为
ttft_mean_s、tpot_mean_s、e2e_mean_s、total_throughput、incremental_throughput、elapsed_time_s等键,配合@export_vars装饰器与 conftest.py 中的pytest_runtest_logreport,将结果以_name/_proj结构导出,由test/common/capture_results/下的后端(localFile / postgresql / mongodb)落库或写文件(config.yaml 中results段配置)。
质量门禁
自动校验规则
测试框架内置以下硬性通过标准(规则在文档中描述,test_performance用例中亦有对应断言,见 test_uc_performance.py):
def validate_metrics(result: dict) -> bool: """ 验证所有数值指标有效性 """ critical_metrics = [ 'results_ttft_s_mean', 'results_inter_token_latency_s_mean', 'results_total_throughput', 'results_num_completed_requests' ] for metric in critical_metrics: value = result['_data'].get(metric) # 规则1:数值必须存在 if value is None: raise ValidationError(f"❌ {metric}: 返回值为 None") # 规则2:数值必须为正 if value <= 0: raise ValidationError(f"❌ {metric}: {value} 不符合 >0 要求") return True即:关键指标缺失即判失败、非正值即判失败。这一校验与metrics_summary()中“过滤错误请求(error_code为 NaN)后再统计”的策略配合,可避免异常请求污染分位数据。
失败判定标准
| 异常类型 | 表现 | 处理建议 |
|---|---|---|
| 指标为 None | 服务超时或统计失败 | 检查timeout配置,增大阈值 |
| 指标 ≤ 0 | 服务异常或计算错误 | 检查推理服务日志 |
| 完成数不足 | num_completed < max_num_completed | 检查并发压力是否过载导致丢请求 |
在 run_inference.py 中,单用例异常会被捕获并记录到failed_case列表,测试结束后统一打印[WARN] Failed case indices: [...];同时客户端对非 200 响应、SSE 流中的error字段都会记录error_code与error_msg(openai_chat_completions_client.py),可作为排查服务异常的原始证据。此外,性能用例结束后会统计并发下的 GPU 显存利用率等辅助信息(由 conftest.py 的 GPU 分配 fixture 注入环境变量E2E_TEST_GPU_MEMORY_UTILIZATION),帮助判断资源是否成为瓶颈。
总结与使用建议
- 验证缓存收益:通过
hit_rate梯度(如[0, 50, 90])对比同一负载下的 TTFT 与吞吐,可量化 Prefix Cache 的加速效果,是评估 UCM 前缀缓存、GSA、KV 复用等能力的最直接手段; - 刻画并发曲线:固定输入/输出长度,逐步抬高
concurrent_requests,绘制延迟分位与吞吐的衰减曲线,可用于容量规划与限流阈值设定; - 保证结果可比:回归或 A/B 对比时务必使用非零
random_seed,配合enable_clear_hbm=true清空前缀缓存,确保多轮测试的 Prompt 与缓存起点一致; - 关注质量门禁:以
num_completed_requests是否达标、四项关键指标是否为正作为每次性能迭代的硬性通过条件,防止“看起来快但丢请求”的假吞吐。
如需深入了解框架细节,可继续阅读 token_benchmark.py(发压与统计)、openai_chat_completions_client.py(流式客户端与延迟测量)、run_inference.py(引擎分派与缓存预埋)以及 test_uc_performance.py(pytest 入口与结果导出)。
- 大模型
- 人工智能
- 缓存
【免费下载链接】unified-cache-management
Unified Cache Manager(推理记忆数据管理器),是一款以KV Cache为中心的推理加速套件,其融合了多类型缓存加速算法工具,分级管理并持久化推理过程中产生的KV Cache记忆数据,扩大推理上下文窗口,以实现高吞吐、低时延的推理体验,降低每Token推理成本。
相关推荐
unified-cache-management 测试框架指南:基于 pytest 7.0+ 的配置管理、结果采集与 E2E 性能测试实战
unified cache management 测试框架指南:基于 pytest 7.0+ 的配置管理、结果采集与 E2E 性能测试实战 本文系统讲解 uni
大模型人工智能缓存unified-cache-management dev-sandbox 性能测试沙箱:构建、copy/trans/aio 子命令与全量 case 实战指南
unified cache management dev sandbox 性能测试沙箱:构建、copy/trans/aio 子命令与全量 case 实战指南 本
大模型人工智能缓存Unified Cache Management 环境预检套件(EnvPreCheck)实战指南:模型部署前六大维度集群健康检查
Unified Cache Management 环境预检套件(EnvPreCheck)实战指南:模型部署前六大维度集群健康检查 在 Unified Cache
大模型人工智能缓存
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考