ComfyUI AnimateDiff 新手教程最小文生视频工作流搭建与原理解析一、前言刚接触 ComfyUI 和 AnimateDiff 时最常见的两个问题通常是工作流到底能不能先跑起来节点为什么要这样连接能不能换一种接法很多教程一上来就堆很多插件和节点结果还没跑通就先被劝退了。这篇文章只做一件事用一套最小可运行的 AnimateDiff 工作流先跑通再理解原理最后明确下一步该怎么扩展。这篇文章适合刚接触 ComfyUI 的新手已经装好了 AnimateDiff 插件但还不理解节点逻辑的人想做教程、想把原理讲清楚的人工作流截图输出图片截图输出视频截图输出没做任何优化所以效果肯定不怎么滴先能用就行要啥自行车二、先看最终目标这套最小工作流的目标非常明确输入一段 prompt生成一组连续帧再把这些帧合成为 mp4 视频当前这套最小工作流里关键参数是分辨率512 x 512帧数16AnimateDiff motion modulemm_sd_v15_v2.ckpt输出视频节点VHS_VideoCombine输出帧率8 fps也就是说这套工作流的最终结果不是“一张图”而是一个 16 帧、约 2 秒左右的视频片段。因为16 帧8 fps所以视频时长大约是16 / 8 2 秒这非常适合作为新手入门练习。三、先跑通这一部分不讲太深的原理目标只有一个把 AnimateDiff 最小工作流跑起来。1. 需要哪些节点这套最小工作流主要由下面这些节点组成CheckpointLoaderSimpleCLIPTextEncode正向CLIPTextEncode负向EmptyLatentImageADE_AnimateDiffLoaderGen1ADE_UseEvolvedSamplingKSamplerVAEDecodeSaveImageVHS_VideoCombine其中真正和 AnimateDiff 直接相关的核心节点其实只有两个ADE_AnimateDiffLoaderGen1ADE_UseEvolvedSampling2. 关键模型文件至少需要两类模型底模 checkpoint例如dreamshaper_8.safetensorsAnimateDiff motion module当前工作流里使用的是mm_sd_v15_v2.ckpt这个 motion module 是 AnimateDiff 的关键没有它就不是 AnimateDiff 视频链路。3. 最小工作流连接顺序这套工作流的主链路可以概括成CheckpointLoaderSimple ├─ CLIP → 正向/负向 CLIPTextEncode ├─ VAE → VAEDecode └─ MODEL → ADE_AnimateDiffLoaderGen1 ADE_AnimateDiffLoaderGen1 └─ MODEL → ADE_UseEvolvedSampling ADE_UseEvolvedSampling └─ MODEL → KSampler EmptyLatentImage └─ LATENT → KSampler 正向/负向 CLIPTextEncode └─ CONDITIONING → KSampler KSampler └─ LATENT → VAEDecode VAEDecode ├─ IMAGE → SaveImage └─ IMAGE → VHS_VideoCombine如果只想先抄作业这一段最重要。4. 推荐起步参数为了保证新手更容易跑通建议先不要改太多参数。EmptyLatentImagewidth512height512batch size16ADE_AnimateDiffLoaderGen1model_namemm_sd_v15_v2.ckptbeta_scheduleautoselectKSamplersteps24cfg7samplereulerschedulernormaldenoise1.0VHS_VideoCombinefps8输出格式video/h264-mp45. 正负 prompt 示例正向 prompta young woman standing in the wind, cinematic lighting, detailed face, natural motion, slight hair movement负向 promptblurry, low quality, bad anatomy, deformed, distorted face, extra fingers, jitter, flicker这里负向词里已经专门加入了jitterflicker因为视频和单图不一样视频特别怕抖动和闪烁。6. 跑通后的正确结果是什么如果工作流已经跑通应该能得到两类输出1图片序列SaveImage会保存一组逐帧图片文件名前缀可以是animatediff_frames2mp4 视频VHS_VideoCombine会输出一个 h264 编码的 mp4 视频并接收IMAGE作为输入另外还预留了audio输入位这套工作流不是只出图而是同时保留逐帧图片和最终视频。这点非常重要后面解释原理时就会明白为什么这样设计。四、为什么这些节点要这样连接跑通之后才是最关键的部分为什么这套工作流不能乱连这一部分按“节点职责”的方式来讲而不是一上来就讲很抽象的理论。对新手来说这样更容易消化。1.CheckpointLoaderSimple整条链路的起点这个节点会输出三样东西MODELCLIPVAE这三个输出分别负责不同的事。MODEL它是基础扩散模型相当于整条链路里的“主画师”。后面无论是单图还是视频采样真正负责画画的底层能力都来自这个模型。CLIP它负责理解 prompt把文字变成模型可以利用的条件信息。所以它必须连接到正向和负向CLIPTextEncode。VAE它负责把 latent 解码成真正可见的图片。所以它必须连接到VAEDecode而VAEDecode的输入也明确包括samples和vae。CheckpointLoaderSimple不是“加载一个模型就完了”而是同时提供了图像生成链路的三大核心部件。2.CLIPTextEncode为什么要分正向和负向这是 Stable Diffusion 工作流的标准做法但在视频里意义更大。正向 prompt告诉模型应该生成什么内容画面的大方向是什么希望出现什么动作和氛围负向 prompt告诉模型什么是不要的哪些错误特征要尽量避免在当前工作流里负向词包含blurrydeformedjitterflicker这说明负向 prompt 在视频里不仅是“修图”更是在控制帧与帧之间的稳定性。也就是说视频里不仅怕“画坏”还怕“跳帧感太强”。3.EmptyLatentImage为什么 batch size 16 很关键这个节点很容易被低估。当前参数是51251216在普通图像工作流里batch size 往往只是“一次生成多少张图”。但在 AnimateDiff 里它的意义更接近一次生成多少帧。也就是说这里的16不只是“并行生成 16 张图”而是生成一个长度为 16 帧的时间序列。这是理解 AnimateDiff 的一个关键点单图工作流处理的是一个 latentAnimateDiff 工作流处理的是一组带时间关系的 latent所以这个节点不是单纯在“准备画布”而是在准备视频的 latent 帧容器。4.ADE_AnimateDiffLoaderGen1为什么要接在 MODEL 后面这个节点是 AnimateDiff 链路的第一核心节点。当前工作流里它使用的 motion module 是mm_sd_v15_v2.ckpt这个节点输入的是MODEL输出的也是MODEL很多新手第一次会觉得奇怪为什么输入输出都是 MODEL原因在于这个节点不是单纯加载文件而是在“给基础模型增加时序运动能力”。也就是说基础 checkpoint 决定“画什么”motion module 决定“怎么动”ADE_AnimateDiffLoaderGen1的作用就是把这两者结合起来。所以它必须接在CheckpointLoaderSimple.MODEL后面原因非常简单因为 AnimateDiff 不是替代底模而是增强底模。没有底模它无从附着没有 motion module底模又只能出静态图。5.ADE_UseEvolvedSampling为什么还要再经过一次这个节点这一步是很多新手最不理解的地方。既然ADE_AnimateDiffLoaderGen1已经把 motion module 挂到底模上了为什么不直接接KSampler因为“模型具备运动能力” 和 “采样时正确启用时序规则” 是两回事。可以把它理解成ADE_AnimateDiffLoaderGen1改造模型ADE_UseEvolvedSampling改造采样方式当前工作流里ADE_UseEvolvedSampling接收modelm_models留空输出MODEL它的作用是让后面的采样器知道现在处理的不是普通单图采样而是一组带时间关联的帧。如果少了这一步后面的KSampler仍然可能按普通单图批处理的方式去理解这些 latent时序一致性就会失去意义。所以这条链Checkpoint MODEL → ADE_AnimateDiffLoaderGen1 → ADE_UseEvolvedSampling → KSampler本质上做了两件事给模型挂上运动模块让采样器按 AnimateDiff 的逻辑工作这就是为什么这一步不能省。6.KSampler为什么它仍然是核心虽然加入了 AnimateDiff但真正执行扩散去噪的依然是KSampler。它接收四类信息modelpositive conditioningnegative conditioninglatent image这说明 AnimateDiff 并没有另起炉灶而是在 Stable Diffusion 原有采样体系上增加了一层时间建模能力。所以视频不是最后“拼接”出来的而是在KSampler这一步就已经按视频帧序列的方式被生成了。这一点很重要。VHS_VideoCombine只是把图片打包成视频。真正决定“动起来像不像视频”的是前面的采样过程而不是最后的视频节点。7.VAEDecode为什么不能直接输出图片因为KSampler输出的是 latent不是普通图片。所以必须经过VAEDecode.samples - KSampler.LATENTVAEDecode.vae - CheckpointLoaderSimple.VAEVAEDecode的作用就是把模型内部的 latent 表示解码成可以看到的真实图像。这一步完成后才真正得到了逐帧图片。8. 为什么VAEDecode后面同时接SaveImage和VHS_VideoCombine这是一个非常值得新手学习的工作流设计习惯。SaveImage作用是保留逐帧结果。这样可以逐帧看哪里开始跳分析哪一帧出现大变化为后期修帧、补帧做准备当前 JSON 里SaveImage的前缀就是animatediff_frames。VHS_VideoCombine作用是把图像序列按固定帧率合成为 mp4。当前工作流里它接收images和可选audio输入且帧率参数为8。这说明它做的是封装而不是生成运动。所以这两个节点不是重复而是分工明确SaveImage负责调试和检查VHS_VideoCombine负责最终交付五、最后扩展跑通之后该怎么继续学当这套最小工作流已经跑通并且基本理解之后下一步就不是继续乱加节点而是要有顺序地扩展。1. 先把“视频稳定性”学明白虽然这套工作流已经能出视频但很可能会出现每帧构图差异较大镜头远近变化明显服装变化背景漂移角色一致性不够这不是操作错误而是因为纯文本驱动的最小工作流本来就只适合学习原理不适合直接追求高一致性成片。所以第一步要学的是如何写更稳定的 prompt如何减少镜头跳变如何让动作幅度更小2. 从文生视频过渡到图生视频如果发现当前视频“每帧差异太大”这其实非常正常。因为纯文生相当于每一帧都在“重新想象同一个主题”。更稳定的路线通常是先固定一张起始图再让它轻微动起来。这就是图生 AnimateDiff。它比纯文本 AnimateDiff 更适合做角色微动作头发摆动呼吸感轻微镜头推进对教程型学习来说这也是最自然的下一步。3. 再引入更强的一致性约束当最小工作流已经理解清楚之后后面可以继续加ControlNet控制动作结构IPAdapter控制人物风格和一致性FaceID / InstantID锁人物身份LoRA锁角色设定视频后期工具补帧、超分、剪辑、调色但一定要注意顺序先搞懂 AnimateDiff 本身再叠加一致性工具。否则节点一多反而不知道到底是谁在起作用。六、新手最容易误解的 5 个点这一节建议保留因为对新手读者帮助很大。误解 1batch size 一次多出几张图不完全对。在当前 AnimateDiff 工作流里EmptyLatentImage的16更接近16 帧视频片段。误解 2VHS_VideoCombine决定视频动不动不对。VHS_VideoCombine只是把图片按8 fps合成 mp4 。真正决定视频是否有连续动作感的是AnimateDiff motion moduleEvolved SamplingKSampler 的多帧联合采样误解 3AnimateDiff 只是换了个 checkpoint不对。当前工作流里真正承担运动建模的是mm_sd_v15_v2.ckpt这样的 motion module它不是普通底模而是时间维度上的能力模块。误解 4能生成视频就代表视频稳定不对。“能跑通”和“能稳定出片”是两回事。最小工作流适合学习不代表已经具备高一致性成片能力。误解 5节点能接上就说明逻辑对也不对。AnimateDiff 里很多节点虽然名字接近但输入输出类型不一样。所以一定要理解这个节点是在处理模型还是在处理采样还是在处理输出七、常见问题与排查1. 为什么只出图片没有视频大概率是没有加VHS_VideoCombine或者视频节点没有正确接到VAEDecode.IMAGE正确做法是VAEDecode.IMAGE - VHS_VideoCombine.images2. 为什么能出视频但看起来像一堆跳变很大的图片这是纯文本最小工作流最常见的问题。原因通常是prompt 约束不够强没有参考图锚定没有角色一致性控制没有结构控制这不是 AnimateDiff 完全失效而是已经进入了“能跑通但还不稳定”的阶段。3. 为什么mm_sd_v15_v2.ckpt找不到通常是motion module 没放对目录放好了但没重启 ComfyUI当前工作流里ADE_AnimateDiffLoaderGen1使用的就是mm_sd_v15_v2.ckpt4. 为什么会感觉每帧变化太大这其实是很多新手都会遇到的正常现象。因为视频看起来“像动作”前提通常是相邻帧变化小但方向连续。如果每一帧都像重新生成了一张新照片那看起来就不是“动起来”而是“跳来跳去”。这也是为什么最小工作流适合学习原理但后面一定要继续学图生视频和一致性控制。八、这套最小工作流为什么适合做教程主要有三个原因。1. 节点数量少学习成本低虽然有 AnimateDiff但核心新增节点其实只有ADE_AnimateDiffLoaderGen1ADE_UseEvolvedSampling这对新手非常友好。2. 能完整覆盖一条视频生成链路它包含了模型加载文本条件多帧 latentAnimateDiff 注入时序采样解码图片输出视频输出也就是说虽然是最小工作流但已经是一条完整闭环。3. 很适合作为后续进阶的基础后面要加图生输入ControlNetIPAdapter一致性模块都可以在这套链路上逐步升级而不是从头推倒重来。九、总结这篇文章的核心可以概括为AnimateDiff 的视频生成不是“先生成很多图再拼起来”而是在采样阶段就把一组 latent 当作连续帧来联合生成。这也是为什么当前工作流必须这样连接CheckpointLoaderSimple提供MODEL / CLIP / VAECLIPTextEncode提供正负条件EmptyLatentImage提供16帧的 latent 容器ADE_AnimateDiffLoaderGen1把mm_sd_v15_v2.ckpt挂到底模上ADE_UseEvolvedSampling让采样器按时序规则工作并接收model输入KSampler负责真正的多帧联合采样VAEDecode把 latent 变成图像SaveImage保留逐帧结果前缀可设为animatediff_framesVHS_VideoCombine以8 fps合成为 mp4并接收images输入对新手来说更合适的学习顺序是先跑通、再理解、最后扩展。这比一开始就装很多插件、追求复杂成片更容易真正学会 AnimateDiff。