Files
RoRD-Layout-Recognation/docs/description/Performance_Benchmark.md
2025-10-20 10:08:35 -04:00

20 KiB
Raw Permalink Blame History

性能基准报告 — Backbone A/B 与 FPN 对比

最后更新2025-10-20
设备CPU无 GPU
输入1×3×512×512 随机张量
重复次数5每组

说明:本报告为初步 CPU 前向测试,主要用于比较不同骨干的相对推理耗时。实际业务场景与 GPU 上的结论可能不同,建议在目标环境再次复测。

结果汇总ms

Backbone Single Mean ± Std FPN Mean ± Std
vgg16 392.03 ± 4.76 821.91 ± 4.17
resnet34 105.01 ± 1.57 131.17 ± 1.66
efficientnet_b0 62.02 ± 2.64 161.71 ± 1.58
  • 备注:本次测试在 CPU 上进行,gpu_mem_mb 始终为 0。

注意力 A/BCPUresnet34512×512runs=10places=backbone_high+desc_head

Attention Single Mean ± Std FPN Mean ± Std
none 97.57 ± 0.55 124.57 ± 0.48
se 101.48 ± 2.13 123.12 ± 0.50
cbam 119.80 ± 2.38 123.11 ± 0.71

观察:

  • 单尺度路径对注意力类型更敏感CBAM 开销相对更高SE 较轻;
  • FPN 路径耗时在本次设置下差异很小(可能因注意力仅在 backbone_high/desc_head,且 FPN 头部计算占比较高)。

复现实验:

PYTHONPATH=. uv run python tests/benchmark_attention.py \
  --device cpu --image-size 512 --runs 10 \
  --backbone resnet34 --places backbone_high desc_head

三维基准Backbone × Attention × Single/FPN

环境CPU输入 1×3×512×512重复 3 次places=backbone_high,desc_head。

Backbone Attention Single Mean ± Std (ms) FPN Mean ± Std (ms)
vgg16 none 351.65 ± 1.88 719.33 ± 3.95
vgg16 se 349.76 ± 2.00 721.41 ± 2.74
vgg16 cbam 354.45 ± 1.49 744.76 ± 29.32
resnet34 none 90.99 ± 0.41 117.22 ± 0.41
resnet34 se 90.78 ± 0.47 115.91 ± 1.31
resnet34 cbam 96.50 ± 3.17 111.09 ± 1.01
efficientnet_b0 none 40.45 ± 1.53 127.30 ± 0.09
efficientnet_b0 se 46.48 ± 0.26 142.35 ± 6.61
efficientnet_b0 cbam 47.11 ± 0.47 150.99 ± 12.47

复现实验:

PYTHONPATH=. uv run python tests/benchmark_grid.py \
  --device cpu --image-size 512 --runs 3 \
  --backbones vgg16 resnet34 efficientnet_b0 \
  --attentions none se cbam \
  --places backbone_high desc_head

运行会同时输出控制台摘要并保存 JSONbenchmark_grid.json

GPU 测试结果A100

最后更新2025-01-XX
设备NVIDIA A100CUDA
输入1×3×512×512 随机张量
重复次数5每组
注意力放置位置backbone_high

说明:本测试在 A100 GPU 上进行,展示了不同骨干网络和注意力模块组合在 GPU 上的推理性能。

结果汇总ms

Backbone Attention Single Mean ± Std FPN Mean ± Std
vgg16 none 4.53 ± 0.02 8.51 ± 0.002
vgg16 se 3.80 ± 0.01 7.12 ± 0.004
vgg16 cbam 3.73 ± 0.02 6.95 ± 0.09
resnet34 none 2.32 ± 0.04 2.73 ± 0.007
resnet34 se 2.33 ± 0.01 2.73 ± 0.004
resnet34 cbam 2.46 ± 0.04 2.74 ± 0.004
efficientnet_b0 none 3.69 ± 0.07 4.38 ± 0.02
efficientnet_b0 se 3.76 ± 0.06 4.37 ± 0.03
efficientnet_b0 cbam 3.99 ± 0.08 4.41 ± 0.02

复现实验:

PYTHONPATH=. uv run python tests/benchmark_grid.py \
  --device cuda --image-size 512 --runs 5 \
  --backbones vgg16 resnet34 efficientnet_b0 \
  --attentions none se cbam \
  --places backbone_high

GPU 测试观察

  • ResNet34 表现最佳:在 GPU 上ResNet34 在单尺度和 FPN 路径上都表现出色,单尺度约 2.3msFPN 约 2.7ms。
  • VGG16 在 GPU 上仍有明显开销:尽管在 GPU 上加速VGG16 仍然是三种骨干中最慢的,单尺度约 3.7-4.5ms。
  • EfficientNet-B0 表现中等:在 GPU 上介于 VGG16 和 ResNet34 之间,单尺度约 3.7-4.0ms。
  • 注意力模块影响较小:在 GPU 上注意力模块SE、CBAM对性能的影响相对较小FPN 路径上的差异尤其不明显。
  • FPN 开销相对可控:在 GPU 上FPN 路径相比单尺度的额外开销较小ResNet34 仅增加约 18%。

观察与解读

  • vgg16 明显最慢FPN 额外的横向/上采样代价在 CPU 上更突出(>2×
  • resnet34 在单尺度上显著快于 vgg16FPN 增幅较小(约 +25%)。
  • efficientnet_b0 单尺度最快,但 FPN 路径的额外代价相对较高(约 +161%)。

建议

  1. 训练/推理优先考虑 resnet34 或 efficientnet_b0 替代 vgg16以获得更好的吞吐若业务更多依赖多尺度鲁棒性则进一步权衡 FPN 的开销。
  2. 在 GPU 与真实数据上复测:
  • 固定输入尺寸与批次,比较三种骨干在单尺度与 FPN 的耗时与显存。
  • 对齐预处理(utils/data_utils.get_transform)并验证检测/匹配效果。
  1. 若选择 efficientnet_b0建议探索更适配的中间层组合例如 features[3]/[4]/[6]),以在精度与速度上取得更好的折中。

复现实验

  • 安装依赖并在仓库根目录执行:
# CPU 复现
PYTHONPATH=. uv run python tests/benchmark_backbones.py --device cpu --image-size 512 --runs 5

# CUDA 复现(如可用)
PYTHONPATH=. uv run python tests/benchmark_backbones.py --device cuda --runs 20 --backbones vgg16 resnet34 efficientnet_b0

附:脚本与实现位置

  • 模型与 FPN 实现:models/rord.py
  • 骨干 A/B 基准脚本:tests/benchmark_backbones.py
  • 相关说明:docs/description/Backbone_FPN_Test_Change_Notes.md

🚀 性能基准测试报告

完成日期: 2025-10-20
测试工具: tests/benchmark_fpn.py
对标对象: FPN 推理 vs 滑窗推理


📋 目录

  1. 执行摘要
  2. 测试环境
  3. 测试方法
  4. 测试数据
  5. 性能指标
  6. 对标结果
  7. 分析与建议
  8. 使用指南

执行摘要

本报告对比了 FPN特征金字塔网络推理路径传统滑窗推理路径 的性能差异。

🎯 预期目标

指标 目标 说明
推理速度 FPN 提速 ≥ 30% 同输入条件下FPN 路径应快 30% 以上
内存占用 内存节省 ≥ 20% GPU 显存占用应降低 20% 以上
检测精度 无下降 关键点数和匹配内点数应相当或更优

测试环境

硬件配置

GPU: NVIDIA CUDA 计算能力 >= 7.0(可选 CPU
内存: >= 8GB RAM
显存: >= 8GB VRAM推荐 16GB+

软件环境

Python: >= 3.12
PyTorch: >= 2.7.1
CUDA: >= 12.1(如使用 GPU
关键依赖:
  - torch
  - torchvision
  - numpy
  - psutil (用于内存监测)

配置文件

使用默认配置 configs/base_config.yaml

model:
  fpn:
    enabled: true
    out_channels: 256
    levels: [2, 3, 4]

matching:
  keypoint_threshold: 0.5
  pyramid_scales: [0.75, 1.0, 1.5]
  inference_window_size: 1024
  inference_stride: 768
  use_fpn: true
  nms:
    enabled: true
    radius: 4
    score_threshold: 0.5

测试方法

1. 测试流程

┌─────────────────────────────────────┐
│      加载模型与预处理配置            │
└────────────┬────────────────────────┘
             │
    ┌────────▼────────┐
    │  FPN 路径测试   │
    │  (N 次运行)     │
    └────────┬────────┘
             │
    ┌────────▼────────┐
    │ 滑窗路径测试    │
    │  (N 次运行)     │
    └────────┬────────┘
             │
    ┌────────▼────────┐
    │  计算对标指标   │
    │  生成报告       │
    └─────────────────┘

2. 性能指标采集

每个方法的每次运行采集以下指标:

指标 说明 单位
推理时间 从特征提取到匹配完成的总耗时 ms
关键点数 检测到的关键点总数
匹配数 通过互近邻匹配的对应点对数
GPU 内存 推理过程中显存峰值 MB

3. 运行方式

基础命令:

uv run python tests/benchmark_fpn.py \
  --layout /path/to/layout.png \
  --template /path/to/template.png \
  --num-runs 5 \
  --output benchmark_results.json

完整参数:

uv run python tests/benchmark_fpn.py \
  --config configs/base_config.yaml \
  --model_path path/to/save/model_final.pth \
  --layout /path/to/layout.png \
  --template /path/to/template.png \
  --num-runs 5 \
  --output benchmark_results.json \
  --device cuda

测试数据

数据集要求

测试数据应满足以下条件:

条件 说明 推荐值
版图尺寸 大版图,代表实际应用场景 ≥ 2000×2000 px
模板尺寸 中等尺寸,能在版图中找到 500×500~1000×1000 px
版图类型 实际电路版图或相似图像 PNG/JPEG 格式
模板类型 版图中的某个器件或结构 PNG/JPEG 格式
质量 清晰,具代表性 适当的对比度和细节

数据准备步骤

  1. 准备版图和模板

    # 将测试数据放在合适位置
    mkdir -p test_data
    cp /path/to/layout.png test_data/
    cp /path/to/template.png test_data/
    
  2. **验证数据

    # 检查图像尺寸和格式
    python -c "
    from PIL import Image
    layout = Image.open('test_data/layout.png')
    template = Image.open('test_data/template.png')
    print(f'Layout size: {layout.size}')
    print(f'Template size: {template.size}')
    "
    

性能指标

1. 原始数据格式

测试脚本输出 JSON 文件,包含以下结构:

{
  "timestamp": "2025-10-20 14:30:45",
  "config": "configs/base_config.yaml",
  "model_path": "path/to/model_final.pth",
  "layout_path": "test_data/layout.png",
  "layout_size": [3000, 2500],
  "template_path": "test_data/template.png",
  "template_size": [800, 600],
  "device": "cuda:0",
  "fpn": {
    "method": "FPN",
    "mean_time_ms": 245.32,
    "std_time_ms": 12.45,
    "min_time_ms": 230.21,
    "max_time_ms": 268.91,
    "all_times_ms": [...],
    "mean_keypoints": 1523.4,
    "mean_matches": 187.2,
    "gpu_memory_mb": 1024.5,
    "num_runs": 5
  },
  "sliding_window": {
    "method": "Sliding Window",
    "mean_time_ms": 352.18,
    "std_time_ms": 18.67,
    ...
  },
  "comparison": {
    "speedup_percent": 30.35,
    "memory_saving_percent": 21.14,
    "fpn_faster": true,
    "meets_speedup_target": true,
    "meets_memory_target": true
  }
}

2. 主要性能指标

推理时间:

  • 平均耗时 (mean_time_ms)
  • 标准差 (std_time_ms)
  • 最小/最大耗时范围

关键点检测:

  • 平均关键点数量
  • 影响因素keypoint_thresholdNMS 半径

匹配性能:

  • 平均匹配对数量
  • 反映特征匹配质量

内存效率:

  • GPU 显存占用 (MB)
  • CPU 内存占用可选

3. 对标指标

指标 计算公式 目标值 说明
推理速度提升 (SW_time - FPN_time) / SW_time × 100% ≥ 30% 正值表示 FPN 更快
内存节省 (SW_mem - FPN_mem) / SW_mem × 100% ≥ 20% 正值表示 FPN 更省
精度保证 FPN_matches ≥ SW_matches × 0.95 匹配数不显著下降

对标结果

测试执行

运行测试脚本,预期输出示例:

================================================================================
                            性能基准测试结果
================================================================================

指标                        FPN                  滑窗
----------------------------------------------------------------------
平均推理时间 (ms)          245.32               352.18
标准差 (ms)                12.45                18.67
最小时间 (ms)              230.21               328.45
最大时间 (ms)              268.91               387.22

平均关键点数               1523                 1687
平均匹配数                 187                  189

GPU 内存占用 (MB)          1024.5               1305.3

================================================================================
                              对标结果
================================================================================

推理速度提升: +30.35% ✅
  (目标: ≥30% | 达成: 是)

内存节省: +21.14% ✅
  (目标: ≥20% | 达成: 是)

🎉 FPN 相比滑窗快 30.35%

================================================================================

预期结果分析

根据设计预期:

情况 速度提升 内存节省 匹配数 判断
最佳 ≥30% ≥20% 相当/更优 FPN 完全优于滑窗
良好 20-30% 15-20% 相当/更优 FPN 显著优于滑窗
⚠️ 可接受 10-20% 5-15% 相当 FPN 略优,需验证
需改进 <10% <5% 下降 需要优化 FPN

分析与建议

1. 性能原因分析

FPN 优势

  • 多尺度特征复用: 单次前向传播提取所有尺度,避免重复计算
  • 显存效率: 特征金字塔共享骨干网络的显存占用
  • 推理时间: 避免多次图像缩放和前向传播

滑窗劣势

  • 重复计算: 多个 stride 下重复特征提取
  • 显存压力: 窗口缓存和中间特征占用
  • I/O 开销: 图像缩放和逐窗口处理

2. 优化建议

如果 FPN 性能未达预期:

  1. 检查模型配置

    # configs/base_config.yaml
    model:
      fpn:
        out_channels: 256  # 尝试降低至 128
        norm: "bn"         # 尝试 "gn" 或 "none"
    
  2. 优化关键点提取

    matching:
      keypoint_threshold: 0.5  # 调整阈值
      nms:
        radius: 4  # 调整 NMS 半径
    
  3. 批量处理优化

    • 使用更大的 batch size如果显存允许
    • 启用 GPU 预热和同步
  4. 代码优化

    • 减少 Python 循环,使用向量化操作
    • 使用 torch.jit.script 编译关键函数

3. 后续测试步骤

  1. 多数据集测试

    • 测试多张不同尺寸的版图
    • 验证性能的稳定性
  2. 精度验证

    # 对比 FPN vs 滑窗的检测结果
    # 确保关键点和匹配内点相当或更优
    
  3. 混合模式测试

    • 小图像:考虑单尺度推理
    • 大图像:使用 FPN 路径
  4. 实际应用验证

    • 在真实版图上测试
    • 验证检测精度和召回率

使用指南

快速开始

1. 准备测试数据

# 创建测试目录
mkdir -p test_data

# 放置版图和模板(需要自己准备)
# test_data/layout.png
# test_data/template.png

2. 运行测试

# 5 次运行,输出 JSON 结果
uv run python tests/benchmark_fpn.py \
  --layout test_data/layout.png \
  --template test_data/template.png \
  --num-runs 5 \
  --output results/benchmark_fpn.json

3. 查看结果

# JSON 格式结果
cat results/benchmark_fpn.json | python -m json.tool

# 手动解析 JSON
python -c "
import json
with open('results/benchmark_fpn.json') as f:
    data = json.load(f)
    comparison = data['comparison']
    print(f\"Speed: {comparison['speedup_percent']:.2f}%\")
    print(f\"Memory: {comparison['memory_saving_percent']:.2f}%\")
"

高级用法

1. 多组测试对比

# 测试不同配置
for nms_radius in 2 4 8; do
  uv run python tests/benchmark_fpn.py \
    --layout test_data/layout.png \
    --template test_data/template.png \
    --output results/benchmark_nms_${nms_radius}.json
done

2. CPU vs GPU 对比

# GPU 测试
uv run python tests/benchmark_fpn.py \
  --layout test_data/layout.png \
  --template test_data/template.png \
  --device cuda \
  --output results/benchmark_gpu.json

# CPU 测试
uv run python tests/benchmark_fpn.py \
  --layout test_data/layout.png \
  --template test_data/template.png \
  --device cpu \
  --output results/benchmark_cpu.json

3. 详细日志输出

# 添加调试输出(需要修改脚本)
# 测试脚本会打印每次运行的详细信息
uv run python tests/benchmark_fpn.py \
  --layout test_data/layout.png \
  --template test_data/template.png \
  --num-runs 5 \
  --output results/benchmark.json 2>&1 | tee benchmark.log

常见问题

Q1: 测试失败,提示 "找不到模型"

# 检查模型路径
ls -la path/to/save/model_final.pth

# 指定模型路径
uv run python tests/benchmark_fpn.py \
  --model_path /absolute/path/to/model.pth \
  --layout test_data/layout.png \
  --template test_data/template.png

Q2: GPU 内存不足

# 使用较小的图像测试
uv run python tests/benchmark_fpn.py \
  --layout test_data/layout_small.png \
  --template test_data/template_small.png

# 或使用 CPU
uv run python tests/benchmark_fpn.py \
  --layout test_data/layout.png \
  --template test_data/template.png \
  --device cpu

Q3: 性能数据波动大

# 增加运行次数取平均
uv run python tests/benchmark_fpn.py \
  --layout test_data/layout.png \
  --template test_data/template.png \
  --num-runs 10  # 从 5 增加到 10

附录

A. 脚本接口

# 编程调用
from tests.benchmark_fpn import benchmark_fpn, benchmark_sliding_window
from models.rord import RoRD
from utils.data_utils import get_transform
from PIL import Image
import torch

model = RoRD().cuda()
model.load_state_dict(torch.load("path/to/model.pth"))
model.eval()

layout_img = Image.open("layout.png").convert('L')
template_img = Image.open("template.png").convert('L')
transform = get_transform()

# 获取 YAML 配置
from utils.config_loader import load_config
cfg = load_config("configs/base_config.yaml")

# 测试 FPN
fpn_result = benchmark_fpn(
    model, layout_img, template_img, transform, 
    cfg.matching, num_runs=5
)

print(f"FPN 平均时间: {fpn_result['mean_time_ms']:.2f}ms")

B. 导出 TensorBoard 数据

配合导出工具 tools/export_tb_summary.py 导出训练日志:

# 导出 TensorBoard 标量数据
uv run python tools/export_tb_summary.py \
  --log-dir runs/train/baseline \
  --output-format csv \
  --output-file export_train_metrics.csv

C. 参考资源


📝 更新日志

日期 版本 变更
2025-10-20 v1.0 初始版本:完整的 FPN vs 滑窗性能对标文档

验收清单

性能基准测试已完成以下内容:

  • 创建 tests/benchmark_fpn.py 测试脚本

    • FPN 性能测试函数
    • 滑窗性能测试函数
    • 性能对标计算
    • JSON 结果输出
  • 创建性能基准测试报告(本文档)

    • 测试方法和流程
    • 性能指标说明
    • 对标结果分析
    • 优化建议
  • 支持多种配置和参数

    • CLI 参数灵活配置
    • 支持 CPU/GPU 切换
    • 支持自定义模型路径
  • 完整的文档和示例

    • 快速开始指南
    • 高级用法示例
    • 常见问题解答

🎉 性能基准测试工具已就绪!

下一步:准备测试数据,运行测试,并根据结果优化模型配置。