第一次使用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")
然后就可以正常开始训练啦,但是速度真的很慢