在 Mac 上如果不做任何修改直接运行 python trainer/train_pretrain.py,它会完全运行在 CPU 上,无法调用 Mac 的 GPU。
一、 核心代码证据
- 设备默认回退到了 cpu 在参数解析部分(Line 90):
python
parser.add_argument("--device", type=str, default="cuda:0" if torch.cuda.is_available() else "cpu", help="训练设备") Mac 上由于没有 NVIDIA CUDA 环境,torch.cuda.is_available() 永远是 False,因此系统会直接分配 device = "cpu",代码中没有检测 torch.backends.mps.is_available()。
- 混合精度(AMP)只针对 CUDA 在 Line 121-124:
python
device_type = "cuda" if "cuda" in args.device else "cpu" dtype = torch.bfloat16 if args.dtype == "bfloat16" else torch.float16 autocast_ctx = nullcontext() if device_type == "cpu" else torch.cuda.amp.autocast(dtype=dtype) 即使你在命令行强行指定 --device mps,因为 "cuda" not in "mps",device_type 依然会被判断为 "cpu",导致 autocast_ctx 变成了空上下文 nullcontext(),混合精度自动失效。
- GradScaler 强绑定 CUDA 在 Line 138:
python
scaler = torch.cuda.amp.GradScaler(enabled=(args.dtype == 'float16')) 使用的是旧版针对 CUDA 的 torch.cuda.amp.GradScaler,如果强制在 MPS 上运行且用了 float16,会直接报 CUDA 设备不存在的错误。
- 辅助工具仅支持 CUDA 在 trainer/trainer_utils.py 中:
setup_seed 中调用的是 torch.cuda.manual_seed(...),未调用 torch.mps.manual_seed(...)。 init_model 默认参数 device='cuda'。 二、 如何修改以在 Mac (Apple Silicon) 上开启 MPS 训练? 如果想在 Mac M 系列芯片(M1/M2/M3/M4)上利用 GPU 进行训练,只需对 trainer/train_pretrain.py 做如下几处小调整:
- 修改设备检测逻辑 python
def get_default_device(): if torch.cuda.is_available(): return "cuda:0" elif torch.backends.mps.is_available(): return "mps" return "cpu" parser.add_argument("--device", type=str, default=get_default_device(), help="训练设备") 2. 适配设备类型与 Autocast PyTorch 2.1+ 已统一了 torch.autocast 和 torch.amp.GradScaler:
python
device_type = "cuda" if "cuda" in args.device else ("mps" if "mps" in args.device else "cpu") dtype = torch.bfloat16 if args.dtype == "bfloat16" else torch.float16
MPS 下支持 bfloat16 / float16 autocast (PyTorch >= 2.0)
if device_type in ["cuda", "mps"]: autocast_ctx = torch.autocast(device_type=device_type, dtype=dtype) else: autocast_ctx = nullcontext() 3. 替换 GradScaler python
统一使用通用的 torch.amp.GradScaler
scaler = torch.amp.GradScaler(device=device_type, enabled=(args.dtype == 'float16' and device_type == 'cuda')) NOTE
在 Mac MPS 上,通常推荐使用 bfloat16 或直接使用 float32,不建议开启 float16 + GradScaler(部分低版本 PyTorch 的 MPS 后端对 float16 的缩放算子支持不全)。
- DataLoader 的 pin_memory Mac 上使用 MPS 时,将 DataLoader 中的 pin_memory=True 改为 pin_memory=False,避免无谓的内存锁页开销。
Source: jingyaogong/minimind