不启用。PyTorch 2.0+ 虽支持 MPS 后端,但默认设备为 CPU;需安装 macOS 原生 wheel、确认 torch.backends.mps.is_available() 为 True,并手动将模型与数据统一移至 MPS 设备,同时规避不兼容算子与混合设备操作。

PyTorch是否默认启用Apple Silicon的Metal加速?
不启用。PyTorch 2.0+ 虽已内置 torch.compile 和 mps 后端支持,但默认设备仍是 cpu,即使你调用 .to("mps"),也需满足多个前提条件,否则会直接报错或静默回退到 CPU。
常见错误现象:RuntimeError: Found no NVIDIA driver on your system(误以为只检查 CUDA)、AttributeError: module 'torch' has no attribute 'mps'(版本太低)、或训练速度无提升(实际仍在 CPU 运行)。
- 必须使用 PyTorch ≥ 2.0,且通过
pip install torch torchvision torchaudio --extra-index-url https://download.pytorch.org/whl/macos安装 macOS 原生 wheel(非通用 x86_64 版) - 确认安装正确:运行
torch.backends.mps.is_available()返回True,且torch.device("mps")不抛异常 - 注意:MPS 不支持所有算子(如
torch.nn.BatchNorm3d、某些torch.fft变体),遇到时会自动 fallback 到 CPU,但不会报错——需用torch.autograd.set_detect_anomaly(True)或手动插入.to("mps")检查设备一致性
如何安全地将模型和数据迁移到MPS设备?
不能简单把模型 .to("mps") 就完事。MPS 对张量类型、布局、甚至随机数生成器状态都有隐式要求,稍有不慎就会触发不可恢复的崩溃或 NaN 损失。
实操建议:
立即学习“Python免费学习笔记(深入)”;
- 模型、输入数据、损失函数中的所有张量必须统一设备:先创建模型,再调用
model.to("mps");所有torch.tensor(...)或dataset加载的数据都需显式.to("mps") - 避免混合设备操作:例如
loss = criterion(output, target)中 output 在 MPS、target 在 CPU,会直接 crash。可用assert output.device == target.device快速定位 - 优化器必须在模型移到 MPS 后再初始化:
optimizer = torch.optim.Adam(model.parameters())必须在model.to("mps")之后,否则其内部缓存仍驻留在 CPU - 禁用不兼容的训练技巧:
torch.cuda.amp(自动混合精度)对 MPS 无效;改用torch.autocast("mps"),且仅限 forward 阶段,backward 仍需手动处理
为什么验证集推理变慢,甚至比 CPU 还慢?
这是 MPS 最常被忽略的性能陷阱:MPS 的 kernel 启动开销高,小 batch(如 batch_size=1)或频繁切换 device(如每步都 .to("mps"))会导致大量同步等待,实际吞吐反而下降。
关键参数与调整方向:
- batch_size 至少设为 8~16:低于此值,MPS 的调度开销 > 计算收益
- 避免在循环内重复调用
.to("mps"):预先把 dataloader 的输出 tensor 绑定到 MPS,或用pin_memory=True+non_blocking=True(虽对 MPS 效果有限,但可减少 host-device 拷贝阻塞) - 禁用梯度计算时务必用
torch.no_grad():MPS 下未关闭 grad 会额外记录计算图,显著拖慢 inference - 注意 DataLoader 的 num_workers:macOS 上多进程 + MPS 易引发 fork 问题,建议设为
0(主线程加载),或改用torch.utils.data.IterableDataset手动控制
遇到 MPS 相关 RuntimeError 怎么快速定位?
MPS 错误信息通常模糊(如 Invalid device ordinal 或直接 segmentation fault),根本原因往往不在报错行,而在上游张量的 device 或 dtype 不一致。
调试步骤:
- 在 model.forward() 开头加
print(f"input device: {x.device}, dtype: {x.dtype}"),确认输入合规(dtype 推荐torch.float32,MPS 对float64或int64支持极差) - 逐层检查:用
for name, param in model.named_parameters(): print(name, param.device)确保无参数意外滞留 CPU - 临时替换为 CPU 运行一次:若 CPU 正常而 MPS 报错,基本可锁定为 MPS 不支持的算子;此时查 MPS native op 列表,或改用等效替代(如用
torch.nn.functional.interpolate替代部分Upsample) - 升级到最新 nightly 版本:
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cpu(注意选 cpu index,nightly 的 macOS MPS 支持更新更全)
MPS 的最大复杂点不是“怎么开”,而是“怎么稳”——它不像 CUDA 那样经过十年打磨,很多边界 case 仍依赖手动规避。哪怕模型能跑通,也要在每个 epoch 后检查 loss 是否 nan、device 是否意外漂移,这些细节没法靠框架自动兜底。


















