# 社区流水线与组件

社区流水线是 [DiffusionPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline) 类，它们与原始论文中的实现有所不同。这些流水线提供了额外的功能，或对原始流水线实现进行了扩展。

> [!TIP]
> 请查看 [diffusers/examples/community](https://github.com/huggingface/diffusers/tree/main/examples/community) 中的社区流水线，其中包含推理和训练示例，演示了如何使用它们。

社区流水线存储在 Hub 或 Diffusers 的 GitHub 仓库中。Hub 流水线完全可定制（调度器、模型、流水线代码等），而 GitHub 流水线仅限于自定义流水线代码。下表对比了这两种流水线类型。

|  | GitHub | Hub |
|---|---|---|
| 用法 | `custom_pipeline="<filename_without_.py>"` | Hub 仓库 ID，或者当 `_class_name` 指向自定义代码时使用 `trust_remote_code=True` |
| 审查流程 | 在 GitHub 上发起 Pull Request，并在合并前接受 Diffusers 团队的审查流程。此选项速度较慢。 | 直接上传到 Hub 仓库，无需审核。这是最快的选项。 |
| 可见性 | 包含在官方的 Diffusers 仓库和文档中。 | 包含在您的 Hub 个人资料中，并依赖于您自身的使用和推广来获得曝光度。 |

## 加载社区流水线

通过向 [from_pretrained()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) 传递 `custom_pipeline` 来加载任意类型的社区流水线。

```py
import torch
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-3-medium-diffusers",
    custom_pipeline="pipeline_stable_diffusion_3_instruct_pix2pix",
    dtype=torch.float16,
    device_map="cuda"  # or "mps", "xpu", "cpu"
)
```

将 `custom_revision` 参数添加到 [from_pretrained()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) 中，以从特定版本（例如 `v0.30.0` 或 `main`）加载社区流水线。默认情况下，社区流水线从 Diffusers 的最新稳定版本加载。

```py
import torch
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "stabilityai/stable-diffusion-3-medium-diffusers",
    custom_pipeline="pipeline_stable_diffusion_3_instruct_pix2pix",
    custom_revision="main",
    dtype=torch.float16,
    device_map="cuda"  # or "mps", "xpu", "cpu"
)
```

> [!WARNING]
> 在 Hugging Face Hub [扫描](https://huggingface.co/docs/hub/security-malware)文件的同时，您仍应检查 Hub 流水线代码，确保其安全。

加载社区 pipeline 有几种方法。

- 将路径传递给 `custom_pipeline` 以加载本地社区流水线。该目录必须包含一个 `pipeline.py` 文件，其中定义了流水线类。

  ```py
  import torch
  from diffusers import DiffusionPipeline

  pipeline = DiffusionPipeline.from_pretrained(
      "stabilityai/stable-diffusion-3-medium-diffusers",
      custom_pipeline="path/to/pipeline_directory",
      trust_remote_code=True,
      dtype=torch.float16,
      device_map="cuda"  # or "mps", "xpu", "cpu"
  )
  ```

- `custom_pipeline` 参数同样受 [from_pipe()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.from_pipe) 支持，这对于在不占用额外内存的情况下[复用流水线](./loading#reusing-models-in-multiple-pipelines)非常有用。它将内存使用量限制为仅加载的最大流水线。

  ```py
  import torch
  from diffusers import DiffusionPipeline

  pipeline_sd = DiffusionPipeline.from_pretrained(
      "emilianJR/CyberRealistic_V3", dtype=torch.float16, device_map="cuda"  # or "mps", "xpu", "cpu"
  )
  pipeline_lpw = DiffusionPipeline.from_pipe(
      pipeline_sd, custom_pipeline="lpw_stable_diffusion"
  )
  ```

  [from_pipe()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.from_pipe) 方法对于加载社区流水线特别有用，因为许多社区流水线没有预训练权重。社区流水线通常是在现有流水线的基础上增加一项功能。

## 社区组件

社区组件允许您使用 Diffusers 不支持的自定义 transformer、UNet、VAE 和调度器来构建流水线。这些组件需要拥有自己的 Python 模块。

本节以 [showlab/show-1-base](https://huggingface.co/showlab/show-1-base) 为例，展示用户如何使用社区组件来构建社区流水线。

1. 加载所需的组件，即调度器和图像处理器。文本编码器通常从 [Transformers](https://huggingface.co/docs/transformers/index) 中导入。

```python
from transformers import T5Tokenizer, T5EncoderModel, CLIPImageProcessor
from diffusers import DPMSolverMultistepScheduler

pipeline_id = "showlab/show-1-base"
tokenizer = T5Tokenizer.from_pretrained(pipeline_id, subfolder="tokenizer")
text_encoder = T5EncoderModel.from_pretrained(pipeline_id, subfolder="text_encoder")
scheduler = DPMSolverMultistepScheduler.from_pretrained(pipeline_id, subfolder="scheduler")
feature_extractor = CLIPImageProcessor.from_pretrained(pipeline_id, subfolder="feature_extractor")
```

> [!WARNING]
> 在第 2 步和第 3 步中，自定义的 [UNet](https://github.com/showlab/Show-1/blob/main/showone/models/unet_3d_condition.py) 和 [pipeline](https://huggingface.co/sayakpaul/show-1-base-with-code/blob/main/unet/showone_unet_3d_condition.py) 实现必须与其文件中的格式一致，本示例才能正常运行。

2. 加载一个已在 [showone_unet_3d_condition.py](https://huggingface.co/sayakpaul/show-1-base-with-code/blob/main/unet/showone_unet_3d_condition.py) 中实现的[自定义 UNet](https://github.com/showlab/Show-1/blob/main/showone/models/unet_3d_condition.py)。由于 [UNet3DConditionModel](/docs/diffusers/v0.43.0/zh/api/models/unet3d-cond#diffusers.UNet3DConditionModel) 在 Diffusers 中已存在，因此将 [UNet3DConditionModel](/docs/diffusers/v0.43.0/zh/api/models/unet3d-cond#diffusers.UNet3DConditionModel) 类名重命名为自定义实现 `ShowOneUNet3DConditionModel`。`ShowOneUNet3DConditionModel` 类所需的任何组件都应放置在 `showone_unet_3d_condition.py` 中。

```python
from showone_unet_3d_condition import ShowOneUNet3DConditionModel

unet = ShowOneUNet3DConditionModel.from_pretrained(pipeline_id, subfolder="unet")
```

3. 加载自定义流水线代码（已在 [pipeline_t2v_base_pixel.py](https://huggingface.co/sayakpaul/show-1-base-with-code/blob/main/pipeline_t2v_base_pixel.py) 中实现）。该脚本包含一个用于从文本生成视频的自定义 `TextToVideoIFPipeline` 类。与自定义 UNet 类似，`TextToVideoIFPipeline` 所需的任何代码都应放置在 `pipeline_t2v_base_pixel.py` 中。

使用 `ShowOneUNet3DConditionModel` 初始化 `TextToVideoIFPipeline`。

```python
import torch
from pipeline_t2v_base_pixel import TextToVideoIFPipeline

pipeline = TextToVideoIFPipeline(
    unet=unet,
    text_encoder=text_encoder,
    tokenizer=tokenizer,
    scheduler=scheduler,
    feature_extractor=feature_extractor,
)
pipeline = pipeline.to("cuda")  # or "mps", "xpu", "cpu"
```

4. 将流水线推送到 Hub，与社区共享。

```python
pipeline.push_to_hub("custom-t2v-pipeline")
```

成功推送流水线后，进行以下更改。

- 将 [model_index.json](https://huggingface.co/sayakpaul/show-1-base-with-code/blob/main/model_index.json#L2) 中的 `_class_name` 属性更改为 `["pipeline_t2v_base_pixel", "TextToVideoIFPipeline"]`。
- 将 `showone_unet_3d_condition.py` 上传到 [unet](https://huggingface.co/sayakpaul/show-1-base-with-code/blob/main/unet/showone_unet_3d_condition.py) 子文件夹中。
- 将 `pipeline_t2v_base_pixel.py` 上传到 [pipeline 仓库](https://huggingface.co/sayakpaul/show-1-base-with-code/tree/main)。

要运行推理，请在初始化 pipeline 时添加 `trust_remote_code` 参数，以处理所有幕后“魔法”。

```python
import torch
from diffusers import DiffusionPipeline

pipeline = DiffusionPipeline.from_pretrained(
    "<change-username>/<change-id>", trust_remote_code=True, dtype=torch.float16
)
```

> [!WARNING]
> 作为额外的预防措施，在使用 `trust_remote_code=True` 时，请在 [from_pretrained()](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) 中向 `revision` 参数传入一个 commit hash，以确保代码未被更新为包含新的恶意代码（除非你完全信任模型所有者）。

## 后续步骤

- 请查看 Issue [#841](https://github.com/huggingface/diffusers/issues/841)，以了解更多关于我们为何要添加社区流水线（community pipelines）的背景信息，旨在帮助大家轻松分享自己的工作，而不受阻碍。
- 请查看 [stabilityai/japanese-stable-diffusion-xl](https://huggingface.co/stabilityai/japanese-stable-diffusion-xl/) 仓库，了解另一个同样使用 `trust_remote_code` 功能的社区流水线示例。

