Merge pull request #513 from Lightricks/pr-2026-06-17

Update ComfyUI-LTXVideo - 2026-06-17
This commit is contained in:
Amit Pintz
2026-06-17 17:28:40 +03:00
committed by GitHub
14 changed files with 16882 additions and 1 deletions
+20
View File
@@ -55,6 +55,7 @@ LTX-2.3 Workflows:
* [`IC-LoRA distilled model I2V motion tracking`](./example_workflows/2.3/LTX-2.3_ICLoRA_Motion_Track_Distilled.json)
* [`IC-LoRA distilled model HDR`](./example_workflows/2.3/LTX-2.3_ICLoRA_HDR_Distilled.json)
* [`IC-LoRA distilled model Lipdub; two stages (with upsampling)`](./example_workflows/2.3/LTX-2.3_ICLoRA_Lipdub_Two_Stage_Distilled.json)
* [`Text to audio distilled model; single stage`](./example_workflows/2.3/LTX-2.3_T2A_Single_Stage_Distilled.json)
Older Workflows (LTX-2.0):
@@ -103,6 +104,16 @@ We provide a **Lipdub IC-LoRA** that dubs or rephrases speech in video. Given a
- **Two-stage pipeline**: Stage 1 generates the video and audio at base resolution; Stage 2 upscales while freezing the audio.
- **Speaker identity preservation**: Reference audio tokens provide speaker context so the generated voice stays consistent.
## Text-to-Audio (T2A)
LTX-2 is a single joint audio/video transformer, but it can generate audio on its own. The `LTXVAudioOnlyModel` node puts the model into audio-only mode for text-to-audio, with no video output.
### Key Features
- **Audio-only sampling**: The node sets the model's `run_vx`, `a2v_cross_attn` and `v2a_cross_attn` flags off, so the audio is denoised with no dependence on the video latent and the video stream is skipped. This matches the reference single-stage T2A pipeline's `video=None` behavior.
- **Minimal dummy video latent**: The model splits its input positionally into `[video, audio]`, so the sampler still needs a video latent at index 0. Use the `LTXVAudioOnlyEmptyVideoLatent` node (a fixed 64x64 single-frame placeholder, no params to tweak) joined with the audio latent via `LTXVConcatAVLatent`; with `LTXVAudioOnlyModel` active it is never attended to and adds negligible cost.
- **Audio decode**: `LTXVAudioVAEDecode` extracts the audio directly from the joint latent, then save it with a standard built-in audio node (for example `Save Audio (FLAC)`).
## Required Models
Download the following models:
@@ -138,6 +149,15 @@ Download the following models:
* [`ltx-2-19b-lora-camera-control-jib-down.safetensors`](https://huggingface.co/Lightricks/LTX-2-19b-LoRA-Camera-Control-Jib-Down/blob/main/ltx-2-19b-lora-camera-control-jib-down.safetensors)
* [`ltx-2-19b-lora-camera-control-jib-up.safetensors`](https://huggingface.co/Lightricks/LTX-2-19b-LoRA-Camera-Control-Jib-Up/blob/main/ltx-2-19b-lora-camera-control-jib-up.safetensors)
* [`ltx-2-19b-lora-camera-control-static.safetensors`](https://huggingface.co/Lightricks/LTX-2-19b-LoRA-Camera-Control-Static/blob/main/ltx-2-19b-lora-camera-control-static.safetensors)
* [`ltx-2.3-22b-ic-lora-instant-shave-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Instant-Shave/blob/main/ltx-2.3-22b-ic-lora-instant-shave-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-colorization-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Colorization/blob/main/ltx-2.3-22b-ic-lora-colorization-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-cross-eyed-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Cross-Eyed/blob/main/ltx-2.3-22b-ic-lora-cross-eyed-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-day-to-night-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Day-To-Night/blob/main/ltx-2.3-22b-ic-lora-day-to-night-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-deblur-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Deblur/blob/main/ltx-2.3-22b-ic-lora-deblur-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-decompression-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Decompression/blob/main/ltx-2.3-22b-ic-lora-decompression-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-in-outpainting-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-In-Outpainting/blob/main/ltx-2.3-22b-ic-lora-in-outpainting-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-water-simulation-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Water-Simulation/blob/main/ltx-2.3-22b-ic-lora-water-simulation-0.9.safetensors)
* [`ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors`](https://huggingface.co/Lightricks/LTX-2.3-22b-IC-LoRA-Ingredients/blob/main/ltx-2.3-22b-ic-lora-ingredients-0.9.safetensors)
## Advanced Techniques
+3
View File
@@ -1,3 +1,4 @@
from .audio_only import LTXVAudioOnlyEmptyVideoLatent, LTXVAudioOnlyModel
from .conditioning_loader import LTXVLoadConditioning
from .conditioning_saver import LTXVSaveConditioning
from .decoder_noise import DecoderNoise
@@ -117,6 +118,8 @@ NODE_CLASS_MAPPINGS = {
"LTXVInpaintPreprocess": LTXVInpaintPreprocess,
"LTXVLaplacianPyramidBlend": LTXVLaplacianPyramidBlend,
"LTXVHDRDecodePostprocess": LTXVHDRDecodePostprocess,
"LTXVAudioOnlyModel": LTXVAudioOnlyModel,
"LTXVAudioOnlyEmptyVideoLatent": LTXVAudioOnlyEmptyVideoLatent,
}
# Consistent display names between static and dynamic node mappings in nodes_registry.py,
+89
View File
@@ -0,0 +1,89 @@
"""Audio-only (text-to-audio) mode for the LTX-2 audio/video model.
The LTX-2 transformer in ComfyUI core (``comfy/ldm/lightricks/av_model.py``)
already supports an audio-only path: every block reads ``run_vx``,
``a2v_cross_attn`` and ``v2a_cross_attn`` from ``transformer_options`` and skips
the video self-attention/FFN and the audio<->video cross-attention when they are
``False``. These flags default to ``True``, so the model normally runs jointly.
``LTXVAudioOnlyModel`` flips those flags, which is the equivalent of the
reference pipeline's ``video=None``: the audio is denoised with no dependence on
the video latent, and the video stream is skipped for speed.
Note: the model splits its input positionally into ``[video, audio]``, so the
sampler still needs a (tiny) dummy video latent at index 0. Use
``LTXVAudioOnlyEmptyVideoLatent`` (a fixed 64x64 single-frame placeholder) joined
with the audio latent via ``LTXVConcatAVLatent``. With ``LTXVAudioOnlyModel``
active that dummy video is never attended to.
"""
import comfy.model_management
import torch
from comfy.model_patcher import ModelPatcher
from .nodes_registry import comfy_node
@comfy_node(name="LTXVAudioOnlyModel")
class LTXVAudioOnlyModel:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"model": (
"MODEL",
{
"tooltip": "The LTX-2 audio/video model to run in audio-only mode."
},
),
},
}
RETURN_TYPES = ("MODEL",)
RETURN_NAMES = ("model",)
FUNCTION = "patch"
CATEGORY = "Lightricks/audio"
DESCRIPTION = (
"Run the LTX-2 audio/video model in audio-only mode for text-to-audio. "
"Skips the video stream and disables the audio<->video cross-attention, so "
"the generated audio does not depend on the video latent. The sampler still "
"needs a minimal dummy video latent (EmptyLTXVLatentVideo at 64x64 length 1, "
"joined with LTXVConcatAVLatent); it is never attended to. Remove or bypass "
"this node to restore normal joint audio+video generation."
)
def patch(self, model: ModelPatcher):
new_model = model.clone()
transformer_options = new_model.model_options["transformer_options"]
transformer_options["run_vx"] = False
transformer_options["a2v_cross_attn"] = False
transformer_options["v2a_cross_attn"] = False
return (new_model,)
@comfy_node(name="LTXVAudioOnlyEmptyVideoLatent")
class LTXVAudioOnlyEmptyVideoLatent:
@classmethod
def INPUT_TYPES(s):
return {"required": {}}
RETURN_TYPES = ("LATENT",)
RETURN_NAMES = ("latent",)
FUNCTION = "generate"
CATEGORY = "Lightricks/audio"
DESCRIPTION = (
"Fixed minimal placeholder video latent for audio-only (text-to-audio) "
"generation - a single 64x64 frame. LTX-2 needs a video latent at input "
"index 0, but with LTXV Audio Only Model it is never attended to, so the "
"dimensions are fixed (and hidden) to avoid confusion. Join it with the "
"audio latent via LTXVConcatAVLatent."
)
def generate(self):
# LTX-2 video latent shape: (batch, 128 channels, frames, H/32, W/32).
# Fixed to batch 1, a single frame, 64x64 -> (1, 128, 1, 2, 2).
latent = torch.zeros(
[1, 128, 1, 2, 2],
device=comfy.model_management.intermediate_device(),
)
return ({"samples": latent},)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6666a36c4acf4ac1b1f0e85df38551ab51616593b4b93d08502f08223d18f307
size 250432
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a04e0a13b03d31c119e3d988bd840dec04b9d15c737e1e8951dc293add136a2a
size 3334888
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a89b03aa9d353dd28441cacd22258deac24ca6c8ff689471e2a968cadd2d8a26
size 35624
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7d64dea45a90dc0a0cecd0317b84bc84979bb3b2074733d5157c53c792a665db
size 3653150
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a5ced045ce8bd87b6b6e9d5e9eedb7ffc89d271509780765134aeb0555b427d3
size 2738806
+1 -1
View File
@@ -23,7 +23,7 @@ class LTXVDilateVideoMask(io.ComfyNode):
"spatial_radius",
default=1,
min=0,
max=30,
max=300,
tooltip="Half-size of the spatial dilation kernel. Kernel = 2*radius+1.",
),
io.Int.Input(