# Утилиты

Вспомогательные и служебные функции для работы с 🤗 Diffusers.

## numpy_to_pil[[diffusers.utils.numpy_to_pil]]

#### diffusers.utils.numpy_to_pil[[diffusers.utils.numpy_to_pil]]

```python
diffusers.utils.numpy_to_pil(images)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/pil_utils.py#L35)

Преобразование изображения numpy или пакета изображений в изображение PIL.

## pt_to_pil[[diffusers.utils.pt_to_pil]]

#### diffusers.utils.pt_to_pil[[diffusers.utils.pt_to_pil]]

```python
diffusers.utils.pt_to_pil(images)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/pil_utils.py#L25)

Преобразование изображения torch в изображение PIL.

## load_image[[diffusers.utils.load_image]]

#### diffusers.utils.load_image[[diffusers.utils.load_image]]

```python
diffusers.utils.load_image(image: str | PIL.Image.Image, convert_method: typing.Optional[typing.Callable[[PIL.Image.Image], PIL.Image.Image]] = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/loading_utils.py#L14)

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

image (`str` или `PIL.Image.Image`) : изображение, которое нужно преобразовать в формат PIL Image.

convert_method (Callable[[PIL.Image.Image], PIL.Image.Image], *optional*) : Метод преобразования, применяемый к изображению после его загрузки. Если установлено значение `None`, изображение будет преобразовано в формат "RGB".

**Возвращает:** `PIL.Image.Image`

Изображение PIL.

Загружает `image` в изображение PIL.

## load_video[[diffusers.utils.load_video]]

#### diffusers.utils.load_video[[diffusers.utils.load_video]]

```python
diffusers.utils.load_video(video: str, convert_method: typing.Optional[typing.Callable[[list[PIL.Image.Image]], list[PIL.Image.Image]]] = None, return_fps: bool = False)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/loading_utils.py#L57)

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

video (`str`) : URL или путь к видео для преобразования в список изображений в формате PIL Image.

convert_method (Callable[[list[PIL.Image.Image]], list[PIL.Image.Image]], *необязательный*) : Метод преобразования, применяемый к видео после его загрузки. Если установлено значение `None`, изображения будут преобразованы в формат "RGB".

return_fps (`bool`, *необязательный*, по умолчанию `False`) : Нужно ли также возвращать частоту кадров, с которой было закодировано видео. Требуется для конвейеров, которые пересэмплируют входные данные до частоты кадров, с которой работает их модель, поскольку список кадров не содержит этой информации.

**Возвращает:** `list[PIL.Image.Image]` или `tuple[list[PIL.Image.Image], float]`

Видео в виде списка изображений PIL, а также частота кадров, если задан параметр `return_fps`.

Загружает `video` в список изображений PIL.

## export_to_gif[[diffusers.utils.export_to_gif]]

#### diffusers.utils.export_to_gif[[diffusers.utils.export_to_gif]]

```python
diffusers.utils.export_to_gif(image: list[PIL.Image.Image], output_gif_path: str = None, fps: int = 10)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/export_utils.py#L37)

## export_to_video[[diffusers.utils.export_to_video]]

#### diffusers.utils.export_to_video[[diffusers.utils.export_to_video]]

```python
diffusers.utils.export_to_video(video_frames: list[np.ndarray] | list[PIL.Image.Image], output_video_path: str = None, fps: int = 10, quality: float = 5.0, bitrate: int | None = None, macro_block_size: int | None = 16)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/export_utils.py#L150)

quality: Качество видеовыхода. По умолчанию 5. Используется переменная битрейт. Максимальное качество — 10, минимальное — 0. Установите None, чтобы не передавать флаги переменной битрейт в FFMPEG, что позволит указать их вручную с помощью output_params. Указание фиксированного битрейта с помощью `bitrate` отключает этот параметр.

bitrate: задаёт постоянную скорость кодирования видео. По умолчанию значение None, в этом случае используется параметр `quality`. Использование переменной скорости кодирования через параметр `quality` позволяет получить видео лучшего качества при меньшем размере файла, чем при задании фиксированной скорости с помощью этого параметра.

macro_block_size: Ограничение размера для видео. Ширина и высота должны делиться на это число. Если они не делятся, imageio укажет ffmpeg масштабировать изображение до ближайшего размера, делящегося на это число. Большинство кодеков совместимы с размером макроблока 16 (по умолчанию), некоторые поддерживают меньшие значения (4, 8). Чтобы отключить эту автоматическую функцию, установите значение None или 1, однако имейте в виду, что многие плееры не могут декодировать видео с нечётными размерами, а некоторые кодеки могут выдавать низкое качество или завершаться ошибкой. См. https://en.wikipedia.org/wiki/Macroblock.

## encode_video[[diffusers.utils.encode_video]]

#### diffusers.utils.encode_video[[diffusers.utils.encode_video]]

```python
diffusers.utils.encode_video(video: list[PIL.Image.Image] | np.ndarray | 'torch.Tensor' | Iterator['torch.Tensor'], fps: int, output_path: str, audio: 'torch.Tensor' | None = None, audio_sample_rate: int | None = None, video_chunks_number: int = 1)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/export_utils.py#L304)

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

video (`List[PIL.Image.Image]` или `np.ndarray` или `torch.Tensor`) : Тензор видео с формой [frames, height, width, channels] и целочисленными значениями пикселей в диапазоне [0, 255]. Если входом является `np.ndarray`, ожидается, что это будет массив float со значениями в диапазоне [0, 1] (именно такой формат обычно возвращают пайплайны при `output_type="np"`).

fps (`int`) : Количество кадров в секунду (FPS) закодированного видео.

output_path (`str`) : Путь для сохранения закодированного видео.

audio (`torch.Tensor`, *необязательный*) : Аудиоволна формы [audio_channels, samples].

audio_sample_rate : (`int`, *optional*): Частота дискретизации аудиосигнала.

video_chunks_number (`int`, *optional*, по умолчанию `1`) : Количество фрагментов, на которые видео делится для кодирования. Каждый фрагмент кодируется отдельно. Количество используемых фрагментов часто зависит от конфигурации тайлинга для видео-VAE.

Кодирует видео с необязательным аудио с использованием библиотеки PyAV. Основано на коде из оригинального репозитория LTX-2: https://github.com/Lightricks/LTX-2/blob/4f410820b198e05074a1e92de793e3b59e9ab5a0/packages/ltx-pipelines/src/ltx_pipelines/utils/media_io.py#L182

## make_image_grid[[diffusers.utils.make_image_grid]]

#### diffusers.utils.make_image_grid[[diffusers.utils.make_image_grid]]

```python
diffusers.utils.make_image_grid(images: list[PIL.Image.Image], rows: int, cols: int, resize: int = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/pil_utils.py#L51)

Готовит единую сетку изображений. Полезно для целей визуализации.

## randn_tensor[[diffusers.utils.torch_utils.randn_tensor]]

#### diffusers.utils.torch_utils.randn_tensor[[diffusers.utils.torch_utils.randn_tensor]]

```python
diffusers.utils.torch_utils.randn_tensor(shape: tuple | list, generator: list['torch.Generator'] | 'torch.Generator' | None = None, device: str | 'torch.device' | None = None, dtype: 'torch.dtype' | None = None, layout: 'torch.layout' | None = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/torch_utils.py#L61)

Вспомогательная функция для создания случайных тензоров на нужном `device` с нужным `dtype`. При передаче списка генераторов можно задать отдельный seed для каждого размера батча. Если переданы генераторы для CPU, тензор всегда создаётся на CPU.

## TorchDeviceBackend[[diffusers.utils.torch_utils.TorchDeviceBackend]]

#### diffusers.utils.torch_utils.TorchDeviceBackend[[diffusers.utils.torch_utils.TorchDeviceBackend]]

```python
diffusers.utils.torch_utils.TorchDeviceBackend(device: str | torch.device | None = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/torch_utils.py#L228)

Прокси для пространства имён `torch.<backend>` (`torch.cuda`, `torch.xpu`, `torch.mps`, ...) одного устройства. Атрибуты, которые класс не определяет, принадлежат самому модулю (`synchronize`, `device_count`, `Stream`, `current_stream`, ...); методы, определённые здесь, переопределяют операции, доступность которых различается между бэкендами и для которых требуется запасной вариант: очистка кэша, установка seed и запросы о памяти. Если `device` не указан, ускоритель хоста определяется через `torch.accelerator`. Если у torch нет модуля для данного бэкенда, возникает исключение, а не происходит тихого переключения на `torch.cuda`.

#### max_memory_allocated[[diffusers.utils.torch_utils.TorchDeviceBackend.max_memory_allocated]]

```python
max_memory_allocated()
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/torch_utils.py#L291)

Пиковый объём памяти, выделенной на устройстве в байтах с момента последнего сброса; 0, если бэкенд не ведёт статистику.

#### mem_get_info[[diffusers.utils.torch_utils.TorchDeviceBackend.mem_get_info]]

```python
mem_get_info()
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/utils/torch_utils.py#L279)

Свободная и общая память устройства в байтах.

## apply_layerwise_casting[[diffusers.hooks.apply_layerwise_casting]]

#### diffusers.hooks.apply_layerwise_casting[[diffusers.hooks.apply_layerwise_casting]]

```python
diffusers.hooks.apply_layerwise_casting(module: Module, storage_dtype: dtype, compute_dtype: dtype, skip_modules_pattern: str | tuple[str, ...] = 'auto', skip_modules_classes: tuple[typing.Type[torch.nn.Module], ...] | None = None, non_blocking: bool = False)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/hooks/layerwise_casting.py#L101)

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

module (`torch.nn.Module`) : модуль, дочерние модули которого будут приведены к типу данных высокой точности для вычислений и к типу данных низкой точности для хранения.

storage_dtype (`torch.dtype`) : тип данных, к которому модуль приводится до/после прямого прохода для хранения.

compute_dtype (`torch.dtype`) : тип данных, к которому модуль приводится во время прямого прохода для вычислений.

skip_modules_pattern (`tuple[str, ...]`, по умолчанию `"auto"`) : Список шаблонов для сопоставления с именами модулей, которые нужно пропустить в процессе послойного приведения типов. Если установлено значение `"auto"`, используются шаблоны по умолчанию. Если установлено значение `None`, модули не пропускаются. Если установлено значение `None` при условии, что `skip_modules_classes` также равно `None`, послойное приведение типов применяется непосредственно к модулю, а не к его внутренним подмодулям.

skip_modules_classes (`tuple[Type[torch.nn.Module], ...]`, по умолчанию `None`) : Список классов модулей, которые нужно пропустить при послойном приведении типов.

non_blocking (`bool`, по умолчанию `False`) : Если `True`, операции приведения весов выполняются без блокировки.

Применяет послойное приведение типов к заданному модулю. Ожидаемым модулем здесь является Diffusers ModelMixin, но это может быть любой nn.Module, использующий слои diffusers или примитивы pytorch.

Пример:

```python
>>> import torch
>>> from diffusers import CogVideoXTransformer3DModel

>>> transformer = CogVideoXTransformer3DModel.from_pretrained(
...     model_id, subfolder="transformer", torch_dtype=torch.bfloat16
... )

>>> apply_layerwise_casting(
...     transformer,
...     storage_dtype=torch.float8_e4m3fn,
...     compute_dtype=torch.bfloat16,
...     skip_modules_pattern=["patch_embed", "norm", "proj_out"],
...     non_blocking=True,
... )
```

## apply_group_offloading[[diffusers.hooks.apply_group_offloading]]

#### diffusers.hooks.apply_group_offloading[[diffusers.hooks.apply_group_offloading]]

```python
diffusers.hooks.apply_group_offloading(module: Module, onload_device: typing.Union[str, torch.device], offload_device: typing.Union[str, torch.device] = torch.device(), offload_type: str | diffusers.hooks.group_offloading.GroupOffloadingType = 'block_level', num_blocks_per_group: int | None = None, non_blocking: bool = False, use_stream: bool = False, record_stream: bool = False, low_cpu_mem_usage: bool = False, offload_to_disk_path: str | None = None, block_modules: list[str] | None = None, exclude_kwargs: list[str] | None = None)
```

[Источник](https://github.com/huggingface/diffusers/blob/v0.43.0/src/diffusers/hooks/group_offloading.py#L567)

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

module (`torch.nn.Module`) : модуль, к которому применяется групповая разгрузка.

onload_device (`torch.device`) : Устройство, на котором загружена группа модулей.

offload_device (`torch.device`, по умолчанию `torch.device("cpu")`) : Устройство, на которое выгружается группа модулей. Обычно это должно быть CPU. По умолчанию — CPU.

offload_type (`str` или `GroupOffloadingType`, по умолчанию "block_level") : Тип применяемого выгрузки. Может быть "block_level" или "leaf_level". По умолчанию "block_level".

offload_to_disk_path (`str`, *необязательный*, по умолчанию `None`) : Путь к каталогу, в который будут выгружаться параметры. Установка этого параметра может быть полезна в условиях ограниченной оперативной памяти, когда требуется разумный компромисс между скоростью и потреблением памяти.

num_blocks_per_group (`int`, *optional*) : количество блоков в группе при использовании offload_type="block_level". Это значение обязательно при использовании offload_type="block_level".

non_blocking (`bool`, по умолчанию `False`) : Если True, выгрузка и загрузка данных выполняются с неблокирующей передачей.

use_stream (`bool`, по умолчанию `False`) : Если True, выгрузка и загрузка выполняются асинхронно с использованием CUDA-потока. Это может быть полезно для перекрытия вычислений и передачи данных.

record_stream (`bool`, по умолчанию `False`) : При включении вместе с `use_stream` помечает текущий тензор как использованный этим потоком. Работает быстрее за счёт немного большего потребления памяти. Подробности см. в [официальной документации PyTorch](https://pytorch.org/docs/stable/generated/torch.Tensor.record_stream.html).

low_cpu_mem_usage (`bool`, по умолчанию `False`) : Если установлено в True, использование памяти CPU минимизируется за счёт закрепления тензоров на лету, а не их предварительного закрепления. Этот параметр имеет значение только при использовании потоковой разгрузки на CPU (т. е. `use_stream=True`). Это может быть полезно, когда память CPU является узким местом, но может нивелировать преимущества использования потоков.

block_modules (`list[str]`, *необязательный*) : Список имён модулей, которые следует рассматривать как блоки для выгрузки. Если указан, для выгрузки на уровне блоков будут учитываться только эти модули. Если не указан, будет использоваться логика обнаружения блоков по умолчанию.

exclude_kwargs (`list[str]`, *необязательный*) : Список ключей аргументов kwargs, которые не должны обрабатываться send_to_device. Это полезно для изменяемого состояния, такого как списки кэширования, которые должны сохранять идентичность объектов между проходами forward. Если не указано, будет выведено из атрибута `_skip_keys` модуля, если он существует.

Применяет групповую разгрузку (group offloading) для внутренних слоёв модуля torch.nn.Module. Чтобы понять, что такое групповая разгрузка и в каких случаях она полезна, сначала нужно дать некоторый контекст о том, как работают другие поддерживаемые методы разгрузки.

Как правило, выгрузка выполняется на двух уровнях:
- На уровне модуля: в Diffusers это можно включить с помощью метода `ModelMixin::enable_model_cpu_offload()`. Он работает за счёт выгрузки каждого компонента пайплайна на CPU для хранения и загрузки на устройство ускорителя по мере необходимости для вычислений. Этот метод более эффективен по памяти, чем хранение всех компонентов на ускорителе, однако требования к памяти всё ещё остаются довольно высокими. Для работы этого метода необходимо выделить память, эквивалентную размеру модели в рабочем типе данных (runtime dtype) + размеру крупнейших промежуточных тензоров активаций, чтобы завершить прямой проход (forward pass).
- Уровень листьев: в Diffusers это можно включить с помощью метода `ModelMixin::enable_sequential_cpu_offload()`. Он работает за счёт выгрузки параметров нижнего уровня (листьев) вычислительного графа на CPU для хранения и загрузки только этих листьев на устройство ускорителя для вычислений. Такой подход использует минимальное количество памяти ускорителя, но может быть медленнее из-за избыточного числа синхронизаций устройств.

Групповое выгружение представляет собой промежуточный вариант между двумя методами. Оно работает путём выгрузки групп внутренних слоёв (либо `torch.nn.ModuleList`, либо `torch.nn.Sequential`). Этот метод потребляет меньше памяти, чем выгружение на уровне модулей. Он также быстрее, чем выгружение на уровне листьев/последовательное выгружение, поскольку уменьшается количество синхронизаций устройств.

Ещё одна поддерживаемая функция (для CUDA-устройств с поддержкой потоков асинхронной передачи данных) — возможность перекрывать передачу данных и вычисления, чтобы сократить общее время выполнения по сравнению с последовательным offloading. Это реализуется с помощью предварительной загрузки слоёв (layer prefetching) с использованием потоков: слой, который будет выполнен следующим, начинает onloading на ускорительное устройство, пока выполняется текущий слой, — это немного увеличивает требования к памяти. Обратите внимание, что данная реализация также поддерживает offloading на уровне листьев (leaf-level), но может стать значительно быстрее при использовании потоков.

Пример:
```python
>>> from diffusers import CogVideoXTransformer3DModel
>>> from diffusers.hooks import apply_group_offloading

>>> transformer = CogVideoXTransformer3DModel.from_pretrained(
...     "THUDM/CogVideoX-5b", subfolder="transformer", torch_dtype=torch.bfloat16
... )

>>> apply_group_offloading(
...     transformer,
...     onload_device=torch.device("cuda"),
...     offload_device=torch.device("cpu"),
...     offload_type="block_level",
...     num_blocks_per_group=2,
...     use_stream=True,
... )
```

