# CogVideoX

CogVideoX — это модель генерации видео по тексту, ориентированная на создание более связных видео, соответствующих промпту. Она достигает этого с помощью нескольких методов.

- 3D вариационный автоэнкодер, сжимающий видео по пространственному и временному измерениям, что повышает коэффициент сжатия и точность видео.

- экспертный трансформерный блок для выравнивания текста и видео, а также модуль полного 3D-внимания для захвата и создания пространственно и временно точных видео.

Фактическое тестирование по измерению видеонаправлений показало, что CogVideoX демонстрирует хорошие результаты в отношении согласованности темы, динамической информации, согласованности фона, информации об объектах, плавности движения, цвета, сцены, стиля внешнего вида и временного стиля, однако не позволяет достичь хороших результатов в задачах, связанных с действиями человека, пространственными отношениями и несколькими объектами.

Дополнительная настройка с помощью Diffusers может помочь компенсировать эти неудовлетворительные результаты.

## Подготовка данных

Скрипты обучения принимают данные в двух форматах.

Первый формат подходит для обучения в небольших масштабах, а второй использует формат CSV, который лучше подходит для потоковой передачи данных при обучении в больших масштабах. В будущем Diffusers будет поддерживать тег `<Video>`.

### Малый формат

Два файла: один содержит промпты, разделённые по строкам, а другой — пути к видеоданным, также разделённые по строкам (пути к файлам видео должны быть относительными по отношению к пути, который вы указываете при задании `--instance_data_root`). Давайте рассмотрим пример, чтобы лучше это понять!

Допустим, вы указали `--instance_data_root` как `/dataset`, и в этом каталоге находятся файлы: `prompts.txt` и `videos.txt`.

Файл `prompts.txt` должен содержать промпты, разделённые по строкам:

```
A black and white animated sequence featuring a rabbit, named Rabbity Ribfried, and an anthropomorphic goat in a musical, playful environment, showcasing their evolving interaction.
A black and white animated sequence on a ship's deck features a bulldog character, named Bully Bulldoger, showcasing exaggerated facial expressions and body language. The character progresses from confident to focused, then to strained and distressed, displaying a range of emotions as it navigates challenges. The ship's interior remains static in the background, with minimalistic details such as a bell and open door. The character's dynamic movements and changing expressions drive the narrative, with no camera movement to distract from its evolving reactions and physical gestures.
...
```

Файл `videos.txt` должен содержать пути к файлам видео, разделённые по строкам. Обратите внимание, что путь должен быть _относительным_ к каталогу `--instance_data_root`.

```
videos/00000.mp4
videos/00001.mp4
...
```

В целом, если бы вы выполнили команду `tree` в корневой директории набора данных, он выглядел бы так:

```
/dataset
├── prompts.txt
├── videos.txt
├── videos
    ├── videos/00000.mp4
    ├── videos/00001.mp4
    ├── ...
```

При использовании этого формата `--caption_column` должен быть `prompts.txt`, а `--video_column` — `videos.txt`.

### Формат потока

Можно использовать один файл CSV. Для целей этого примера допустим, что у вас есть файл `metadata.csv`. Ожидаемый формат:

```
<CAPTION_COLUMN>,<PATH_TO_VIDEO_COLUMN>
"""A black and white animated sequence featuring a rabbit, named Rabbity Ribfried, and an anthropomorphic goat in a musical, playful environment, showcasing their evolving interaction.""","""00000.mp4"""
"""A black and white animated sequence on a ship's deck features a bulldog character, named Bully Bulldoger, showcasing exaggerated facial expressions and body language. The character progresses from confident to focused, then to strained and distressed, displaying a range of emotions as it navigates challenges. The ship's interior remains static in the background, with minimalistic details such as a bell and open door. The character's dynamic movements and changing expressions drive the narrative, with no camera movement to distract from its evolving reactions and physical gestures.""","""00001.mp4"""
...
```

В этом случае `--instance_data_root` должен указывать на место, где хранятся видео, а `--dataset_name` — на путь к локальной папке или на совместимый с [load_dataset](https://huggingface.co/docs/datasets/main/en/package_reference/loading_methods#datasets.load_dataset) датасет, размещённый на Hub. Если у вас есть видео с геймплеем Minecraft по адресу `https://huggingface.co/datasets/my-awesome-username/minecraft-videos`, вам нужно будет указать `my-awesome-username/minecraft-videos`.

При использовании этого формата `--caption_column` должен быть `<CAPTION_COLUMN>`, а `--video_column` — `<PATH_TO_VIDEO_COLUMN>`.

Вы не ограничены исключительно форматом CSV. Подойдёт любой формат, который поддерживает метод `load_dataset` для загрузки базовых `<PATH_TO_VIDEO_COLUMN>` и `<CAPTION_COLUMN>`. Причина, по которой приходится прибегать к таким ухищрениям при организации датасета для загрузки видеоданных, заключается в том, что `load_dataset` не поддерживает все виды форматов видео.

> [!NOTE]
> CogVideoX лучше всего работает с длинными и описательными промптами, дополненными LLM, для генерации видео. Мы рекомендуем предварительно обрабатывать видео: сначала сгенерировать краткое описание с помощью VLM, а затем дополнить промпты с помощью LLM. Для генерации приведённых выше подписей мы используем [MiniCPM-V-26](https://huggingface.co/openbmb/MiniCPM-V-2_6) и [Llama-3.1-8B-Instruct](https://huggingface.co/meta-llama/Meta-Llama-3.1-8B-Instruct). Очень простой и минималистичный пример этого процесса доступен [здесь](https://gist.github.com/a-r-r-o-w/4dee20250e82f4e44690a02351324a4a). Официальная рекомендация по дополнению промптов — использовать [ChatGLM](https://huggingface.co/THUDM?search_models=chatglm), при этом оптимальной считается длина в 50–100 слов.

>![NOTE] Ожидается, что ваш набор данных уже предварительно обработан. Если это не так, базовая предварительная обработка может быть выполнена путём настройки следующих параметров: `--height`, `--width`, `--fps`, `--max_num_frames`, `--skip_frames_start` и `--skip_frames_end`. В настоящее время, при использовании размера обучающей выборки > 1, все видео в вашем наборе данных должны содержать одинаковое количество кадров.

## Обучение

Необходимо настроить среду разработки, установив необходимые зависимости. Требуется установить следующие пакеты:
- Torch 2.0 или выше в зависимости от используемых вами функций обучения (для обучения с квантованием/deepspeed могут потребоваться последние или nightly-версии)
- `pip install diffusers transformers accelerate peft huggingface_hub` для всех задач, связанных с моделированием и обучением
- `pip install datasets decord` для загрузки данных для обучения на видео
- `pip install bitsandbytes` для использования оптимизаторов 8-bit Adam или AdamW для обучения с оптимизацией памяти
- `pip install wandb` — по желанию, для мониторинга журналов обучения
- `pip install deepspeed` при необходимости для обучения с [DeepSpeed](https://github.com/microsoft/DeepSpeed)
- `pip install prodigyopt` при необходимости, если вы хотите использовать оптимизатор Prodigy для обучения

Чтобы убедиться, что вы можете успешно запускать последние версии примеров скриптов, мы настоятельно рекомендуем **установить из исходного кода** и поддерживать установку в актуальном состоянии, так как мы часто обновляем примеры скриптов и устанавливаем некоторые специфичные для примеров зависимости. Для этого выполните следующие шаги в новом виртуальном окружении:

Перед запуском скрипта убедитесь, что вы установили библиотеку из исходного кода:
```bash
git clone https://github.com/huggingface/diffusers
cd diffusers
pip install -e .
```

 

Затем перейдите в папку с примером, содержащую скрипт обучения, и установите необходимые зависимости для используемого вами скрипта:

- PyTorch

```bash
cd examples/cogvideo
pip install -r requirements.txt
```

И инициализируйте среду [🤗 Accelerate](https://github.com/huggingface/accelerate/) с помощью:

```bash
accelerate config
```

Или для конфигурации accelerate по умолчанию без ответов на вопросы о вашем окружении

```bash
accelerate config default
```

Или если ваша среда не поддерживает интерактивную оболочку (например, ноутбук)

```python
from accelerate.utils import write_basic_config
write_basic_config()
```

При запуске `accelerate config` использование torch.compile может привести к значительному ускорению. Библиотека PEFT используется в качестве backend для обучения LoRA, поэтому убедитесь, что в вашем окружении установлена версия `peft>=0.6.0`.

Если вы хотите загрузить модель на Hub после завершения обучения с аккуратной карточкой модели, убедитесь, что вы вошли в систему:

```bash
hf auth login

# Alternatively, you could upload your model manually using:
# hf upload my-cool-account-name/my-cool-lora-name /path/to/awesome/lora
```

Убедитесь, что данные подготовлены, как описано в разделе [Подготовка данных](#data-preparation). Когда всё готово, можно приступать к обучению!

При обучении на 50 видео с похожим концептом мы обнаружили, что 1500–2000 шагов работают хорошо. Однако официальная рекомендация — это 100 видео с общим количеством шагов 4000. При обучении на одном GPU с `--train_batch_size`, равным `1`:
- 1500 шагов на 50 видео соответствует `30` эпохам обучения
- 4000 шагов на 100 видео соответствует `40` эпохам обучения

```bash
#!/bin/bash

GPU_IDS="0"

accelerate launch --gpu_ids $GPU_IDS examples/cogvideo/train_cogvideox_lora.py \
  --pretrained_model_name_or_path THUDM/CogVideoX-2b \
  --cache_dir <CACHE_DIR> \
  --instance_data_root <PATH_TO_WHERE_VIDEO_FILES_ARE_STORED> \
  --dataset_name my-awesome-name/my-awesome-dataset \
  --caption_column <CAPTION_COLUMN> \
  --video_column <PATH_TO_VIDEO_COLUMN> \
  --id_token <ID_TOKEN> \
  --validation_prompt "<ID_TOKEN> Spiderman swinging over buildings:::A panda, dressed in a small, red jacket and a tiny hat, sits on a wooden stool in a serene bamboo forest. The panda's fluffy paws strum a miniature acoustic guitar, producing soft, melodic tunes. Nearby, a few other pandas gather, watching curiously and some clapping in rhythm. Sunlight filters through the tall bamboo, casting a gentle glow on the scene. The panda's face is expressive, showing concentration and joy as it plays. The background includes a small, flowing stream and vibrant green foliage, enhancing the peaceful and magical atmosphere of this unique musical performance" \
  --validation_prompt_separator ::: \
  --num_validation_videos 1 \
  --validation_epochs 10 \
  --seed 42 \
  --rank 64 \
  --lora_alpha 64 \
  --mixed_precision fp16 \
  --output_dir /raid/aryan/cogvideox-lora \
  --height 480 --width 720 --fps 8 --max_num_frames 49 --skip_frames_start 0 --skip_frames_end 0 \
  --train_batch_size 1 \
  --num_train_epochs 30 \
  --checkpointing_steps 1000 \
  --gradient_accumulation_steps 1 \
  --learning_rate 1e-3 \
  --lr_scheduler cosine_with_restarts \
  --lr_warmup_steps 200 \
  --lr_num_cycles 1 \
  --enable_slicing \
  --enable_tiling \
  --optimizer Adam \
  --adam_beta1 0.9 \
  --adam_beta2 0.95 \
  --max_grad_norm 1.0 \
  --report_to wandb
```

Чтобы лучше отслеживать эксперименты по обучению, в команде выше используются следующие флаги:
* `--report_to wandb` гарантирует, что запуски обучения будут отслеживаться в Weights and Biases. Для этого убедитесь, что `wandb` установлен с помощью `pip install wandb`.
* `validation_prompt` и `validation_epochs`, чтобы скрипт выполнял несколько проходов валидации. Это позволяет качественно оценить, идёт ли обучение в ожидаемом направлении.

Установка `<ID_TOKEN>` не является обязательной. В ходе ограниченных экспериментов мы обнаружили, что результат лучше (поскольку это напоминает обучение [Dreambooth](https://huggingface.co/docs/diffusers/en/training/dreambooth)), чем без него. Если `<ID_TOKEN>` указан, он добавляется в начало каждого промпта. Таким образом, если ваш `<ID_TOKEN>` был `"DISNEY"`, а ваш промпт — `"Spiderman swinging over buildings"`, то эффективный промпт, используемый при обучении, будет `"DISNEY Spiderman swinging over buildings"`. Если токен не указан, вы можете обучать модель без дополнительных токенов или дополнить набор данных, добавив токен в нужное место перед началом обучения.

> [!NOTE]
> Вы можете передать `--use_8bit_adam`, чтобы снизить требования к памяти при обучении.

> [!IMPORTANT]
> Следующие настройки были протестированы на момент добавления поддержки обучения LoRA для CogVideoX: - Наши тесты проводились преимущественно на CogVideoX-2b. Мы скоро займёмся CogVideoX-5b и CogVideoX-5b-I2V - Один набор данных состоял из 70 обучающих видео с разрешением `200 x 480 x 720` (F x H x W). Из них, используя пропуск кадров на этапе предобработки данных, мы создали два меньших набора данных на 49 и 16 кадров для более быстрого экспериментирования, а также потому, что максимальное значение, рекомендуемое командой CogVideoX, составляет 49 кадров. Из 70 видео мы создали три группы по 10, 25 и 50 видео. Все видео были схожи по характеру концепции, которой обучалась модель. - Для обучения новым концепциям и стилям лучше всего работали наборы из 25 и более видео. - Мы обнаружили, что лучше обучать модель с использованием идентификаторного токена, который можно указать с помощью `--id_token`. Это похоже на обучение в стиле Dreambooth, но обычная дообучение без такого токена тоже работает. - Обученная концепция работала достаточно хорошо в сочетании с полностью нерелевантными промптами. Мы ожидаем ещё лучших результатов при дообучении CogVideoX-5B. - В исходном репозитории используется `lora_alpha` со значением `1`. Мы обнаружили, что это значение не подходит во многих случаях, возможно, из-за различий в бэкендах моделирования и настройках обучения. Наша рекомендация — установить `lora_alpha` в значение `rank` или `rank // 2`. - Если вы обучаете модель на данных, описания которых дают плохие результаты с исходной моделью, `rank` 64 и выше является хорошим выбором и также рекомендуется командой, стоящей за CogVideoX. Если генерации уже достаточно хороши на ваших обучающих описаниях, `rank` 16/32 должен подойти. Мы обнаружили, что установка слишком низкого ранга, например `4`, не является оптимальной и не даёт перспективных результатов. - Авторы CogVideoX рекомендуют 4000 шагов обучения и 100 обучающих видео в целом для достижения наилучшего результата. Хотя это может дать лучшие результаты, из наших ограниченных экспериментов мы выяснили, что 2000 шагов и 25 видео также могут быть достаточны. - При использовании оптимизатора Prodigy для обучения можно следовать рекомендациям из [этого](https://huggingface.co/blog/sdxl_lora_advanced_script) блога. Prodigy склонен к быстрой переобученности. Из моих очень ограниченных тестов я обнаружил, что скорость обучения `0.5` является подходящей в дополнение к `--prodigy_use_bias_correction`, `prodigy_safeguard_warmup` и `--prodigy_decouple`. - Рекомендуемая авторами CogVideoX и подтверждённая нашими экспериментами с Adam/AdamW скорость обучения составляет от `1e-3` до `1e-4` для набора данных из 25 и более видео.
>
> Обратите внимание, что наши тесты не являются исчерпывающими из-за ограниченного времени на исследование. Мы рекомендуем поэкспериментировать с различными параметрами, чтобы найти оптимальные настройки для ваших данных.

## Вывод

После обучения модели lora для вывода достаточно просто загрузить веса lora в `CogVideoXPipeline`.

```python
import torch
from diffusers import CogVideoXPipeline
from diffusers.utils import export_to_video

pipe = CogVideoXPipeline.from_pretrained("THUDM/CogVideoX-2b", dtype=torch.float16)
# pipe.load_lora_weights("/path/to/lora/weights", adapter_name="cogvideox-lora") # Or,
pipe.load_lora_weights("my-awesome-hf-username/my-awesome-lora-name", adapter_name="cogvideox-lora") # If loading from the HF Hub
pipe.to("cuda")  # or "mps", "xpu", "cpu"

# Assuming lora_alpha=32 and rank=64 for training. If different, set accordingly
pipe.set_adapters(["cogvideox-lora"], [32 / 64])

prompt = "A vast, shimmering ocean flows gracefully under a twilight sky, its waves undulating in a mesmerizing dance of blues and greens. The surface glints with the last rays of the setting sun, casting golden highlights that ripple across the water. Seagulls soar above, their cries blending with the gentle roar of the waves. The horizon stretches infinitely, where the ocean meets the sky in a seamless blend of hues. Close-ups reveal the intricate patterns of the waves, capturing the fluidity and dynamic beauty of the sea in motion."
frames = pipe(prompt, guidance_scale=6, use_dynamic_cfg=True).frames[0]
export_to_video(frames, "output.mp4", fps=8)
```

## Сокращение использования памяти

Во время тестирования с использованием библиотеки diffusers были включены все оптимизации, входящие в состав библиотеки diffusers. Данный сценарий не был протестирован на фактическое потребление памяти на устройствах, отличных от архитектур **NVIDIA A100 / H100**. Как правило, этот сценарий можно адаптировать для всех устройств на архитектуре **NVIDIA Ampere** и выше. Если оптимизации отключены, потребление памяти возрастает, при этом пиковое использование памяти составляет примерно в 3 раза больше значения, указанного в таблице. Однако скорость возрастает примерно в 3–4 раза. Вы можете выборочно отключить некоторые оптимизации, в том числе:

```
pipe.enable_sequential_cpu_offload()
pipe.vae.enable_slicing()
pipe.vae.enable_tiling()
```

+ Для вывода на нескольких GPU необходимо отключить оптимизацию `enable_sequential_cpu_offload()`.
+ Использование моделей INT8 замедляет инференс. Это сделано для поддержки GPU с меньшим объёмом памяти при минимальной потере качества видео, однако скорость инференса значительно снизится.
+ Модель CogVideoX-2B обучалась в точности `FP16`, а все модели CogVideoX-5B — в точности `BF16`. Для инференса рекомендуется использовать ту же точность, в которой обучалась модель.
+ [PytorchAO](https://github.com/pytorch/ao) и [Optimum-quanto](https://github.com/huggingface/optimum-quanto/) можно использовать для квантования модулей текстового энкодера, трансформера и VAE, чтобы снизить требования к памяти для CogVideoX. Это позволяет запускать модель на бесплатных T4 Colabs или на GPU с меньшим объёмом памяти! Также обратите внимание, что квантование TorchAO полностью совместимо с `torch.compile`, что может значительно повысить скорость инференса. Точность FP8 необходимо использовать на устройствах NVIDIA H100 и выше, для чего требуется установка из исходников Python-пакетов `torch`, `torchao`, `diffusers` и `accelerate`. Рекомендуется использовать CUDA 12.4.
+ Тесты скорости инференса также использовали описанную выше схему оптимизации памяти. Без оптимизации памяти скорость инференса возрастает примерно на 10%. Квантование поддерживается только версией модели в `diffusers`.
+ Модель поддерживает только входные данные на английском языке; другие языки можно перевести на английский для использования с помощью уточнения с помощью большой модели.
+ Использование памяти при дообучении модели проверяется в среде `8 * H100`, при этом программа автоматически применяет оптимизацию `Zero 2`. Если в таблице указано конкретное количество GPU, для дообучения необходимо использовать это количество или больше.

 | **Атрибут**                        | **CogVideoX-2B**                                                       | **CogVideoX-5B**                                                       |
| ------------------------------------ | ---------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| **Название модели**                       | CogVideoX-2B                                                           | CogVideoX-5B                                                           |
| **Точность вывода**              | FP16* (рекомендуется), BF16, FP32, FP8*, INT8, не поддерживается INT4         | BF16 (рекомендуется), FP16, FP32, FP8*, INT8, INT4 не поддерживается         |
| **VRAM для инференса на одном GPU**        | FP16: Использование diffusers 12,5 ГБ* INT8: Использование diffusers с torchao 7,8 ГБ* | BF16: Использование diffusers 20,7 ГБ* INT8: Использование diffusers с torchao 11,4 ГБ* |
| **VRAM для инференса на нескольких GPU**         | FP16: Использование diffusers 10 ГБ*                                             | BF16: Использование diffusers 15 ГБ*                                             |
| **Скорость инференса**                  | Один A100: ~90 секунд, один H100: ~45 секунд                      | Один A100: ~180 секунд, один H100: ~90 секунд                     |
| **Точность дообучения**            | FP16                                                                   | BF16                                                                   |
| **Потребление VRAM при дообучении**     | 47 ГБ (bs=1, LORA) 61 ГБ (bs=2, LORA) 62 ГБ (bs=1, SFT)                 | 63 ГБ (bs=1, LORA) 80 ГБ (bs=2, LORA) 75 ГБ (bs=1, SFT)                 |

