| # План внедрения: Python-скрипт для генерации SCAIL-2 видео |
|
|
| ## Цель |
|
|
| Написать Python-скрипт, который генерирует видео через SCAIL-2 пайплайн, |
| используя прямое обращение к нодам ComfyUI (без API, без сервера, без GUI). |
|
|
| ## Исходные данные |
|
|
| ### Железо |
| - 7× NVIDIA RTX PRO 6000 Blackwell (97 GB VRAM каждая) |
| - CUDA 0 свободна (~97 GB) |
|
|
| ### Софт (уже установлено) |
| - ComfyUI: `/home/ubuntu/ComfyUI` |
| - Python 3.12.3, torch 2.12.1+cu130 |
|
|
| ### Модели (уже скачаны) |
| | Файл | Путь | |
| |------|------| |
| | SCAIL-2 diffusion model | `models/diffusion_models/wan2.1_14B_SCAIL_2_fp8_scaled.safetensors` | |
| | VAE | `models/vae/wan_2.1_vae.safetensors` | |
| | Text encoder (umt5) | `models/text_encoders/umt5_xxl_fp8_e4m3fn_scaled.safetensors` | |
| | CLIP vision | `models/clip_vision/clip_vision_h_fp16.safetensors` | |
| | LoRA (lightx2v) | `models/loras/lightx2v_I2V_14B_480p_cfg_step_distill_rank64_bf16.safetensors` | |
|
|
| ### Custom nodes (уже установлены) |
| - `scail-auto-extend` — референсная реализация, делает то же самое (прямой вызов нод) |
| - `comfyui-videohelpersuite` — VHS для загрузки/сохранения видео |
| - `comfyui-kjnodes` — утилиты (ресайз и т.д.) |
|
|
| ### Встроенные ноды ComfyUI (уже есть) |
| - `comfy_extras.nodes_scail.WanSCAILToVideo` — SCAIL-2 conditioning |
| - `comfy_extras.nodes_custom_sampler.SamplerCustom` — sampling |
| - `comfy_extras.nodes_post_processing.ColorTransfer` — color matching |
| - Базовые: `CheckpointLoaderSimple`, `VAELoader`, `CLIPLoader`, `CLIPVisionLoader` и т.д. |
|
|
| ## Архитектура скрипта (v1 — базовый SCAIL-2) |
|
|
| ### Этап 1: загрузка моделей |
|
|
| ``` |
| 1. LoadDiffusionModel (SCAIL-2) → MODEL |
| 2. LoadVAE (wan_2.1) → VAE |
| 3. LoadCLIP (umt5) → CLIP |
| 4. LoadCLIPVision (clip_h) → CLIP_VISION |
| ``` |
|
|
| Используем существующие ноды ComfyUI: `CheckpointLoaderSimple`, `VAELoader`, `CLIPLoader`, `CLIPVisionLoader`. |
|
|
| ### Этап 2: подготовка conditioning |
|
|
| ``` |
| 5. CLIPTextEncode(positive_prompt) → CONDITIONING (+) |
| 6. CLIPTextEncode(negative_prompt) → CONDITIONING (−) |
| 7. CLIPVisionEncode(ref_image) → CLIP_VISION_OUTPUT |
| 8. LoadVideo(pose_video) → IMAGE (pose frames) |
| 9. WanSCAILToVideo( → SCAIL conditioning |
| positive, negative, vae, |
| width, height, length, |
| pose_video, reference_image, |
| clip_vision_output, ... |
| ) |
| ``` |
|
|
| ### Этап 3: sampling |
|
|
| ``` |
| 10. KSamplerSelect(sampler_name) → SAMPLER |
| 11. BasicScheduler(sigmas) → SIGMAS |
| 12. SamplerCustom( → denoised latents |
| model, positive, negative, |
| sampler, sigmas, latent |
| ) |
| ``` |
|
|
| ### Этап 4: декодирование и сохранение |
|
|
| ``` |
| 13. VAEDecode(samples) → IMAGE |
| 14. SaveVideo / VHS_VideoCombine → video.mp4 |
| ``` |
|
|
| ## Входные параметры скрипта (v1) |
|
|
| ```python |
| CONFIG = { |
| # Модели |
| "diffusion_model": "wan2.1_14B_SCAIL_2_fp8_scaled.safetensors", |
| "vae": "wan_2.1_vae.safetensors", |
| "text_encoder": "umt5_xxl_fp8_e4m3fn_scaled.safetensors", |
| "clip_vision": "clip_vision_h_fp16.safetensors", |
| |
| # Входные данные |
| "pose_video": "pose.mp4", # драйвер-видео с позами |
| "reference_image": "ref.png", # референсное изображение |
| "reference_mask": None, # маска референса (опционально) |
| "pose_mask": None, # маска поз (опционально) |
| |
| # Параметры генерации |
| "width": 832, |
| "height": 480, |
| "num_frames": 81, # длина одного чанка |
| "overlap": 5, # перекрытие между чанками |
| "total_frames": None, # если None = длина pose_video |
| "seed": 42, |
| "cfg": 1.0, |
| "steps": 20, |
| "sampler": "dpmpp_2m_sde", |
| "scheduler": "karras", |
| |
| # SCAIL-2 специфичные |
| "replacement_mode": False, # False = animation, True = replacement |
| "pose_strength": 1.0, |
| "pose_start": 0.0, |
| "pose_end": 1.0, |
| |
| # Промпты |
| "positive_prompt": "...", |
| "negative_prompt": "...", |
| |
| # LoRA (опционально) |
| "lora": "lightx2v_I2V_14B_480p_cfg_step_distill_rank64_bf16.safetensors", |
| "lora_strength": 1.0, |
| |
| # Вывод |
| "output": "output.mp4", |
| "fps": 24, |
| } |
| ``` |
|
|
| ## План разработки (по шагам) |
|
|
| ### Шаг 1: разведать API загрузки моделей |
| - Посмотреть, как `CheckpointLoaderSimple` загружает diffusion model |
| - Посмотреть, как `VAELoader` загружает VAE |
| - Посмотреть, как `CLIPLoader` / `CLIPVisionLoader` работают |
| - Понять сигнатуры `.execute()` или прямого вызова |
|
|
| ### Шаг 2: написать загрузку моделей |
| - Функции `load_model()`, `load_vae()`, `load_clip()`, `load_clip_vision()` |
| - Проверить, что всё загружается без ошибок |
|
|
| ### Шаг 3: написать conditioning |
| - Разобрать сигнатуру `WanSCAILToVideo.execute()` |
| - Подготовить все входы (pose video, reference image, masks, clip vision) |
| - Вызвать и получить conditioning |
|
|
| ### Шаг 4: написать sampling |
| - Разобрать `SamplerCustom.execute()` |
| - Подготовить sampler, sigmas, noise |
| - Запустить sampling на одном чанке |
|
|
| ### Шаг 5: цикл по чанкам (auto-extend) |
| - Реализовать логику как в `scail-auto-extend`: |
| - Первый чанк: полная генерация |
| - Последующие чанки: overlap с предыдущим, продление |
| - Color transfer между чанками для борьбы с дрифтом |
| - Склейка результата |
|
|
| ### Шаг 6: декодирование и сохранение |
| - VAE decode |
| - Сохранение в mp4 (через torchvision или imageio) |
|
|
| ### Шаг 7: обвязка — CLI и конфиг |
| - Чтение параметров из JSON/YAML конфига |
| - Прогресс-бар |
| - Обработка ошибок |
|
|
| ## Что НЕ делаем в v1 |
|
|
| - ❌ prefix_frames / transition_video (требует установки WanAnimatePlus + WanVideoWrapper) |
| - ❌ Bernini |
| - ❌ Uni3C ControlNet |
| - ❌ Face detection / pose detection (видео подаётся уже готовое) |
| - ❌ Real-time preview |
|
|
| ## Что можно добавить в v2 |
|
|
| - Установить `ComfyUI-WanVideoWrapper` + `ComfyUI-WanAnimatePlus` |
| - prefix_frames (1–5 reference-изображений) |
| - transition_video (бесшовная склейка сегментов) |
| - Bernini (v2v, rv2v, r2v) |
| - Автоматическая детекция поз/лиц через SDPoseOOD + YOLO |
|
|
| ## Референсы для изучения |
|
|
| 1. `/home/ubuntu/ComfyUI/custom_nodes/scail-auto-extend/__init__.py` — как делать прямой вызов нод |
| 2. `/home/ubuntu/ComfyUI/comfy_extras/nodes_scail.py` — сигнатура WanSCAILToVideo |
| 3. `/home/ubuntu/ComfyUI/comfy_extras/nodes_custom_sampler.py` — сигнатура SamplerCustom |
| 4. https://github.com/wuwukaka/ComfyUI-WanAnimatePlus — целевой пайплайн (для v2) |
|
|
| ## Открытые вопросы |
|
|
| 1. **Загрузка SCAIL-2 модели**: `CheckpointLoaderSimple` ожидает чекпоинт в `models/checkpoints/`, |
| а SCAIL-2 лежит в `models/diffusion_models/`. Нужно выяснить, какой loader использовать. |
|
|
| 2. **Текстовый энкодер**: SCAIL-2 использует umt5. Нужно выяснить, как `WanSCAILToVideo` |
| получает текстовые эмбеддинги — через стандартный `CLIPTextEncode` или иначе. |
|
|
| 3. **CLIP Vision**: как именно `clip_vision_output` подаётся в `WanSCAILToVideo` — |
| нужно посмотреть на example workflow (SCAIL Auto Extend V2/V3.json). |
|
|
| 4. **LoRA**: как применять LoRA к SCAIL-2 модели. Есть ли встроенный механизм или нужно |
| использовать отдельную ноду. |
|
|
| 5. **Memory**: SCAIL-2 14B в fp8 ≈ 22 GB VRAM. С 97 GB на GPU 0 проблем быть не должно, |
| но нужно проверить, что torch не аллоцирует лишнего. |
|
|