mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
5814d5c4b3
2.5 reuses the LTX-2 pipeline classes, so it is described through the capability table: Gemma 4 text encoder, cross-timestep conditioning, and the upsampler and stage 2 LoRA that now ship inside the model repo. The repo carries the distilled scheduler config, so Dev rows restore the terminal shift, and the Dev transformer sits in transformer_full. Distilled rows stop forcing dynamic shifting on, which remapped their sigma schedule. Auto duration hands the clip length to the duration head.
117 lines
5.8 KiB
Python
117 lines
5.8 KiB
Python
import os
|
|
import torch
|
|
import diffusers
|
|
from modules import shared, processing, devices
|
|
from modules.logger import log
|
|
from modules.video_models.models_def import Model
|
|
|
|
|
|
debug = log.trace if os.environ.get('SD_VIDEO_DEBUG', None) is not None else lambda *args, **kwargs: None
|
|
|
|
|
|
def load_override(selected: Model, **load_args):
|
|
kwargs = {}
|
|
# Allegro
|
|
if 'Allegro T2V' in selected.name:
|
|
kwargs['vae'] = diffusers.AutoencoderKLAllegro.from_pretrained(selected.repo, subfolder="vae", torch_dtype=torch.float32, cache_dir=shared.opts.hfcache_dir, **load_args)
|
|
# LTX
|
|
if 'LTXVideo 0.9.5 I2V' in selected.name:
|
|
kwargs['vae'] = diffusers.AutoencoderKLLTXVideo.from_pretrained(selected.repo, subfolder="vae", torch_dtype=torch.float32, cache_dir=shared.opts.hfcache_dir, **load_args)
|
|
# OzzyGT LTX-2.3 mirrors and the LTX-2.5 repo pack connectors/ twice by design: sharded
|
|
# (*-00001-of-0000N + .index.json) and unsharded diffusion_pytorch_model.safetensors of the
|
|
# byte-identical weights. snapshot_download faithfully fetches both; diffusers' component
|
|
# loader picks sharded when the index is present. ignore_patterns skips the ~6.3 GB unsharded
|
|
# copy without reaching for a cleaner upstream mirror.
|
|
ltx2_redundant_connector_repos = {
|
|
'OzzyGT/LTX-2.3',
|
|
'OzzyGT/LTX-2.3-sdnq-dynamic-int4',
|
|
}
|
|
ltx2_ignore = []
|
|
if selected.repo in ltx2_redundant_connector_repos or 'LTXVideo 2.5' in selected.name:
|
|
ltx2_ignore.append('connectors/diffusion_pytorch_model.safetensors')
|
|
if 'LTXVideo 2.5' in selected.name:
|
|
# the pipeline fetch pulls every model-index folder except passed components: transformer_full
|
|
# is not one, the diffusion decoder is a separate pipeline, the LoRA is fetched on demand
|
|
ltx2_ignore += ['transformer_full/*', 'diffusion_decoder/*', 'ltx-2.5-22b-distilled-lora-450-bf16.safetensors']
|
|
if ltx2_ignore:
|
|
kwargs['ignore_patterns'] = ltx2_ignore
|
|
# LTX2TextConnectors weights are byte-identical across all 2.3 variants (verified by blob
|
|
# hash). Pre-load from a canonical repo so per-variant fetches skip connectors/ entirely.
|
|
# FP16 variants share OzzyGT/LTX-2.3; SDNQ variants share the pre-quantized mirror.
|
|
ltx2_connectors_cls = None
|
|
try:
|
|
from diffusers.pipelines.ltx2 import LTX2TextConnectors
|
|
ltx2_connectors_cls = LTX2TextConnectors
|
|
except ImportError as e:
|
|
log.warning(f'Load video: LTX2TextConnectors unavailable ({e}); dedup of LTX-2.3 connectors disabled')
|
|
if ('LTXVideo 2.3' in selected.name and shared.opts.te_shared_te and ltx2_connectors_cls is not None):
|
|
conn_repo = 'OzzyGT/LTX-2.3-sdnq-dynamic-int4' if 'SDNQ' in selected.name else 'OzzyGT/LTX-2.3'
|
|
log.debug(f'Load video: module=connectors repo="{conn_repo}" cls={ltx2_connectors_cls.__name__} shared={shared.opts.te_shared_te}')
|
|
kwargs['connectors'] = ltx2_connectors_cls.from_pretrained(
|
|
conn_repo,
|
|
subfolder='connectors',
|
|
torch_dtype=devices.dtype,
|
|
cache_dir=shared.opts.hfcache_dir,
|
|
**load_args,
|
|
)
|
|
# WAN
|
|
if 'WAN 2.1 14B' in selected.name:
|
|
kwargs['vae'] = diffusers.AutoencoderKLWan.from_pretrained(selected.repo, subfolder="vae", torch_dtype=torch.float32, cache_dir=shared.opts.hfcache_dir, **load_args)
|
|
if ('A14B' in selected.name) or ('14B VACE' in selected.name):
|
|
# combined keeps both experts loaded and tunes boundary_ratio at runtime (set_pipeline_args), so
|
|
# it is not set here; only the single-expert stages need load time because they drop a transformer.
|
|
if shared.opts.model_wan_stage == 'high noise':
|
|
kwargs['transformer_2'] = None
|
|
kwargs['boundary_ratio'] = 0.0
|
|
elif shared.opts.model_wan_stage == 'low noise':
|
|
kwargs['boundary_ratio'] = 1000.0
|
|
kwargs['transformer'] = None
|
|
debug(f'Video overrides: model="{selected.name}" kwargs={list(kwargs)}')
|
|
return kwargs
|
|
|
|
|
|
def set_overrides(p: processing.StableDiffusionProcessingVideo, selected: Model):
|
|
cls = shared.sd_model.__class__.__name__
|
|
# Allegro
|
|
if selected.name == 'Allegro T2V':
|
|
shared.sd_model.vae.enable_tiling()
|
|
# Latte
|
|
if selected.name == 'Latte 1 T2V':
|
|
p.task_args['enable_temporal_attentions'] = True
|
|
p.task_args['video_length'] = 16 * (max(p.frames // 16, 1))
|
|
# SkyReels
|
|
if 'SkyReelsV2DiffusionForcing' in cls:
|
|
p.task_args['overlap_history'] = 17
|
|
# LTX
|
|
ltx_i2v_classes = ('LTXImageToVideoPipeline', 'LTXConditionPipeline', 'LTX2ImageToVideoPipeline', 'LTX2ConditionPipeline')
|
|
if cls in ltx_i2v_classes:
|
|
p.task_args['generator'] = None
|
|
if cls == 'LTXConditionPipeline':
|
|
p.task_args['strength'] = p.denoising_strength
|
|
if 'LTX' in cls:
|
|
p.task_args['width'] = 32 * (p.width // 32)
|
|
p.task_args['height'] = 32 * (p.height // 32)
|
|
# WAN
|
|
if 'Wan' in cls:
|
|
p.task_args['width'] = 16 * (p.width // 16)
|
|
p.task_args['height'] = 16 * (p.height // 16)
|
|
p.frames = 4 * (max(p.frames // 4, 1)) + 1
|
|
# WAN VACE
|
|
if 'WanVACEPipeline' in cls:
|
|
if (getattr(p, 'init_images', None) is not None) and (len(p.init_images) > 0):
|
|
p.task_args['reference_images'] = p.init_images
|
|
# WAN 2.2-5B
|
|
if 'WAN 2.2 5B' in selected.name:
|
|
shared.sd_model.vae.disable_tiling()
|
|
# Kandinsky 5
|
|
if 'Kandinsky 5.0 Lite 5s' in selected.name:
|
|
# p.task_args['time_length'] = 5
|
|
pass
|
|
if 'Kandinsky 5.0 Lite 10s' in selected.name:
|
|
# p.task_args['time_length'] = 10
|
|
shared.sd_model.transformer.set_attention_backend("flex")
|
|
# MiniMax H3
|
|
if 'MiniMaxH3' in cls:
|
|
from modules.video_models import video_minimax
|
|
video_minimax.apply_overrides(p, shared.sd_model, still=getattr(p, 'video_still', False), audio=getattr(p, 'video_audio', True))
|