Instructions to use Cccccz/HY with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use Cccccz/HY with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("Cccccz/HY", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
File size: 7,606 Bytes
5f0e4a2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 | """Read-only Full-DiT capture of targets and joint-window Context prefeatures."""
from __future__ import annotations
from typing import Any, Callable
import torch
from .prefeature_schema import CONTEXT_BLOCK_IDS
from .v2_hooks import PredictorV2TeacherCapture, _clone_cpu
class PredictorPrefeatureTeacherCapture(PredictorV2TeacherCapture):
"""Capture ``img_modulated`` before selected Teacher K/V projections."""
def __init__(
self,
transformer: torch.nn.Module,
*,
on_chunk: Callable[[int, dict[str, torch.Tensor], dict[int, dict[str, torch.Tensor]]], None],
num_steps: int = 4,
context_block_ids: tuple[int, ...] = CONTEXT_BLOCK_IDS,
capture_direct_kv: bool = False,
) -> None:
super().__init__(
transformer,
on_chunk=on_chunk,
num_steps=num_steps,
context_block_ids=context_block_ids,
)
self.capture_direct_kv = bool(capture_direct_kv)
self.pending_context: dict[int, dict[str, torch.Tensor]] | None = None
self.pending_direct_kv: dict[int, dict[str, torch.Tensor]] | None = None
self._prefill_active = False
self._prefill_features: dict[int, torch.Tensor] = {}
self._prefill_metadata: dict[str, torch.Tensor] = {}
def __enter__(self) -> "PredictorPrefeatureTeacherCapture":
super().__enter__()
for block_id in self.context_block_ids:
block = self.transformer.double_blocks[block_id]
self._handles.append(
block.img_attn_k.register_forward_pre_hook(
self._make_k_pre_hook(block_id), with_kwargs=True
)
)
return self
def _make_k_pre_hook(self, block_id: int):
def hook(module, args, kwargs) -> None:
if not self._prefill_active:
return
if block_id in self._prefill_features:
raise RuntimeError(f"Context block {block_id} was captured twice")
if not args or not torch.is_tensor(args[0]):
raise RuntimeError(f"Missing img_modulated input for block {block_id}")
self._prefill_features[block_id] = _clone_cpu(args[0])
return hook
def _transformer_pre(self, module, args, kwargs) -> None:
if kwargs.get("ar_vision_inference", False) and kwargs.get("cache_vision", False):
if self.pending_context is not None or self._prefill_active:
raise RuntimeError("A Context prefill was not consumed before the next prefill")
frame_indices = kwargs.get("context_frame_indices")
if frame_indices is None:
raise RuntimeError("Context prefill lacks context_frame_indices metadata")
if not torch.is_tensor(frame_indices):
frame_indices = torch.tensor(frame_indices, dtype=torch.int64)
frame_indices = frame_indices.detach().to(device="cpu", dtype=torch.int64).reshape(-1)
frames = int(kwargs["hidden_states"].shape[2])
if frame_indices.numel() != frames:
raise ValueError("Context frame metadata does not match prefill tensor")
self._prefill_metadata = {
"selected_frame_indices": frame_indices.contiguous(),
"context_viewmats": _clone_cpu(kwargs["viewmats"]),
"context_Ks": _clone_cpu(kwargs["Ks"]),
"rope_temporal_size": torch.tensor(
[int(kwargs["rope_temporal_size"])], dtype=torch.int64
),
"start_rope_start_idx": torch.tensor(
[int(kwargs["start_rope_start_idx"])], dtype=torch.int64
),
}
self._prefill_features = {}
self._prefill_active = True
return
super()._transformer_pre(module, args, kwargs)
if self.active is not None and self.active.step_id == 0:
self.chunk_context = self._consume_context()
def _transformer_post(self, module, args, kwargs, output) -> None:
if self._prefill_active:
self._prefill_active = False
missing = set(self.context_block_ids).difference(self._prefill_features)
if missing:
raise RuntimeError(f"Missing prefeatures for blocks {sorted(missing)}")
token_counts = {int(value.shape[1]) for value in self._prefill_features.values()}
if len(token_counts) != 1:
raise RuntimeError("Selected Context blocks have different window lengths")
tokens = next(iter(token_counts))
mask = torch.ones((1, tokens), dtype=torch.bool)
self.pending_context = {
block_id: {
"img_modulated": feature,
"context_valid_mask": mask.clone(),
**{name: value.clone() for name, value in self._prefill_metadata.items()},
}
for block_id, feature in self._prefill_features.items()
}
if self.capture_direct_kv:
self.pending_direct_kv = {
block_id: {
"k_vision": _clone_cpu(output[block_id]["k_vision"]),
"v_vision": _clone_cpu(output[block_id]["v_vision"]),
}
for block_id in self.context_block_ids
}
self._prefill_features = {}
self._prefill_metadata = {}
return
super()._transformer_post(module, args, kwargs, output)
def _consume_context(self) -> dict[int, dict[str, torch.Tensor]]:
if self.pending_context is not None:
context = self.pending_context
self.pending_context = None
return context
# The first chunk has no history prefill.
empty_metadata = {
"context_valid_mask": torch.ones((1, 0), dtype=torch.bool),
"selected_frame_indices": torch.empty((0,), dtype=torch.int64),
"context_viewmats": torch.empty((1, 0, 4, 4), dtype=torch.bfloat16),
"context_Ks": torch.empty((1, 0, 3, 3), dtype=torch.bfloat16),
"rope_temporal_size": torch.tensor([0], dtype=torch.int64),
"start_rope_start_idx": torch.tensor([0], dtype=torch.int64),
}
return {
block_id: {
"img_modulated": torch.empty((1, 0, 2048), dtype=torch.bfloat16),
**{name: value.clone() for name, value in empty_metadata.items()},
}
for block_id in self.context_block_ids
}
def _capture_context(self, kv_cache):
"""Capture only case-level text KV; Context features come from block hooks."""
if self.text_context is None:
text_context: dict[int, dict[str, torch.Tensor]] = {}
for block_id in self.context_block_ids:
cache = kv_cache[block_id]
k_txt, v_txt = cache.get("k_txt"), cache.get("v_txt")
if k_txt is None or v_txt is None:
raise RuntimeError(f"Block {block_id} text KV is unavailable")
text_context[block_id] = {
"k_txt": _clone_cpu(k_txt),
"v_txt": _clone_cpu(v_txt),
}
self.text_context = text_context
return {block_id: {} for block_id in self.context_block_ids}
def take_direct_kv(self) -> dict[int, dict[str, torch.Tensor]] | None:
value = self.pending_direct_kv
self.pending_direct_kv = None
return value
|