MPS 训练完全指南:在 Apple Silicon GPU 上使用 PyTorch Lightning
2026/9/19 20:00:34 网站建设 项目流程

MPS 训练完全指南:在 Apple Silicon GPU 上使用 PyTorch Lightning

【免费下载链接】pytorch-lightningPretrain, finetune ANY AI model of ANY size on 1 or 10,000+ GPUs with zero code changes.项目地址: https://gitcode.com/gh_mirrors/py/pytorch-lightning

核心主题:本文基于 PyTorch Lightning 官方文档中的 MPS 基础指南(docs/source-pytorch/accelerators/mps_basic.rst),系统讲解如何在 Apple Silicon(M 系列芯片)的 GPU 上使用 Lightning 进行训练,包括硬件原理、一行代码切换加速器、MPS 后端特性、常见故障排查,以及配套源码实现细节。

适用读者:想在 MacBook / Mac Mini / Mac Studio / iMac 等 Apple Silicon 设备上用 GPU 训练 PyTorch 模型的开发者。读完本文后,你将掌握:如何用Trainer(accelerator="mps")启用 MPS 加速、MPS 加速器在 Lightning 内部的工作原理与设备限制、遇到MPSAccelerator can not run on your system等异常时的排查方法。

Apple Silicon 是什么

Apple silicon 芯片是 Apple 基于 ARM 架构设计的一体化片上系统(system on a chip,SoC)。与传统的分离式硬件不同,它在同一块芯片上集成了多种计算单元:

  • CPU 核心:负责通用计算与串行逻辑;
  • GPU 核心:负责大规模并行计算,是深度学习训练的主要加速单元;
  • 神经引擎(Neural Engine):针对机器学习推理等特定负载优化的专用硬件;
  • 统一内存(shared memory):以上所有单元共享同一块内存,数据无需在 CPU 内存与显存之间复制,这也是 M 系列芯片能高效跑模型的关键硬件基础。

它只是一颗 CPU 吗

不是。Apple silicon 芯片内部确实包含 CPU 核心,但如果只用CPUAccelerator在 CPU 上运行,你无法发挥这颗芯片的全部硬件加速潜力——因为芯片上还同时存在 GPU 与神经引擎,它们具备 CPU 不具备的并行算力。

PyTorch 通过Metal Performance Shaders(MPS)后端把这些 GPU 核心暴露给深度学习框架。在 Lightning 中,对应的支持实现是MPSAccelerator。它在两个子包中均有实现,且lightning.pytorch的版本直接复用lightning.fabric的底层检测逻辑:

  • src/lightning/pytorch/accelerators/mps.py:PyTorch Trainer 使用的MPSAccelerator,继承自Accelerator基类;
  • src/lightning/fabric/accelerators/mps.py:Fabric 与 PyTorch 共用的底层实现,包含is_available()等核心检测逻辑。

在 Apple silicon GPU 上运行(MPS 设备)

启用方式非常简单:在Trainer中把accelerator设为"mps",并指定设备数量即可:

from lightning.pytorch import Trainer trainer = Trainer(accelerator="mps", devices=1)

你也可以直接传入加速器对象:

from lightning.pytorch.accelerators import MPSAccelerator trainer = Trainer(accelerator=MPSAccelerator(), devices=1)

注意:MPSAccelerator一次只支持 1 个设备。目前市面上还没有搭载多块 MPS 能力 GPU 的机器,M 系列芯片的单颗 SoC 只暴露一个 MPS 设备。

从源码看,这一限制是硬编码的:MPSAccelerator.auto_device_count()返回固定值1_get_all_available_mps_gpus()在加速器可用时只返回[0]。因此如果你试图请求超过 1 个设备,例如devices=2devices=[0, 2],设备解析逻辑会抛出MisconfigurationException: ... But your machine only has: [0],这一点由测试 tests/tests_fabric/accelerators/test_mps.py 专门验证。

MPS 在 Lightning 中的设备解析流程

当你在Trainer(accelerator="mps", devices=1)中传入devices后,Lightning 会调用MPSAccelerator.parse_devices(),其内部最终走向 src/lightning/fabric/utilities/device_parser.py 的_parse_gpu_ids(gpus, include_mps=True)

  • devices=1→ 归一化为[0]
  • devices=[0]devices="0,"→ 直接解析为[0]
  • devices=-1"-1"(表示“使用所有可用设备”)→ 由于 MPS 机器只有 1 个设备,仍解析为[0]
  • 请求2个及以上设备 → 抛出MisconfigurationException

随后get_parallel_devices()将解析结果映射为torch.device("mps", 0),训练便会在 MPS 设备上执行。测试 tests/tests_pytorch/accelerators/test_mps.py 中覆盖了devices1[0]"-1"三种写法都能正常训练一个完整的BoringModel

自动选择加速器

如果不显式指定accelerator,Lightning 会根据硬件可用性自动选择。在 device_parser.py 的_select_auto_accelerator()中,检测顺序为:TPU →MPS→ CUDA → CPU。也就是说,在一台没有 XLA/TPU 的 Apple Silicon Mac 上,Trainer()会自动选中 MPS 作为加速器;而在 NVIDIA GPU 机器上则自动选中 CUDA。

把 batch 数据搬到 MPS 设备

Lightning 的策略层负责把每个 batch 转移到目标设备。在 MPS 场景下,batch_to_device支持几乎所有常见数据结构,测试 tests/tests_pytorch/accelerators/test_mps.py 覆盖了:

  • 纯 Tensor;
  • Tensor 列表、列表的列表;
  • Tensor 字典、字典列表;
  • 元组混合嵌套、namedtuple
  • 定义了.to()方法的自定义对象。

这些结构都会被递归地迁移到torch.mps.FloatTensor。简单类型(None{}[]1.0、字符串等)则原样返回,不会报错。

在 Lightning Fabric 中使用 MPS

如果你在使用更轻量的 Lightning Fabric,写法等价:

from lightning.fabric import Fabric fabric = Fabric(accelerator="mps", devices=1)

命令行方式同样支持--accelerator mps(见 docs/source-fabric/fundamentals/launch.rst)。Fabric 的MPSAccelerator与 PyTorch 版本共享is_available()parse_devices()等核心逻辑,区别仅在于setup_device()校验失败时抛出的异常类型(Fabric 抛ValueError,PyTorch 抛MisconfigurationException)。

MPS 代表什么

MPS 是Metal Performance Shaders的缩写,这是 Apple 的Metal图形与计算框架中用于 GPU 通信与计算的技术(Metal 是 Apple 面向 GPU 编程的底层 API)。PyTorch 的 MPS 后端通过它把张量运算映射到 Apple silicon 的 GPU 核心上执行,从而获得比 CPU 高得多的并行吞吐。

当前状态提醒:MPS 加速器与 PyTorch 的 MPS 后端目前仍处于实验阶段。并非所有算子都已被支持。不过随着 PyTorch 团队的持续开发,可用算子的覆盖范围正在不断扩大。

不支持算子的回退方案

如果在训练中遇到某个算子尚未被 MPS 后端支持,可以通过设置环境变量让 PyTorch 自动回退到 CPU 执行该算子:

PYTORCH_ENABLE_MPS_FALLBACK=1 python your_script.py

这条命令的作用是:当 MPS 后端遇到不支持的算子时,回退到 CPU 实现而不是直接报错,从而让实验性功能尽可能跑通。

禁用 MPS 的开关

Lightning 还提供了一个显式禁用 MPS 的环境变量DISABLE_MPS。在 src/lightning/fabric/accelerators/mps.py 的is_available()实现中:

mps_disabled = os.getenv("DISABLE_MPS", "0") == "1" return not mps_disabled and torch.backends.mps.is_available() and platform.processor() in ("arm", "arm64")

它同时满足三个条件才算“MPS 可用”:

  1. 未设置DISABLE_MPS=1
  2. torch.backends.mps.is_available()返回True(即你安装的 PyTorch 版本编译并启用了 MPS 后端);
  3. CPU 架构是armarm64(即真实运行在 Apple Silicon 上,而不是被转译的 x86 环境)。

结果会被lru_cache缓存,避免重复检测的开销。

故障排查(Troubleshooting)

报错:MPSAccelerator can not run on your system since the accelerator is not available

如果 Lightning 无法在你的系统上检测到 Apple silicon 硬件,Trainer(accelerator="mps")会抛出如下异常:

MisconfigurationException: `MPSAccelerator` can not run on your system since the accelerator is not available.

最可能的原因:你的 Python 正在被模拟(emulated)运行,导致系统认为你身处 Intel CPU 环境。

当你在一台 ARM 版 Mac 上安装了为 Intel 编译的 Python 解释器时,macOS 的 Rosetta 转译层会把它模拟成 x86 进程。此时platform.processor()返回的不是arm64MPSAccelerator.is_available()的三个条件无法全部满足,Lightning 便认为 MPS 不可用——尽管你的硬件完全支持。

解决方法:重新安装原生 ARM(Apple silicon,M1/M2 及更新)版本的 Python。具体来说:

  1. 卸载当前被模拟的 Python 可执行文件;
  2. 如果你使用 conda / miniconda 等环境管理器,需要连同环境管理器一起重新安装ARM 版本(conda 官方提供 Apple M1/M2 版安装包,注意选择 Apple silicon 版本而非 Intel 版本,不要选 x86_64 的安装包);
  3. 重新创建虚拟环境并安装 PyTorch(需使用支持 MPS 的版本,PyTorch 2.0+ 起 macOS 官方构建默认包含 MPS 支持)。

安装完成后,可以通过一个最小脚本快速验证:

import torch from lightning.pytorch.accelerators import MPSAccelerator print("PyTorch MPS backend available:", torch.backends.mps.is_available()) print("Lightning MPSAccelerator available:", MPSAccelerator.is_available())

两个输出都为True时,即可正常使用Trainer(accelerator="mps", devices=1)

其他常见疑问

  • “GPU available but not used”警告:如果在 MPS 机器上显式使用accelerator="cpu",Lightning 会发出GPU available but not used的用户警告(见测试 tests/tests_pytorch/accelerators/test_mps.py)。这是提示你有 MPS 设备可用但当前配置没有使用它。
  • 如何确认训练确实跑在 MPS 上:训练开始时的日志中,Lightning 会打印类似GPU available: True (mps)的信息;也可通过trainer.strategy.batch_to_device(batch, torch.device("mps"))后检查张量类型是否为torch.mps.FloatTensor来确认。

进阶:监控 MPS 设备状态

除训练外,Lightning 还提供了 MPS 设备状态监控能力。MPSAccelerator.get_device_stats()返回当前机器的 CPU + GPU 整体状态(M 系列为统一内存架构,故统计的是整机指标),字段包括:

  • M1_vm_percent:虚拟内存(virtual memory)使用百分比;
  • M1_percent:CPU 使用百分比;
  • M1_swap_percent:交换内存(swap)使用百分比。

该功能依赖psutil包,未安装时会抛出ModuleNotFoundError提示。可通过 tests/tests_pytorch/accelerators/test_mps.py 中展示的方式获取:

from lightning.pytorch.accelerators import MPSAccelerator import torch stats = MPSAccelerator().get_device_stats(torch.device("mps")) print(stats)

对于长时间训练,可以利用这些指标结合 Lightning 的 DeviceStatsMonitor 回调定期记录,帮助定位显存/内存压力问题。

小结

在 Apple silicon 上使用 PyTorch Lightning 训练模型,核心步骤只有一句话:Traineraccelerator设为"mps"devices设为1。其余工作——设备检测、batch 迁移、单设备策略选择——都由 Lightning 的MPSAccelerator自动完成。

需要记住的三件事:

  1. MPS 目前仅支持单设备MPSAccelerator.auto_device_count()固定返回 1,多设备请求会抛出MisconfigurationException
  2. 实验性功能:PyTorch 的 MPS 后端尚在完善中,遇到不支持的算子可用PYTORCH_ENABLE_MPS_FALLBACK=1回退到 CPU;
  3. 报错先查 Python 架构MPSAccelerator can not run on your system最常由 Rosetta 模拟的 x86 Python 导致,重新安装 Apple silicon 原生构建即可解决。

【免费下载链接】pytorch-lightningPretrain, finetune ANY AI model of ANY size on 1 or 10,000+ GPUs with zero code changes.项目地址: https://gitcode.com/gh_mirrors/py/pytorch-lightning

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询