已关闭
[Bug]: LoRA 微调 adapter-only 存盘仍写入全量 DCP,每次保存无谓复制冻结基模型(~36G) #577
iceflysnow创建于  8月7日关闭于  6 天前
iceflysnow
8月7日 创建

环境信息

- 昇腾硬件:8 × 910B2
- CANN:25.3.RC1
- torch_npu:2.7.1
- 代码版本:master 分支,HEAD 852ddffd(2026-08-07)
- 模型:Qwen3.5-9B(LoRA r=8)

问题描述

在 LoRA 微调 + 仅导出 adapter(no_save_optim: trueno_save_rng: true)的配置下,每次 checkpoint 保存虽然正确写出了 adapter 的 .safetensors,但控制流未在此处返回,继续落入下方的「全量模型 DCP 写入」分支,导致每个 iter 的 save 都把冻结的基模型整份再写一遍(Qwen3.5-9B 约 36G/次)。

既无训练态可续(optim/rng 都不存),全量 DCP 写只服务于 resumption,此刻纯属浪费:磁盘与 IO 被吞掉,但训练本身不崩,是静默 bug

根因

mindspeed_mm/fsdp/train/train_engine.py save() 方法,LoRA 分支在 save_lora_only(...) 之后没有 return,直接落到 # Default save behavior (full model) 的全量 DCP 写入:

https://gitcode.com/Ascend/MindSpeed-MM/blob/master/mindspeed_mm/fsdp/train/train_engine.py#L390-L404

def save(self, iteration, consumed_train_samples):
    """Save checkpoint with model, optimizer, and training state."""
    args = self.args

    # Handle LoRA save modes
    if args.training.lora.enable:
        # Save only LoRA adapter weights
        if self.lora_weight_manager is not None:
            self.lora_weight_manager.save_lora_only(          # ← 只存 adapter
                save_path=args.training.save,
                iteration=iteration,
            )
                                                            # ← 此处缺少 return
    # Default save behavior (full model)                       ← 落入全量 DCP 写
    state = {
        "model": self.model,
        "extra_state": { ... },
    }

复现步骤

  1. 用官方 qwen3_5 插件 + qwen3_vl_nothink 模板的 Qwen3.5-9B LoRA 配置,关键字段:
training:
  lora:
    enable: true
    r: 8
  save: /path/to/save
  no_save_optim: true      # adapter-only 意图
  no_save_rng: true
  save_interval: 2
  train_iters: 3
  1. 启动:
torchrun --nproc_per_node 8 mindspeed_mm/fsdp/train/trainer.py <config>.yaml

预期行为

no_save_optim + no_save_rng 时只写 adapter(~56M/次),save 目录总计应在百 MB 量级,不出现 iter_* 目录、不出现 *.distcp 分片

实际行为

save 目录总计 71G,含 iter_0000002/ + iter_0000003/ 两个全量 DCP 目录(各约 36G,含 __*_0.distcp 分片),另有两个 adapter lora_adapter_iteration_*.safetensors。rc=0,无报错——静默浪费。

$ du -sh /path/to/save
71G
$ ls -d /path/to/save/iter_*
iter_0000002  iter_0000003
$ find /path/to/save -name '*.distcp' | head
.../iter_0000003/__0_0.distcp

建议修复

在 LoRA 分支 save_lora_only(...) 之后,当既不存 optim 也不存 rng(即无训练态可续)时早退 return,跳过只服务于 resumption 的全量 DCP 写入:

         if args.training.lora.enable:
             # Save only LoRA adapter weights
             if self.lora_weight_manager is not None:
                 self.lora_weight_manager.save_lora_only(
                     save_path=args.training.save,
                     iteration=iteration,
                 )
+            # Adapter-only export: when neither optimizer nor RNG state is being
+            # saved there is no training state to resume from, so the full-model
+            # DCP write (which only exists to support resumption) would duplicate
+            # the frozen base model on every save with no benefit. Skip it.
+            if args.training.no_save_optim and args.training.no_save_rng:
+                torch.distributed.barrier()
+                return
         # Default save behavior (full model, for resumption)
         state = {

说明:当 no_save_optim/no_save_rng 任一为 false(即确有训练态需续)时,仍走全量 DCP,行为不变——修复只裁掉「纯 adapter 导出」这一无意义全量写。

likedislike
ascend-robotascend-robot成员
8月7日 添加了label:bug
Iiceflysnow
8月7日 关联了pull request:fix(train): skip full-model DCP write on LoRA adapter-only export
htwang成员
8月8日 评论:

您好,感谢您使用MindSpeed MM。您的问题已收到,我们会尽快排查!

likedislike
Hhtwang成员
8月8日 将 WendongPang 设为负责人
Hhtwang成员
8月8日 将 htwang 设为负责人
Hhtwang成员
8 天前 将 wanglikai1019 设为负责人
Hhtwang成员
8 天前 移除了负责人 WendongPang
LKONE
LKONE成员
7 天前 评论:

您好,该问题当前已有其他改进方案,新增 lora_save_only 参数控制是否仅保存 lora adapter权重,具体使用方式和场景如下:

  1. lora_save_only 开启时,仅保存 lora adapter 权重,包括 lora 权重文件和 adapter.json 配置文件,可用于权重融合和加载 lora 权重训练;
  2. lora_save_only 关闭且 save_format 为 dcp 时,保存全量权重信息(包括基础权重和 lora 权重),并可以结合 no_save_optim: false 和no_save_rng: false 参数保存优化器/随机数状态以进行断点续训;
  3. lora_save_only 关闭且 save_format 为 hf 时(且当前模型支持 hf 权重直接导出),将 lora 权重与基础权重进行融合后导出,可直接用于后续的推理/评测任务。

若有其他改进意见,欢迎继续提出,感谢您的支持!

likedislike
LKONELKONE成员
7 天前 关联了pull request:feat: support configurable LoRA weight saving
LKONELKONE成员
6 天前 添加了label:resolved
young256young256成员
6 天前 issue状态由 TODO 改变为 DONE
young256young256成员
6 天前 关闭了 issue