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

[Hunyuan-DiT: мощный диффузионный трансформер с поддержкой нескольких разрешений и тонким пониманием китайского языка](https://huggingface.co/papers/2405.08748) от Tencent Hunyuan.

Аннотация из статьи:

*Мы представляем Hunyuan-DiT — диффузионный трансформер для генерации изображений по тексту, обеспечивающий детальное понимание как английского, так и китайского языков. Для создания Hunyuan-DiT мы тщательно спроектировали структуру трансформера, текстовый энкодер и позиционное кодирование. Кроме того, мы с нуля построили полный конвейер данных для обновления и оценки данных в процессе итеративной оптимизации модели. Для детального понимания языка мы обучили мультимодальную большую языковую модель для уточнения описаний изображений. В итоге Hunyuan-DiT способен вести многоходовой мультимодальный диалог с пользователями, генерируя и уточняя изображения в соответствии с контекстом. Благодаря нашей комплексной протоколе человеческой оценки с участием более 50 профессиональных оценщиков, Hunyuan-DiT устанавливает новый уровень качества в генерации изображений по китайскому тексту по сравнению с другими открытыми моделями.*

Исходный код можно найти в [Tencent/HunyuanDiT](https://github.com/Tencent/HunyuanDiT), а все доступные контрольные точки — в [Tencent-Hunyuan](https://huggingface.co/Tencent-Hunyuan/HunyuanDiT).

**Ключевые особенности**: HunyuanDiT поддерживает генерацию изображений по описаниям на китайском и английском языках, а также создание изображений в нескольких разрешениях.

HunyuanDiT включает следующие компоненты:
* В качестве основы используется диффузионный трансформер
* Он объединяет два текстовых кодировщика: двуязычный 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 и feed-forward chunking. Чтобы узнать о других методах оптимизации, ознакомьтесь с руководствами [Ускорение вывода](../../optimization/fp16) и [Сокращение использования памяти](../../optimization/memory).

### Вывод

Используйте [`torch.compile`](https://huggingface.co/docs/diffusers/main/en/tutorials/fast_diffusion#torchcompile) для снижения задержки при выводе.

Сначала загрузите конвейер:

```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]
```

Результаты [бенчмарка](https://gist.github.com/sayakpaul/29d3a14905cfcbf611fe71ebd22e9b23) на машине с 80 ГБ A100:

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

### Оптимизация памяти

Загрузив текстовый энкодер T5 в 8-битном формате, вы можете запустить конвейер, используя менее 6 ГБ видеопамяти GPU. Подробности см. в [этом скрипте](https://gist.github.com/sayakpaul/3154605f6af05b98a41081aaba5ca43e).

Кроме того, вы можете использовать метод [enable_forward_chunking()](/docs/diffusers/main/ru/api/models/hunyuan_transformer2d#diffusers.HunyuanDiT2DModel.enable_forward_chunking) для снижения потребления памяти. Feed-forward chunking выполняет слои feed-forward в блоке трансформера в цикле, а не все сразу. Это позволяет выбирать между расходом памяти и временем инференса.

```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/main/src/diffusers/pipelines/hunyuandit/pipeline_hunyuandit.py#L149)

**Параметры:**

vae ([AutoencoderKL](/docs/diffusers/main/ru/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 использует дообученный [двуязычный CLIP].

tokenizer (`~transformers.BertTokenizer`, `~transformers.CLIPTokenizer` | None) : `BertTokenizer` или `CLIPTokenizer` для токенизации текста.

transformer ([HunyuanDiT2DModel](/docs/diffusers/main/ru/api/models/hunyuan_transformer2d#diffusers.HunyuanDiT2DModel)) : Модель HunyuanDiT, разработанная командой Tencent Hunyuan.

text_encoder_2 (`T5EncoderModel`) : встраиватель mT5. Конкретно, это 't5-v1_1-xxl'.

tokenizer_2 (`T5Tokenizer`) : токенизатор для встраивателя mT5.

scheduler ([DDPMScheduler](/docs/diffusers/main/ru/api/schedulers/ddpm#diffusers.DDPMScheduler)) : планировщик, используемый в сочетании с HunyuanDiT для удаления шума из закодированных латентов изображения.

Pipeline для генерации изображений из текста на английском/китайском языке с использованием HunyuanDiT.

Эта модель наследуется от [DiffusionPipeline](/docs/diffusers/main/ru/api/pipelines/overview#diffusers.DiffusionPipeline). См. документацию родительского класса для общих методов, которые библиотека реализует для всех пайплайнов (например, загрузка или сохранение, запуск на конкретном устройстве и т. д.)

HunyuanDiT использует два текстовых кодировщика: [mT5](https://huggingface.co/google/mt5-base) и [двуязычный CLIP](fine-tuned by ourselves)

#### __call__[[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 = ['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 = (0, 0), use_resolution_binning: bool = True)
```

[Источник](https://github.com/huggingface/diffusers/blob/main/src/diffusers/pipelines/hunyuandit/pipeline_hunyuandit.py#L568)

**Параметры:**

prompt (`str` или `list[str]`, *необязательный*) : Промпт или промпты для управления генерацией изображения. Если не задан, необходимо передать `prompt_embeds`.

height (`int`) : Высота генерируемого изображения в пикселях.

width (`int`) : Ширина сгенерированного изображения в пикселях.

num_inference_steps (`int`, *optional*, по умолчанию 50) : Количество шагов денойзинга. Как правило, большее число шагов денойзинга приводит к изображению более высокого качества, но за счёт более медленного вывода. Этот параметр модулируется `strength`.

guidance_scale (`float`, *optional*, по умолчанию 7.5) : Более высокое значение guidance scale побуждает модель генерировать изображения, тесно связанные с текстовым `prompt`, за счёт снижения качества изображения. Guidance scale активируется, когда `guidance_scale > 1`.

negative_prompt (`str` или `list[str]`, *необязательный*) : Промпт или промпты, определяющие, что следует исключить из генерируемого изображения. Если не задан, необходимо передать `negative_prompt_embeds`. Игнорируется, если не используется направляющая (`guidance_scale < 1`).

num_images_per_prompt (`int`, *необязательный*, по умолчанию 1) : Количество изображений, генерируемых на один запрос.

eta (`float`, *необязательный*, по умолчанию 0.0) : Соответствует параметру eta (η) из статьи [DDIM](https://huggingface.co/papers/2010.02502). Применяется только к [DDIMScheduler](/docs/diffusers/main/ru/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/main/ru/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput) вместо обычного кортежа.

callback_on_step_end (`Callable[[int, int], None]`, `PipelineCallback`, `MultiPipelineCallbacks`, *optional*) : Функция обратного вызова или список функций обратного вызова, которые вызываются в конце каждого шага удаления шума.

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)`) : исходный размер изображения. Используется для вычисления временных идентификаторов.

target_size (`tuple[int, int]`, *необязательный*) : Целевой размер изображения. Используется для вычисления временных идентификаторов.

crops_coords_top_left (`tuple[int, int]`, *необязательный*, по умолчанию `(0, 0)`) : координаты верхнего левого угла кадрирования. Используется для вычисления временных идентификаторов.

use_resolution_binning (`bool`, *необязательный*, по умолчанию `True`) : Использовать ли биннинг разрешения. Если `True`, входное разрешение будет сопоставлено с ближайшим стандартным разрешением. Поддерживаемые разрешения: 1024x1024, 1280x1280, 1024x768, 1152x864, 1280x960, 768x1024, 864x1152, 960x1280, 1280x768 и 768x1280. Рекомендуется установить это значение в `True`.

**Возвращает:** [StableDiffusionPipelineOutput](/docs/diffusers/main/ru/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput) или `tuple`

Если `return_dict` равно `True`, возвращается [StableDiffusionPipelineOutput](/docs/diffusers/main/ru/api/pipelines/stable_diffusion/img2img#diffusers.pipelines.stable_diffusion.StableDiffusionPipelineOutput), иначе возвращается `tuple`, где первый элемент — это список сгенерированных изображений, а второй — список значений `bool`, указывающих, содержит ли соответствующее сгенерированное изображение контент, нежелательный для просмотра на рабочем месте (nsfw).

Функция вызова pipeline для генерации с 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/main/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`, *optional*) : Индекс используемого текстового энкодера. `0` для clip и `1` для T5.

Кодирует промпт в скрытые состояния текстового энкодера.

