MAC M1 芯片训练huggingface上的模型,报错RuntimeError: Placeholder storage has not been allocated on MPS device!

       第一次使用Mac Pro尝试拉取和训练模型,考虑到性能问题选择了"Qwen/Qwen2-0.5B-Instruct"做测试,测试代码也出现过RuntimeError: Placeholder storage has not been allocated on MPS device!,发现是需要把model和model_input都放入mps的问题:

device = "mps" 
model = AutoModelForCausalLM.from_pretrained(
     "Qwen/Qwen2-0.5B-Instruct",
     torch_dtype="auto",
     device_map="auto").to(device)
model_inputs = tokenizer([text], return_tensors="pt", padding=True, truncation=True).to(device)

        设置完.to(device)之后可以正常运行,注意tensors的格式需要是“pt”

        在后续训练环节,按着同样的方式设置,在检查了一万遍后,还是会出现RuntimeError: Placeholder storage has not been allocated on MPS device!的问题,打断点发现初始化训练参数的时候train_args后续会自动把device修改成cpu,加上use_cpu=False和use_mps_device=True后还是会变成cpu,也尝试过禁用mps加速依然不解决问题。

train_args = TrainingArguments(
    output_dir=path + train_model_name,
    per_device_train_batch_size=1,# 训练batch大小
    per_device_eval_batch_size=1,# 评估batch大小
    learning_rate=1e-5,# 学习率
    overwrite_output_dir=False,# 是否覆盖输出目录
    weight_decay=0.01,#权重衰减系数,用于正则化,防止过拟合。
    num_train_epochs=2,# 训练轮数
    max_steps=1643,# 训练步数
    logging_steps=10,#日志记录间隔,每多少个步骤记录一次训练状态。
    save_strategy="steps",#模型保存策略,可以是"no"(不保存)、"epoch"(按轮数保存)或"steps"(按步数保存)。
    save_steps=120,#保存模型的间隔步数。
    save_total_limit=2,#最多保存的检查点数量,超过此数将删除旧的检查点。
    eval_strategy="steps",#评估策略,类似于保存策略,决定何时运行评估。
    eval_steps=120,#进行评估的间隔步数
    warmup_steps=100,#学习率预热步骤数,学习率逐渐增加到·learning_rat
    disable_tqdm=False,#如果为True,禁用进度条
    logging_strategy="steps",#日志记录策略,类似于保存策略
    optim="adafactor",#优化器类型,默认是AdamW,
    gradient_accumulation_steps=4,#梯度累积步数,用于模拟更大的批次大小,同时保持较小的实际批次大小以适应GPU内存。
    gradient_checkpointing=False,#如果为True,启用梯度检查点,节省内存但可能增加计算时间。

    load_best_model_at_end=True,#如果为True,训练结束后加载最佳模型。
    metric_for_best_model="eval_loss",#用于确定最佳模型的指标名称。
    greater_is_better=False,#如果为True,表示metric_for_best_model的较高值更好。

    eval_accumulation_steps=1,#评估时的梯度累积步数,类似于gradient_accumulation_steps。
    report_to="tensorboard",#要报告训练进度的集成工具,如"WandB"、"CometML"或"TensorBoard"。
    run_name=train_model_name,#实验的名称,用于日志和报告。

    use_cpu=False,  # 如果为True,使用CPU进行训练。
    use_mps_device=True,#如果为True,使用MPS设备进行训练。

)

        后来看参数初始化的源码training_args.py,发现在设置只使用mps的时候会有问题,在判断use_mps_device后device设置为“mps”,但是在use_cpu的判断里会在else里面判断是否能使用cuda,如果不能就设置为cpu,在这个判断之后device设置为“cpu”,后续代码就会根据这个设置把input放到cpu中,就会报错。

            if self.use_mps_device:
                warnings.warn(
                    "`use_mps_device` is deprecated and will be removed in version 5.0 of 🤗 Transformers. "
                    "`mps` device will be used by default if available similar to the way `cuda` device is used."
                    "Therefore, no action from user is required. "
                )
                if device.type != "mps":
                    raise ValueError(
                        "Either you do not have an MPS-enabled device on this machine or MacOS version is not 12.3+ "
                        "or current PyTorch install was not built with MPS enabled."
                    )
            if self.use_cpu:
                device = torch.device("cpu")
            elif is_torch_xpu_available():
                if not is_ipex_available() and not is_accelerate_available("0.32.0.dev"):
                    raise ImportError("Using the XPU PyTorch backend requires `accelerate>=0.32.0.dev`")
                device = torch.device("xpu:0")
                torch.xpu.set_device(device)
            elif is_torch_mlu_available():
                device = torch.device("mlu:0")
                torch.mlu.set_device(device)
            elif is_torch_npu_available():
                device = torch.device("npu:0")
                torch.npu.set_device(device)
            else:
                # if n_gpu is > 1 we'll use nn.DataParallel.
                # If you only want to use a specific subset of GPUs use `CUDA_VISIBLE_DEVICES=0`
                # Explicitly set CUDA to the first (index 0) CUDA device, otherwise `set_device` will
                # trigger an error that a device index is missing. Index 0 takes into account the
                # GPUs available in the environment, so `CUDA_VISIBLE_DEVICES=1,2` with `cuda:0`
                # will use the first GPU in that env, i.e. GPU#1
                device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
                # Sometimes the line in the postinit has not been run before we end up here, so just checking we're not at
                # the default value.
                self._n_gpu = torch.cuda.device_count()
                if device.type == "cuda":
                    torch.cuda.set_device(device)

          根据我的情况修改为elif就不会进最后的else语句里面了。

源码:
            if self.use_cpu:
                device = torch.device("cpu")

修改:
            elif self.use_cpu:
                device = torch.device("cpu")

        然后就可以正常开始训练啦,但是速度真的很慢

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值