FEATURED · 精选文章

vLLM-Omni 中的 Cache-DiT:为 DiT 扩散流水线接入跨步缓存加速的完整指南

发布时间 / 2026/9/17 11:58:59
来源 / 创域科博编辑部
栏目 / 资讯中心
vLLM-Omni 中的 Cache-DiT:为 DiT 扩散流水线接入跨步缓存加速的完整指南 vLLM-Omni 中的 Cache-DiT为 DiT 扩散流水线接入跨步缓存加速的完整指南【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni本文基于 vLLM-omni 仓库的设计文档 Cache-DiT 展开面向需要为新扩散流水线接入 Cache-DiT 加速的开发者。文章以 Qwen-Image 与 LongCat-Image 为参考实现系统讲解「标准模型零代码接入」与「自定义架构手写 enabler」两条路径并结合 CacheDiTBackend、model_specific.py 与 config.py 等源码还原加速机制、配置投影与注册流程的底层实现。读完本文你将掌握如何判断模型属于哪一类接入模式、如何编写并注册模型专属 enabler、以及如何验证缓存是否真正生效。1. Cache-DiT 是什么用缓存换掉冗余的块级计算Cache-DiT 是面向 Diffusion TransformerDiT的加速库核心思想是相邻去噪步denoising steps产生的中间特征往往高度相似因此可以复用上一时刻的缓存结果跳过部分 Transformer 块的重计算。它支持三种可组合的缓存策略DBCache动态块级缓存Dynamic Block-level caching基于残差差异residual difference动态决定哪些 Transformer 块「计算」、哪些「取缓存」TaylorSeer基于校准的预测用泰勒展开估计块输出允许更大跨度地跳过计算SCMStep Computation Masking按可配置策略mask policy在步骤粒度上动态跳步。在 vLLM-Omni 中Cache-DiT 通过CacheDiTBackend类统一接入。设计文档明确了一条包内导入规范vllm_omni/diffusion/cache目录之外的任何代码必须从包级 API vllm_omni/diffusion/cache/cachedit/init.py 导入 Cache-DiT 符号而不是直接import cache_dit或深入子模块。该__init__.py在包加载时显式调用_register_custom_dit_enablers()保证模型专属 enabler 的注册不依赖「某处碰巧导入了模型符号」的副作用——这一点在 model_specific.py 的register_custom_dit_enablers()文档字符串中有明确说明并有 test_cache_dit.py 中test_custom_cache_dit_enablers_are_registered_explicitly用例对注册表做全量断言。两个核心入口的职责如下源自设计文档的 API 表方法/类用途行为CacheDiTBackend统一的后端接口自动处理 enabler 选择与缓存刷新cache refreshenable_cache_for_dit()对 transformer 应用缓存在 transformer 块上配置 DBCache从源码看CacheDiTBackend的生命周期由三个方法组成见 backend.pyenable(pipeline)按type(pipeline).__name__查CUSTOM_DIT_ENABLERS注册表命中则调用模型专属 enabler未命中则遍历流水线的 DiT 模块默认属性名transformer可用_dit_modules声明多个走默认路径最后记录pipeline._cache_dit_targets并打印Cache-dit enabled successfully on %s日志——这正是后文「验证缓存是否生效」要检查的日志。disable(pipeline)对每个缓存目标调用cache_dit.disable_cache(target)移除 hook让后续请求回到原生 forward。refresh(pipeline, num_inference_steps, verbose)逐个调用enable阶段收集的 refresh 回调把本次请求的步数同步给 Cache-DiT 上下文。Cache-DiT 库本身提供的关键原语API说明BlockAdapter把 Cache-DiT 应用到 transformer 的核心抽象指定 transformer 模块、块列表block list与 forward 签名模式ForwardPattern块 forward 的签名模式Pattern_0、Pattern_1、Pattern_2源码中还出现了Pattern_3等用于更特殊的调用契约ParamsModifier按 transformer 或按块列表定制缓存参数DBCacheConfigDBCache 参数配置warmup 步数、缓存步数上限、阈值等refresh_context()更新缓存上下文每次生成边界generation boundary调用2. 标准模型零代码自动接入大多数 DiT 模型满足以下特征时属于「标准模型」单个 transformer内含一个块的nn.ModuleList标准的 forward 签名可被 Cache-DiT 的自动检测识别。典型例子Qwen-Image、Z-Image。对这类模型不需要任何代码改动CacheDiTBackend会自动使用enable_cache_for_dit()from vllm_omni import Omni # Works automatically for standard models omni Omni( modelQwen/Qwen-Image, # Standard single-transformer model cache_backendcache_dit, cache_config{ Fn_compute_blocks: 1, Bn_compute_blocks: 0, max_warmup_steps: 4, } )2.1 自动路径内部做了什么设计文档给出的enable_cache_for_dit语义流程是构建DBCacheConfig→ 调cache_dit.enable_cache(pipeline.transformer, ...)→ 返回一个refresh_cache_context闭包供后续更新num_inference_steps。仓库中的实际实现backend.py 中enable_cache_for_dit与_build_cache_context_refresh在其之上又做了两层扩展值得了解配置投影用户传入的DiffusionCacheConfig会先经 config.py 中CacheDiTConfig.from_diffusion_config()投影为 Cache-DiT 专属字段再分别转换成DBCacheConfigto_db_cache_config()与可选的 TaylorSeer 校准器配置to_calibrator_config()仅当enable_taylorseerTrue时返回TaylorSeerCalibratorConfig。投影后的默认值CacheDiTConfigdataclass为字段默认值Fn_compute_blocks1Bn_compute_blocks0max_warmup_steps4max_cached_steps-1不限制residual_diff_threshold0.24max_continuous_cached_steps3enable_taylorseerFalsetaylorseer_order1scm_steps_mask_policyNone禁用scm_steps_policydynamicSCM 掩码刷新refresh 回调里如果配置了scm_steps_mask_policy且当前num_inference_steps满足支持条件源码中判断为 8或属于{4, 6}会用cache_dit.steps_mask(...)重新生成步骤掩码后刷新否则走普通刷新。此外force_refresh_step_hint支持在每次请求边界重复下发Cache-DiT 的once策略触发后即清除该 hint源码注释解释了这一点。声明式块适配器即使没有注册 enabler模型也可以在 transformer 类上声明_cache_dit_adapter_config属性_maybe_build_block_adapter()会据此自动构建BlockAdapter。这正是下一节 LongCat 案例的落地方式——「多块列表」模型不必写 enabler用类属性声明即可。3. 自定义架构编写模型专属实现部分模型无法走自动路径设计文档归纳了三类场景单/双 transformer可能使用一个或两个 transformer如 Wan2.2多块列表multi-block-list一个 transformer 内有多组块列表如 LongCat-Image 的transformer_blockssingle_transformer_blocks特殊 forward 模式块执行契约非标准。3.1 示例一单/双 Transformer 模型Wan2.2Wan2.2 可能是单 transformer也可能是双 transformer高噪声步用一个、低噪声步用transformer_2。实现上通过检测transformer_2是否存在来自动判定模式见 enable_cache_for_wan22。与标准路径的关键差异一用BlockAdapter把多个 transformer 连同各自的配置包在一起# Standard: cache_dit.enable_cache(pipeline.transformer, ...) # Custom: Use BlockAdapter to handle multiple transformers cache_dit.enable_cache( BlockAdapter( transformer[pipeline.transformer, pipeline.transformer_2], # Multiple transformers blocks[pipeline.transformer.blocks, pipeline.transformer_2.blocks], forward_pattern[ForwardPattern.Pattern_2, ForwardPattern.Pattern_2], params_modifiers[ ParamsModifier(...), # Config for high-noise transformer ParamsModifier(...), # Config for low-noise transformer (different params) ], ), cache_configdb_cache_config, )源码里这个「不同参数」是实打实的双 transformer 分支中高噪声侧沿用全局max_warmup_steps/max_cached_steps而低噪声侧被单独收紧为max_warmup_steps2, max_cached_steps20因为它的步数只占约 30%。与标准路径的关键差异二refresh_context必须对每个 transformer 分别调用且步数要按噪声边界拆分# Standard: cache_dit.refresh_context(pipeline.transformer, num_inference_stepsN) # Custom: Refresh each transformer with its own step count def refresh_cache_context(pipeline, num_inference_steps, verboseTrue): high_steps, low_steps _split_inference_steps(num_inference_steps) cache_dit.refresh_context(pipeline.transformer, num_inference_stepshigh_steps, ...) cache_dit.refresh_context(pipeline.transformer_2, num_inference_stepslow_steps, ...)对应的真实实现是 model_specific.py 中的_split_wan22_inference_steps()它利用 pipeline 的boundary_ratio与 scheduler 的num_train_timesteps算出边界时间步再用scheduler.set_timesteps(num_inference_steps)生成完整时间步序列逐个统计落在高噪声区间t boundary_timestep的步数返回(num_high_noise_steps, num_low_noise_steps)。3.2 示例二多块列表模型LongCat-ImageLongCat-Image 只有一个 transformer但内部有两组块列表transformer_blocks与single_transformer_blocks。关键差异用BlockAdapter显式指定同一个 transformer 内的多个块列表# Standard: cache_dit.enable_cache(pipeline.transformer, ...) # - Automatically detects single block list # Custom: Use BlockAdapter to specify multiple block lists cache_dit.enable_cache( BlockAdapter( transformerpipeline.transformer, # Single transformer blocks[ pipeline.transformer.transformer_blocks, # Block list 1 pipeline.transformer.single_transformer_blocks, # Block list 2 ], forward_pattern[ForwardPattern.Pattern_1, ForwardPattern.Pattern_1], params_modifiers[modifier], ), cache_configdb_cache_config, )注意对于「单 transformer 多块列表」的模型refresh_context的用法与标准模型完全相同无需拆分。值得强调的是在当前仓库中LongCat并没有采用手写 enabler而是走了更轻量的声明式路线——在 longcat_image_transformer.py 中LongCatImageTransformer2DModel直接以类属性声明_cache_dit_adapter_config CacheDiTAdapterConfig( block_forward_patterns{ transformer_blocks: ForwardPattern.Pattern_1, single_transformer_blocks: ForwardPattern.Pattern_1, }, has_separate_cfgTrue, )CacheDiTAdapterConfigconfig.py的字段为block_forward_patterns块属性名 →ForwardPattern的映射、has_separate_cfg是否条件/无条件两路 CFG 分别 forward默认False、cached_adapter_cls可选指向自定义CachedAdapter类、check_forward_pattern是否校验签名模式默认True。后端在enable()阶段由_maybe_build_block_adapter()读取该属性并自动构建BlockAdapter属性缺失时回退到 Cache-DiT 自带的适配器注册表。从源码结构看这意味着 LongCat 属于「默认 enabler 声明式适配器」组合只有当 forward 契约特殊到声明式描述不够用时如 Wan2.2 需要拆分步数、Krea2 需要按 checkpoint 决定是否has_separate_cfg才需要真正手写 enabler。3.3 注册自定义 enabler若确实需要手写 enabler签名必须是(pipeline, cache_config) - refresh_func或返回携带缓存目标的CacheDiTEnableResult把它加入CUSTOM_DIT_ENABLERS。设计文档给出的注册示意CUSTOM_DIT_ENABLERS { Wan22Pipeline: enable_cache_for_wan22, LongCatImagePipeline: enable_cache_for_longcat_image, YourCustomPipeline: enable_cache_for_your_model, # Add here }对应地当前仓库的真实注册入口是 register_custom_dit_enablers()注册表按流水线类名映射现有条目包括Wan22Pipeline/Wan22I2VPipeline/Wan22TI2VPipeline/Wan22VACEPipeline→enable_cache_for_wan22Wan22S2VPipeline→enable_cache_for_wan22_s2vS2V 的块循环调用契约不同使用Pattern_3并自定义Wan22S2VCachedBlocks以保留逐层音频注入Cosmos3OmniDiffusersPipeline/Cosmos3OmniPipeline→enable_cache_for_cosmos3仅包裹每步执行的 GEN 通路gen_layersUND 通路只算一次、由流水线自身缓存 K/VKrea2Pipeline→enable_cache_for_krea2Magi2Pipeline→enable_cache_for_magi2返回CacheDiTEnableResult只缓存重复执行的 transformer 层栈pre/post adapter 每步仍执行两个工程细节值得注意其一注册表的键必须与pipeline.__class__.__name__完全一致后端就是用这个名字查表的其二enabler 返回CacheDiTEnableResult(refresh..., targets(...))时后端会用其中的targets做 teardown——例如enable_cache_for_magi2缓存的目标是BlockAdapter而非pipeline.transformerdisable()时必须对正确的目标调cache_dit.disable_cache。4. 测试与验证接入完成后用下面的方式做端到端验证from vllm_omni import Omni from vllm_omni.inputs.data import OmniDiffusionSamplingParams # Test your custom model omni Omni( modelyour-model-name, cache_backendcache_dit, cache_config{ Fn_compute_blocks: 1, Bn_compute_blocks: 0, max_warmup_steps: 4, residual_diff_threshold: 0.24, } ) images omni.generate( a beautiful landscape, OmniDiffusionSamplingParams(num_inference_steps50), )验证清单缓存确实生效检查日志中是否出现Cache-dit enabled successfully on xxx——该日志出自 backend.py 的CacheDiTBackend.enable()末尾性能提升文档给出的经验值是约 1.5x–2x配合 SCM 等策略用户指南给出的上限可到 3x图像质量与cache_backendNone的基线输出对比。回归层面tests/diffusion/cache/test_cache_dit.py 提供了可直接参考的 CPU 级单测模式它用pytest.mark.cpu标记、mock TP 组断言注册表内容expected_enablers全量比对并用 Helios、LongCat、Cosmos3 等 transformer 验证has_separate_cfg与_cache_dit_adapter_config声明是否被正确解析tests/diffusion/cache/test_cache_backends.py 则覆盖后端通用生命周期。新增模型接入时仿照这两个文件补一条「enabler 已注册 / 适配器可构建」的断言用例是最低成本的防线。5. 故障排查问题一缓存未生效症状没有加速也没有任何缓存相关日志。原因与对策——enabler 未注册流水线的类名不在CUSTOM_DIT_ENABLERS注册表中。解决确认pipeline.__class__.__name__与注册表键一致大小写、Pipeline后缀都不能差然后把 enabler 加入CUSTOM_DIT_ENABLERS。问题二质量劣化症状与无缓存推理相比生成图像出现伪影或细节损失。原因与对策——缓存参数过于激进。文档建议的保守化调参方向cache_config{ residual_diff_threshold: 0.12, # Lower from 0.24 (try 0.12-0.18) max_warmup_steps: 6, # Increase from 4 (try 6-8) max_continuous_cached_steps: 2, # Reduce if higher }即调低残差阈值让「是否复用缓存」的判定更严格拉长 warmup 让前期步数全部实算缩短连续缓存上限防止误差累积。完整的可调参数表、SCM 掩码策略slow/medium/fast/ultra与 TaylorSeer 用法参见用户指南 Cache-DiT Guide。6. 参考实现速查设计文档列出的参考实现表与当前仓库源码逐一对应模型实现位置模式说明标准 DiTcachedit/backend.pyenable_cache_for_dit默认 enabler单 transformer全自动Wan2.2cachedit/model_specific.pyenable_cache_for_wan22单/双 transformer依据transformer_2是否存在自动识别模式LongCatcachedit/config.pyCacheDiTAdapterConfig声明式块适配器单 transformer 内两组块列表BAGELcachedit/model_specific.pyBagelCachedAdapter自定义 CachedAdapter复杂架构自定义 context manager 与 blocks 包装器安全处理非张量的NaiveCacheencoder hidden states从源码结构看BAGEL 是最重的一类接入BagelCachedContextManager覆写apply_cache、BagelCachedBlocks覆写call_Mn_blocks/compute_or_prune增加isinstance(torch.Tensor)检查避免对非张量缓存做张量运算再由BagelCachedAdapter.create_context与collect_unified_blocks把两者串进 Cache-DiT 的通用适配器框架。它代表「forward 契约特殊到声明式配置不够用」时的最终形态。7. 接入流程小结为一条新扩散流水线接入 Cache-DiT按以下步骤走判断模型类型标准单 transformer 模型零代码自动生效自定义架构才需要 enabler 或声明式适配器如需编写 enabler复杂架构用BlockAdapter描述 transformer/块列表/forward 模式/参数修饰器能用_cache_dit_adapter_config声明解决的优先声明如需注册 enabler加入CUSTOM_DIT_ENABLERS键必须等于流水线类名如需返回 refresh 函数正确处理num_inference_steps变化多 transformer 场景按各自步数分别刷新测试以cache_backendcache_dit跑通生成核对成功日志、加速比与画质。对绝大多数模型默认 enabler 就够用只有真正复杂的架构才值得手写 enabler。更细的运行时参数调优、SCM/TaylorSeer 组合策略与线上服务的--cache-backend cache_dit启动方式可延伸阅读 Cache-DiT Guide。【免费下载链接】vllm-omniA framework for efficient model inference with omni-modality models项目地址: https://gitcode.com/GitHub_Trending/vl/vllm-omni创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻