AI on the Lot 2026 - Final WF - t2v
The sixth and final workflow released for AI on the Lot 2026, made available for ComfyUI 101 workshop attendees to open and follow along if they choose. A text-to-video workflow that brings together everything built and used in the previous workflows into one complete setup.
About
AI on the Lot 2026 - Final WF - t2v is a complete text-to-video pipeline that stitches together prompt design, image synthesis, and video assembly inside ComfyUI. It uses AILab_QwenVL and AILab_QwenVL_PromptEnhancer to turn a simple idea into a rich, structured prompt. From there, the workflow generates high-quality keyframes with the image synthesis stage (node ID e9d2dda8-2509-4d8d-9702-a9bf00c26650), previews results with PreviewAny, and then builds a cohesive video clip in the video stage (node ID 99c27236-513e-427c-9ed4-49406365f0d3).
SaveImage and SaveVideo provide clean, reproducible exports at each stage.
Technically, the flow is: your base text prompt (and optionally a reference image) goes into AILab_QwenVL to extract and enrich scene details. AILab_QwenVL_PromptEnhancer refines the text into a model-friendly prompt with clearer subjects, styles, and shot descriptors. That prompt feeds the image generator node (e9d2dda8-2509-4d8d-9702-a9bf00c26650) to produce one or more seed-controlled keyframes at your chosen resolution. Those frames are then passed to the video node (99c27236-513e-427c-9ed4-49406365f0d3), which synthesizes a clip based on duration and motion/consistency settings.
PreviewAny helps you iterate quickly, while SaveImage and SaveVideo lock in stills or a final video once you’re happy. Because the stages are modular, you can use it for text-to-image only, image-to-video only, or end-to-end text-to-video with the same graph.
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({
"74": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "z-image-turbo",
"images": [
"76:8",
0
]
},
"_meta": {
"title": "Save Image"
}
},
"77": {
"class_type": "AILab_QwenVL_PromptEnhancer",
"inputs": {
"attention_mode": "auto",
"custom_system_prompt": "You are an expert prompt writer for a photorealistic image generator. Given a short concept, expand it into a detailed prompt covering subject, lighting, setting, lens, and mood. One dense paragraph. No bullet points.",
"device": "auto",
"enhancement_style": "📝 Enhance",
"keep_model_loaded": True,
"max_tokens": 256,
"model_name": "Qwen3-VL-8B-Instruct",
"prompt_text": "a boxer alone in the locker room after a fight",
"quantization": "None (FP16)",
"repetition_penalty": 1.1,
"seed": 1,
"temperature": 0.7,
"top_p": 0.9,
"use_torch_compile": False
},
"_meta": {
"title": "QwenVL Prompt Enhancer"
}
},
"78": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"77",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"324": {
"class_type": "SaveVideo",
"inputs": {
"filename_prefix": "video/LTX_2.3_i2v",
"format": "auto",
"format.codec": "auto",
"video": [
"326:310",
0
]
},
"_meta": {
"title": "Save Video"
}
},
"330": {
"class_type": "AILab_QwenVL",
"inputs": {
"attention_mode": "auto",
"custom_prompt": "You are writing a motion prompt for an image-to-video generator that creates 5-second clips with synced audio. Describe the motion that unfolds over the next 5 seconds. State subject motion (or stillness) and camera motion as separate sentences. Be explicit about what does NOT move to prevent hallucinations. Include environmental motion (smoke, fog, light, water, fabric). Optional ambient audio at the end. Do not redescribe static visual content. One paragraph focused on motion.",
"keep_model_loaded": True,
"max_tokens": 512,
"model_name": "Qwen3-VL-8B-Instruct",
"preset_prompt": "🎬 Cinematic Description",
"quantization": "None (FP16)",
"seed": 1
},
"_meta": {
"title": "QwenVL"
}
},
"331": {
"class_type": "PreviewAny",
"inputs": {
"source": [
"330",
0
]
},
"_meta": {
"title": "Preview as Text"
}
},
"326:276": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 42
},
"_meta": {
"title": "RandomNoise"
}
},
"326:277": {
"class_type": "RandomNoise",
"inputs": {
"noise_seed": 1072283399870947
},
"_meta": {
"title": "RandomNoise"
}
},
"326:278": {
"class_type": "LTXVConcatAVLatent",
"inputs": {
"audio_latent": [
"326:307",
1
],
"video_latent": [
"326:288",
0
]
},
"_meta": {
"title": "Concat AV Latent"
}
},
"326:279": {
"class_type": "LTXVAudioVAELoader",
"inputs": {
"ckpt_name": "ltx-2.3-22b-distilled-fp8.safetensors"
},
"_meta": {
"title": "Load LTXV Audio VAE"
}
},
"326:280": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler_cfg_pp"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"326:281": {
"class_type": "ManualSigmas",
"inputs": {
"sigmas": "0.85, 0.7250, 0.4219, 0.0"
},
"_meta": {
"title": "ManualSigmas"
}
},
"326:282": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 1,
"model": [
"326:285",
0
],
"negative": [
"326:284",
1
],
"positive": [
"326:284",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"326:283": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"326:314",
0
],
"latent_image": [
"326:318",
0
],
"noise": [
"326:277",
0
],
"sampler": [
"326:291",
0
],
"sigmas": [
"326:306",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"326:284": {
"class_type": "LTXVCropGuides",
"inputs": {
"latent": [
"326:307",
0
],
"negative": [
"326:304",
1
],
"positive": [
"326:304",
0
]
},
"_meta": {
"title": "LTXVCropGuides"
}
},
"326:285": {
"class_type": "LoraLoaderModelOnly",
"inputs": {
"lora_name": "ltx-2.3-22b-distilled-lora-384-1.1.safetensors",
"model": [
"326:316",
0
],
"strength_model": 0.5
},
"_meta": {
"title": "Load LoRA"
}
},
"326:286": {
"class_type": "ResizeImagesByLongerEdge",
"inputs": {
"images": [
"326:290",
0
],
"longer_edge": 1536
},
"_meta": {
"title": "Resize Images by Longer Edge (DEPRECATED)"
}
},
"326:287": {
"class_type": "LTXVLatentUpsampler",
"inputs": {
"samples": [
"326:307",
0
],
"upscale_model": [
"326:311",
0
],
"vae": [
"326:316",
2
]
},
"_meta": {
"title": "LTXVLatentUpsampler"
}
},
"326:288": {
"class_type": "LTXVImgToVideoInplace",
"inputs": {
"bypass": [
"326:302",
0
],
"image": [
"326:289",
0
],
"latent": [
"326:287",
0
],
"strength": 1,
"vae": [
"326:316",
2
]
},
"_meta": {
"title": "LTXVImgToVideoInplace"
}
},
"326:289": {
"class_type": "LTXVPreprocess",
"inputs": {
"image": [
"326:286",
0
],
"img_compression": 18
},
"_meta": {
"title": "LTXV Preprocess"
}
},
"326:290": {
"class_type": "ResizeImageMaskNode",
"inputs": {
"input": [
"76:8",
0
],
"resize_type": "scale dimensions",
"resize_type.crop": "center",
"resize_type.height": [
"326:299",
0
],
"resize_type.width": [
"326:312",
0
],
"scale_method": "lanczos"
},
"_meta": {
"title": "Resize Image/Mask"
}
},
"326:291": {
"class_type": "KSamplerSelect",
"inputs": {
"sampler_name": "euler_ancestral_cfg_pp"
},
"_meta": {
"title": "KSamplerSelect"
}
},
"326:292": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a/2",
"values.a": [
"326:312",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"326:294": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a/2",
"values.a": [
"326:299",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"326:295": {
"class_type": "EmptyLTXVLatentVideo",
"inputs": {
"batch_size": 1,
"height": [
"326:294",
1
],
"length": [
"326:323",
1
],
"width": [
"326:292",
1
]
},
"_meta": {
"title": "Empty LTXV Latent Video"
}
},
"326:296": {
"class_type": "LTXVImgToVideoInplace",
"inputs": {
"bypass": [
"326:302",
0
],
"image": [
"326:289",
0
],
"latent": [
"326:295",
0
],
"strength": 0.7,
"vae": [
"326:316",
2
]
},
"_meta": {
"title": "LTXVImgToVideoInplace"
}
},
"326:297": {
"class_type": "LTXVAudioVAEDecode",
"inputs": {
"audio_vae": [
"326:279",
0
],
"samples": [
"326:309",
1
]
},
"_meta": {
"title": "LTXV Audio VAE Decode"
}
},
"326:298": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a",
"values.a": [
"326:300",
0
]
},
"_meta": {
"title": "Math Expression"
}
},
"326:299": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1080
},
"_meta": {
"title": "Height"
}
},
"326:300": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 25
},
"_meta": {
"title": "Frame Rate"
}
},
"326:301": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 5
},
"_meta": {
"title": "Duration"
}
},
"326:302": {
"class_type": "PrimitiveBoolean",
"inputs": {
"value": False
},
"_meta": {
"title": "Switch to Text to Video?"
}
},
"326:303": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"326:317",
0
],
"text": [
"326:319",
0
]
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"326:304": {
"class_type": "LTXVConditioning",
"inputs": {
"frame_rate": [
"326:298",
0
],
"negative": [
"326:313",
0
],
"positive": [
"326:303",
0
]
},
"_meta": {
"title": "LTXVConditioning"
}
},
"326:305": {
"class_type": "LTXVEmptyLatentAudio",
"inputs": {
"audio_vae": [
"326:279",
0
],
"batch_size": 1,
"frame_rate": [
"326:298",
1
],
"frames_number": [
"326:323",
1
]
},
"_meta": {
"title": "Empty LTXV Latent Audio"
}
},
"326: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"
}
},
"326:307": {
"class_type": "LTXVSeparateAVLatent",
"inputs": {
"av_latent": [
"326:283",
0
]
},
"_meta": {
"title": "Separate AV Latent"
}
},
"326:308": {
"class_type": "SamplerCustomAdvanced",
"inputs": {
"guider": [
"326:282",
0
],
"latent_image": [
"326:278",
0
],
"noise": [
"326:276",
0
],
"sampler": [
"326:280",
0
],
"sigmas": [
"326:281",
0
]
},
"_meta": {
"title": "SamplerCustomAdvanced"
}
},
"326:309": {
"class_type": "LTXVSeparateAVLatent",
"inputs": {
"av_latent": [
"326:308",
0
]
},
"_meta": {
"title": "Separate AV Latent"
}
},
"326:310": {
"class_type": "CreateVideo",
"inputs": {
"audio": [
"326:297",
0
],
"bit_depth": "auto",
"codec": "none",
"color_space": "sRGB",
"fps": [
"326:298",
0
],
"images": [
"326:315",
0
]
},
"_meta": {
"title": "Create Video"
}
},
"326:311": {
"class_type": "LatentUpscaleModelLoader",
"inputs": {
"model_name": "ltx-2.3-spatial-upscaler-x2-1.1.safetensors"
},
"_meta": {
"title": "Load Latent Upscale Model"
}
},
"326:312": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1920
},
"_meta": {
"title": "Width"
}
},
"326:313": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"326:317",
0
],
"text": "pc game, console game, video game, cartoon, childish, ugly"
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"326:314": {
"class_type": "CFGGuider",
"inputs": {
"cfg": 1,
"model": [
"326:285",
0
],
"negative": [
"326:304",
1
],
"positive": [
"326:304",
0
]
},
"_meta": {
"title": "CFG Guider"
}
},
"326:315": {
"class_type": "VAEDecodeTiled",
"inputs": {
"overlap": 64,
"samples": [
"326:309",
0
],
"temporal_overlap": 4,
"temporal_size": 4096,
"tile_size": 768,
"vae": [
"326:316",
2
]
},
"_meta": {
"title": "VAE Decode (Tiled)"
}
},
"326:316": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "ltx-2.3-22b-distilled-fp8.safetensors"
},
"_meta": {
"title": "Load Checkpoint"
}
},
"326: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"
}
},
"326:318": {
"class_type": "LTXVConcatAVLatent",
"inputs": {
"audio_latent": [
"326:305",
0
],
"video_latent": [
"326:296",
0
]
},
"_meta": {
"title": "Concat AV Latent"
}
},
"326:319": {
"class_type": "PrimitiveStringMultiline",
"inputs": {
"value": [
"330",
0
]
},
"_meta": {
"title": "Prompt"
}
},
"326:323": {
"class_type": "ComfyMathExpression",
"inputs": {
"expression": "a * b + 1",
"values.a": [
"326:301",
0
],
"values.b": [
"326:300",
0
]
},
"_meta": {
"title": "Math Expression (length)"
}
},
"76:11": {
"class_type": "ModelSamplingAuraFlow",
"inputs": {
"model": [
"76:28",
0
],
"sampling": "flow",
"shift": 3
},
"_meta": {
"title": "ModelSamplingAuraFlow"
}
},
"76:13": {
"class_type": "EmptySD3LatentImage",
"inputs": {
"batch_size": 1,
"height": 512,
"width": 912
},
"_meta": {
"title": "EmptySD3LatentImage"
}
},
"76:27": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"76:30",
0
],
"text": [
"77",
0
]
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"76:28": {
"class_type": "UNETLoader",
"inputs": {
"unet_name": "z_image_turbo_bf16.safetensors",
"weight_dtype": "default"
},
"_meta": {
"title": "Load Diffusion Model"
}
},
"76:29": {
"class_type": "VAELoader",
"inputs": {
"vae_name": "ae.safetensors"
},
"_meta": {
"title": "Load VAE"
}
},
"76:3": {
"class_type": "KSampler",
"inputs": {
"cfg": 1,
"denoise": 1,
"latent_image": [
"76:13",
0
],
"model": [
"76:11",
0
],
"negative": [
"76:33",
0
],
"positive": [
"76:27",
0
],
"sampler_name": "res_multistep",
"scheduler": "simple",
"seed": 65154781543635,
"steps": 8
},
"_meta": {
"title": "KSampler"
}
},
"76:30": {
"class_type": "CLIPLoader",
"inputs": {
"clip_name": "qwen_3_4b.safetensors",
"device": "default",
"type": "lumina2"
},
"_meta": {
"title": "Load CLIP"
}
},
"76:33": {
"class_type": "ConditioningZeroOut",
"inputs": {
"conditioning": [
"76:27",
0
]
},
"_meta": {
"title": "Conditioning Zero Out"
}
},
"76:337": {
"class_type": "UpscaleModelLoader",
"inputs": {
"model_name": "4x-UltraSharp.pth"
},
"_meta": {
"title": "Load Upscale Model"
}
},
"76:63": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"76:3",
0
],
"vae": [
"76:29",
0
]
},
"_meta": {
"title": "VAE Decode"
}
},
"76:70": {
"class_type": "FL_UpscaleModel",
"inputs": {
"batch_size": 1,
"downscale_by": 0.5,
"image": [
"76:63",
0
],
"precision": "32",
"rescale_method": "bicubic",
"upscale_model": [
"76:337",
0
]
},
"_meta": {
"title": "FL Upscale Model"
}
},
"76:71": {
"class_type": "FL_KsamplerPlus",
"inputs": {
"batch_size": 4,
"cfg": 1,
"denoise": 0.2,
"image": [
"76:70",
0
],
"input_type": "image",
"model": [
"76:11",
0
],
"negative": [
"76:33",
0
],
"overlap": 0.05,
"positive": [
"76:27",
0
],
"sampler_name": "res_multistep",
"scheduler": "simple",
"seed": 974,
"steps": 9,
"use_sliced_conditioning": True,
"vae": [
"76:29",
0
],
"x_slices": 1,
"y_slices": 2
},
"_meta": {
"title": "FL KSampler Plus"
}
},
"76:8": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"76:71",
3
],
"vae": [
"76:29",
0
]
},
"_meta": {
"title": "VAE Decode"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)Questions & answers
You need the custom AILab_QwenVL nodes to load successfully; they will rely on Qwen‑VL assets for prompt enhancement. The image and video synthesis nodes (e9d2dda8‑… and 99c27236‑…) use whatever model/checkpoint configuration the workflow provides or you connect. If ComfyUI reports missing models, follow the node warnings to download or point to the correct files.
Try increasing motion/consistency strength in the video node, lowering noise strength, and keeping a fixed seed in the image stage. Clear, specific prompts from AILab_QwenVL_PromptEnhancer (subjects, camera, style) also help. Shorter clips and moderate resolutions are easier to stabilize during iteration.
Lower resolution, reduce steps in the image node (e9d2dda8‑…), use a smaller clip length or fps in the video node (99c27236‑…), and keep a fixed seed. Use PreviewAny to validate direction before committing to a full‑quality render.
Both. You can stop after the image stage and export stills (SaveImage), or feed existing/reference imagery through the prompt and video stages to produce motion. The end‑to‑end path is text‑to‑video, but the stages are modular so you can mix and match.