linoyts HF Staff commited on
Commit
fc62d8e
·
verified ·
1 Parent(s): 51b541a

full LightVAE: lite encoder (remote-code class) + lite decoder; index -> AutoModel

Browse files
modular_model_index.json CHANGED
@@ -46,11 +46,11 @@
46
  ],
47
  "vae": [
48
  "diffusers",
49
- "AutoencoderKLMiniMaxH3",
50
  {
51
  "type_hint": [
52
  "diffusers",
53
- "AutoencoderKLMiniMaxH3"
54
  ],
55
  "pretrained_model_name_or_path": "diffusers-modular/MiniMax-H3-LightVAE",
56
  "subfolder": "vae",
 
46
  ],
47
  "vae": [
48
  "diffusers",
49
+ "AutoModel",
50
  {
51
  "type_hint": [
52
  "diffusers",
53
+ "AutoModel"
54
  ],
55
  "pretrained_model_name_or_path": "diffusers-modular/MiniMax-H3-LightVAE",
56
  "subfolder": "vae",
vae/config.json CHANGED
@@ -1,5 +1,5 @@
1
  {
2
- "_class_name": "AutoencoderKLMiniMaxH3",
3
  "_diffusers_version": "0.40.0.dev0",
4
  "block_out_channels": [
5
  128,
@@ -93,5 +93,8 @@
93
  1,
94
  1
95
  ],
96
- "token_drop": 3
97
- }
 
 
 
 
1
  {
2
+ "_class_name": "AutoencoderKLMiniMaxH3LightVAE",
3
  "_diffusers_version": "0.40.0.dev0",
4
  "block_out_channels": [
5
  128,
 
93
  1,
94
  1
95
  ],
96
+ "token_drop": 3,
97
+ "auto_map": {
98
+ "AutoModel": "modeling_minimax_h3_lightvae.AutoencoderKLMiniMaxH3LightVAE"
99
+ }
100
+ }
vae/diffusion_pytorch_model.safetensors CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:f1c69d47b24b0d5f8bbfba28bb04e93b4c16a3db1c4928e8b94dd7c4bfa3bf1d
3
- size 3969719952
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bccba90f8dfd77cd446e965d70596ab0d52d60a620d5867ddcbdbb7d4f857f6e
3
+ size 3654687872
vae/modeling_minimax_h3_lightvae.py ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Remote-code VAE for the LightVAE build of MiniMax-H3: stock-shaped H3 video VAE whose encoder is replaced by
2
+ lightx2v's block-pruned Lite encoder and whose ViT decoder is pruned 36 -> 12 blocks.
3
+
4
+ `AutoencoderKLMiniMaxH3LightVAE` subclasses the merged `AutoencoderKLMiniMaxH3`, so it is a drop-in `vae` component
5
+ (the latent interface is identical). The decoder depth is set by `decoder_num_layers=12` in the config; the encoder is
6
+ rebuilt here because lightx2v's Lite encoder is structurally pruned (block 5's first resnet is a bare 1x1 channel
7
+ projection), which a scalar `layers_per_block` cannot express.
8
+ """
9
+ from __future__ import annotations
10
+
11
+ import torch
12
+ import torch.nn as nn
13
+
14
+ from diffusers import AutoencoderKLMiniMaxH3
15
+ from diffusers.models.autoencoders.autoencoder_kl_minimax_h3 import (
16
+ MiniMaxH3VideoCausalConv3d,
17
+ MiniMaxH3VideoDownBlock3d,
18
+ MiniMaxH3VideoEncoder3d,
19
+ MiniMaxH3VideoGroupNorm,
20
+ MiniMaxH3VideoResnetBlock3d,
21
+ )
22
+
23
+
24
+ class _ShortcutResnet(nn.Module):
25
+ """A resnet pruned to its 1x1 channel-projection shortcut alone; forward is `conv_shortcut(x)`."""
26
+
27
+ def __init__(self, in_channels: int, out_channels: int) -> None:
28
+ super().__init__()
29
+ self.conv_shortcut = MiniMaxH3VideoCausalConv3d(in_channels, out_channels, kernel_size=1)
30
+
31
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
32
+ return self.conv_shortcut(hidden_states)
33
+
34
+
35
+ class _CustomDownBlock(nn.Module):
36
+ """A down block with an explicit resnet list and no downsampler."""
37
+
38
+ def __init__(self, resnets: list[nn.Module]) -> None:
39
+ super().__init__()
40
+ self.resnets = nn.ModuleList(resnets)
41
+ self.downsamplers = None
42
+
43
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
44
+ for resnet in self.resnets:
45
+ hidden_states = resnet(hidden_states)
46
+ return hidden_states
47
+
48
+
49
+ class _LiteEncoder3d(MiniMaxH3VideoEncoder3d):
50
+ """lightx2v Lite H3 encoder. Blocks 0-4 are standard single-resnet down blocks (0-3 keep their downsampler);
51
+ block 5 is a projection-only resnet (512 -> 1024) followed by one full resnet (1024 -> 1024), no downsampler."""
52
+
53
+ def __init__(
54
+ self,
55
+ in_channels: int,
56
+ out_channels: int,
57
+ block_out_channels,
58
+ spatial_downsample_factors,
59
+ temporal_downsample_factors,
60
+ norm_num_groups: int = 32,
61
+ norm_eps: float = 1e-6,
62
+ spatial_padding_mode: str = "reflect",
63
+ ) -> None:
64
+ nn.Module.__init__(self)
65
+ self.conv_in = MiniMaxH3VideoCausalConv3d(
66
+ in_channels, block_out_channels[0], kernel_size=3,
67
+ spatial_padding=1, temporal_padding=2, spatial_padding_mode=spatial_padding_mode,
68
+ )
69
+ block_in_channels = (block_out_channels[0],) + tuple(block_out_channels[:-1])
70
+ down_blocks = []
71
+ for i in range(len(block_out_channels) - 1):
72
+ down_blocks.append(
73
+ MiniMaxH3VideoDownBlock3d(
74
+ in_channels=block_in_channels[i],
75
+ out_channels=block_out_channels[i],
76
+ num_layers=1,
77
+ temporal_downsample_factor=temporal_downsample_factors[i],
78
+ spatial_downsample_factor=spatial_downsample_factors[i],
79
+ norm_num_groups=norm_num_groups,
80
+ norm_eps=norm_eps,
81
+ spatial_padding_mode=spatial_padding_mode,
82
+ )
83
+ )
84
+ down_blocks.append(
85
+ _CustomDownBlock(
86
+ [
87
+ _ShortcutResnet(block_in_channels[-1], block_out_channels[-1]),
88
+ MiniMaxH3VideoResnetBlock3d(
89
+ in_channels=block_out_channels[-1],
90
+ out_channels=block_out_channels[-1],
91
+ norm_num_groups=norm_num_groups,
92
+ norm_eps=norm_eps,
93
+ spatial_padding_mode=spatial_padding_mode,
94
+ ),
95
+ ]
96
+ )
97
+ )
98
+ self.down_blocks = nn.ModuleList(down_blocks)
99
+ self.norm_out = MiniMaxH3VideoGroupNorm(norm_num_groups, block_out_channels[-1], eps=norm_eps, affine=True)
100
+ self.conv_out = MiniMaxH3VideoCausalConv3d(
101
+ block_out_channels[-1], out_channels, kernel_size=3,
102
+ spatial_padding=1, temporal_padding=2, spatial_padding_mode=spatial_padding_mode,
103
+ )
104
+
105
+
106
+ class AutoencoderKLMiniMaxH3LightVAE(AutoencoderKLMiniMaxH3):
107
+ """Stock H3 VAE with the Lite encoder swapped in. Decoder depth comes from `decoder_num_layers` in the config.
108
+
109
+ The parameter list is declared explicitly (not ``**kwargs``) so diffusers' ``from_config`` introspection forwards
110
+ every config key to ``super().__init__`` (which is ``@register_to_config``); the Lite encoder is then built in place.
111
+ """
112
+
113
+ def __init__(
114
+ self,
115
+ in_channels: int = 3,
116
+ out_channels: int = 3,
117
+ latent_channels: int = 24,
118
+ block_out_channels=(128, 256, 256, 512, 512, 1024),
119
+ layers_per_block: int = 2,
120
+ spatial_downsample_factors=(2, 2, 2, 2, 1, 1),
121
+ temporal_downsample_factors=(1, 2, 2, 1, 1, 1),
122
+ norm_num_groups: int = 32,
123
+ norm_eps: float = 1e-6,
124
+ spatial_padding_mode: str = "reflect",
125
+ decoder_num_layers: int = 36,
126
+ decoder_num_attention_heads: int = 32,
127
+ decoder_attention_head_dim: int = 64,
128
+ decoder_num_register_tokens: int = 4,
129
+ decoder_ffn_mult: int = 4,
130
+ decoder_rope_theta: float = 100.0,
131
+ decoder_rope_dim_ratio: float = 0.75,
132
+ decoder_norm_eps: float = 1e-5,
133
+ clip_length: int = 17,
134
+ token_drop: int = 3,
135
+ latents_mean=(0.0,) * 24,
136
+ latents_std=(1.0,) * 24,
137
+ ):
138
+ super().__init__(
139
+ in_channels=in_channels,
140
+ out_channels=out_channels,
141
+ latent_channels=latent_channels,
142
+ block_out_channels=block_out_channels,
143
+ layers_per_block=layers_per_block,
144
+ spatial_downsample_factors=spatial_downsample_factors,
145
+ temporal_downsample_factors=temporal_downsample_factors,
146
+ norm_num_groups=norm_num_groups,
147
+ norm_eps=norm_eps,
148
+ spatial_padding_mode=spatial_padding_mode,
149
+ decoder_num_layers=decoder_num_layers,
150
+ decoder_num_attention_heads=decoder_num_attention_heads,
151
+ decoder_attention_head_dim=decoder_attention_head_dim,
152
+ decoder_num_register_tokens=decoder_num_register_tokens,
153
+ decoder_ffn_mult=decoder_ffn_mult,
154
+ decoder_rope_theta=decoder_rope_theta,
155
+ decoder_rope_dim_ratio=decoder_rope_dim_ratio,
156
+ decoder_norm_eps=decoder_norm_eps,
157
+ clip_length=clip_length,
158
+ token_drop=token_drop,
159
+ latents_mean=latents_mean,
160
+ latents_std=latents_std,
161
+ )
162
+ self.encoder = _LiteEncoder3d(
163
+ in_channels=in_channels,
164
+ out_channels=2 * latent_channels,
165
+ block_out_channels=block_out_channels,
166
+ spatial_downsample_factors=spatial_downsample_factors,
167
+ temporal_downsample_factors=temporal_downsample_factors,
168
+ norm_num_groups=norm_num_groups,
169
+ norm_eps=norm_eps,
170
+ spatial_padding_mode=spatial_padding_mode,
171
+ )