资讯动态

Diffusers 中的 CogVideoXDPMScheduler:为 CogVideoX 视频生成量身定制的 DPM-Solver++ 多步调度器解析

发布时间:2026/9/10 23:57:58 来源:尧图企业网站定制
Diffusers 中的 CogVideoXDPMScheduler为 CogVideoX 视频生成量身定制的 DPM-Solver 多步调度器解析【免费下载链接】diffusers Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers导读本文围绕 Diffusers 仓库中为 CogVideoX 视频扩散模型专门实现的CogVideoXDPMScheduler对应文档见 multistep_dpm_solver_cogvideox.md展开深入讲解其理论基础、完整配置参数、采样算法细节二阶多步 DPM-Solver以及它与 CogVideoX 文生视频 / 图生视频 / 视频生视频三条 pipeline 的集成方式。读完本文你将掌握该调度器的每个构造参数的作用与默认值、采样循环中step方法的调用契约并能直接在自己的 CogVideoX 推理脚本中正确替换、配置与调优该调度器。一、CogVideoXDPMScheduler 是什么CogVideoXDPMScheduler是 Diffusers 库中面向 CogVideoX 视频生成模型的高阶 ODE 求解调度器其核心实现位于 scheduling_dpm_cogvideox.py类定义见 L134。官方文档对其定位的说明非常明确CogVideoXDPMScheduler基于 DPM-SolverDPM-Solver: A Fast ODE Solver for Diffusion Probabilistic Model Sampling in Around 10 Steps与 DPM-SolverDPM-Solver: Fast Solver for Guided Sampling of Diffusion Probabilistic Models两篇论文专门面向 CogVideoX 模型设计。与通用的DPMSolverMultistepScheduler相比该调度器针对 CogVideoX 的视频潜空间扩散任务做了三处关键定制SNR 偏移SNR shift仿照 Stable Diffusion 3 的做法在初始化阶段对alphas_cumprod施加snr_shift_scale偏移适配高分辨率视频潜空间的信噪比分布二阶多步2M更新采样时缓存上一步预测的原始样本old_pred_original_sample用 DPM-Solver(2M) 的二阶校正公式提升少步数采样质量zero-SNR 支持通过rescale_betas_zero_snr对 beta 序列做零终端信噪比重标定。该调度器在仓库中已注册为公开导出 API见 schedulers/init.py 与 diffusers/init.py可以直接通过from diffusers import CogVideoXDPMScheduler导入使用。二、算法背景从 DPM-Solver 到 DPM-Solver(2M)扩散模型的采样本质上是求解一条概率流 ODEdx / dt ...DPM-Solver 系列论文的核心思想是利用扩散模型输出的噪声估计构造关于 log-SNR即lambda(t)的精确解形式从而用远比 DDPM/DDIM 更少的步数完成采样。在 DPM-Solver 中模型被用来直接预测原始样本x_0去噪结果而不是预测噪声。二阶多步2M形式进一步利用上一步的模型预测结果构造二阶泰勒校正项使每一步的截断误差更小。CogVideoXDPMScheduler正是实现了这种二阶多步更新它在采样循环外维护一个old_pred_original_sample变量把上一时间步预测的x_0传入当前步参与二阶校正项的计算。这一设计在 pipeline_cogvideox.py 的采样循环中有完整的体现。三、完整配置参数详解CogVideoXDPMScheduler的构造函数通过register_to_config注册全部超参数见 scheduling_dpm_cogvideox.py。下面按功能分组列出全部参数、类型、默认值与作用3.1 噪声调度beta schedule参数默认值说明num_train_timesteps1000训练时使用的扩散步数决定 beta 序列长度也是推理时间步的最大值beta_start0.00085beta 起始值注意类 docstring 写的是 0.0001实际构造函数默认值为 0.00085beta_end0.0120beta 终止值docstring 写 0.02实际默认值为 0.0120beta_schedulescaled_linear支持linear、scaled_linear、squaredcos_cap_v2三种trained_betasNone直接传入训练好的 beta 数组传入后将绕过beta_start/beta_endbeta_schedule的三种取值在 scheduling_dpm_cogvideox.py 中实现lineartorch.linspace(beta_start, beta_end, ...)线性插值scaled_linear对beta_start/beta_end开方后线性插值再平方这是潜扩散模型latent diffusion特有的调度也是本类的默认值squaredcos_cap_v2调用betas_for_alpha_bar见 L52生成 Glide 风格的余弦调度底层支持cosine、exp、laplace三种alpha_transform_type。3.2 采样稳定性相关参数默认值说明clip_sampleTrue是否将预测样本裁剪到[-clip_sample_range, clip_sample_range]保证数值稳定性clip_sample_range1.0样本裁剪的最大幅值仅当clip_sampleTrue时生效set_alpha_to_oneTrue最后一步无上一步 alpha时将上一时刻的alphas_cumprod固定为 1否则取第 0 步的 alpha 值见 L239-L243thresholdingFalse是否启用动态阈值dynamic thresholding方法文档明确提示该方法不适用于潜空间扩散模型dynamic_thresholding_ratio0.995动态阈值比率仅当thresholdingTrue时生效sample_max_value1.0动态阈值的阈值上限仅当thresholdingTrue时生效3.3 预测类型与时间步参数默认值说明prediction_typeepsilon模型输出类型epsilon预测噪声、sample直接预测干净样本、v_prediction预测速度见 Imagen Video 论文 2.4 节timestep_spacingleading时间步缩放方式支持leading、linspace、trailing对应论文Common Diffusion Noise Schedules and Sample Steps are Flawed中 Table 2 的三种方案steps_offset0推理时间步的偏移量某些模型族需要rescale_betas_zero_snrFalse是否将 beta 重标定为零终端 SNR见下文 3.4snr_shift_scale3.0SNR 偏移尺度SNR shift是本调度器针对 CogVideoX 的关键定制项3.4 SNR 偏移与 zero-SNR 重标定初始化阶段对噪声调度的两个后处理是理解本调度器专为 CogVideoX 定制的关键实现见 scheduling_dpm_cogvideox.pyself.alphas 1.0 - self.betas self.alphas_cumprod torch.cumprod(self.alphas, dim0) # Modify: SNR shift following SD3 self.alphas_cumprod self.alphas_cumprod / (snr_shift_scale (1 - snr_shift_scale) * self.alphas_cumprod) # Rescale for zero SNR if rescale_betas_zero_snr: self.alphas_cumprod rescale_zero_terminal_snr(self.alphas_cumprod)SNR shift将alphas_cumprod按snr_shift_scale进行非线性缩放。SNR信噪比定义为alpha / (1 - alpha)偏移后整个扩散过程的信噪比曲线整体上移/变形使模型在低噪声端也能获得足够的梯度信息这对大分辨率、大压缩比的视频潜空间尤为重要zero-SNR 重标定rescale_zero_terminal_snr见 L104按论文Common Diffusion Noise Schedules and Sample Steps are Flawed的 Algorithm 1 实现先对alphas_cumprod开方减去末项使最后一步为零再等比缩放回首项原始值最后平方还原。零终端 SNR 允许模型生成极亮、极暗的样本而不是被限制在中等亮度区间。这两个机制决定了采样所使用的alphas_cumprod曲线进而影响set_timesteps与step中所有alpha_prod_*的计算。四、时间步设置set_timesteps 的三种间距策略set_timesteps方法见 scheduling_dpm_cogvideox.py负责在推理前生成离散时间步序列其签名如下def set_timesteps(self, num_inference_steps: int, device: str | torch.device | None None)有两个需要注意的约束若num_inference_steps num_train_timesteps默认 1000会直接抛出ValueError因为模型最多只能处理训练步数对应的时间步三种timestep_spacing策略的行为均返回降序时间步策略生成方式linspace在[0, num_train_timesteps-1]上均匀取num_inference_steps个点round 后反转leading按step_ratio num_train_timesteps // num_inference_steps整数倍取步并叠加steps_offset默认策略trailing从num_train_timesteps开始以-step_ratio步长回退取整再整体减 1生成的timesteps会移动到device上并保存在self.timesteps中供采样循环逐项消费。另外采样所需的final_alpha_cumprod最后一步无前序 alpha 时的回退值set_alpha_to_oneTrue时为 1.0与init_noise_sigma 1.0初始噪声标准差都在构造函数中完成设置。五、采样核心step 方法中的 DPM-Solver(2M) 更新step方法是整个调度器的灵魂见 scheduling_dpm_cogvideox.py。与常规调度器不同它的签名多出两个关键参数def step( self, model_output: torch.Tensor, # 当前时间步的模型输出 old_pred_original_sample: torch.Tensor, # 上一步预测的原始样本 x_02M 二阶校正用 timestep: int, # 当前时间步 timestep_back: int, # 需要回看的时间步即上一步 sample: torch.Tensor, # 当前带噪样本 x_t eta: float 0.0, use_clipped_model_output: bool False, generator: torch.Generator | None None, variance_noise: torch.Tensor | None None, return_dict: bool False, ) - DDIMSchedulerOutput | tuple5.1 第一步由预测类型还原 x_0根据prediction_type从模型输出还原预测原始样本pred_original_sample见 L479-L492epsilonx_0 (x_t - sqrt(1 - alpha_t) * eps) / sqrt(alpha_t)sample模型直接输出x_0v_predictionx_0 sqrt(alpha_t) * x_t - sqrt(1 - alpha_t) * v5.2 第二步计算 log-SNR 差与乘子get_variables见 L331把alphas_cumprod转换成 log-SNR 值lamb log(sqrt(alpha / (1 - alpha))) # 当前步 lamb_next log(sqrt(alpha_prev / (1 - alpha_prev))) # 前一步 h lamb_next - lamb # log-SNR 差步长若提供了alpha_prod_t_back即timestep_back对应的累积 alpha还会额外计算上一步与上上步的 log-SNR 差比值r h_last / h用于二阶校正。get_mult见 L364则基于这些量计算 DPM-Solver 的更新乘子mult1 sqrt((1 - alpha_prev) / (1 - alpha)) * exp(-h) mult2 expm1(-2h) * sqrt(alpha_prev) mult3 1 1/(2r) # 二阶校正系数仅二阶步 mult4 1/(2r) # 二阶校正系数仅二阶步5.3 第三步执行二阶多步更新完成一阶项与二阶校正项的合成见 L494-L514h, r, lamb, lamb_next self.get_variables(alpha_prod_t, alpha_prod_t_prev, alpha_prod_t_back) mult list(self.get_mult(h, r, alpha_prod_t, alpha_prod_t_prev, alpha_prod_t_back)) mult_noise (1 - alpha_prod_t_prev) ** 0.5 * (1 - (-2 * h).exp()) ** 0.5 # 一阶项含随机噪声项mult_noise * noise prev_sample mult[0] * sample - mult[1] * pred_original_sample mult_noise * noise if old_pred_original_sample is None or prev_timestep 0: # 第一步或最后一步省去一次网络评估直接返回 return prev_sample, pred_original_sample else: # 二阶校正用上一步的 x_0 预测修正当前步 denoised_d mult[2] * pred_original_sample - mult[3] * old_pred_original_sample x_advanced mult[0] * sample - mult[1] * denoised_d mult_noise * noise prev_sample x_advanced这段代码的注释L455-L464给出了符号对照pred_original_sample - f_theta(x_t, t)prev_sample - x_{t-1}。注意step的返回值是(prev_sample, pred_original_sample)二元组或DDIMSchedulerOutput其结构定义见 L32-L48包含prev_sample与可选的pred_original_sample两个字段return_dictFalse时返回 tuple。调用方需要把返回的pred_original_sample作为下一次调用的old_pred_original_sample传回这是 2M 算法的必要约定。5.4 其他辅助方法scale_model_inputL262恒等返回sample用于与其他需要按时间步缩放输入的调度器保持接口一致add_noiseL522前向扩散加噪x_t sqrt(alpha_t) * x_0 sqrt(1 - alpha_t) * noise会先把alphas_cumprod移到与输入相同的 device/dtype减少跨设备拷贝get_velocityL565v sqrt(alpha_t) * noise - sqrt(1 - alpha_t) * sample供v_prediction训练使用__len__返回num_train_timesteps。另外需要留意类属性order 1L188虽然算法本身是二阶多步但每个时间步只调用一次网络利用缓存的上一步预测因此order被标记为 1它直接参与 pipeline 中进度条与 warm-up 步数的计算见下文第六节。六、与 CogVideoX Pipeline 的集成方式CogVideoXDPMScheduler在仓库中被以下 pipeline 使用见 pipelines/cogvideo 目录pipeline_cogvideox.py文生视频构造函数的scheduler参数类型标注为CogVideoXDDIMScheduler | CogVideoXDPMSchedulerL185pipeline_cogvideox_image2video.py图生视频pipeline_cogvideox_video2video.py视频生视频此外pipeline_cogview3plus.py、pipeline_consisid.py等也引用了该类。6.1 采样循环中的特殊调用契约在 pipeline_cogvideox.py 的去噪循环中对 DPM 调度器与其他调度器做了分支处理num_warmup_steps max(len(timesteps) - num_inference_steps * self.scheduler.order, 0) with self.progress_bar(totalnum_inference_steps) as progress_bar: # for DPM-solver old_pred_original_sample None for i, t in enumerate(timesteps): ... # compute the previous noisy sample x_t - x_t-1 if not isinstance(self.scheduler, CogVideoXDPMScheduler): latents self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dictFalse)[0] else: latents, old_pred_original_sample self.scheduler.step( noise_pred, old_pred_original_sample, # 回传上一步的 x_0 预测 t, timesteps[i - 1] if i 0 else None, # timestep_back latents, **extra_step_kwargs, return_dictFalse, ) latents latents.to(prompt_embeds.dtype)从源码可以清晰地看到 2M 算法的完整协作模式循环外初始化old_pred_original_sample None每次调用step时传入上一步的pred_original_sample与上一步的时间步timesteps[i-1]第一步传Nonestep内部据此决定执行一阶第一步还是二阶后续步更新并把(prev_sample, pred_original_sample)返回pipeline 将返回的pred_original_sample存回old_pred_original_sample进入下一轮迭代。timesteps[i-1]正是step签名中的timestep_back用于在alphas_cumprod中索引alpha_prod_t_back从而计算二阶校正系数r。6.2 动态 CFG 与进度控制采样循环中还有两点与本调度器间接相关动态引导dynamic CFG当use_dynamic_cfgTrue时pipeline 会按余弦曲线在采样过程中动态调整引导系数L742-L745CogVideoX 的官方推理脚本例如 image2video 示例中pipe(image, prompt, use_dynamic_cfgTrue)常配合本调度器一起使用warm-up 步数num_warmup_steps的计算使用了self.scheduler.order由于本类order1进度条按每步一次网络评估推进L776。6.3 如何切换到该调度器视频生视频 pipeline 的官方示例见 pipeline_cogvideox_video2video.py展示了标准的替换方式——保留原配置并原地换调度器import torch from diffusers import CogVideoXDPMScheduler, CogVideoXVideoToVideoPipeline from diffusers.utils import export_to_video, load_video pipe CogVideoXVideoToVideoPipeline.from_pretrained(THUDM/CogVideoX-5b, torch_dtypetorch.bfloat16) pipe.to(cuda) pipe.scheduler CogVideoXDPMScheduler.from_config(pipe.scheduler.config) input_video load_video(path/to/input.mp4) prompt ( An astronaut stands triumphantly at the peak of a towering mountain. Panorama of rugged peaks and valleys. Very futuristic vibe and animated aesthetic. Highlights of purple and golden colors in the scene. The sky is looks like an animated/cartoonish dream of galaxies, nebulae, stars, planets, moons, but the remainder of the scene is mostly realistic. ) video pipe(videoinput_video, promptprompt, strength0.8, guidance_scale6, num_inference_steps50).frames[0] export_to_video(video, output.mp4, fps8)from_config(pipe.scheduler.config)会继承原调度器配置num_train_timesteps、beta_*、prediction_type等确保与已训练好的模型匹配需要调参时只需在from_config后传入覆盖参数例如pipe.scheduler CogVideoXDPMScheduler.from_config( pipe.scheduler.config, snr_shift_scale3.0, timestep_spacingleading, prediction_typev_prediction, )文生视频与图生视频 pipeline 的用法完全一致from diffusers import CogVideoXPipeline/CogVideoXImageToVideoPipeline官方图生视频示例见 pipeline_cogvideox_image2video.py中pipe(image, prompt, use_dynamic_cfgTrue)即默认配合该调度器工作。七、使用建议与注意事项综合源码与文档使用CogVideoXDPMScheduler时有以下几点需要留意推理步数上限num_inference_steps不能超过num_train_timesteps默认 1000否则set_timesteps会抛错L295-L300官方示例通常使用 50 步这也是 DPM-Solver 系列擅长的少步数区间二阶校正依赖上一步预测不要在采样循环中破坏old_pred_original_sample的回传链路否则退化为低阶更新eta参数对该调度器无效etaDDIM 论文中的随机噪声权重仅对DDIMScheduler生效pipeline 的prepare_extra_step_kwargsL359-L368会检测step是否接受eta参数——虽然本类step签名中声明了eta但实现中并未使用它来引入随机性随机性只来自mult_noise * noise项thresholding不建议开启动态阈值是为像素空间模型设计的对潜空间模型包括 CogVideoX不适用文档原文即有明确提示rescale_betas_zero_snr需要配合训练一致该开关会改变整个噪声调度曲线只有模型在 zero-SNR 设定下训练或与官方 checkpoint 配置一致时才应开启与 DDIM 的互换性CogVideoX pipeline 同时支持CogVideoXDDIMScheduler与本调度器L185当isinstance判断不命中 DPM 分支时走通用step调用路径两条分支的返回契约return_dictFalse取第一个元素保持一致因此可以在两种调度器间平滑切换对比效果。八、小结CogVideoXDPMScheduler是 Diffusers 为 CogVideoX 视频生成场景定制的高阶多步 ODE 求解器它以 DPM-Solver/DPM-Solver 理论为基础通过snr_shift_scale完成针对视频潜空间的 SNR 偏移通过缓存上一步x_0预测的 2M 二阶校正换取少步数下的高质量采样并通过set_alpha_to_one、zero-SNR 重标定、clip_sample等一系列开关保证数值稳定性。其实现集中在一个文件 scheduling_dpm_cogvideox.py 中约 600 行采样循环的协作契约old_pred_original_sample与timestep_back的传递则在 pipeline_cogvideox.py 中清晰可见是理解调度器如何与扩散 pipeline 协作的极佳范本。若要深入对比可同时阅读通用多步求解器 scheduling_dpmsolver_multistep.py其中solver_order2配合algorithm_typedpmsolver即为通用场景下的同类推荐配置以及文档站点的调度器索引页面 index.md若存在获取完整调度器清单。【免费下载链接】diffusers Diffusers: State-of-the-art diffusion models for image, video, and audio generation in PyTorch.项目地址: https://gitcode.com/GitHub_Trending/di/diffusers创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价