joyai-echo-multishot-workflow / INSTRUCTIONS_LITE.md
joeygambino's picture
Lite workflow to 24 fps (accents) + doc math; v1.7 zip refreshed with the fixed Lite graph
1d491ef verified
|
Raw
History Blame Contribute Delete
9.99 kB

Multishot Lite β€” full instructions

Everything here is also written into note blocks inside the workflow itself, so you can work from the graph alone. This file is the long version.


1. Install

There is nothing to install. Every node in this graph ships with ComfyUI.

If a node shows up red on load, your ComfyUI is older than ManualSigmas or ComfySwitchNode β€” update ComfyUI and reopen.

Open the workflow: Workflows β†’ Open, or drag workflow/LTX23_Multishot_Lite.json onto the canvas.

2. Models β€” six loaders, five different folders

This trips up nearly everyone: each loader reads a different folder, and a model in the wrong one simply will not appear in its dropdown.

# node file folder
1 Diffusion model ltx-2.3-22b-distilled-1.1 or another distilled build models/diffusion_models/
1b ID-LoRA LTX-2.3-ID-LoRA-TalkVid-3K.safetensors models/loras/
2 Video VAE LTX-2.3 video VAE models/vae/
3 Gemma + text projection Gemma-3-12B and the LTX text projection models/text_encoders/ + models/checkpoints/
4 Audio VAE LTX-2.3 audio VAE models/checkpoints/

Node 3 takes two files on purpose: Gemma produces the embeddings, and LTX's text projection maps them into the DiT's conditioning space. Gemma alone is not enough.

The weight_dtype widget on node 1 will drop the model to fp8 without needing a separate file β€” useful on 24 GB cards.

3. Your two inputs

  • 5. Voice reference β€” 3–5 seconds of clean, solo, continuous speech. No music, no second speaker, no long silences. Put it in ComfyUI/input/.
  • 6. Shot 1 first frame β€” the image shot 1 opens on. Also ComfyUI/input/.

Both ship as <YOUR ...> placeholders, so they will show as unset until you pick your own β€” that is intentional.

4. First render

  1. Set the six loaders and your two inputs.
  2. Leave everything else at defaults (960Γ—544, 241 frames β‰ˆ 9.6 s per shot).
  3. Queue.
  4. Watch multishot_lite/FINAL β€” that is the joined, refined output. The per-shot files are previews.

5. Audio modes

Mode 1 (default) β€” your reference voice. The character speaks the quoted line from your prompt in the voice from your sample. Requires the ID-LoRA.

Mode 2 β€” the model invents a voice. Select both reference nodes (one per shot) and press Ctrl+B. They turn purple. Everything else is unchanged.

There is no track substitution in either mode β€” what you hear is always what the model generated.

If the audio garbles

Symptom: your line comes out plus extra garbled words.

  1. Shorten the voice reference toward 3 seconds. The whole clip becomes conditioning tokens; a long one gives the model words to echo. This is usually the entire fix.
  2. Confirm the ID-LoRA is loaded (node 1b). Without it the model has no trained path for identity transfer and echoes fragments instead.
  3. Lower identity_guidance_scale toward 1.5 where that widget exists. Note that identity_guidance_scale = 0 is not a clean "no reference" test β€” it only skips the guidance pass; the reference tokens stay attached. Only Ctrl+B removes them.

5b. Tuning: checkpoint first, then widgets

Start with your checkpoint, not a slider. Lip sync lives in the video branch's cross-attention to the audio conditioning - not in the audio branch. Video-side merges and finetunes routinely rewrite exactly those layers, so a checkpoint can be excellent at scenery and markedly worse at mouths while its audio weights sit untouched. Measured on one merge vs stock ltx-2.3-22b-distilled-1.1: audio branch bit-identical, only 2 of 24 sampled video cross-attention tensors unchanged.

If mouths are poor, A/B a stock checkpoint first. Change only the UNETLoader, keep the seed, change nothing else. Match the schedule: the sigmas here are the 8-step distilled ladder at cfg 1, so compare against a distilled build - never -dev, which needs a many-step cfg>1 schedule and will produce garbage on this ladder and have you blaming the wrong thing.

strength (guide node) - ships at 1.0. Sets frame 0's noise mask to 1.0 - strength, i.e. how free the model is to move that frame. 1.0 pins it to your guide and gives the tightest identity hold; on a healthy checkpoint it still animates.

  • Mouth frozen -> 0.8, then 0.7.
  • Needing below ~0.6 for any movement -> checkpoint problem, see above.
  • Face drifting off your reference / looks like T2V -> back toward 1.0.

img_compression (LTXVPreprocess) - ships at 25. Not a motion dial. LTX is trained on video frames, which carry codec artifacts; a pristine photo is out-of-distribution as a "frame", so a light H.264 round-trip helps the model read it as one. But the value is passed straight to x264 as CRF, so it is a quality-destruction knob:

  • x264 clamps CRF at 51 - every value from 51 to 100 is byte-identical. Running it at 100 is not "maximum motion", it is CRF 51.
  • At CRF 51 fine detail drops to ~83% of source. Patterned fabric, curtains, hair and skin texture turn to mush and the model invents replacements - it restyles the whole frame, not just the face.

Leave it at 25. If you are tempted past 40, the problem is elsewhere.

identity_guidance_scale + end_percent - ship at 3.0 / 0.5. Guidance amplifies the reference across the WHOLE denoised tensor - audio and video - so run across every step it restyles the face while fixing the voice. Identity is decided in the early high-noise steps; detail forms late. end_percent 0.5 switches guidance off halfway.

  • Face stylized -> lower end_percent (0.3-0.4), not the scale.
  • Voice not holding -> raise the scale (4-5), leave end_percent.

Change one thing at a time. Every wrong turn in this workflow's history came from moving two dials at once and crediting the wrong one.

6. Length and resolution

Both are set once in the GLOBAL group. length must be 8n+1 (97, 145, 241, 265, 329...), duration = length / 24, dimensions divisible by 32.

Everything downstream of length now follows it automatically (the last-frame picker uses negative indexing, the trims clamp). The one manual value: the AV-extend node's video_end_time/audio_end_time = (length + 72) / 24. At the shipped 241 that is 13.04; for a ~20 s shot set length 265 and end times 14.04.

7. Prompting

Only text inside "double quotes" should be spoken. But the model has a narrator prior and will read your scene description aloud unless told not to β€” quoting alone is not enough.

The shipped prompts carry an exclusivity block:

They are the only person speaking, and the only voice on the audio track is theirs. One continuous line with natural breaths and brief pauses. No narration, no voice-over, no other speech, and nothing else is read aloud.

Keep that when you rewrite. Other rules that carry over:

  • ~26–32 spoken words per shot. Longer and delivery drifts.
  • One speaker per shot. Two quoted lines in one prompt tend to come out simultaneously, in the same voice.
  • Name the accent explicitly ("a casual American accent") β€” it drifts otherwise.
  • If you are using a first-frame image, describe what should happen, not a fixed person or place. A prompt that contradicts the image makes the model fight the guide, which reads as the image being ignored.

8. The chain (v2: a true extension)

Shot 2 does not restart β€” it extends shot 1. The last 73 frames (3.04 s) of shot 1's video and audio are encoded as latent context on the AV-extend node (LTXVAudioVideoMask, pad mode), the model generates forward from an ongoing utterance, and the context region is dropped from the output before the join.

Because the audio never restarts, the voice carries over automatically β€” the chained shot has no reference-audio node and needs none.

To add a shot 3: copy the whole SHOT 2 group and feed its two context nodes from shot 2's decodes instead of shot 1's. Identity drifts slowly over many extensions; for long chains use the full JoyAI-Echo pack (memory bank).

9. The FINISH group

Both shots are joined (video and audio) and refined with a deterministic 1.5Γ— bicubic upscale plus a gentle sharpen. Deterministic on purpose β€” generative refiners re-invent detail per frame, which reads as texture shimmer.

  • Turn refine off: set scale_by to 1.0.
  • The sharpen node ships bypassed. Core ImageSharpen moves the whole batch to the GPU and allocates two more full-size copies, so it needs roughly 3Γ— the batch in VRAM β€” fine for a few hundred frames, an OOM on a 2000-frame run at any resolution. Ctrl+B to enable it on short renders. For long ones, sharpen the finished file instead:
ffmpeg -i FINAL.mp4 -vf "cas=0.55" -c:v libx264 -crf 16 -preset medium \
       -tune grain -bf 0 -c:a copy FINAL_sharp.mp4
  • Shot 2's first frame is shot 1's last frame, so the joint holds one duplicated frame β€” 1/24th of a second, invisible at a cut.

10. Troubleshooting

symptom cause
A loader dropdown is empty / red model is in the wrong folder β€” see Β§2
Line spoken plus garbled words voice reference too long, or ID-LoRA missing β€” Β§5
The model reads your description aloud exclusivity block removed from the prompt β€” Β§7
Mouth barely moves A/B a stock distilled checkpoint first β€” see Β§5b
Face soft / stylized / "smoothed" lower img_compression, then end_percent β€” Β§5b
Shot 2 looks unrelated to shot 1 ImageFromBatch β†’ batch_index β‰  length βˆ’ 1
ComfyUI dies during load, RAM at 100%, VRAM idle system RAM β€” raise the Windows pagefile to 64–128 GB
OOM in ImageSharpen on a long render expected; leave it bypassed and use ffmpeg β€” Β§9
Video looks soft scale_by is doing a plain upscale; enable sharpen on short runs