AI on the Lot 2026 - LTX-2.3 - i2v
The fifth workflow released for AI on the Lot 2026, made available for ComfyUI 101 workshop attendees to open and follow along if they choose. An image-to-video workflow built on the LTX 2.3 model, turning a still image into a generated video clip.
About
This ComfyUI workflow turns a single still image into a short, animated video using Lightricks’ LTX‑2.3 image‑to‑video model. The pipeline is straightforward: LoadImage brings your source frame into the graph, a custom LTX‑2.3 node (2454ad83-157c-40dd-9f19-5daaf4041ce0) synthesizes motion conditioned on that image and a text prompt, and SaveVideo assembles the generated frames into a playable clip. MarkdownNote nodes inside the graph provide in‑context guidance and prompt tips so you can follow along during the AI on the Lot 2026 ComfyUI 101 workshop.
Technically, the LTX‑2.3 node encodes your input image into the model’s latent space and generates a temporally coherent sequence guided by your prompt. You control the character and pace of motion by describing events over time ("Core Actions") and specifying concrete "Visual Details" you want to preserve, as recommended in the LTX‑2.3 prompting tips. Typical controls exposed by the node include the text prompt, seed for reproducibility, and clip characteristics such as number of frames and/or FPS (exact parameters depend on the node build).
SaveVideo then writes the frames to disk at your chosen frame rate. For model weights, use Lightricks/LTX‑2.3 from Hugging Face (see the links provided), and follow the node’s loader field to point to the correct files.
What you provide
- Reading the workflow
Runs in ComfyUI. This workflow can't run on this page. Open it in Comfy Cloud with everything loaded, or download it for your own ComfyUI.
Try in CloudInside the workflow
A read-only preview of the node graph. Open it in Comfy Cloud or download it to edit the nodes.
Loading the graph
Open full-size workflow preview- Author
- Julien Durand | MJM
Requires custom nodes
- Reading the workflow
Use this workflow from code
Generated from the workflow graph and inputs when possible; stored examples are shown otherwise. Review credentials and endpoints before running code, which may incur charges.
What you need
- Runs on
- Comfy Cloud
- Key
- COMFY_API_KEY
Needs a paid Cloud plan and credits.
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"75": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/LTX_2.3_i2v",
"format": "auto",
"format.codec": "auto",
"video": [
"320:310",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"269": {
"class_type": "LoadImage",
"inputs": {
"image": "92a9314e31dced3cd7c657effe9240281caf8802bf430d699574869bb15dc58f.png"
},
"_meta": {
"title": "Load Image"
}
},
"320:276": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 42
},
"_meta": {
"title": "RandomNoise"
}
},
"320:277": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 1107858748962189
},
"_meta": {
"title": "RandomNoise"
}
},
"320:278": {
"class_type": "LTXVConcatAVLatent",
"inputs": {
"audio_latent": [
"320:307",
1
],
"video_latent": [
"320:288",
0
]
},
"_meta": {
"title": "Concat AV Latent"
}
},
"320:279": {
"class_type": "LTXVAudioVAELoader",
"inputs": {
"ckpt_name": "ltx-2.3-22b-distilled-fp8.safetensors"
},
"_meta": {
"title": "Load LTXV Audio VAE"
}
},
"320:280": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler_cfg_pp"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"320:281": {
"class_type": "ManualSigmas",
"inputs": {
"sigmas": "0.85, 0.7250, 0.4219, 0.0"
},
"_meta": {
"title": "ManualSigmas"
}
},
"320:282": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 1,
"model": [
"320:285",
0
],
"negative": [
"320:284",
1
],
"positive": [
"320:284",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"320:283": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"320:314",
0
],
"latent_image": [
"320:318",
0
],
"noise": [
"320:277",
0
],
"sampler": [
"320:291",
0
],
"sigmas": [
"320:306",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"320:284": {
"class_type": "LTXVCropGuides",
"inputs": {
"latent": [
"320:307",
0
],
"negative": [
"320:304",
1
],
"positive": [
"320:304",
0
]
},
"_meta": {
"title": "LTXVCropGuides"
}
},
"320:285": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "ltx-2.3-22b-distilled-lora-384-1.1.safetensors",
"model": [
"320:316",
0
],
"strength_model": 0.5
},
"_meta": {
"title": "Load LoRA"
}
},
"320:286": {
"class_type": "ResizeImagesByLongerEdge",
"inputs": {
"images": [
"320:290",
0
],
"longer_edge": 1536
},
"_meta": {
"title": "Resize Images by Longer Edge (DEPRECATED)"
}
},
"320:287": {
"class_type": "LTXVLatentUpsampler",
"inputs": {
"samples": [
"320:307",
0
],
"upscale_model": [
"320:311",
0
],
"vae": [
"320:316",
2
]
},
"_meta": {
"title": "LTXVLatentUpsampler"
}
},
"320:288": {
"class_type": "LTXVImgToVideoInplace",
"inputs": {
"bypass": [
"320:302",
0
],
"image": [
"320:289",
0
],
"latent": [
"320:287",
0
],
"strength": 1,
"vae": [
"320:316",
2
]
},
"_meta": {
"title": "LTXVImgToVideoInplace"
}
},
"320:289": {
"class_type": "LTXVPreprocess",
"inputs": {
"image": [
"320:286",
0
],
"img_compression": 18
},
"_meta": {
"title": "LTXV Preprocess"
}
},
"320:290": {
"class_type": "ResizeImageMaskNode",
"inputs": {
"input": [
"269",
0
],
"resize_type": "scale dimensions",
"resize_type.crop": "center",
"resize_type.height": [
"320:299",
0
],
"resize_type.width": [
"320:312",
0
],
"scale_method": "lanczos"
},
"_meta": {
"title": "Resize Image/Mask"
}
},
"320:291": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler_ancestral_cfg_pp"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"320:292": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a/2",
"values.a": [
"320:312",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"320:294": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a/2",
"values.a": [
"320:299",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"320:295": {
"class_type": "EmptyLTXVLatentVideo",
"inputs": {
"batch_size": 1,
"height": [
"320:294",
1
],
"length": [
"320:323",
1
],
"width": [
"320:292",
1
]
},
"_meta": {
"title": "Empty LTXV Latent Video"
}
},
"320:296": {
"class_type": "LTXVImgToVideoInplace",
"inputs": {
"bypass": [
"320:302",
0
],
"image": [
"320:289",
0
],
"latent": [
"320:295",
0
],
"strength": 0.7,
"vae": [
"320:316",
2
]
},
"_meta": {
"title": "LTXVImgToVideoInplace"
}
},
"320:297": {
"class_type": "LTXVAudioVAEDecode",
"inputs": {
"audio_vae": [
"320:279",
0
],
"samples": [
"320:309",
1
]
},
"_meta": {
"title": "LTXV Audio VAE Decode"
}
},
"320:298": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a",
"values.a": [
"320:300",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"320:299": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1024
},
"_meta": {
"title": "Height"
}
},
"320:300": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 25
},
"_meta": {
"title": "Frame Rate"
}
},
"320:301": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 5
},
"_meta": {
"title": "Duration"
}
},
"320:302": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Switch to Text to Video?"
}
},
"320:303": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"320:317",
0
],
"text": [
"320:319",
0
]
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"320:304": {
"class_type": "LTXVConditioning",
"inputs": {
"frame_rate": [
"320:298",
0
],
"negative": [
"320:313",
0
],
"positive": [
"320:303",
0
]
},
"_meta": {
"title": "LTXVConditioning"
}
},
"320:305": {
"class_type": "LTXVEmptyLatentAudio",
"inputs": {
"audio_vae": [
"320:279",
0
],
"batch_size": 1,
"frame_rate": [
"320:298",
1
],
"frames_number": [
"320:323",
1
]
},
"_meta": {
"title": "Empty LTXV Latent Audio"
}
},
"320:306": {
"class_type": "ManualSigmas",
"inputs": {
"sigmas": "1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0"
},
"_meta": {
"title": "ManualSigmas"
}
},
"320:307": {
"class_type": "LTXVSeparateAVLatent",
"inputs": {
"av_latent": [
"320:283",
0
]
},
"_meta": {
"title": "Separate AV Latent"
}
},
"320:308": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"320:282",
0
],
"latent_image": [
"320:278",
0
],
"noise": [
"320:276",
0
],
"sampler": [
"320:280",
0
],
"sigmas": [
"320:281",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"320:309": {
"class_type": "LTXVSeparateAVLatent",
"inputs": {
"av_latent": [
"320:308",
0
]
},
"_meta": {
"title": "Separate AV Latent"
}
},
"320:310": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"320:297",
0
],
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"320:298",
0
],
"images": [
"320:315",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"320:311": {
"class_type": "LatentUpscaleModelLoader",
"inputs": {
"model_name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors"
},
"_meta": {
"title": "Load Latent Upscale Model"
}
},
"320:312": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1024
},
"_meta": {
"title": "Width"
}
},
"320:313": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"320:317",
0
],
"text": "pc game, console game, video game, cartoon, childish, ugly"
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"320:314": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 1,
"model": [
"320:285",
0
],
"negative": [
"320:304",
1
],
"positive": [
"320:304",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"320:315": {
"class_type": "VAEDecodeTiled",
"inputs": {
"overlap": 64,
"samples": [
"320:309",
0
],
"temporal_overlap": 4,
"temporal_size": 4096,
"tile_size": 768,
"vae": [
"320:316",
2
]
},
"_meta": {
"title": "VAE Decode (Tiled)"
}
},
"320:316": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "ltx-2.3-22b-distilled-fp8.safetensors"
},
"_meta": {
"title": "Load Checkpoint"
}
},
"320:317": {
"class_type": "LTXAVTextEncoderLoader",
"inputs": {
"ckpt_name": "ltx-2.3-22b-distilled-fp8.safetensors",
"device": "default",
"text_encoder": "gemma_3_12B_it_fp4_mixed.safetensors"
},
"_meta": {
"title": "Load LTXV Audio Text Encoder"
}
},
"320:318": {
"class_type": "LTXVConcatAVLatent",
"inputs": {
"audio_latent": [
"320:305",
0
],
"video_latent": [
"320:296",
0
]
},
"_meta": {
"title": "Concat AV Latent"
}
},
"320:319": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": "Static medium close-up of the man, framing locked, no camera movement. He looks directly at camera and says, in a low, gravelly, weathered voice: \"Enjoy the workshop at A.I. on the Lot, twenty twenty-six.\" Natural mouth movement matching the dialogue, subtle micro-expressions, eyes steady on lens. Smoke continues to drift across frame from camera right, curling and dissipating. A few wisps of hair shift slightly in the warm breeze. No head turn, no body movement, no eye darting, no other people, no sudden gestures."
},
"_meta": {
"title": "Prompt"
}
},
"320:323": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a * b + 1",
"values.a": [
"320:301",
0
],
"values.b": [
"320:300",
0
]
},
"_meta": {
"title": "Math Expression (length)"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)Questions & answers
Describe Core Actions as they unfold over time (e.g., “the camera slowly dolly‑zooms in as leaves drift across the foreground”) and list concrete Visual Details you want to preserve (composition, lighting, color, subject attributes). Keep directives concise and unambiguous.
Clean, well‑lit images with clear subject separation tend to animate more coherently. Use a resolution that matches your VRAM and the workflow’s defaults, and keep the aspect ratio consistent across input and output to avoid stretching.
Clip length is a function of the number of generated frames and the SaveVideo FPS. Increase frames for longer clips and adjust FPS for playback feel. If the LTX‑2.3 node exposes frame count or duration, change it there; then set the desired FPS in SaveVideo.
Set and reuse a fixed seed in the LTX‑2.3 node (if available), keep the prompt identical, and avoid changing other generation parameters. Changing the seed is useful when you want controlled variations.