基准测试最佳实践
版本: 0.3.2 状态: 持续更新文档——随方法论演进而更新 参考: MLPerf Inference、SPEC CPU 2017、NVIDIA GenAI-Perf
概述
asiai bench 遵循既定的基准测试标准,在 Apple Silicon 推理引擎间产出可靠、可重现、可比较的结果。本文档追踪哪些最佳实践已实现、计划中或有意排除。
合规性总结
| 类别 | 实践 | 状态 | 起始版本 |
|---|---|---|---|
| 指标 | TTFT 与 tok/s 分离 | 已实现 | v0.3.1 |
| 确定性采样(temperature=0) | 已实现 | v0.3.2 | |
| Token 计数来自服务器 API(非 SSE chunk) | 已实现 | v0.3.1 | |
| 按引擎功耗监控 | 已实现 | v0.3.1 | |
| generation_duration_ms 显式字段 | 已实现 | v0.3.1 | |
| 预热 | 每引擎 1 次预热生成(不计时) | 已实现 | v0.3.2 |
| 运行 | 默认 3 次运行(SPEC 最低要求) | 已实现 | v0.3.2 |
| 中位数作为主要指标(SPEC 标准) | 已实现 | v0.3.2 | |
| 均值 + 标准差作为次要指标 | 已实现 | v0.3.0 | |
| 方差 | Pooled 提示词内标准差 | 已实现 | v0.3.1 |
| 基于 CV 的稳定性分类 | 已实现 | v0.3.0 | |
| 环境 | 引擎顺序执行(内存隔离) | 已实现 | v0.1 |
| 温控降频检测 + 告警 | 已实现 | v0.3.2 | |
| 温控级别 + speed_limit 记录 | 已实现 | v0.1 | |
| 可重现性 | 引擎版本按基准测试存储 | 已实现 | v0.3.2 |
| 模型格式 + 量化存储 | 已实现 | v0.3.2 | |
| 硬件芯片 + macOS 版本存储 | 已实现 | v0.3.2 | |
| 开源基准测试代码 | 已实现 | v0.1 | |
| 回归 | 历史基线比较(SQLite) | 已实现 | v0.3.0 |
| 按(引擎、模型、提示词类型)比较 | 已实现 | v0.3.1 | |
| metrics_version 过滤 | 已实现 | v0.3.1 | |
| 提示词 | 4 种多样化提示词类型 + 上下文填充 | 已实现 | v0.1 |
| 每提示词固定 max_tokens | 已实现 | v0.1 |
计划改进
P1 — 统计严谨性
| 实践 | 描述 | 标准 |
|---|---|---|
| 95% 置信区间 | CI = mean +/- 2*SE。比 +/- stddev 更有信息量。 | 学术 |
| 百分位数(P50/P90/P99) | 特别是 TTFT——尾部延迟很重要。 | NVIDIA GenAI-Perf |
| 异常值检测(IQR) | 标记 [Q1 - 1.5IQR, Q3 + 1.5IQR] 范围外的运行。 | 统计标准 |
| 趋势检测 | 检测跨运行的单调性能下降(温控漂移)。 | 学术 |
P2 — 可重现性
| 实践 | 描述 | 标准 |
|---|---|---|
| 引擎间冷却 | 引擎间暂停 3-5 秒让温度稳定。 | GPU 基准测试 |
| Token 比率验证 | 当 tokens_generated < 90% max_tokens 时告警。 | MLPerf |
| 导出格式 | asiai bench --export JSON 用于社区提交。 |
MLPerf 提交 |
P3 — 高级
| 实践 | 描述 | 标准 |
|---|---|---|
ignore_eos 选项 |
强制生成到 max_tokens 用于吞吐量基准测试。 | NVIDIA |
| 并发请求测试 | 测试批处理吞吐量(适用于 vllm-mlx)。 | NVIDIA |
| 后台进程审计 | 基准测试期间有重度进程运行时告警。 | SPEC |
有意偏差
| 实践 | 偏差原因 |
|---|---|
| MLPerf 最少 600s 时长 | 设计用于数据中心 GPU。Apple Silicon 上 3 次运行 + 4 个提示词已需 2-5 分钟。结果已足够稳定。 |
| SPEC 2 次非计时预热工作负载 | 我们使用 1 次预热生成(非 2 个完整工作负载)。单次预热对 JIT 预热最小的本地推理引擎已足够。 |
| 总体标准差 vs 样本标准差 | 我们使用总体标准差(N 除数)而非样本标准差(N-1 除数)。小 N(3-5 次运行)时差异很小,总体方式更保守。 |
| 频率缩放控制 | Apple Silicon 不暴露 CPU governor 控制。我们记录 thermal_speed_limit 来检测降频。 |
Apple Silicon 特定注意事项
统一内存架构
Apple Silicon 在 CPU 和 GPU 间共享内存。两个关键影响:
- 永远不要同时对两个引擎做基准测试 — 它们竞争同一个内存池。
asiai bench设计为顺序运行引擎。 - VRAM 报告 — Ollama 和 LM Studio 原生报告
size_vram。其他引擎(llama.cpp、mlx-lm、oMLX、vLLM-MLX、Exo),asiai 通过ri_phys_footprint(libproc 的 macOS 物理占用指标,与活动监视器显示相同)作为后备估算。估算值在 UI 中标记为"(est.)"。
温控降频
- MacBook Air(无风扇):持续负载下严重降频。5-10 分钟后结果下降。
- MacBook Pro(有风扇):降频轻微,通常通过风扇加速处理。
- Mac Mini/Studio/Pro:主动散热,降频极小。
asiai bench 按结果记录 thermal_speed_limit,在任何运行期间检测到降频(speed_limit < 100%)时发出告警。
KV Cache 和上下文长度
大上下文(32k+)可能在模型加载时预分配 KV cache 的引擎上导致性能不稳定。例如:LM Studio 默认 loaded_context_length: 262144(256k),对 35B 模型分配约 15-25 GB KV cache,可能使 64 GB 统一内存饱和。
建议:
- 测试大上下文时,将引擎上下文长度设为实际测试大小(如 64k 测试用 lms load model --context-length 65536)。
- 使用等效上下文长度设置比较引擎以获得公平结果。
每次基准测试存储的元数据
SQLite 中每个基准测试结果包含:
| 字段 | 示例 | 用途 |
|---|---|---|
engine |
"ollama" | 引擎识别 |
engine_version |
"0.17.4" | 检测跨更新的性能变化 |
model |
"qwen3.5:35b-a3b" | 模型识别 |
model_format |
"gguf" | 区分格式变体 |
model_quantization |
"Q4_K_M" | 区分量化级别 |
hw_chip |
"Apple M4 Pro" | 硬件识别 |
os_version |
"15.3" | macOS 版本追踪 |
thermal_level |
"nominal" | 环境条件 |
thermal_speed_limit |
100 | 降频检测 |
metrics_version |
2 | 公式版本(防止跨版本回归) |
这些元数据支持: - 公平回归比较:仅比较元数据匹配的结果 - 跨机器基准测试:识别硬件差异 - 社区数据共享:自描述结果(v1.x 计划)