multimodalart's picture
multimodalart HF Staff
Calibrate duration from three timed runs; set verified 44k token ceiling; document memory findings
0581e9d verified
|
Raw
History Blame Contribute Delete
7.16 kB

A newer version of the Gradio SDK is available: 6.27.0

Upgrade
metadata
title: LTX-2.5 Multiple Subject Reference
emoji: 🎭
colorFrom: indigo
colorTo: red
sdk: gradio
sdk_version: 6.26.0
app_file: app.py
python_version: '3.12'
pinned: false
short_description: Multi-subject reference images to video with LTX-2.5
startup_duration_timeout: 1h
models:
  - LiconStudio/LTX-2.5-Multiple-Subject-Reference
  - Lightricks/LTX-2.5-Diffusers
tags:
  - ltx-2.5
  - ic-lora
  - multi-subject
  - reference-to-video
  - image-to-video

🎭 LTX-2.5 · Licon MSR V1

Up to four subject stills plus one scene still, named in the prompt (Image 1:, Image 2:, Image 3: Scene, …), become a video with native audio that keeps every subject's identity, clothing and the scene's look.

LiconStudio/LTX-2.5-Multiple-Subject-Reference (rank 128, apache-2.0) on Lightricks/LTX-2.5 (22B, distilled), run through upstream diffusers.

How it works

Each reference still is repeated to 33 frames, VAE-encoded, given a learned slot embedding and placed at a negative temporal position — slot i of N sits at pixel-frame -(N - i), i.e. just before frame 0. The video tokens then retrieve subject identity through the transformer's own self-attention. Reference tokens ride along at conditioning_mask = 1 (fully clean) and are cropped off before decoding.

Base Lightricks/LTX-2.5-Diffusers — distilled 22B DiT + Gemma-4 text encoder + video/audio VAEs. transformer_full/, prompt_enhancer/, diffusion_decoder/ and temporal_latent_upsampler/ are excluded from the snapshot
Adapter LTX-2.5-Licon-MSR-V1.safetensors, strength 1.0. The file holds ComfyUI-style LoRA keys (only conversion: diffusion_model.transformer.) and the non-LoRA reference_slot_embedding MLP, which is applied by hand
Code diffusers main @ d57cecdeLTX2InContextPipeline, subclassed in msr.py
Hardware ZeroGPU xlarge (96 GB). The 22B DiT plus the Gemma-4 encoder packs to ~71 GB, over the 48 GB slice
Output 1280×704 @ 24 fps by default (1664×960 available), with LTX-2.5's native audio
Memory expandable_segments:True. Stage 2 cycles ~1 GB activation buffers against a nearly full card; the default arena fragments and OOMs at 43k tokens where expandable segments complete in 87 s. Gemma and the connectors are released once each has produced its output

Faithfulness to the reference implementation

The author's reference is a ComfyUI graph: ComfyUI-LTX2.5-MSR plus LTX2.5-MSR-sample-workflow.json. Every node is reproduced:

ComfyUI node Here
ComfyUILTX25MSRICLoRALoader split_slot_state + load_lora_weights. The loader's metadata guards (reference_token_order=prepend, reference_slot_time_offsets=pic1_based_negative_time, reference_downscale_factor=1) hold for this checkpoint
_resize_reference msr.msr_resize — 1:1 port. Subject slots letterbox onto a white canvas unless the source already covers the target in the same aspect family (landscape ≥ 1.25, portrait ≤ 0.8, else square), in which case centre-crop-resize; the background slot always centre-crop-resizes. Bilinear, no antialias, matching comfy.utils.common_upscale
_slot_embedding msr.slot_embeddingslot_id/16[scaled, sin(scaled·f), cos(scaled·f)] → SiLU MLP → 128-dim code, added broadcast over the channel axis of the normalized reference latent. ComfyUI's LTX2 VAE normalizes inside encode (per_channel_statistics.normalize), which is exactly diffusers' _normalize_latents, so the two spaces agree
LTXVAddGuide.append_keyframe(frame_idx=-(N-i)) coords[:, 0] += frame_offset / frame_rate after prepare_video_coords. ComfyUI adds the offset in pixel-frames before the model's × 1/frame_rate; prepare_video_coords applies the same causal shift + clamp(min=0) and has already divided, so the two are algebraically identical
guide strength=1.0, no pixel mask ComfyUI's _build_guide_self_attention_mask returns None in that case, and diffusers builds no mask when conditioning_attention_strength == 1.0 — the stacks agree
LTXVCropGuides output_type="latent" already returns only the base tokens
PromptRelayEncode (one local segment) A single prompt textbox. With one segment the relay's token mask covers everything, so it reduces to encoding global + local concatenated — which is what the UI's prompt box is
two ManualSigmas + two LTXVBaseSampler 8 distilled sigmas at half resolution → ×2 latent upsample → 3 sigmas at full resolution, one torch.Generator threaded through both stages, MSR guide re-attached in stage 2 as in the graph
CFGGuider cfg=1 / LTXVDualCFGGuider [1,1] every guidance knob explicitly zeroed (guidance_scale=1.0, stg_scale=0.0, modality_scale=1.0, guidance_rescale=0.0). The merged pipeline's defaults are SFT values and each adds a blended extra transformer pass that badly degrades distilled output
LTXVAudioVAEDecode audio is decoded and muxed into the mp4

Deviations

  • Resolution. The workflow renders 1664×960 × 361 frames (15 s). The default here is 1280×704 × 97 frames (4 s), which runs in 53 s so it fits comfortably in a visitor's ZeroGPU quota; both the workflow geometry (1664×960 × 97, 87 s) and 8 s at 1280×704 (73 s) are selectable under Advanced.
  • Length ceiling. 76.2 GB stays resident during denoising and stage-2 activations cost ~0.33 MB per token, so the 96 GB slice tops out near 48k tokens. Combinations above 44,000 ((latent_frames + slots × 5) × H/32 × W/32) are refused up front instead of dying in an OOM traceback — 15 s at the workflow resolution is simply out of reach here.
  • Tiled VAE decode. The final decode is tiled (untiled it wants >100 GB). Reference encoding is not tiled, matching the node's use_tiled_encode=False, with a tiled fallback only if it would OOM.
  • use_keyframes_abs_pos_embedding is True in the transformer config, and ComfyUI applies that marker to first-frame tokens. LTX2InContextPipeline never passes video_keyframes_mask, so it is skipped — but the parameter is zero-initialised in the base checkpoint and the LoRA does not train it, so the difference is exactly zero.

Examples

The three examples are the author's own validation references and prompts, taken verbatim from validition_V1/ in the model repo (03, 06, 07 — the three shown on the model card), downscaled to 1280 px and re-encoded as JPEG. The model repo is apache-2.0.

Licenses

Adapter: apache-2.0. Base model: the LTX-2 Community License.