PyTorch 2.15 MPS:FP8 落地、解码提速

PyTorch 2.15 的 MPS 后端由 Hugging Face PyTorch 团队与上游维护者共同推进,目标是让 Mac 成为运行和训练 PyTorch 模型的一等公民。这批更新把 FP8 带到 MPS,为 LLM 解码换上了更快的线性层、softmax 和 MoE 路径,也修复了视频解码时驱动内存暴涨和图像编辑中 VAE 静默损坏的问题。

FP8 支持落地:torch.float8_e4m3fn 在 MPS 上每个值占 1 字节,存储开销只有 FP16/BF16 的一半。配合 F.scaled_mm 可以直接在 GPU 上做缩放矩阵乘法,同时支持 tensorwise 和 rowwise 缩放。

解码提速是这次更新的重点。LLM 解码阶段是单行输入,F.linear 现在走专用 GEMV/矩阵-向量 kernel,并融合 bias。在 96 个来自真实模型的 BF16 层形状上,几何平均提速 1.23 倍;小投影层(如 MoE gate)收益最大。MoE 的 grouped matmul 有了原生 Metal 实现,group offsets 直接在 GPU 上读取,不再拷贝到 CPU 循环。配上 torch.compile,M3 Ultra 上 Qwen3.6-35B-A3B 从 9.4 tokens/s 提到 61.3 tokens/s,LFM2.5-8B-A1B 从 23.6 提到 123.6 tokens/s;官方称 MoE 解码整体比 2.14 快 5–6.5 倍。采样用的 FP32 softmax 在 [1, 128256] 行上从 57 µs 降到 7 µs,约 8 倍。

线性代数侧:complex64 的 LU 分解、LU solve、三角 solve 上 MPS;4×4 以内的小矩阵逆用单个 Metal kernel 合并分解与求解;QR 用分块更新;Gated DeltaNet 的小三角系统有专用路径。SVD 在数值极端情况下更稳,pseudoinverse 和最小二乘结果更可靠。训练和多媒体相关:conv1d 前向、constant/reflection/replication padding、dropout、上采样 backward、channels-last conv2d backward 都有新的 Metal 路径。

显存结果非常直观:Wan2.2 视频 VAE 解码在 28 个 tile 全过程中有 8764 次 padding 调用;padding 移到 Metal 后,驱动内存峰值从约 270 GiB 降到约 8 GiB。另一个修复是 Qwen-Image-2.1 VAE encoder 在 MPS 上静默损坏图像的问题:同一 padding 改动让 encode-decode 往返的 PSNR 从 10.06 dB 回到 29.95 dB,与 CPU 一致。

工程控制上,Python 可直接用 torch.mps.Stream 选择流,Tensor.record_stream 跟踪跨流使用。新支持 frexp、logspace、take/put_、heaviside、laguerre_polynomial_l、无符号整数比较等操作;attention 的 batch/head broadcasting 正确性修复。要求 macOS 15+ 与 Python 3.11+。2.16 预览:attention 全部切到 Metal;每 16 个 kernel 提交一次 command buffer,让 GPU 提前开始工作。编译 BF16 解码下 LFM2.5-8B-A1B 从 108.8 提到 126.0 tokens/s,Qwen3.6-35B-A3B 从 52.9 提到 62.8 tokens/s;libtorch_cpu.dylib 体积将缩小约 25%,从 384 MiB 降到 287 MiB。

MPS in PyTorch 2.15

查看原文