# Hunyuan-DiT
![chinese elements understanding](https://github.com/gnobitab/diffusers-hunyuan/assets/1157982/39b99036-c3cb-4f16-bb1a-40ec25eda573)

来自腾讯混元的[Hunyuan-DiT：一款具备细粒度中文理解能力的强大多分辨率扩散 Transformer](https://huggingface.co/papers/2405.08748)。

该论文的摘要如下：

*我们提出了 Hunyuan-DiT，这是一种能够精细理解中英文的文本生成图像扩散 Transformer。为了构建 Hunyuan-DiT，我们精心设计了 Transformer 结构、文本编码器和位置编码。我们还从零开始构建了一套完整的数据流水线，用于更新和评估数据，以支持模型的迭代优化。为了实现精细的语言理解，我们训练了一个多模态大语言模型来优化图像的文本描述。最终，Hunyuan-DiT 能够与用户进行多轮多模态对话，并根据上下文生成和优化图像。通过我们全面的人工评估协议，由 50 多位专业人工评估员参与，Hunyuan-DiT 在中文生成图像方面相较于其他开源模型达到了新的最先进水平。*

您可以在 [Tencent/HunyuanDiT](https://github.com/Tencent/HunyuanDiT) 找到原始代码库，在 [Tencent-Hunyuan](https://huggingface.co/Tencent-Hunyuan/HunyuanDiT) 找到所有可用的检查点。

**亮点**：HunyuanDiT 支持中英文到图像生成，以及多分辨率生成。

HunyuanDiT 包含以下组件：
* 它使用扩散 Transformer 作为骨干网络
* 它结合了两种文本编码器：一个双语 CLIP 和一个多语言 T5 编码器

> [!TIP]
> 请务必参阅 [调度器指南](../../using-diffusers/schedulers)，了解如何探索调度器速度与质量之间的权衡，并查看 [跨流水线复用组件](../../using-diffusers/loading#reusing-models-in-multiple-pipelines) 部分，了解如何高效地将相同组件加载到多个流水线中。

> [!TIP]
> 您可以通过将 `HungyuanDiTPipeline` 生成的图像传递给 [SDXL refiner](./stable_diffusion/stable_diffusion_xl#base-to-refiner-model) 模型，进一步提升生成质量。

## 优化

你可以使用 torch.compile 和前馈分块来优化流水线的运行时间和内存占用。要了解其他优化方法，请参阅 [加速推理](../../optimization/fp16) 和 [减少内存使用](../../optimization/memory) 指南。

### 推理

使用 [`torch.compile`](https://huggingface.co/docs/diffusers/main/en/tutorials/fast_diffusion#torchcompile) 来降低推理延迟。

首先，加载 pipeline：

```python
from diffusers import HunyuanDiTPipeline
import torch

pipeline = HunyuanDiTPipeline.from_pretrained(
	"Tencent-Hunyuan/HunyuanDiT-Diffusers", dtype=torch.float16
).to("cuda")  # or "mps", "xpu", "cpu"
```

然后，将流水线中 `transformer` 和 `vae` 组件的内存布局更改为 `torch.channels-last`：

```python
pipeline.transformer.to(memory_format=torch.channels_last)
pipeline.vae.to(memory_format=torch.channels_last)
```

最后，编译组件并运行推理：

```python
pipeline.transformer = torch.compile(pipeline.transformer, mode="max-autotune", fullgraph=True)
pipeline.vae.decode = torch.compile(pipeline.vae.decode, mode="max-autotune", fullgraph=True)

image = pipeline(prompt="一个宇航员在骑马").images[0]
```

在 80GB A100 机器上的 [benchmark](https://gist.github.com/sayakpaul/29d3a14905cfcbf611fe71ebd22e9b23) 结果如下：

```bash
With torch.compile(): Average inference time: 12.470 seconds.
Without torch.compile(): Average inference time: 20.570 seconds.
```

### 内存优化

通过以 8 位加载 T5 文本编码器，您可以在不到 6 GB 的 GPU 显存中运行该流水线。有关详细信息，请参阅[此脚本](https://gist.github.com/sayakpaul/3154605f6af05b98a41081aaba5ca43e)。

此外，您可以使用 [enable_forward_chunking()](/docs/diffusers/v0.43.0/zh/api/models/hunyuan_transformer2d#diffusers.HunyuanDiT2DModel.enable_forward_chunking) 方法来降低内存占用。前馈分块（feed-forward chunking）会在循环中依次运行 Transformer 块中的前馈层，而不是一次性全部执行。这让您可以在内存消耗和推理运行时间之间进行权衡。

```diff
+ pipeline.transformer.enable_forward_chunking(chunk_size=1, dim=1)
```

## HunyuanDiTPipeline[[diffusers.HunyuanDiTPipeline]]

#### diffusers.HunyuanDiTPipeline[[diffusers.HunyuanDiTPipeline]]

```python
diffusers.HunyuanDiTPipeline(vae: AutoencoderKL, text_encoder: BertModel, tokenizer: BertTokenizer, transformer: HunyuanDiT2DModel, scheduler: DDPMScheduler, safety_checker: StableDiffusionSafetyChecker, feature_extractor: CLIPImageProcessorPil, requires_safety_checker: bool = True, text_encoder_2: transformers.models.t5.modeling_t5.T5EncoderModel | None = None, tokenizer_2: transformers.models.t5.tokenization_t5.T5Tokenizer | None = None)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/hunyuandit/pipeline_hunyuandit.py#L149)

**参数：**

vae ([AutoencoderKL](/docs/diffusers/v0.43.0/zh/api/models/autoencoderkl#diffusers.AutoencoderKL))：变分自编码器（VAE）模型，用于将图像编码为潜在表示，以及从潜在表示解码为图像。我们使用 `sdxl-vae-fp16-fix`。

text_encoder (`~transformers.BertModel`, `~transformers.CLIPTextModel` | None) : 冻结的文本编码器 ([clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14))。HunyuanDiT 使用经过微调的 [bilingual CLIP]。

tokenizer (`~transformers.BertTokenizer`、`~transformers.CLIPTokenizer` | None) : 用于对文本进行分词的 `BertTokenizer` 或 `CLIPTokenizer`。

transformer ([HunyuanDiT2DModel](/docs/diffusers/v0.43.0/zh/api/models/hunyuan_transformer2d#diffusers.HunyuanDiT2DModel))：由腾讯混元设计的 HunyuanDiT 模型。

text_encoder_2 (`T5EncoderModel`)：mT5 嵌入器。具体而言，它是 't5-v1_1-xxl'。

tokenizer_2 (`T5Tokenizer`)：mT5 嵌入器的分词器。

scheduler ([DDPMScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/ddpm#diffusers.DDPMScheduler))：用于配合 HunyuanDiT 对编码后的图像潜在表示进行去噪的调度器。

用于使用 HunyuanDiT 进行英语/中文到图像生成的 Pipeline。

该模型继承自 [DiffusionPipeline](/docs/diffusers/v0.43.0/zh/api/pipelines/overview#diffusers.DiffusionPipeline)。请查阅父类文档，了解该库为所有 pipeline 实现的通用方法（例如下载或保存、在特定设备上运行等）。

HunyuanDiT 使用两个文本编码器：[mT5](https://huggingface.co/google/mt5-base) 和 [双语 CLIP](由我们自行微调)

#### __调用__[[diffusers.HunyuanDiTPipeline.__call__]]

```python
__call__(prompt: str | list[str] = None, height: int | None = None, width: int | None = None, num_inference_steps: int | None = 50, guidance_scale: float | None = 5.0, negative_prompt: str | list[str] | None = None, num_images_per_prompt: int | None = 1, eta: float | None = 0.0, generator: typing.Union[torch.Generator, list[torch.Generator], NoneType] = None, latents: typing.Optional[torch.Tensor] = None, prompt_embeds: typing.Optional[torch.Tensor] = None, prompt_embeds_2: typing.Optional[torch.Tensor] = None, negative_prompt_embeds: typing.Optional[torch.Tensor] = None, negative_prompt_embeds_2: typing.Optional[torch.Tensor] = None, prompt_attention_mask: typing.Optional[torch.Tensor] = None, prompt_attention_mask_2: typing.Optional[torch.Tensor] = None, negative_prompt_attention_mask: typing.Optional[torch.Tensor] = None, negative_prompt_attention_mask_2: typing.Optional[torch.Tensor] = None, output_type: str | None = 'pil', return_dict: bool = True, callback_on_step_end: typing.Union[typing.Callable[[int, int], NoneType], diffusers.callbacks.PipelineCallback, diffusers.callbacks.MultiPipelineCallbacks, NoneType] = None, callback_on_step_end_tensor_inputs: list[str] = ['latents'], guidance_rescale: float = 0.0, original_size: tuple[int, int] | None = (1024, 1024), target_size: tuple[int, int] | None = None, crops_coords_top_left: tuple[int, int] = (0, 0), use_resolution_binning: bool = True)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/hunyuandit/pipeline_hunyuandit.py#L568)

**参数：**

prompt (`str` 或 `list[str]`，*可选*)：用于引导图像生成的提示词或提示词列表。如果未定义，则需要传入 `prompt_embeds`。

height (`int`) : 生成图像的高度（以像素为单位）。

width (`int`) : 生成图像的宽度（以像素为单位）。

num_inference_steps (`int`，*可选*，默认值为 50)：去噪步数。更多的去噪步数通常能生成更高质量的图像，但代价是推理速度变慢。此参数受 `strength` 调节。

guidance_scale (`float`, *可选*，默认值为 7.5)：较高的 guidance scale 值会促使模型生成与文本 `prompt` 紧密相关的图像，但代价是图像质量降低。当 `guidance_scale > 1` 时，guidance scale 生效。

negative_prompt (`str` 或 `list[str]`，*可选*)：用于指导图像生成中不应包含的内容的提示词或提示词列表。如果未定义，则需要改为传入 `negative_prompt_embeds`。在未使用引导（`guidance_scale < 1`）时将被忽略。

num_images_per_prompt (`int`，*可选*，默认为 1)：每个提示词生成的图像数量。

eta (`float`，*可选*，默认值为 0.0)：对应 [DDIM](https://huggingface.co/papers/2010.02502) 论文中的参数 eta (η)。仅适用于 [DDIMScheduler](/docs/diffusers/v0.43.0/zh/api/schedulers/ddim#diffusers.DDIMScheduler)，在其他调度器中会被忽略。

generator (`torch.Generator` 或 `list[torch.Generator]`，*可选*)：用于使生成过程确定性的 [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html)。

latents (`torch.Tensor`, *可选*) : 从高斯分布中采样的预生成噪声潜变量，用作图像生成的输入。可用于以不同的提示词微调同一生成过程。如果未提供，则使用提供的随机`generator`进行采样来生成潜变量张量。

prompt_embeds (`torch.Tensor`, *可选*) : 预生成的文本嵌入。可用于轻松调整文本输入（提示词权重）。如果未提供，则从 `prompt` 输入参数生成文本嵌入。

prompt_embeds_2 (`torch.Tensor`, *可选*) : 预生成的文本嵌入。可用于轻松调整文本输入（提示词权重）。如果未提供，则从 `prompt` 输入参数生成文本嵌入。

negative_prompt_embeds (`torch.Tensor`, *可选*) : 预生成的负向文本嵌入。可用于轻松调整文本输入（提示词权重）。如果未提供，`negative_prompt_embeds` 将从 `negative_prompt` 输入参数生成。

negative_prompt_embeds_2 (`torch.Tensor`, *可选*) : 预生成的负向文本嵌入。可用于轻松调整文本输入（提示词权重）。如果未提供，`negative_prompt_embeds` 将从 `negative_prompt` 输入参数生成。

prompt_attention_mask (`torch.Tensor`, *可选*) : 提示词的注意力掩码。当直接传入 `prompt_embeds` 时，此项为必填。

prompt_attention_mask_2 (`torch.Tensor`，*可选*)：提示词的注意力掩码。当直接传入 `prompt_embeds_2` 时，此项为必填。

negative_prompt_attention_mask (`torch.Tensor`，*可选*)：用于负面提示词的注意力掩码。当直接传入 `negative_prompt_embeds` 时，此参数为必填项。

negative_prompt_attention_mask_2 (`torch.Tensor`, *可选*) : 负面提示词的注意力掩码。当直接传入 `negative_prompt_embeds_2` 时，此参数为必填项。

output_type (`str`，*可选*，默认为 `"pil"`)：生成图像的输出格式。在 `PIL.Image` 或 `np.array` 之间选择。

return_dict (`bool`，*可选*，默认为 `True`)：是否返回 [StableDiffusionPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput) 而不是普通元组。

callback_on_step_end (`Callable[[int, int], None]`、`PipelineCallback`、`MultiPipelineCallbacks`、*可选*)：在每个去噪步骤结束时调用的回调函数或回调函数列表。

callback_on_step_end_tensor_inputs (`list[str]`，*可选*) : 应传递给回调函数的张量输入列表。如果未定义，则所有张量输入都会被传递。

guidance_rescale (`float`, *optional*, defaults to 0.0) : Rescale the noise_cfg according to `guidance_rescale`. Based on findings of [Common Diffusion Noise Schedules and Sample Steps are Flawed](https://huggingface.co/papers/2305.08891). See Section 3.4

original_size (`tuple[int, int]`，*可选*，默认为 `(1024, 1024)`)：图像的原始尺寸。用于计算时间 ID。

target_size (`tuple[int, int]`，*可选*)：图像的目标尺寸。用于计算时间 ID。

crops_coords_top_left (`tuple[int, int]`，*可选*，默认为 `(0, 0)`)：裁剪区域的左上角坐标。用于计算时间 ID。

use_resolution_binning (`bool`，*可选*，默认为 `True`)：是否使用分辨率分箱。如果为 `True`，输入分辨率将被映射到最接近的标准分辨率。支持的分辨率为 1024x1024、1280x1280、1024x768、1152x864、1280x960、768x1024、864x1152、960x1280、1280x768 和 768x1280。建议将此值设置为 `True`。

**返回：** [StableDiffusionPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput) 或 `tuple`

如果 `return_dict` 为 `True`，则返回 [StableDiffusionPipelineOutput](/docs/diffusers/v0.43.0/zh/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput)；否则返回一个 `tuple`，其中第一个元素是包含生成图像的列表，第二个元素是 `bool` 列表，用于指示对应的生成图像是否包含“不适合工作场所”（nsfw）内容。

调用 pipeline 的 call 函数，使用 HunyuanDiT 进行生成。

示例：
```py
>>> import torch
>>> from diffusers import HunyuanDiTPipeline

>>> pipe = HunyuanDiTPipeline.from_pretrained(
...     "Tencent-Hunyuan/HunyuanDiT-Diffusers", torch_dtype=torch.float16
... )
>>> pipe.to("cuda")

>>> # You may also use English prompt as HunyuanDiT supports both English and Chinese
>>> # prompt = "An astronaut riding a horse"
>>> prompt = "一个宇航员在骑马"
>>> image = pipe(prompt).images[0]
```

#### encode_prompt[[diffusers.HunyuanDiTPipeline.encode_prompt]]

```python
encode_prompt(prompt: str, device: device = None, dtype: dtype = None, num_images_per_prompt: int = 1, do_classifier_free_guidance: bool = True, negative_prompt: str | None = None, prompt_embeds: typing.Optional[torch.Tensor] = None, negative_prompt_embeds: typing.Optional[torch.Tensor] = None, prompt_attention_mask: typing.Optional[torch.Tensor] = None, negative_prompt_attention_mask: typing.Optional[torch.Tensor] = None, max_sequence_length: int | None = None, text_encoder_index: int = 0)
```

[源代码](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/pipelines/hunyuandit/pipeline_hunyuandit.py#L248)

**参数：**

prompt (`str` 或 `list[str]`，*可选*)：要编码的提示

device : (`torch.device`): torch 设备

dtype (`torch.dtype`)：torch 数据类型

num_images_per_prompt (`int`) : 每个提示词应生成的图像数量

do_classifier_free_guidance (`bool`) : 是否使用 classifier free guidance

negative_prompt (`str` 或 `list[str]`，*可选*)：用于引导图像生成的负面提示词。如果未定义，则必须传入 `negative_prompt_embeds`。当不使用引导时（即 `guidance_scale` 小于 `1` 时），此参数将被忽略。

prompt_embeds (`torch.Tensor`, *可选*) : 预生成的文本嵌入。可用于轻松调整文本输入，*例如* 提示词加权。如果未提供，文本嵌入将从 `prompt` 输入参数生成。

negative_prompt_embeds (`torch.Tensor`, *可选*) : 预生成的负向文本嵌入。可用于轻松调整文本输入，*例如* 提示词权重。如果未提供，negative_prompt_embeds 将从 `negative_prompt` 输入参数生成。

prompt_attention_mask (`torch.Tensor`, *可选*) : 提示词的注意力掩码。当直接传入 `prompt_embeds` 时，此项为必填。

negative_prompt_attention_mask (`torch.Tensor`，*可选*)：用于负面提示词的注意力掩码。当直接传入 `negative_prompt_embeds` 时，此参数为必填项。

max_sequence_length (`int`, *可选*) : 用于提示词的最大序列长度。

text_encoder_index (`int`, *可选*) : 要使用的文本编码器索引。`0` 表示 clip，`1` 表示 T5。

将提示词编码为文本编码器的隐藏状态。

