Accelerate 拒绝对 device_map="auto" 模型做分布式训练
自动分派用于大模型推理,不能直接叠加 DDP。按训练策略重新加载模型,避免绕过保护。
accelerate launch 启动后,prepare 报 You can't train a model that has been loaded with device_map='auto' in any distributed mode。错误指向加载阶段:脚本把大模型推理的自动分派和分布式训练组合在一起。
Accelerate 1.0.1 的源码会检查模型及子模块的 hf_device_map,发现多条映射且处于分布式模式时拒绝继续。官方 issue #2311记录了同一 prepare 错误的原始 traceback;具体触发条件以 1.0.1 的固定源码为准。不是只要参数名叫 device_map 就必然触发错误,判断要结合映射内容与分布式状态。
让一种机制负责训练时的放置
普通非量化 DDP 路径里,每个 rank 维护一份模型,Accelerate 负责设备放置与封装。加载时去掉推理自动分派,例如:
from accelerate import Accelerator
from transformers import AutoModelForCausalLM
accelerator = Accelerator()
model = AutoModelForCausalLM.from_pretrained(
"./model", local_files_only=True,
)
print(accelerator.distributed_type)
print(getattr(model, "hf_device_map", None))
随后按现有训练代码创建 optimizer、dataloader,并交给 accelerator.prepare;不要把示例中没有训练循环理解为完整训练脚本。去掉自动分派后,每个 rank 的模型副本可能装不下显存,这时应规划 FSDP 或 DeepSpeed ZeRO 等训练分片,按所选版本的官方流程加载。它们不是把 device_map="auto" 换个字符串就能完成的配置。
量化 LoRA 的加载又有专门的设备约束。不能把普通 DDP 示例无条件用于 4-bit/8-bit 模型,更不能先把量化模型分散在所有卡上,再让每个 rank 使用同一份映射。
不用环境变量跳过这道检查
1.0.1 源码包含 ACCELERATE_BYPASS_DEVICE_MAP 分支,但跳过检查不会自动建立正确的梯度同步或训练分片。把这个变量设为 true 只能让错误延后出现,不能作为修复证明。也不要把进程数改成 1 后宣称分布式训练已经恢复;那是换了运行方式。
验证时打印各 rank 的实际设备和模型映射,跑至少一个完整 optimizer step,确认梯度更新与 checkpoint 保存。再逐步恢复 batch 与序列长度。若改为训练分片,需要同时验证 checkpoint 的保存与重载,避免训练能跑、恢复时却没有完整权重。


