PyTorch MPS后端不支持torch.linalg.svd?Apple Silicon GPU如何运行SVD?
关于PyTorch MPS后端支持SVD的问题解答
1. MPS后端是否原生支持SVD?
目前PyTorch的MPS后端不原生支持torch.linalg.svd和torch.svd,这就是你调用时收到回退CPU警告的原因——当MPS后端无法处理该算子时,会自动将张量转移到CPU执行,确实会带来性能损耗。
2. 在Apple GPU上高效运行SVD的替代方案
- 仅需奇异值时:使用torch.linalg.svdvals
如果你的场景只需要计算奇异值(不需要U、V矩阵),可以使用torch.linalg.svdvals,该算子已经在MPS后端实现支持,能直接在Apple GPU上运行,示例代码:
import torch device = torch.device("mps" if torch.backends.mps.is_available() else "cpu") tensor = torch.randn(1024, 512, device=device) s = torch.linalg.svdvals(tensor) # 直接在MPS上执行
- 利用Apple Accelerate框架优化CPU执行
如果需要完整的U、S、V矩阵,可借助Apple针对Silicon芯片优化的Accelerate框架。该框架的numpy.linalg.svd或scipy.linalg.svd(需确保SciPy基于Accelerate编译)性能远优于普通CPU实现,步骤:
- 将MPS张量转移到CPU(PyTorch MPS张量转NumPy会自动完成CPU复制)
- 使用Accelerate优化的SVD计算
- 将结果转回MPS张量(如果后续需要在GPU上处理)
示例代码:
import torch import numpy as np device = torch.device("mps" if torch.backends.mps.is_available() else "cpu") tensor = torch.randn(1024, 512, device=device) # 转CPU并计算SVD cpu_tensor = tensor.cpu().numpy() u, s, vh = np.linalg.svd(cpu_tensor, full_matrices=False) # 转回MPS张量 u_mps = torch.from_numpy(u).to(device) s_mps = torch.from_numpy(s).to(device) vh_mps = torch.from_numpy(vh).to(device)
这种方式的性能会比PyTorch默认CPU执行好很多,因为Accelerate充分利用了Apple Silicon的架构优势。
- 关注PyTorch版本更新
PyTorch团队一直在完善MPS后端的算子支持,后续版本大概率会添加linalg.svd的原生MPS实现。你可以定期升级PyTorch到最新稳定版,查看官方Release Notes确认算子支持情况。
内容的提问来源于stack exchange,提问作者Kris Bailey
相关产品推荐
相关产品推荐

