CoolFace
Modelpublic

1ST-PLACE-WINNER/MiniMax-H3

sourceHugging Faceotherupdated 2d agoView on Hugging Face
0likes77downloads
base_module.py283 linesDownload Raw Back to video_vae
1# SPDX-License-Identifier: Apache-2.02# Transformer building blocks for the MiniMax H3 visual VAE ViT decoder.3import math4import os5import torch6import torch.nn as nn7from typing import Optional8from diffusers.utils import logging9from diffusers.utils.torch_utils import maybe_allow_in_graph10 11from .attention import Attention12 13logger = logging.get_logger(__name__)  # pylint: disable=invalid-name14 15 16def _env_flag(name, default="0"):17    value = os.environ.get(name, default)18    return str(value).strip().lower() in ("1", "true", "yes", "on")19 20 21def _env_optional_bool(name, default=""):22    value = str(os.environ.get(name, default)).strip().lower()23    if value in ("", "default", "auto", "none", "unset"):24        return None25    return value not in ("0", "false", "no", "off", "disabled")26 27 28def _vit_torch_compile_kwargs(prefix):29    kwargs = {}30    backend = os.environ.get(f"{prefix}_BACKEND", "inductor").strip()31    mode = os.environ.get(f"{prefix}_MODE", "reduce-overhead").strip()32    if backend and backend.lower() not in ("default", "none"):33        kwargs["backend"] = backend34    if mode and mode.lower() not in ("default", "none"):35        kwargs["mode"] = mode36    kwargs["fullgraph"] = _env_flag(f"{prefix}_FULLGRAPH", "0")37    dynamic = _env_optional_bool(f"{prefix}_DYNAMIC")38    if dynamic is not None:39        kwargs["dynamic"] = dynamic40    return kwargs41 42 43 44 45def _vit_norm_input(module, hidden_states):46    if _env_flag("MINIMAX_H3_VAE_DECODER_VIT_FP32_NORM", "1"):47        return hidden_states.float()48    return hidden_states.to(getattr(module.weight, "dtype", hidden_states.dtype))49 50 51 52 53 54 55class FeedForward(nn.Module):56    def __init__(57        self,58        dim: int,59        dim_out: Optional[int] = None,60        mult: int = 4,61        activation_fn: str = "silu",62        bias: bool = True,63        use_gated: bool = True,64        glu_balanced: bool = False,65    ):66        super().__init__()67        ratio = 2 / 3 if (use_gated and glu_balanced) else 168        inner_dim = round(dim * mult * ratio)69        dim_out = dim_out if dim_out is not None else dim70        self.use_gated = use_gated71 72        if use_gated:73            self.w1 = nn.Linear(dim, inner_dim * 2, bias=bias)74        else:75            self.w1 = nn.Linear(dim, inner_dim, bias=bias)76 77        if activation_fn == "silu":78            self.act_fn = nn.SiLU()79        elif activation_fn == "gelu":80            self.act_fn = nn.GELU()81        elif activation_fn == "gelu-approximate":82            self.act_fn = nn.GELU(approximate="tanh")83        else:84            raise ValueError(f"Unsupported activation function: {activation_fn}")85 86        self.w2 = nn.Linear(inner_dim, dim_out, bias=bias)87        self._compile_forward_enabled = _env_flag(88            "MINIMAX_H3_VAE_DECODER_VIT_FF_TORCH_COMPILE", "0"89        )90        self._compile_forward_fatal = _env_flag(91            "MINIMAX_H3_VAE_DECODER_VIT_FF_TORCH_COMPILE_FATAL", "0"92        )93        self._compiled_forward = None94 95    def _forward_impl(self, hidden_states: torch.Tensor) -> torch.Tensor:96        hidden_states = self.w1(hidden_states)97 98        if self.use_gated:99            gate, hidden_states = hidden_states.chunk(2, dim=-1)100            hidden_states = self.act_fn(gate) * hidden_states101        else:102            hidden_states = self.act_fn(hidden_states)103 104        hidden_states = self.w2(hidden_states)105        return hidden_states106 107    def _get_forward_impl(self):108        if not self._compile_forward_enabled:109            return self._forward_impl110        if self._compiled_forward is not None:111            return self._compiled_forward112        if not hasattr(torch, "compile"):113            message = "torch.compile is unavailable; falling back to eager ViT FeedForward"114            if self._compile_forward_fatal:115                raise RuntimeError(message)116            logger.warning(f"[ViTFeedForward] {message}")117            self._compile_forward_enabled = False118            return self._forward_impl119 120        kwargs = _vit_torch_compile_kwargs("MINIMAX_H3_VAE_DECODER_VIT_FF_TORCH_COMPILE")121        try:122            self._compiled_forward = torch.compile(self._forward_impl, **kwargs)123            logger.info(f"[ViTFeedForward] torch.compile enabled kwargs={kwargs}")124        except Exception as exc:125            if self._compile_forward_fatal:126                raise127            logger.warning(128                f"[ViTFeedForward] torch.compile setup failed: {type(exc).__name__}: {exc}; "129                "falling back to eager"130            )131            self._compile_forward_enabled = False132            self._compiled_forward = None133            return self._forward_impl134        return self._compiled_forward135 136    def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:137        forward_impl = self._get_forward_impl()138        try:139            return forward_impl(hidden_states)140        except Exception as exc:141            if (142                self._compile_forward_enabled143                and self._compiled_forward is not None144                and forward_impl is self._compiled_forward145                and not self._compile_forward_fatal146            ):147                logger.warning(148                    f"[ViTFeedForward] compiled forward failed: {type(exc).__name__}: {exc}; "149                    "disabling compile and retrying eager"150                )151                self._compile_forward_enabled = False152                self._compiled_forward = None153                return self._forward_impl(hidden_states)154            raise155 156 157class RotaryEmbeddingND(nn.Module):158    def __init__(self, dim, rotary_base=10000, n_dim=3, use_angle=False):159        super().__init__()160        self.dim = dim161        self.n_dim = n_dim162 163        if dim % (2 * n_dim) != 0:164            raise ValueError(165                f"head_dim {dim} must be divisible by 2 * n_dim {2 * n_dim}"166            )167 168        if use_angle:169            self.angle_scale = 2.0 * math.pi170        else:171            self.angle_scale = 1.0172 173        inv_freq = 1 / rotary_base ** torch.arange(174            0, 1, 2 * n_dim / dim, dtype=torch.float32175        )176        self.register_buffer("inv_freq", inv_freq, persistent=False)177 178    def forward(self, img_ids):179        B, N, D = img_ids.shape180        if D != self.n_dim:181            raise ValueError(f"Expected {self.n_dim} dimensions, got {D}")182 183        with torch.autocast("cuda", enabled=False):184            angles = (185                self.angle_scale186                * img_ids[:, :, :, None]187                * self.inv_freq.to(img_ids.device)[None, None, None, :]188            )189            angles = angles.flatten(2, 3)190            angles = angles.tile(2)191            angles = angles.unsqueeze(2)192 193            cos = torch.cos(angles)194            sin = torch.sin(angles)195 196        return cos.to(dtype=img_ids.dtype), sin.to(dtype=img_ids.dtype)197 198 199@maybe_allow_in_graph200class TransformerBlock(nn.Module):201    def __init__(202        self,203        heads: int,204        dim_head: int,205        embed_dim: Optional[int] = None,206        ffn_glu_balanced: bool = False,207        norm_type: str = "layer_norm",208        norm_affine: bool = True,209        qk_norm_type: str = "rms_norm",210        qk_norm_affine: bool = False,211        ffn_activation_fn: str = "silu",212        ffn_use_gated: bool = True,213        use_scale: bool = True,214        bias: bool = True,215        eps: float = 1e-5,216        **kwargs,217    ):218        super().__init__()219        dim = embed_dim if embed_dim is not None else dim_head * heads220        self.use_scale = use_scale221 222        if norm_type == "layer_norm":223            norm_class = nn.LayerNorm224        elif norm_type == "rms_norm":225            norm_class = nn.RMSNorm226        else:227            raise ValueError(f"unknown norm_type {norm_type}")228 229        self.norm1 = norm_class(230            dim,231            elementwise_affine=norm_affine,232            eps=eps,233        )234        self.attn = Attention(235            heads=heads,236            dim_head=dim_head,237            embed_dim=dim,238            qk_norm_type=qk_norm_type,239            qk_norm_affine=qk_norm_affine,240            bias=bias,241            eps=eps,242            **kwargs,243        )244        if use_scale:245            self.scale1 = nn.Parameter(torch.zeros(dim))246 247        self.norm2 = norm_class(248            dim,249            elementwise_affine=norm_affine,250            eps=eps,251        )252        self.ff = FeedForward(253            dim=dim,254            activation_fn=ffn_activation_fn,255            bias=bias,256            use_gated=ffn_use_gated,257            glu_balanced=ffn_glu_balanced,258        )259        if use_scale:260            self.scale2 = nn.Parameter(torch.zeros(dim))261 262    def forward(263        self,264        hidden_states: torch.FloatTensor,265        rotary_pos_emb: Optional[torch.FloatTensor] = None,266        pack_info: dict = {},267    ):268        norm_hidden_states = self.norm1(_vit_norm_input(self.norm1, hidden_states)).to(hidden_states.dtype)269        attn_output = self.attn(norm_hidden_states, rotary_pos_emb, pack_info)270        if self.use_scale:271            hidden_states = hidden_states + attn_output * self.scale1272        else:273            hidden_states = hidden_states + attn_output274 275        norm_hidden_states = self.norm2(_vit_norm_input(self.norm2, hidden_states)).to(hidden_states.dtype)276        ff_output = self.ff(norm_hidden_states)277        if self.use_scale:278            hidden_states = hidden_states + ff_output * self.scale2279        else:280            hidden_states = hidden_states + ff_output281 282        return hidden_states283