共计 2081 个字符,预计需要花费 6 分钟才能阅读完成。
为什么需要标准化基准测试?
刚入行 AI 开发时,我最头疼的就是模型性能对比。同一个模型,不同人测出来的结果能差出好几倍——有人用 CPU 测推理速度,有人开着其他程序跑测试,甚至有人直接用训练集当测试数据。这种混乱导致:
- 团队内部无法客观评估优化效果
- 论文中的 SOTA 模型复现结果总对不上
- 生产环境部署后才发现性能不达标
主流测试框架怎么选?
先对比两个最常用的工具:
- MLPerf:
- 优势:覆盖视觉 /NLP 等全场景,测试用例严格标准化
- 缺点:配置复杂,适合学术机构或大厂
-
适用场景:发表论文或横向对比不同硬件
-
AI Benchmark:
- 优势:手机端优化好,提供现成的 APK
- 缺点:自定义空间小
- 适用场景:移动端 AI 应用快速验证
对于大多数开发者,我建议先用 Python 自建测试框架,等需要横向对比时再接入这些标准平台。
手把手搭建测试环境
最小测试单元实现
先看核心代码结构(完整代码见文末 Gist):
# 基础性能测试模块
import time
from typing import Callable
import psutil # 内存监控
def benchmark(
model_fn: Callable,
input_data: torch.Tensor,
warmup: int = 3,
repeats: int = 10
) -> dict:
"""
基准测试主函数
:param model_fn: 待测试的模型函数
:param input_data: 标准化输入数据
:param warmup: 预热次数(消除冷启动影响):param repeats: 正式测试重复次数
"""
# 内存基线记录
process = psutil.Process()
mem_before = process.memory_info().rss / 1024 ** 2 # MB
# 预热阶段
for _ in range(warmup):
_ = model_fn(input_data)
# 正式测试
latencies = []
for _ in range(repeats):
start = time.perf_counter() # 微秒级精度
_ = model_fn(input_data)
latencies.append((time.perf_counter() - start) * 1000) # 转毫秒
# 结果统计
return {"throughput": 1000 / (sum(latencies) / repeats), # 请求数 / 秒
"p99_latency": sorted(latencies)[int(repeats * 0.99)],
"max_mem": process.memory_info().rss / 1024 ** 2 - mem_before}
关键设计点:
- 使用
time.perf_counter()而非time.time(),前者专为性能测试优化 - 必须包含预热阶段,避免首次推理因模型加载产生的误差
- 内存统计要区分基线值和峰值增量
测试指标详解
核心三要素
- 吞吐量(Throughput):单位时间处理的样本数
- 计算公式:
总样本数 / (结束时间 - 开始时间) -
适用场景:批处理任务(如视频分析)
-
延迟(Latency):单个请求的响应时间
- 注意区分:
- 平均延迟:易受极端值影响
- P99 延迟:反映最坏情况
-
适用场景:实时交互(如语音助手)
-
内存占用:包括:
- 模型加载内存
- 推理时临时内存
可视化方法
用 Matplotlib 绘制对比曲线示例:
import matplotlib.pyplot as plt
# 假设测试了三种模型
models = ["ResNet18", "EfficientNet", "MobileNet"]
throughputs = [120, 85, 210]
latencies = [8.3, 12.1, 4.7]
plt.figure(figsize=(10,4))
plt.subplot(121)
plt.bar(models, throughputs, color='skyblue')
plt.title("Throughput (req/s)")
plt.subplot(122)
plt.bar(models, latencies, color='salmon')
plt.title("Latency (ms)")
plt.tight_layout()
plt.savefig("benchmark_result.png")

避坑指南
冷启动误差
- 现象:首次推理耗时明显更长
- 解决方案:
- 正式测试前执行 3 - 5 次预热
- 单独统计首次推理时间(反映用户体验)
多 GPU 测试
常见问题:多个进程争抢显存
解决方案:
import os
os.environ["CUDA_VISIBLE_DEVICES"] = "0" # 指定测试卡
CI 集成
推荐方案:
- 使用
pytest-benchmark插件 - 设置性能阈值触发告警
- 每次 commit 自动生成对比报告
当测试与生产不一致时
典型排查路径:
- 检查输入数据分布是否一致
- 监控生产环境 GPU 利用率
- 使用
py-spy进行火焰图分析
最后留个思考题:如果 P99 延迟突然飙升,但平均延迟正常,可能是什么原因?欢迎在评论区讨论你的排查思路!
完整代码示例:https://gist.github.com/example/benchmark.py
正文完
