Prhub

#30040 [diffusion] feat: add LingBot realtime prompt, KV window, and lazy VAE controls

原始 PR 作者 IPostYellow 合并时间 2026-07-05 11:11 文件变更 13 提交数 16 评论 11 代码增减 +1286 / -57

执行摘要

LingBot 实时新增复合输入、KV 窗口和延迟 VAE

来自 PR body:"Add LingBot realtime support for composite prompt and camera-action inputs in a single event." 此外,为了在实时视频生成中减少 prompt 更新导致的 cross-attention cache 全量清除开销、改善 camera-motion 下的运动连续性、以及降低 VAE 编码计算负担。

值得精读。交互式 KV 窗口的设计模式(重置默认值 + 按需调整)和复合输入原子性校验可复用。关注 causal_attention_cache 的 recent_window_tokens 参数,它是通用层的变化,可能被其他模型使用。

讨论亮点
  1. 状态污染风险:gemini-code-assist[bot] 指出共享 stage 实例的 self.sink_sizeself.sliding_window_num_frames 在请求间需重置,否则状态污染。作者添加 _reset_causal_cache_config_defaults()_apply_causal_cache_overrides 开头恢复默认值。
  2. 复合输入原子性:gemini-code-assist[bot] 建议先验证所有输入类型再更新状态,避免部分失败留下脏数据。作者重写 _ingest_composite_input 为两阶段:先解析验证所有 input_types,再统一更新状态。
  3. 常量文件位置:mickqian 建议将 LingBot 常量从通用 realtime 目录移到模型专属目录。作者将 constants.py 移至 model_specific_stages/lingbot_world/ 下。
  4. 文档完善:mickqian 两次要求为 _visible_attention_kv 方法和 update_and_get_attention_kvrecent_window_tokens 参数添加文档。作者均已完成。

实现拆解

  1. 复合输入事件解析与原子性更新lingbot_world_realtime_adapter.py):新增 _ingest_composite_input 方法,先验证所有 input_types 再依次调用 _ingest_camera_actions_ingest_prompt,确保部分失败时不改变状态。
  2. 交互式 KV 窗口控制lingbot_world_causal_denoising.py):新增 _apply_causal_cache_overrides 重写父类方法,先重置 cache 配置为模型默认值,再调用父类 override,最后通过 _sync_interactive_kv_cache_window 根据 camera-motion 动态调整 sliding_window_num_framessink_size_chunk_has_camera_motion_uses_interactive_kv_window 判断是否需要启用。
  3. 动态 recent_window_tokens 支持causal_attention_cache.py):update_and_get_attention_kv 新增 recent_window_tokens 参数,提取 _visible_attention_kv 方法返回 sink tokens + 动态窗口的 KV 切片,为交互式窗口提供底层实现。
  4. Prompt 更新标记与 cross-attention 重置:adapter 在 ingest prompt 时设置 LINGBOT_PROMPT_UPDATED_CONDITION 条件,denoising stage 据此决定是否重置 cross-attention cache。
  5. 延迟 VAE 编码lingbot_world.py):preprocess_vae_encode 根据 SGLANG_LINGBOT_LAZY_VAE_ENCODE_BLACK_FRAMES 环境变量或配置,只编码首帧和指定数量的填充帧,后续用最后一帧的 latent 重复填充。
  6. 环境变量与配置项:新增 interactive_kv_window_enableinteractive_kv_still_windowinteractive_kv_moving_windowlazy_vae_encode_black_frames 等字段,默认关闭/零。
文件 模块 状态 重要度
python/sglang/multimodal_gen/runtime/pipelines_core/stages/model_specific_stages/lingbot_world/lingbot_world_causal_denoising.py 去噪阶段 modified 9.21
python/sglang/multimodal_gen/runtime/entrypoints/openai/realtime/adapters/lingbot_world_realtime_adapter.py 实时适配器 modified 8.77
python/sglang/multimodal_gen/runtime/layers/kvcache/causal_attention_cache.py KV 缓存 modified 7.7
python/sglang/multimodal_gen/configs/pipeline_configs/lingbot_world.py 配置 modified 7.39
python/sglang/multimodal_gen/test/unit/realtime/test_lingbot_causal_denoising.py 测试 modified 7.82
python/sglang/multimodal_gen/test/unit/realtime/test_realtime_runtime.py 测试 modified 7.04

关键符号

_chunk_has_camera_motion _uses_interactive_kv_window _interactive_kv_window_enabled _apply_causal_cache_overrides _reset_causal_cache_config_defaults _sync_interactive_kv_cache_window _effective_interactive_kv_cache_num_frames _build_realtime_causal_cache_policy receive_camera_control_event_payload parse_camera_control_event_payload receive_parsed_camera_control_event_payload _ingest_camera_actions _ingest_prompt _validate_prompt_payload _ingest_composite_input _parse_composite_input_item _visible_attention_kv preprocess_vae_encode

关键源码片段

python/sglang/multimodal_gen/runtime/layers/kvcache/causal_attention_cache.py core-logic

通用因果 KV 缓存新增 recent_window_tokens 动态窗口选择,影响所有使用该缓存的模型

def _visible_attention_kv(
    self,
    *,
    local_start_index: int,
    updated_local_end: int,
    attn_start_index: int,
    recent_window_tokens: int | None,
    cache_head_slice: slice | None = None,
) -> tuple[torch.Tensor, torch.Tensor]:
    """返回当前 attention 调用可见的 KV 切片。    * 当 ``recent_window_tokens`` 为 ``None`` 时,返回标准滑动窗口
      ``[attn_start_index, updated_local_end)``;
    * 当启用 recent-window 选择时,返回 sink tokens 加上当前 chunk
      以及最多 recent_window_tokens 个历史帧的 KV:
      ``[0, sink_end) + [recent_start, updated_local_end)``;
      其中 ``recent_start = max(sink_end, local_start_index - recent_window_tokens)``。
    * 传入 ``0`` 则只保留 sink tokens 加当前 chunk。
    * 负值视为 ``None``(全窗口)。
    """
    if recent_window_tokens is None:
        # 标准滑动窗口行为:无动态截断
        visible_k = self.k[:, attn_start_index:updated_local_end]
        visible_v = self.v[:, attn_start_index:updated_local_end]
    else:
        # 动态窗口:保持 sink tokens 和最近的 recent_window_tokens
        sink_end = min(self.sink_tokens, updated_local_end)
        # 计算 recent 部分的起始位置,不能早于 sink_end
        recent_start = max(sink_end, local_start_index - recent_window_tokens)
        # 拼接 sink 部分和 recent 部分
        visible_k = torch.cat(
            [self.k[:, :sink_end], self.k[:, recent_start:updated_local_end]], dim=1
        )
        visible_v = torch.cat(
            [self.v[:, :sink_end], self.v[:, recent_start:updated_local_end]], dim=1
        )
    if cache_head_slice is not None:
        visible_k = visible_k[:, :, cache_head_slice, :]
        visible_v = visible_v[:, :, cache_head_slice, :]
    return visible_k, visible_v

评论区精华

状态污染风险:共享 stage 属性需重置 正确性

gemini-code-assist[bot] 指出 LingBotWorldCausalDMDDenoisingStage 是共享实例,直接修改 self.sink_size 和 sliding_window_num_frames 会导致请求间状态污染。

结论:作者添加 _reset_causal_cache_config_defaults() 在 _apply_causal_cache_overrides 开头恢复默认值,确保请求隔离。 · 已解决

复合输入原子性:部分失败导致脏状态 正确性

gemini-code-assist[bot] 指出 _ingest_composite_input 顺序处理 input_types,若某类型无效会抛出 ValueError 但之前类型已更新状态。

结论:作者重写 _ingest_composite_input 先解析验证所有 input_types,再统一更新状态,保证原子性。 · 已解决

常量文件位置:迁移到模型专属目录 设计

mickqian 建议将 LingBot 常量从通用 realtime 文件夹移到模型专属目录下。

结论:作者将 constants.py 移至 model_specific_stages/lingbot_world/constants.py。 · 已解决

文档完善:_visible_attention_kv 和 recent_window_tokens 参数 documentation

mickqian 两次要求为 _visible_attention_kv 方法和 update_and_get_attention_kv 的 recent_window_tokens 参数添加详细文档。

结论:作者添加了完整的 docstring 和注释,解释 None/0/ 正值的含义及返回的 token 范围。 · 已解决

风险与影响

状态重置有效性:虽然已增加 _reset_causal_cache_config_defaults(),但若模型 arch_config 中缺少相关属性,重置可能失败,导致配置残留。并发安全:real time 路径假设请求串行处理,但若引入并行 pipeline,共享 stage 属性仍可能有竞态。性能分支:recent_window_tokens 为 None 时走原路径,开销为零;非 None 时增加一次 token 拼接和判断,影响较小。测试覆盖:新增单元测试覆盖主要逻辑,但缺少集成端到端测试。

用户影响:使用 LingBot-World 实时服务的用户可以传入 composite_input 事件并在一次请求中同时更新 prompt 和 camera-actions;可开启交互式 KV 窗口获得更流畅的运动变化;延迟 VAE 编码减少初始化延迟。系统影响:新增环境变量(SGLANG_LINGBOT_ENABLE_INTERACTIVE_KV_WINDOWSGLANG_LINGBOT_LAZY_VAE_ENCODE_BLACK_FRAMES),默认关闭,不影响现有行为。团队影响:需维护新的配置项和条件分支,但代码有测试保护。

核心缓存层变更 状态管理已修复 配置项默认关闭

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论