使用MPS后端时出现RuntimeError:view尺寸与输入张量的尺寸和步长不兼容
这个错误是MPS后端的典型兼容性问题——MPS对张量内存连续性的要求比CPU严格得多,view()操作要求张量在内存中是完全连续的(即张量的stride布局满足连续条件),但你的模型在MPS设备上运行时,部分张量因为跨设备迁移、多线程数据加载等原因变成了非连续的,而CPU后端会自动兼容这种情况,所以CPU上能正常运行。
结合你的代码和报错信息,给你几个针对性的解决方案,按优先级从高到低:
1. 强制模型参数与输入张量为连续张量
MPS不允许对非连续张量执行view(),所以我们可以在模型迁移到设备后,强制所有参数为连续;同时自定义数据collator,确保训练时的输入张量也是连续的:
步骤1:处理模型参数连续性
在model.to(device)之后添加这段代码:
model.to(device) # 遍历所有参数,强制转为连续张量 for param in model.parameters(): if not param.is_contiguous(): param.data = param.data.contiguous()
步骤2:自定义MPS兼容的数据collator
替换默认的default_data_collator,确保输入张量都连续:
from transformers import default_data_collator def mps_safe_collator(features): # 先用默认collator生成batch batch = default_data_collator(features) # 遍历batch中的所有张量,强制连续 for key, tensor in batch.items(): if isinstance(tensor, torch.Tensor) and not tensor.is_contiguous(): batch[key] = tensor.contiguous() return batch
然后在Trainer中使用这个自定义collator:
trainer = Trainer( processing_class=feature_extractor, model=model, args=training_args, train_dataset=train_dataset, data_collator=mps_safe_collator # 替换为自定义collator )
2. 升级Transformers与PyTorch版本
旧版本的Hugging Face Transformers对MPS的支持不完善,部分模型(比如VisionEncoderDecoderModel)内部可能用了view()而不是reshape(),升级到最新版本可以修复很多MPS兼容性问题:
pip install --upgrade transformers torch
注意:确保你的PyTorch版本≥1.12,MacOS版本≥12.3(MPS的最低运行要求)。
3. 调整训练参数避免张量不连续
多线程数据加载可能导致CPU上创建的张量迁移到MPS后变成非连续的,建议禁用多线程:
在TrainingArguments中添加:
training_args = TrainingArguments( # 其他已有参数... dataloader_num_workers=0, # 禁用多线程数据加载 )
4. 临时 workaround:替换view()为reshape()(进阶方案)
如果你愿意修改Hugging Face模型的局部代码,可以找到报错位置的view()调用,替换为reshape()——reshape()会自动判断张量是否连续,非连续时会先调用contiguous()再执行类似view()的操作,完美适配MPS。
不过这个方法需要定位到具体的报错代码行,适合有一定源码阅读能力的开发者。
你可以先尝试方案1和方案3,这两个改动最小,通常能解决大部分MPS上的view()/stride问题。如果还是不行,再升级依赖版本。
备注:内容来源于stack exchange,提问作者Harsh

