bev-project/docs/technical/CHECKPOINT_LOADING_STRATEGY.md

5.5 KiB
Raw Permalink Blame History

Task-specific GCA - Checkpoint部分加载策略


🎯 加载策略说明

问题

epoch_5.pth (旧checkpoint):
  ✅ encoders.camera
  ✅ encoders.lidar
  ✅ fuser
  ✅ decoder.backbone
  ✅ decoder.neck
  ✅ heads.object
  ✅ heads.map
  ❌ task_gca (不存在)

新模型 (Task-specific GCA):
  ✅ encoders.camera
  ✅ encoders.lidar
  ✅ fuser
  ✅ decoder.backbone
  ✅ decoder.neck
  ✅ heads.object
  ✅ heads.map
  ✨ task_gca['object'] (新增)
  ✨ task_gca['map'] (新增)

解决方案: 部分加载


📊 两种加载方式对比

方式1: --resume-from (严格加载)

--resume-from epoch_5.pth

行为:

  • 加载模型权重
  • 加载optimizer状态
  • 加载学习率调度器
  • 恢复epoch和iteration
  • 严格匹配:所有键必须完全一致
  • 问题checkpoint中没有task_gca会报错或警告

结果: 不适用(模型结构已改变)


方式2: --load_from (部分加载) 推荐

--load_from epoch_5.pth

行为:

  • 只加载模型权重
  • 忽略不匹配的键
  • checkpoint有但新模型没有的键忽略
  • 新模型有但checkpoint没有的键随机初始化
  • 不加载optimizer重新初始化
  • 不加载epoch从配置文件中的起始epoch开始

结果: 适用于模型结构改变的情况


🔄 具体加载过程

Step 1: 加载已有权重

从epoch_5.pth加载:
  ✅ encoders.camera.backbone.*        (Swin Transformer~88M参数)
  ✅ encoders.camera.neck.*            (FPN~3M参数)
  ✅ encoders.camera.vtransform.*      (LSSTransform~2M参数)
  ✅ encoders.lidar.voxelize.*         (Voxelization)
  ✅ encoders.lidar.backbone.*         (Sparse Encoder~8M参数)
  ✅ fuser.*                           (ConvFuser~0.2M参数)
  ✅ decoder.backbone.*                (SECOND~5M参数)
  ✅ decoder.neck.*                    (SECONDFPN~3M参数)
  ✅ heads.object.*                    (TransFusion~15M参数)
  ✅ heads.map.*                       (EnhancedBEVSeg~8M参数)

总计: ~132M参数从checkpoint加载

Step 2: 随机初始化新模块

新增模块checkpoint中不存在:
  ✨ task_gca.object.avg_pool          (AdaptiveAvgPool2d)
  ✨ task_gca.object.fc.0              (Conv2d: 512→128)
  ✨ task_gca.object.fc.2              (Conv2d: 128→512)
  ✨ task_gca.map.avg_pool             (AdaptiveAvgPool2d)
  ✨ task_gca.map.fc.0                 (Conv2d: 512→128)
  ✨ task_gca.map.fc.2                 (Conv2d: 128→512)

总计: ~0.26M参数随机初始化

📝 日志验证

启动后应该看到

Loading checkpoint from /workspace/bevfusion/runs/run-326653dc-2334d461/epoch_5.pth

The following keys in checkpoint are not matched with model:
  (可能会列出一些不需要的键,可以忽略)

The following keys in model are not found in checkpoint:
  task_gca.object.fc.0.weight
  task_gca.object.fc.2.weight
  task_gca.map.fc.0.weight
  task_gca.map.fc.2.weight
  ... (task_gca相关的所有参数)

✅ 这是正常的!这些参数会被随机初始化。

🎯 训练策略

Epoch和学习率

配置文件设置:
  max_epochs: 20
  
加载checkpoint:
  --load_from epoch_5.pth
  
实际行为:
  ✅ 从epoch 0开始配置中的默认值
  ✅ 学习率从初始值开始
  ✅ Optimizer重新初始化

如果想从epoch 6继续:
  在配置中设置: start_epoch: 6
  或命令行: --cfg-options runner.start_epoch=6

建议策略

方案A: 从epoch 0重新开始 (保守,推荐用于新架构) ✅
  - 让task_gca模块充分学习
  - 整个模型重新适应新架构
  - max_epochs: 20 (epoch 0-19)
  
方案B: 从epoch 6继续 (激进)
  - 节省已训练的5个epoch
  - max_epochs: 20 (epoch 6-19共14 epochs)
  - 需要验证task_gca初始化是否影响训练稳定性

当前使用: 方案A (从epoch 0开始)


🔍 权重匹配检查

成功加载的标志

# 检查日志中的权重加载信息
grep "load checkpoint" /data/runs/phase4a_stage1_task_gca/*.log

# 应该看到:
load checkpoint from local path: /workspace/bevfusion/runs/.../epoch_5.pth

验证task_gca是否正确初始化

# 检查模型初始化日志
grep "Task-specific GCA" /data/runs/phase4a_stage1_task_gca/*.log

# 应该看到:
[BEVFusion] ✨✨ Task-specific GCA mode enabled ✨✨
  [object] GCA: params: 131,072
  [map] GCA: params: 131,072

📊 参数统计

总参数: ~132.26M
  
从checkpoint加载: ~132.00M (99.8%)
  ├─ Encoders: ~93M
  ├─ Fuser: ~0.2M
  ├─ Decoder: ~8M
  ├─ Detection Head: ~15M
  └─ Segmentation Head: ~8M

随机初始化: ~0.26M (0.2%)
  ├─ task_gca['object']: ~0.13M
  └─ task_gca['map']: ~0.13M

优势

1. ✅ 最大化利用已训练权重
   - 骨干、neck、heads都保留训练成果
   - 只有262K参数需要重新学习

2. ✅ 避免加载冲突
   - 不会因为结构不匹配报错
   - 灵活处理新增模块

3. ✅ 训练稳定性
   - 大部分参数已经收敛
   - 只需微调task_gca模块

4. ✅ 快速收敛
   - 预期3-5 epochs内task_gca收敛
   - 整体性能提升明显

🚀 启动命令

# 在Docker容器内
cd /workspace/bevfusion
bash START_PHASE4A_TASK_GCA.sh

# 脚本会自动使用 --load_from 策略

🎯 部分加载策略完美解决了模型结构改变的问题!