План внедрения: 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 conditioningcomfy_extras.nodes_custom_sampler.SamplerCustom— samplingcomfy_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)
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
Референсы для изучения
/home/ubuntu/ComfyUI/custom_nodes/scail-auto-extend/__init__.py— как делать прямой вызов нод/home/ubuntu/ComfyUI/comfy_extras/nodes_scail.py— сигнатура WanSCAILToVideo/home/ubuntu/ComfyUI/comfy_extras/nodes_custom_sampler.py— сигнатура SamplerCustom- https://github.com/wuwukaka/ComfyUI-WanAnimatePlus — целевой пайплайн (для v2)
Открытые вопросы
Загрузка SCAIL-2 модели:
CheckpointLoaderSimpleожидает чекпоинт вmodels/checkpoints/, а SCAIL-2 лежит вmodels/diffusion_models/. Нужно выяснить, какой loader использовать.Текстовый энкодер: SCAIL-2 использует umt5. Нужно выяснить, как
WanSCAILToVideoполучает текстовые эмбеддинги — через стандартныйCLIPTextEncodeили иначе.CLIP Vision: как именно
clip_vision_outputподаётся вWanSCAILToVideo— нужно посмотреть на example workflow (SCAIL Auto Extend V2/V3.json).LoRA: как применять LoRA к SCAIL-2 модели. Есть ли встроенный механизм или нужно использовать отдельную ноду.
Memory: SCAIL-2 14B в fp8 ≈ 22 GB VRAM. С 97 GB на GPU 0 проблем быть не должно, но нужно проверить, что torch не аллоцирует лишнего.