# Metal 性能着色器 (MPS)

> [!TIP]
> 带有  徽章的 Pipeline 表示该模型可以利用 Apple 芯片设备上的 MPS 后端来加速推理。欢迎提交 [Pull Request](https://github.com/huggingface/diffusers/compare)，为缺少此徽章的 Pipeline 添加该徽章。

🤗 Diffusers 兼容 Apple 芯片（M1/M2），使用 PyTorch 的 [`mps`](https://pytorch.org/docs/stable/notes/mps.html) 设备，该设备通过 Metal 框架利用 MacOS 设备上的 GPU。您需要具备以下条件：

- 配备 Apple silicon (M1/M2) 硬件的 macOS 电脑
- macOS 12.6 或更高版本（推荐 13.0 或更高版本）
- arm64 版本的 Python
- [PyTorch 2.0](https://pytorch.org/get-started/locally/)（推荐）或 1.13（`mps` 支持的最低版本）

`mps` 后端使用 PyTorch 的 `.to()` 接口将 Stable Diffusion 流水线迁移到 M1 或 M2 设备上：

```python
from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5")
pipe = pipe.to("mps")

# Recommended if your computer has < 64 GB of RAM
pipe.enable_attention_slicing()

prompt = "a photo of an astronaut riding a horse on mars"
image = pipe(prompt).images[0]
image
```

> [!WARNING]
> PyTorch 的 [mps](https://pytorch.org/docs/stable/notes/mps.html) 后端不支持大于 `2**32` 的 NDArray 大小。如果您遇到此问题，请提交一个 [Issue](https://github.com/huggingface/diffusers/issues/new/choose)，以便我们进行调查。

如果你使用的是 **PyTorch 1.13**，你需要通过一次额外的单次遍历来“预热”流水线。这是针对首次推理遍历的结果与后续遍历结果略有差异这一问题的临时解决方案。你只需执行一次该遍历，在仅进行一步推理后，即可丢弃其结果。

```diff
  from diffusers import DiffusionPipeline

  pipe = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5").to("mps")
  pipe.enable_attention_slicing()

  prompt = "a photo of an astronaut riding a horse on mars"
  # First-time "warmup" pass if PyTorch version is 1.13
+ _ = pipe(prompt, num_inference_steps=1)

  # Results match those from the CPU device after the warmup pass.
  image = pipe(prompt).images[0]
```

## 故障排除

本节列出了使用 `mps` 后端时的一些常见问题及其解决方法。

### 注意力切片

M1/M2 的性能对内存压力非常敏感。当出现这种情况时，系统会自动进行交换（swap），这会显著降低性能。

为防止此问题发生，我们建议启用 *注意力切片*，以降低推理过程中的内存压力并避免交换。如果您的计算机系统内存小于 64GB，或者您以大于 512×512 像素的非标准分辨率生成图像，这一点尤为重要。请在您的 pipeline 上调用 [enable_attention_slicing()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.enable_attention_slicing) 函数：

```py
from diffusers import DiffusionPipeline
import torch

pipeline = DiffusionPipeline.from_pretrained("stable-diffusion-v1-5/stable-diffusion-v1-5", dtype=torch.float16, variant="fp16", use_safetensors=True).to("mps")
pipeline.enable_attention_slicing()
```

注意力切片（Attention slicing）将耗时的注意力操作拆分为多个步骤执行，而不是一次性完成。在没有统一内存的计算机上，它通常能带来约 20% 的性能提升，但我们观察到，除非您的内存达到 64GB 或更多，否则在大多数 Apple 硅芯片计算机上，*性能会更好*。

### 批量推理

批量生成多个提示词可能会导致崩溃或无法可靠运行。如果出现这种情况，请尝试使用迭代方式代替批量处理。

