Diffusers
Safetensors
HY / models /predictor_disca.py
Cccccz's picture
Upload batch 46: 223 files (7.45 GiB)
ba798d3 verified
Raw History Blame Contribute Delete
3.25 kB
"""Predictor-DisCa: current/anchor fusion without AR Context Vision K/V."""
from __future__ import annotations
from typing import Mapping
import torch
from .predictor_v2 import HYWorldPlayPredictorV2, PredictorV2Config
class HYWorldPlayPredictorDisCa(HYWorldPlayPredictorV2):
"""Two-block Predictor using only current/anchor image features and text K/V.
This is the project-local ``predictor-disca`` variant. Unlike Predictor-v4,
it neither fuses previous-chunk hidden states nor injects Context Vision K/V.
The cached text K/V remains available because HY-WorldPlay AR vision blocks
require text conditioning.
"""
uses_context_kv = True
uses_context_vision_kv = False
uses_context_prefeature = False
requires_previous_chunk_hidden = False
def _text_only_cache(
self,
values: Mapping[int, Mapping[str, torch.Tensor]],
) -> dict[int, dict[str, torch.Tensor | None]]:
result: dict[int, dict[str, torch.Tensor | None]] = {}
for block_id in self.predictor_config.source_block_ids:
if block_id not in values:
raise ValueError(f"Missing Predictor-DisCa text block {block_id}")
block = values[block_id]
missing = {"k_txt", "v_txt"}.difference(block)
if missing:
raise ValueError(
f"Predictor-DisCa block {block_id} lacks {sorted(missing)}"
)
result[block_id] = {
"k_txt": block["k_txt"],
"v_txt": block["v_txt"],
"text_valid_mask": block.get("text_valid_mask"),
# Deliberately discard online Context Vision K/V and construct
# zero-length vision caches in HYWorldPlayPredictorV2._make_cache.
"k_vision": None,
"v_vision": None,
}
return result
def forward(
self,
*,
target_model_input: torch.Tensor,
anchor_hidden: torch.Tensor,
target_frame_condition: torch.Tensor,
target_viewmats: torch.Tensor,
target_Ks: torch.Tensor,
rope_temporal_size: torch.Tensor | int,
start_rope_start_idx: torch.Tensor | int,
text_kv: Mapping[int, Mapping[str, torch.Tensor]] | None = None,
context_kv: Mapping[int, Mapping[str, torch.Tensor]] | None = None,
previous_chunk_hidden: torch.Tensor | None = None,
) -> dict[str, torch.Tensor]:
if previous_chunk_hidden is not None:
raise ValueError("Predictor-DisCa does not accept previous_chunk_hidden")
source = text_kv if text_kv is not None else context_kv
if source is None:
raise ValueError("Predictor-DisCa requires text_kv or online context_kv")
return super().forward(
target_model_input=target_model_input,
anchor_hidden=anchor_hidden,
target_frame_condition=target_frame_condition,
target_viewmats=target_viewmats,
target_Ks=target_Ks,
rope_temporal_size=rope_temporal_size,
start_rope_start_idx=start_rope_start_idx,
context_kv=self._text_only_cache(source),
previous_chunk_hidden=None,
)