bev-project/project/docs/剪枝工具使用指南.md

573 lines
13 KiB
Markdown
Raw Normal View History

# BEVFusion 剪枝工具使用指南
**更新时间**: 2025-10-30
**工具类型**: PyTorch内置剪枝适用于PyTorch 1.10+
---
## 📚 剪枝知识快速理解
### 什么是剪枝?
```
训练好的模型中,有些神经元/通道不太重要
剪枝 = 移除这些不重要的部分
结果 = 更小更快的模型,精度略有下降
```
### 剪枝需要重新训练吗?
```
❌ 不是完全重新训练
✅ 只需要短期微调3-5 epochs
对比:
完全训练: 20-24 epochs, 7-8天
剪枝微调: 3-5 epochs, 12-20小时 ← 快30倍
```
### 为什么需要微调?
```
剪枝后 → 精度下降3-5%
微调训练 → 恢复精度,最终损失<2%
微调时间短,因为:
✓ 起点好epoch_23已训练得很好
✓ 只需调整,不需学习新特征
✓ 使用很小的学习率
```
---
## 🛠️ 已准备的工具
### 1. 剪枝脚本
**文件**: `tools/pruning/prune_bevfusion_builtin.py`
**功能**:
- 基于L1范数自动剪枝
- 智能分配各模块剪枝比例
- 保留最重要的通道
### 2. 一键执行脚本
**文件**: `一键剪枝和微调.sh`
**功能**:
- 自动执行剪枝
- 可选启动微调训练
- 生成完整日志
### 3. 分析工具
**文件**: `tools/analysis/analyze_checkpoint.py`
**功能**: 分析剪枝前后的模型
---
## ⚡ 快速开始3种方式
### 方式1: 一键执行(推荐)
```bash
cd /workspace/bevfusion
# 一键剪枝+微调
chmod +x 一键剪枝和微调.sh
bash 一键剪枝和微调.sh
# 根据提示选择:
# [1] 立即微调后台12小时
# [2] 稍后微调
# [3] 先查看结果
```
**适合**: 快速上手用户
---
### 方式2: 分步执行
#### Step 1: 只剪枝15分钟
```bash
cd /workspace/bevfusion
# 执行剪枝
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/bevfusion_pruned_32M.pth \
--target-ratio 0.70
# 输出: bevfusion_pruned_32M.pth (~32M参数)
```
#### Step 2: 查看剪枝结果
```bash
# 分析剪枝后的模型
python tools/analysis/analyze_checkpoint.py \
pruning_results/bevfusion_pruned_32M.pth
```
#### Step 3: 微调训练12小时
```bash
# 仅在对剪枝结果满意后执行
torchpack dist-run -np 8 python tools/train.py \
configs/nuscenes/det/transfusion/secfpn/camera+lidar/swint_v0p075/multitask_enhanced_phase1_HIGHRES.yaml \
--load_from pruning_results/bevfusion_pruned_32M.pth \
--run-dir runs/pruned_finetune \
--cfg-options \
max_epochs=3 \
optimizer.lr=5.0e-6 \
data.samples_per_gpu=2 \
data.workers_per_gpu=0
```
**适合**: 想逐步控制的用户
---
### 方式3: 仅剪枝不微调(测试用)
```bash
# 快速剪枝测试
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/test_pruned.pth \
--target-ratio 0.80 # 保守测试只剪20%
# 查看结果
python tools/analysis/analyze_checkpoint.py \
pruning_results/test_pruned.pth
```
**适合**: 想先测试效果的用户
---
## 📊 剪枝参数说明
### --target-ratio 参数
| 值 | 含义 | 保留参数 | 剪枝比例 | 适用场景 |
|----|------|---------|---------|---------|
| 0.80 | 保留80% | 36.6M | 20%剪枝 | 保守测试 |
| **0.70** | **保留70%** | **32M** | **30%剪枝** | **推荐** ✅ |
| 0.60 | 保留60% | 27.4M | 40%剪枝 | 激进优化 |
| 0.50 | 保留50% | 22.9M | 50%剪枝 | 极限压缩 |
**推荐**: 0.70保留70%剪枝30%
- 平衡精度和大小
- 预期精度损失<2%
- 适合Orin部署
---
## 🎯 剪枝策略详解
### 自动分配的剪枝比例
剪枝脚本会自动对不同模块使用不同比例:
```python
剪枝计划:
encoders.camera.backbone: 剪20% # 最大模块,温和剪枝
heads.map.aspp: 剪25% # ASPP模块可适度剪枝
decoder: 剪15% # Decoder保守剪枝
encoders.camera.vtransform: 剪10% # VTransform轻度剪枝
其他模块: 不剪枝如LiDAR backbone, heads等
```
### 为什么这样分配?
1. **Camera Backbone (27.55M, 60%)**
- 最大模块,剪枝收益最大
- 但也重要所以只剪20%
2. **ASPP (4.13M, 9%)**
- 可以适度剪枝25%
- 主要影响分割,检测不受影响
3. **Decoder (4.58M, 10%)**
- 保守剪枝15%
- 影响最终特征质量
4. **不剪枝的模块**
- LiDAR Backbone: 已经很小2.7M
- Detection Head: 影响检测精度
- Fuser: 很小0.78M
---
## ⏱️ 完整流程时间表
### 今天(准备阶段)
```
✅ 创建剪枝工具 (已完成)
⏳ 测试剪枝功能 (5分钟)
⏳ 执行实际剪枝 (15分钟)
⏳ 分析剪枝结果 (5分钟)
总计: ~30分钟
```
### 明天(微调阶段)
```
启动微调训练:
- 3 epochs
- 每epoch ~4小时
- 总计: 12小时后台运行
监控和评估:
- 监控loss下降
- Epoch 3完成后评估
```
### 后天(评估和量化)
```
评估剪枝效果:
- 对比epoch_23 baseline
- 确认精度损失<2%
如果满意:
→ 进入INT8量化阶段
```
---
## 📋 执行检查清单
### 剪枝前检查
- [x] Checkpoint存在: epoch_23.pth ✅
- [x] 剪枝工具已创建 ✅
- [x] 输出目录已创建 ✅
- [ ] Stage 1训练状态不要冲突
### 剪枝中检查
- [ ] 剪枝进度正常
- [ ] 无错误信息
- [ ] 输出文件生成
### 剪枝后检查
- [ ] 参数量符合预期(~32M
- [ ] 模型文件完整
- [ ] 可正常加载
### 微调前检查
- [ ] GPU资源可用8张或4张
- [ ] 配置文件正确
- [ ] 学习率设置合理5e-6
---
## 🚀 立即执行命令
### 快速测试5分钟
```bash
cd /workspace/bevfusion
# 小规模剪枝测试剪20%
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/test_pruned_20percent.pth \
--target-ratio 0.80
# 查看结果
python tools/analysis/analyze_checkpoint.py \
pruning_results/test_pruned_20percent.pth
```
### 正式剪枝15分钟
```bash
# 剪枝30%(推荐)
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/bevfusion_pruned_32M.pth \
--target-ratio 0.70
```
### 一键完整流程
```bash
# 自动化执行剪枝+询问是否微调
bash 一键剪枝和微调.sh
```
---
## 📊 预期结果
### 剪枝后(立即)
```
参数量: 45.72M → ~32M (-30%)
模型大小: 174MB → ~122MB (FP32)
精度: 未知(需要评估或微调)
预期精度损失(剪枝直接评估): 3-5%
```
### 微调后12小时后
```
参数量: 32M不变
模型大小: ~122MB (FP32)
精度恢复: 预期损失<2%
NDS: 0.6941 → 0.680-0.690
mAP: 0.6446 → 0.630-0.640
mIoU: 0.4130 → 0.400-0.410
```
### INT8量化后5天后
```
参数量: 32M不变
模型大小: 122MB → 30MB (INT8)
精度: 微调后基础上再损失<1%
总精度损失: <3%
推理加速: 2-3倍
```
---
## 🔍 监控剪枝和微调
### 剪枝过程监控
```bash
# 实时查看剪枝进度
tail -f pruning_results/pruning_log_*.txt
```
### 微调过程监控
```bash
# 查看微调训练
tail -f runs/pruned_finetune_*/finetune.log | grep "Epoch \["
# 查看GPU状态
watch -n 10 nvidia-smi
```
---
## ⚠️ 注意事项
### 1. 与Stage 1训练的关系
- **Stage 1训练**: 使用GPU 0-3还需~9天
- **剪枝操作**: CPU操作15分钟
- **微调训练**: 建议等Stage 1完成后再启动
- 或者使用不同的GPU
### 2. 剪枝的不可逆性
- 剪枝后无法直接恢复被删除的通道
- 建议保留原始checkpointepoch_23.pth
- 剪枝后的模型需要微调才能使用
### 3. 微调的重要性
```
剪枝不微调: 精度损失3-5% ❌
剪枝+微调: 精度损失<2%
微调时间: 仅12小时
收益: 恢复2-3%精度
结论: 微调必不可少!
```
---
## 📂 工具文件清单
```
工具和脚本:
├── tools/pruning/
│ ├── prune_bevfusion_builtin.py # 剪枝主脚本
│ └── test_pruning.py # 测试工具可用性
├── tools/analysis/
│ └── analyze_checkpoint.py # 分析模型
├── 一键剪枝和微调.sh # 一键执行
└── 剪枝工具使用指南.md # 本文档
结果目录:
├── pruning_results/
│ ├── bevfusion_pruned_32M.pth # 剪枝后模型(待生成)
│ ├── pruning_log_*.txt # 剪枝日志
│ └── pruning_plan.md # 剪枝方案
└── runs/pruned_finetune_*/
├── epoch_1.pth # 微调checkpoint
├── epoch_2.pth
├── epoch_3.pth
└── finetune.log # 微调日志
```
---
## 🎯 三种使用场景
### 场景1: 我想快速测试剪枝效果
```bash
# 小规模剪枝测试剪20%
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/test_20percent.pth \
--target-ratio 0.80
# 立即查看结果
python tools/analysis/analyze_checkpoint.py \
pruning_results/test_20percent.pth
# 时间: 5分钟
# 风险: 无
```
---
### 场景2: 我想正式剪枝,但手动控制微调
```bash
# Step 1: 剪枝15分钟
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/bevfusion_pruned_32M.pth \
--target-ratio 0.70
# Step 2: 查看结果,决定是否满意
python tools/analysis/analyze_checkpoint.py \
pruning_results/bevfusion_pruned_32M.pth
# Step 3: 如果满意等Stage 1完成后启动微调
# (或者现在启动使用不同GPU)
```
---
### 场景3: 我想一键完成所有操作
```bash
# 一键执行,自动询问
bash 一键剪枝和微调.sh
# 根据提示选择是否立即微调
# 如果选择[1],会自动后台启动微调
```
---
## 📊 剪枝效果预期
### 立即效果(剪枝后,未微调)
```
参数量: 45.72M → 32M ✅
模型大小: 174MB → 122MB ✅
推理速度: 预计提升20-30% ✅
精度: 预计下降3-5% ⚠️
此时的模型:
- 可以运行
- 但精度不够
- 需要微调恢复
```
### 微调后效果12小时后
```
参数量: 32M ✅
模型大小: 122MB ✅
推理速度: 提升20-30% ✅
精度损失: <2%
预期性能:
NDS: 0.680-0.690 (vs 0.6941)
mAP: 0.630-0.640 (vs 0.6446)
mIoU: 0.400-0.410 (vs 0.4130)
```
---
## 🚀 推荐执行流程
### 今天30分钟
```bash
# 1. 快速测试5分钟
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/test_pruned.pth \
--target-ratio 0.80
# 2. 查看测试结果2分钟
python tools/analysis/analyze_checkpoint.py \
pruning_results/test_pruned.pth
# 3. 如果满意执行正式剪枝15分钟
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/bevfusion_pruned_32M.pth \
--target-ratio 0.70
# 4. 分析剪枝结果2分钟
python tools/analysis/analyze_checkpoint.py \
pruning_results/bevfusion_pruned_32M.pth
```
### 等Stage 1完成后~9天后
```bash
# 启动微调训练12小时
torchpack dist-run -np 8 python tools/train.py \
configs/.../multitask_enhanced_phase1_HIGHRES.yaml \
--load_from pruning_results/bevfusion_pruned_32M.pth \
--run-dir runs/pruned_finetune \
--cfg-options \
max_epochs=3 \
optimizer.lr=5.0e-6
```
---
## 💡 常见问题
### Q1: 剪枝会损坏模型吗?
**A**: 不会。剪枝只是移除部分通道,模型结构依然完整,可以正常推理。只是精度会下降,需要微调恢复。
### Q2: 可以不微调直接使用吗?
**A**: 可以但不推荐。剪枝后精度会下降3-5%微调12小时可以恢复大部分精度最终损失<2%非常值得
### Q3: 微调可以用更少的GPU吗
**A**: 可以。可以用4张或6张GPU时间会相应延长。
```bash
# 使用4张GPU微调
torchpack dist-run -np 4 python tools/train.py ...
# 时间: ~18小时
```
### Q4: 剪枝失败了怎么办?
**A**:
1. 原始checkpointepoch_23.pth不会被修改
2. 可以重新尝试不同的剪枝比例
3. 或者跳过剪枝直接进行INT8量化
### Q5: 微调失败了怎么办?
**A**:
1. 剪枝后的模型已保存,可以重新微调
2. 尝试更小的学习率1e-6
3. 或者减少剪枝比例重新开始
---
## 🎉 总结
### 剪枝需要训练吗?
```
✅ 需要,但是短期微调,不是完全重新训练
时间对比:
完全训练: 7-8天
剪枝微调: 12小时 ← 快14倍
结论: 剪枝+微调是性价比最高的优化方式
```
### 立即可执行
```bash
# 现在就可以开始剪枝不影响Stage 1训练
cd /workspace/bevfusion
bash 一键剪枝和微调.sh
# 或者分步执行(更可控)
python tools/pruning/prune_bevfusion_builtin.py \
--checkpoint runs/enhanced_from_epoch19/epoch_23.pth \
--output pruning_results/bevfusion_pruned_32M.pth \
--target-ratio 0.70
```
---
**工具状态**: ✅ 已准备就绪
**可立即执行**: 是
**建议**: 先快速测试,满意后正式剪枝