Generated reference · ComfyUI workflow · Flagship (frontier)

LTX-2 Keyframe Interpolation

Keyframe-anchored motion on LTX-2.3 22B distilled: approved stills pin the first frame, the last frame, and optionally a middle anchor (chained LTXVAddGuide at exact frame indices), and the model generates the motion between them with …

Flagship (frontier)29nodesGPU H100out video~300sv1.0.0

On this page

Keyframe-anchored motion on LTX-2.3 22B distilled: approved stills pin the first frame, the last frame, and optionally a middle anchor (chained LTXVAddGuide at exact frame indices), and the model generates the motion between them with optional synchronized audio - the motion engine of the keyframe-first pipeline (plan in stills, spend in motion)

29Graph nodes
22Node classes
10Inputs
2Models

Tags: flagshipltx-2videokeyframesinterpolationkeyframe-first2026-sota

Inputs (10)#

The typed parameter surface callers bind when they request this workflow. Enum options and numeric bounds are the values the workflow document declares.

promptstringrequired
The motion connecting the keyframes (and the soundscape, when audio is on)
first_frameimagerequired
Approved keyframe pinning the start
last_frameimagerequired
Approved keyframe pinning the end
middle_frameimage
Optional middle anchor (use_middle_frame must be on)
use_middle_framebooleandefault false
Anchor a third keyframe at the clip's midpoint (snapped to the 8-frame guide grid)
guide_strengthfloatdefault 0.7min 0.1max 1.0
How strongly the keyframes pin their frames (official FLF blueprint: 0.7)
generate_audiobooleandefault true
Generate synchronized audio in the same sampling pass
resolutionenumdefault landscape_1280
Output geometry (multiples of 32); keyframes should match it
options: landscape_1280portrait_1280base_768
duration_secondsintegerdefault 6min 1max 20
Clip length in seconds at 24fps (frames = 24*s + 1)
seedintegerdefault -1
Random seed (-1 for random)

ComfyUI node graph (29)#

The executable ComfyUI prompt graph: 29 nodes across 22 distinct node classes, wired by 44 data dependencies. Nodes tinted green come from a custom node pack this workflow declares; the rest are ComfyUI core / baked-community classes.

flowchart TD n0["1: CheckpointLoaderSimple"] n1["2: LTXAVTextEncoderLoader"] n2["3: CLIPTextEncode"] n3["4: CLIPTextEncode"] n4["5: LTXVConditioning"] n5["6: EmptyLTXVLatentVideo"] n6["first_load: LoadImage"] n7["first_prep: LTXVPreprocess"] n8["guide_first: LTXVAddGuide"] n9["mid_load: LoadImage"] n10["mid_prep: LTXVPreprocess"] n11["guide_mid: LTXVAddGuide"] n12["guide_last: LTXVAddGuide"] n13["last_load: LoadImage"] n14["last_prep: LTXVPreprocess"] n15["audio_vae: LTXVAudioVAELoader"] n16["audio_latent: LTXVEmptyLatentAudio"] n17["av_concat: LTXVConcatAVLatent"] n18["7: RandomNoise"] n19["8: CFGGuider"] n20["9: KSamplerSelect"] n21["10: ManualSigmas"] n22["11: SamplerCustomAdvanced"] n23["av_split: LTXVSeparateAVLatent"] n24["crop_guides: LTXVCropGuides"] n25["12: VAEDecode"] n26["audio_decode: LTXVAudioVAEDecode"] n27["13: CreateVideo"] n28["14: SaveVideo"] n1 -->|clip| n2 n1 -->|clip| n3 n2 -->|positive| n4 n3 -->|negative| n4 n6 -->|image| n7 n4 -->|positive| n8 n4 -->|negative| n8 n0 -->|vae| n8 n5 -->|latent| n8 n7 -->|image| n8 n9 -->|image| n10 n8 -->|positive| n11 n8 -->|negative| n11 n0 -->|vae| n11 n8 -->|latent| n11 n10 -->|image| n11 n11 -->|positive| n12 n11 -->|negative| n12 n0 -->|vae| n12 n11 -->|latent| n12 n14 -->|image| n12 n13 -->|image| n14 n15 -->|audio_vae| n16 n12 -->|video_latent| n17 n16 -->|audio_latent| n17 n0 -->|model| n19 n12 -->|positive| n19 n12 -->|negative| n19 n18 -->|noise| n22 n19 -->|guider| n22 n20 -->|sampler| n22 n21 -->|sigmas| n22 n17 -->|latent_image| n22 n22 -->|av_latent| n23 n12 -->|positive| n24 n12 -->|negative| n24 n23 -->|latent| n24 n24 -->|samples| n25 n0 -->|vae| n25 n23 -->|samples| n26 n15 -->|audio_vae| n26 n25 -->|images| n27 n26 -->|audio| n27 n27 -->|video| n28
Data-flow DAG — scroll to zoom, drag to pan.

Nodes (29)#

1CheckpointLoaderSimplecore
ckpt_name = ltx-2.3-22b-distilled-fp8.safetensors
outputs: MODELCLIPVAE
2LTXAVTextEncoderLoadercore
text_encoder = gemma_3_12B_it_fp4_mixed.safetensorsckpt_name = ltx-2.3-22b-distilled-fp8.safetensorsdevice = default
outputs: CLIP
3CLIPTextEncodecore
text = {{prompt}} tmplclip = ◂ node 2 · out[0]
outputs: CONDITIONING
4CLIPTextEncodecore
text = static image, jump cut, morphing artifacts, watermark, subtitles, distorted faces, harsh noiseclip = ◂ node 2 · out[0]
outputs: CONDITIONING
5LTXVConditioningcore
positive = ◂ node 3 · out[0]negative = ◂ node 4 · out[0]frame_rate = 24.0
outputs: CONDITIONINGCONDITIONING
6EmptyLTXVLatentVideocore
width = {{resolution_map[resolution].width}} tmplheight = {{resolution_map[resolution].height}} tmpllength = {{24 * duration_seconds + 1}} tmplbatch_size = 1
outputs: LATENT
first_loadLoadImagecore
image = {{first_frame}} tmpl
outputs: IMAGEMASK
first_prepLTXVPreprocesscore
image = ◂ node first_load · out[0]img_compression = 35
outputs: IMAGE
guide_firstLTXVAddGuidecore
positive = ◂ node 5 · out[0]negative = ◂ node 5 · out[1]vae = ◂ node 1 · out[2]latent = ◂ node 6 · out[0]image = ◂ node first_prep · out[0]frame_idx = 0strength = {{guide_strength}} tmpl
outputs: CONDITIONINGCONDITIONINGLATENT
mid_loadLoadImagecore
image = {{middle_frame}} tmpl
outputs: IMAGEMASK
mid_prepLTXVPreprocesscore
image = ◂ node mid_load · out[0]img_compression = 35
outputs: IMAGE
guide_midLTXVAddGuidecore
positive = ◂ node guide_first · out[0]negative = ◂ node guide_first · out[1]vae = ◂ node 1 · out[2]latent = ◂ node guide_first · out[2]image = ◂ node mid_prep · out[0]frame_idx = {{(24 * duration_seconds // 2) // 8 * 8}} tmplstrength = {{guide_strength}} tmpl
outputs: CONDITIONINGCONDITIONINGLATENT
guide_lastLTXVAddGuidecore
positive = ◂ node guide_mid · out[0]negative = ◂ node guide_mid · out[1]vae = ◂ node 1 · out[2]latent = ◂ node guide_mid · out[2]image = ◂ node last_prep · out[0]frame_idx = -1strength = {{guide_strength}} tmpl
outputs: CONDITIONINGCONDITIONINGLATENT
last_loadLoadImagecore
image = {{last_frame}} tmpl
outputs: IMAGEMASK
last_prepLTXVPreprocesscore
image = ◂ node last_load · out[0]img_compression = 35
outputs: IMAGE
audio_vaeLTXVAudioVAELoadercore
ckpt_name = ltx-2.3-22b-distilled-fp8.safetensors
outputs: VAE
audio_latentLTXVEmptyLatentAudiocore
frames_number = {{24 * duration_seconds + 1}} tmplframe_rate = 24batch_size = 1audio_vae = ◂ node audio_vae · out[0]
outputs: LATENT
av_concatLTXVConcatAVLatentcore
video_latent = ◂ node guide_last · out[2]audio_latent = ◂ node audio_latent · out[0]
outputs: LATENT
7RandomNoisecore
noise_seed = {{seed}} tmpl
outputs: NOISE
8CFGGuidercore
model = ◂ node 1 · out[0]positive = ◂ node guide_last · out[0]negative = ◂ node guide_last · out[1]cfg = 1.0
outputs: GUIDER
9KSamplerSelectcore
sampler_name = euler_cfg_pp
outputs: SAMPLER
10ManualSigmascore
sigmas = 1.0, 0.99375, 0.9875, 0.98125, 0.975, 0.909375, 0.725, 0.421875, 0.0
outputs: SIGMAS
11SamplerCustomAdvancedcore
noise = ◂ node 7 · out[0]guider = ◂ node 8 · out[0]sampler = ◂ node 9 · out[0]sigmas = ◂ node 10 · out[0]latent_image = ◂ node av_concat · out[0]
outputs: LATENTLATENT
av_splitLTXVSeparateAVLatentcore
av_latent = ◂ node 11 · out[0]
outputs: LATENTLATENT
crop_guidesLTXVCropGuidescore
positive = ◂ node guide_last · out[0]negative = ◂ node guide_last · out[1]latent = ◂ node av_split · out[0]
outputs: CONDITIONINGCONDITIONINGLATENT
12VAEDecodecore
samples = ◂ node crop_guides · out[2]vae = ◂ node 1 · out[2]
outputs: IMAGE
audio_decodeLTXVAudioVAEDecodecore
samples = ◂ node av_split · out[1]audio_vae = ◂ node audio_vae · out[0]
outputs: AUDIO
13CreateVideocore
images = ◂ node 12 · out[0]fps = 24audio = ◂ node audio_decode · out[0]
outputs: VIDEO
14SaveVideocore
video = ◂ node 13 · out[0]filename_prefix = ltx2_keyframe_interpformat = autocodec = auto

Parameter banks (1)#

The prompt / configuration lookup tables this workflow keys into from its inputs — the vocabulary that turns a style / palette / preset selection into graph parameters.

resolution_map (3)#

landscape_1280
{"width": 1280, "height": 704}
portrait_1280
{"width": 704, "height": 1280}
base_768
{"width": 768, "height": 512}

Models & dependencies#

Models required (2)#

gemma_3_12B_it_fp4_mixed.safetensors
ltx-2.3-22b-distilled-fp8.safetensors

Output contract#

What a successful run of this workflow returns.

type
video
format
mp4
audio
true

Taxonomy & routing#

How the control plane classifies this workflow — from the committed workflow-taxonomy-registry.json. It drives the consistency / control surface the agentic director can exercise over the workflow.

assetFamily
keyframe-anchored-motion
outputPackageProfile
video-master-profile
controlModalities
keyframe-anchor-lockreference-ensembleseed-lockmodel-locksampler-scheduler-locktemporal-lock
consistencyDimensions
motioncolor-scriptidentity
notes
The keyframe-first motion engine (L2): approved stills pinned at frame 0 / -1 / optional 8-snapped midpoint via chained LTXVAddGuide (strength 0.7 per FLF blueprint), guides cropped before decode.