模型大小超出单卡显存的大模型该如何微调?
收藏回复举报
模型大小超出单卡显存的大模型该如何微调?
t('forum.solved') 已解决
发表于2025-09-19 10:57:29
0 查看

硬件:华为昇腾910B4-1,单卡64G,8张卡

容器环境:swr.cn-south-1.myhuaweicloud.com/ascendhub/cann:8.2.rc1.alpha002-910b-ubuntu22.04-py3.10

torch:2.3.1

torch-npu:2.3.1.post4

transformers:4.49.0

peft:0.11.1

accelerate:1.5.2

deepspeed:0.17.5

我的微调代码大概如下:

# 1. 初始化分布式训练环境

accelerator = Accelerator()
device = accelerator.device

# 在训练脚本中加载DeepSpeed配置
if accelerator.state.deepspeed_plugin is not None:
    ds_config = accelerator.state.deepspeed_plugin.deepspeed_config
    logger.info(f"Loaded DeepSpeed config: {ds_config}")

model_path = get_model_name_path(args.model_name)
if not os.path.exists(model_path):
    raise f"model path: {model_path} not exist."
    logger.info(f"get model path: {model_path}")

# 2. 模型定义
logger.info(f"load model ...")
model = AutoModelForCausalLM.from_pretrained(
    model_path,
    torch_dtype=torch.bfloat16,
    trust_remote_code=True,
    device_map='auto'
    )

model.enable_input_require_grads()  # 关键修复,针对fp16训练,梯度裁剪和梯度检查,防止embedding层也冻结,导致无法训练

peft_config = get_finetune_config(args.model_name, 'lora')
if not peft_config:
    raise "get peft config error."
model = get_peft_model(model, peft_config)
logger.info(f"finetune model:\n {model}")
model.print_trainable_parameters()
model.to(device)

# 加载tokenizer
logger.info(f"load tokenizer ...")
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True)

# 3. 数据加载器
logger.info(f"load dataset ...")
dataset = process_data(tokenizer, args.data_path)
dataset.set_format("torch")
train_dataset = dataset.shuffle(seed=42).select(range(1000))
train_dataloader = DataLoader(train_dataset, shuffle=True, batch_size=args.batch_size)

# 4. 分布式组件准备
model, optimizer, train_loader = accelerator.prepare(
    model,
    torch.optim.AdamW(model.parameters(), lr=args.learning_rate),
    train_dataloader
    )

# 5. 训练控制参数
total_epochs = args.epochs
total_steps = len(train_loader) * total_epochs
start_time = time.time()
current_step = 0

# 6. 创建保存目录(主进程专有)
output_dir = os.path.join(args.output_dir, args.model_name, args.method)
if accelerator.is_main_process:
    save_dir = output_dir+f"_{datetime.now().strftime('%Y%m%d-%H%M%S')}"
    os.makedirs(save_dir, exist_ok=True)

# 7. 分布式训练循环
for epoch in range(total_epochs):
    # 训练阶段
    model.train()
    for batch in train_loader:
      ...

在终端执行指令如下: ASCEND_RT_VISIBLE_DEVICES=0,1 accelerate launch --num_processes 2 --multi_gpu --mixed_precision=bf16 --num_machines 1 train_script.py --model_name Qwen2.5-7B-Instruct

执行命令后,0,1两张卡能正常训练

但我将微调模型切换成Qwen2.5-32B-Instruct后,就报显存不足,报错信息如下: true

尝试过按照报错提示在代码中添加: os.environ["PYTORCH_NPU_ALLOC_CONF"] = "max_split_size_mb:128" 或者设置显卡占用比例:torch_npu.npu.set_per_process_memory_fraction(0.8)依然报错。

请问有什么方式可以训练这种模型大小超出单卡显存容量的的情况?比如类似vllm框架部署大模型一样,能自动切分大模型的层分别加载在不同的显卡上。目前没在网上搜索到类似训练的案例,请求社区大牛帮忙提示一下如何解决这个问题。

我要发帖子