3. 模型加载与基准测试

做剪枝,最忌讳的就是「闭眼剪」。你连原始模型跑多快、精度多少都不知道,剪完怎么判断效果?

我个人习惯,拿到任何预训练权重,第一件事就是跑一遍完整的基准测试。记录下 mAP 和 FPS,这就是后续所有操作的「锚点」。没有这个锚点,后面的一切对比都是空谈。

3.1 加载官方预训练权重

YOLOv11 官方提供了在 COCO 数据集上训好的权重。我建议直接用 ultralytics 库来加载,省心。

from ultralytics import YOLO

# 加载官方预训练模型(会自动下载权重)
model = YOLO('yolo11n.pt')  # 或者 yolo11s.pt, yolo11m.pt 等

嗯,这里要注意:第一次运行会自动下载权重文件,大概十几兆。如果你在离线环境,可以提前去 GitHub Release 页面手动下载。

我的经验: 我曾经在客户内网部署时忘了这茬,结果现场没网,折腾了半天。建议团队统一维护一个权重缓存目录,避免重复下载。

3.2 运行基准推理

加载完模型,接下来就是跑推理。我们需要两个核心指标:mAP(精度)和 FPS(速度)。

先看精度怎么测。用官方提供的验证脚本,在 COCO val2017 上跑一遍:

# 在验证集上评估 mAP
metrics = model.val(data='coco.yaml', batch=16, imgsz=640)
print(f"mAP50: {metrics.box.map50:.4f}")
print(f"mAP50-95: {metrics.box.map:.4f}")

跑一次大概几分钟,取决于你的 GPU。我一般会记录两个值:mAP50 和 mAP50-95。前者是宽松标准,后者更严格,剪枝后通常先掉的是 mAP50-95。

再看速度。FPS 的测量要讲究方法,不能只跑一张图就下结论:

import time
import torch

def benchmark_fps(model, img_size=640, warmup=50, runs=200):
    # 构造虚拟输入
    dummy_input = torch.randn(1, 3, img_size, img_size).cuda()
    
    # 预热
    for _ in range(warmup):
        _ = model(dummy_input)
    
    # 正式计时
    torch.cuda.synchronize()
    start = time.time()
    for _ in range(runs):
        _ = model(dummy_input)
    torch.cuda.synchronize()
    end = time.time()
    
    fps = runs / (end - start)
    return fps

fps = benchmark_fps(model)
print(f"FPS: {fps:.1f}")
避坑指南: 我曾经犯过一个低级错误——没做 warmup 就直接计时。结果第一次推理因为 CUDA 内核加载,速度慢得离谱,FPS 直接少了一半。预热步骤不能省,至少 50 次迭代。

3.3 记录基线数据

跑完测试,把结果整理成表格。我习惯用下面这个模板:

模型版本 输入尺寸 mAP50 mAP50-95 FPS (RTX 3090) 参数量
yolo11n.pt 640×640 0.524 0.392 215.3 2.6M
yolo11s.pt 640×640 0.613 0.474 148.7 9.4M
yolo11m.pt 640×640 0.658 0.517 89.2 20.1M

你想想看,有了这张表,后面剪枝后的结果往旁边一放,效果一目了然。说白了,这就是你的「对照组」。

3.4 核心流程一览

我把整个基准测试的流程画了张图,方便你对照操作:

基准测试流程 加载预训练权重 运行 val() 评估 mAP benchmark_fps() 测速 记录 mAP + FPS 基线 基线数据是剪枝效果的唯一参照,务必保存到实验记录中

3.5 一些实用建议

  • 固定随机种子: 测速前设置 torch.backends.cudnn.deterministic = True,否则每次结果会有波动。
  • 记录硬件信息: 在表格里注明 GPU 型号和驱动版本。同一个模型在 V100 和 4090 上 FPS 差好几倍。
  • 多测几次取平均: 我一般跑 3 轮,每轮 200 次推理,取平均值。单次测量偶然性太大。
核心要点: 基准测试不是走过场。mAP 和 FPS 的基线数据,决定了你剪枝的「止损线」。比如基线 mAP50-95 是 0.392,你剪完后如果掉到 0.35 以下,那这个剪枝方案就得重新审视。

好了,基线数据已经到手。接下来就可以正式进入剪枝环节了——不过在那之前,我建议你把这张表格存好,后面每一步对比都要用到它。