From bad8f78d0fca453c9647bdeec4e0cc4ae0b5c0d1 Mon Sep 17 00:00:00 2001 From: abhinav sengar Date: Mon, 10 Aug 2026 10:52:34 +0530 Subject: [PATCH] Fix login bug --- .../dac_alias_free_filter.cpython-314.pyc | Bin 0 -> 4988 bytes .../dac_alias_free_resample.cpython-314.pyc | Bin 0 -> 3499 bytes .../__pycache__/dac_attn_proj.cpython-314.pyc | Bin 0 -> 6434 bytes FL2VA/audio_vae/dac_alias_free_filter.py | 8 +- FL2VA/audio_vae/dac_attn_proj.py | 32 +- FL2VA/audio_vae/dac_audio_vae.py | 33 +- FL2VA/transformer/config.json | 8 + README.md | 62 ++++ .../dac_alias_free_filter.cpython-314.pyc | Bin 0 -> 4989 bytes .../dac_alias_free_resample.cpython-314.pyc | Bin 0 -> 3500 bytes .../__pycache__/dac_attn_proj.cpython-314.pyc | Bin 0 -> 6435 bytes .../__pycache__/dac_audio_vae.cpython-314.pyc | Bin 0 -> 13429 bytes Ref2VA/audio_vae/dac_alias_free_filter.py | 8 +- Ref2VA/audio_vae/dac_attn_proj.py | 32 +- Ref2VA/audio_vae/dac_audio_vae.py | 33 +- Ref2VA/transformer/config.json | 8 + audio_vae/config.json | 1 + requirements.txt | 5 + scripts/readme/full-2k-i2va-h3-base.sh | 8 +- scripts/readme/full-2k-i2va-h3-context-ir.sh | 2 +- .../readme/full-2k-i2va-h3-regenerate-2k.sh | 2 +- ...t-by-directly-calling-open-platform-api.sh | 2 +- ...t-by-directly-calling-open-platform-api.sh | 2 +- ...3-api-2k-in-open-platform-for-reference.sh | 2 +- scripts/readme/full-2k-ref2va-h3-base.sh | 8 +- .../readme/full-2k-ref2va-h3-context-ir.sh | 2 +- ...t-by-directly-calling-open-platform-api.sh | 2 +- ...t-by-directly-calling-open-platform-api.sh | 2 +- scripts/readme/full-2k-t2va-h3-base.sh | 8 +- scripts/readme/full-2k-t2va-h3-context-ir.sh | 2 +- .../readme/full-2k-t2va-h3-regenerate-2k.sh | 2 +- ...t-by-directly-calling-open-platform-api.sh | 2 +- ...t-by-directly-calling-open-platform-api.sh | 2 +- .../readme/reproducible-768p-fl2va-request.sh | 2 +- .../reproducible-768p-ref2va-request.sh | 2 +- .../readme/reproducible-768p-t2va-request.sh | 2 +- ...t_regressions.cpython-314-pytest-9.1.1.pyc | Bin 0 -> 56123 bytes tests/test_regressions.py | 338 ++++++++++++++++++ tests/verify_fixes.py | 132 +++++++ 39 files changed, 687 insertions(+), 67 deletions(-) create mode 100644 FL2VA/audio_vae/__pycache__/dac_alias_free_filter.cpython-314.pyc create mode 100644 FL2VA/audio_vae/__pycache__/dac_alias_free_resample.cpython-314.pyc create mode 100644 FL2VA/audio_vae/__pycache__/dac_attn_proj.cpython-314.pyc create mode 100644 Ref2VA/audio_vae/__pycache__/dac_alias_free_filter.cpython-314.pyc create mode 100644 Ref2VA/audio_vae/__pycache__/dac_alias_free_resample.cpython-314.pyc create mode 100644 Ref2VA/audio_vae/__pycache__/dac_attn_proj.cpython-314.pyc create mode 100644 Ref2VA/audio_vae/__pycache__/dac_audio_vae.cpython-314.pyc create mode 100644 tests/__pycache__/test_regressions.cpython-314-pytest-9.1.1.pyc create mode 100644 tests/test_regressions.py create mode 100644 tests/verify_fixes.py diff --git a/FL2VA/audio_vae/__pycache__/dac_alias_free_filter.cpython-314.pyc b/FL2VA/audio_vae/__pycache__/dac_alias_free_filter.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2284ad97075f07d42da11c846159eb582a9e764c GIT binary patch literal 4988 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 XBJ}CA#BQQ;ZuF*jUHlvYYRLI7&_?ui literal 0 HcmV?d00001 diff --git a/FL2VA/audio_vae/__pycache__/dac_alias_free_resample.cpython-314.pyc b/FL2VA/audio_vae/__pycache__/dac_alias_free_resample.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a5775fbdc4d7e83b5278d6253b546bbc67aff577 GIT binary patch literal 3499 zcmcgu-ES0C6u)=&Yj(S(-7al+p$2NTvZ1uHTSNtg@)b~M>Oj|zE**y5Svqz)yWE+j zMH16D7bQX;NNXaoJV76f{S)egk;h%_x|<0o2_^)ejG$;@qUX-X?$T6=K5!rIoO|xM z=bn4#{C?+dUeoA9(0+=aefLi{LU-uEZZ1o>{~-v|XcTey5ITr8yn)IL$c*Ly8FP+9 z&Vw$^WynsD-I{v?YDJxhbG0MReH;(1v7Oew{SH&sSi{l-mh59Jy&UdB5$`>^a4>>( zUpl8GH7TPAGK`uIXC{XPRXrfdnn<>$K(%&UkW`WIs-z_Ow53nhVnE0W0^Q#US^)`o z8XZR(=8(pW`ZPxy%3#hJM={Ldb|kYh)|?#Ejx-nN(A;sXdE#gX)>sJ3rTd1nM}>*3 zEN)FDZNGFcxLCRmd;dKKp`EZpf@+O+6nvk6i|)6^8_=803Rsyf&ZIjL>OcvPtr>+q zd+Z+r%2B4LY7JhnX$RUmn`~`+6!#cOV$OpndLE;} zYQHVlzM!qMxApZA{ll)SudDO*=xKXw*YJg?s(19nqr&x({A-NWyG{h{;5iJp-C&Op z0PE55>UYICwp$sNb$~@{ZM`i));jvFzqkQ$h-T>EU32#KuDda#-Psj!=W)&Vck!8WbWbt5XX)72BVUe`qCG$&WIxPxLIuMJ z+RDV3o^`bu>cc1(ULs~?DJf_oR4V60CM8A~LU}=VpCXxDR_(p_7qo~EU^gaYMI9d? zYhl{Jh~AvcC}(($2#T7`s8DiDz_`V!te~U}KZMc(X@f4}Bq8b;PwAM~@m`gl4Y0J4 z(7<$0IzuJ}lG0o1AYtj+!9e{0x@lBt3C=z@^W1q)9_NK0{f!s*f4Kir=j_&V;fnwjlQs)wPqvhMa!-e6u z%fly%!zT*TyUXG6l7F18Ys@Dv_0PUC^9tnt;MKwTU4>w@uqIma$MX1gQ*)jr9S}>z zZE}Qh9o18sWGef4{&Y@|t(hhs9tT9#WJwW~ z49^?+`1fTd zl~rFZG(>|Gz6W8&%LQQYq+c$HYMp#+)uc4C3Q<7av|wHTjxnmEbC6IDB=m0pUg%bY zzHUq?Q6h|5Jr-ws%*8ZF8-ccU0Qf%?)2ZR|$ro`jkVPilI#pysnTh@BG+rq}3w@fM%5O zuQ!1J1pp0MuSpnITO8YO%q$aUfW|Pq!^z7qA8{BIL%KoMnW-t2`U8qF4{Km)?IVY^ z_+<;28Oaa)(ipgyIG>p7{D{vpx0?cauL*XCdBt=W^GY{Ui7q7D=<0e=qO&i}y!0Ca(Qx`VQ3jF` literal 0 HcmV?d00001 diff --git a/FL2VA/audio_vae/__pycache__/dac_attn_proj.cpython-314.pyc b/FL2VA/audio_vae/__pycache__/dac_attn_proj.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dda6dd9244f47f9f9d052a587f5821ac1c9262c4 GIT binary patch literal 6434 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 uba)ugtaxi?Zf27}c5`1h`3He49p>L7CUeXH literal 0 HcmV?d00001 diff --git a/FL2VA/audio_vae/dac_alias_free_filter.py b/FL2VA/audio_vae/dac_alias_free_filter.py index ad02595..26359fc 100644 --- a/FL2VA/audio_vae/dac_alias_free_filter.py +++ b/FL2VA/audio_vae/dac_alias_free_filter.py @@ -49,11 +49,11 @@ def kaiser_sinc_filter1d(cutoff, half_width, kernel_size): # return filter [1,1 filter_ = torch.zeros_like(time) else: filter_ = 2 * cutoff * window * sinc(2 * cutoff * time) - """ - Normalize filter to have sum = 1, otherwise we will have a small leakage of the constant component in the input signal. - """ + # Normalize filter to have sum = 1, otherwise we will have a small + # leakage of the constant component in the input signal. filter_ /= filter_.sum() - filter = filter_.view(1, 1, kernel_size) + # Always reshape into [1, 1, kernel_size] so the return is never undefined. + filter = filter_.view(1, 1, kernel_size) return filter diff --git a/FL2VA/audio_vae/dac_attn_proj.py b/FL2VA/audio_vae/dac_attn_proj.py index d3b9b1f..6f1cd2e 100644 --- a/FL2VA/audio_vae/dac_attn_proj.py +++ b/FL2VA/audio_vae/dac_attn_proj.py @@ -29,15 +29,19 @@ class CausalAttention(nn.Module): def __init__(self, in_dim, out_dim, num_heads): super().__init__() if in_dim > out_dim: - # assert in_dim // num_heads == out_dim + # Projection compresses in_dim → out_dim after attention. + # QKV operates in in_dim space so head_dim = in_dim // num_heads. self.head_dim = in_dim // num_heads + self.qkv_out_dim = in_dim self.qkv = nn.Linear(in_dim, in_dim * 3, bias=False) self.q_bias = nn.Parameter(torch.zeros(in_dim)) self.v_bias = nn.Parameter(torch.zeros(in_dim)) self.register_buffer("zero_k_bias", torch.zeros(in_dim)) else: - # assert out_dim // num_heads == in_dim + # Projection expands (or keeps) in_dim → out_dim after attention. + # QKV operates in out_dim space so head_dim = out_dim // num_heads. self.head_dim = out_dim // num_heads + self.qkv_out_dim = out_dim self.qkv = nn.Linear(in_dim, out_dim * 3, bias=False) self.q_bias = nn.Parameter(torch.zeros(out_dim)) self.v_bias = nn.Parameter(torch.zeros(out_dim)) @@ -47,21 +51,27 @@ def __init__(self, in_dim, out_dim, num_heads): self.out_dim = out_dim self.num_heads = num_heads self.scale = self.head_dim**-0.5 - self.proj = nn.Linear(out_dim, out_dim) + # Final linear maps from the QKV output space to out_dim. + self.proj = nn.Linear(self.qkv_out_dim, out_dim) def forward(self, x: torch.Tensor) -> torch.Tensor: B, N, C = x.shape - qkv = F.linear(input=x, weight=self.qkv.weight, bias=torch.cat((self.q_bias, self.zero_k_bias, self.v_bias))) - q, k, v = qkv.reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4).unbind(0) + qkv = F.linear( + input=x, + weight=self.qkv.weight, + bias=torch.cat((self.q_bias, self.zero_k_bias, self.v_bias)), + ) + q, k, v = ( + qkv.reshape(B, N, 3, self.num_heads, self.head_dim) + .permute(2, 0, 3, 1, 4) + .unbind(0) + ) x = scaled_dot_product_attention(q, k, v, attn_mask=None, dropout_p=0.0, is_causal=True) - if self.in_dim > self.out_dim: - x = torch.mean(x, dim=1) - if self.in_dim // self.num_heads != self.out_dim: - x = nn.functional.adaptive_avg_pool1d(x, self.out_dim) - else: - x = x.transpose(1, 2).reshape(B, N, -1) + # Always reshape to [B, N, qkv_out_dim] so self.proj receives the + # correct input dimension regardless of whether in_dim > out_dim or not. + x = x.transpose(1, 2).reshape(B, N, self.qkv_out_dim) x = self.proj(x) return x diff --git a/FL2VA/audio_vae/dac_audio_vae.py b/FL2VA/audio_vae/dac_audio_vae.py index aebdfb7..d2a9b55 100644 --- a/FL2VA/audio_vae/dac_audio_vae.py +++ b/FL2VA/audio_vae/dac_audio_vae.py @@ -43,6 +43,17 @@ def forward(self, x): def init_weights(m): """Initialize Conv1d layers, including those wrapped with ``weight_norm``. + This is the canonical initializer for ``DacAudioVAE`` (encoder + decoder). + It uses ``trunc_normal_`` with ``std=0.02`` and explicitly zeroes biases, + matching the intended training configuration for this model family. + + Note: ``dac_bigvgan.py`` / ``dac_utils.py`` also contain an ``init_weights`` + helper (``std=0.01``, ``normal_``) used by BigVGAN's own module-level + ``apply()`` calls. Because ``DacAudioVAE.__init__`` calls + ``self.apply(init_weights)`` *after* all sub-modules (including BigVGAN) + have been constructed, this function is the one that takes final effect on + every ``nn.Conv1d`` in the whole model graph. + The encoder (``WNConv1d``) and decoder (BigVGAN) both wrap ``nn.Conv1d`` with ``torch.nn.utils.parametrizations.weight_norm``. Under that parametrization ``m.weight`` is computed on access from @@ -74,9 +85,15 @@ def __init__(self, dim: int = 16, dilation: int = 1): def forward(self, x): y = self.block(x) - pad = (x.shape[-1] - y.shape[-1]) // 2 - if pad > 0: - x = x[..., pad:-pad] + diff = x.shape[-1] - y.shape[-1] + if diff > 0: + # Crop the residual path to match the convolved output length. + # Use explicit left/right amounts to handle both even and odd + # differences safely (avoids the x[..., pad:-pad] pattern which + # silently drops an extra sample when diff is odd). + pad_left = diff // 2 + pad_right = diff - pad_left # == pad_left + (diff % 2) + x = x[..., pad_left : x.shape[-1] - pad_right] return x + y @@ -93,7 +110,11 @@ def __init__(self, dim: int = 16, stride: int = 1): dim, kernel_size=2 * stride, stride=stride, - padding=math.ceil(stride / 2), + # For kernel_size = 2*stride the correct "same-length" padding + # is (kernel_size - stride) // 2 = stride // 2. + # The previous math.ceil(stride / 2) was off by 1 for odd + # strides (e.g. stride=5 gave padding=3 instead of 2). + padding=stride // 2, ), ) @@ -209,7 +230,9 @@ def __init__( if self.attn_proj: self.pre_block = AttnProjection(latent_dim, self.attn_proj_dim, num_heads=8) - self.sample_rate = sample_rate + # Apply canonical weight initialization to all Conv1d layers in the + # entire model graph (encoder + BigVGAN decoder). This single pass + # uses trunc_normal_(std=0.02) and is the intended final initializer. self.apply(init_weights) def preprocess(self, audio_data, sample_rate): diff --git a/FL2VA/transformer/config.json b/FL2VA/transformer/config.json index 94cc6ca..c7dbf0e 100644 --- a/FL2VA/transformer/config.json +++ b/FL2VA/transformer/config.json @@ -4,11 +4,15 @@ "hidden_size": 5376, "num_layers": 50, "token_refiner_num_layers": 2, + "num_refiner_layers": 2, "num_attention_heads": 56, "attention_head_dim": 128, "ffn_hidden_size": 14336, + "ffn_dim": 14336, "latents_dim": 24, + "in_channels": 24, "audio_latents_dim": 32, + "audio_in_channels": 32, "patch_size": [ 1, 2, @@ -16,11 +20,15 @@ ], "text_dim": 5120, "timestep_input_dim": 256, + "freq_dim": 256, "time_embed_hidden_size": 5376, + "time_embed_hidden_dim": 5376, "time_embed_dim": 2688, "adaln_out_features": 96768, "final_adaln_out_features": 10752, "rope_inv_freq_len": 16, + "rope_freq_dim": 16, + "rope_theta": 10000.0, "norm_eps": 1e-05, "qk_norm_eps": 1e-05, "final_norm_eps": 1e-05 diff --git a/README.md b/README.md index 9789aa4..9c1403c 100644 --- a/README.md +++ b/README.md @@ -215,6 +215,68 @@ hf download MiniMaxAI/MiniMax-H3 --include "model_index.json" "FL2VA/*" "Ref2VA/ hf download MiniMaxAI/MiniMax-H3 --include "model_index.json" "FL2VA/*" --local-dir MiniMax-H3 ``` +#### Required Model Weights & Download Instructions + +> **Important:** This repository contains only code and configuration files. +> The model weights (`.safetensors` files) are hosted separately on Hugging Face +> and must be downloaded before running inference. + +**Step 1 — Install dependencies** + +```bash +pip install -r requirements.txt +# For SGLang / vLLM, also install the respective package as documented in the +# framework sections below. +``` + +**Step 2 — Download the weights** + +```bash +# Install the Hugging Face CLI if needed: +pip install huggingface_hub + +# Download FL2VA checkpoint (T2VA + FL2VA tasks): +hf download MiniMaxAI/MiniMax-H3 \ + --include "model_index.json" "modular_model_index.json" \ + --include "FL2VA/**" \ + --include "vae/**" "audio_vae/**" "scheduler/**" "audio_scheduler/**" \ + --local-dir ./MiniMax-H3 + +# Download Ref2VA checkpoint additionally: +hf download MiniMaxAI/MiniMax-H3 \ + --include "Ref2VA/**" \ + --local-dir ./MiniMax-H3 +``` + +**Step 3 — Verify the download** + +After downloading, confirm the key weight files exist: + +```bash +# FL2VA transformer weights (largest file — ~67 GB total for all shards) +ls MiniMax-H3/FL2VA/transformer/model-*.safetensors + +# Audio VAE weights +ls MiniMax-H3/FL2VA/audio_vae/*.safetensors + +# Visual VAE weights +ls MiniMax-H3/FL2VA/vae/*.safetensors +``` + +If any files are missing, re-run the `hf download` command above. The `hf` CLI +is resumable — it will skip files that are already complete. + +**Step 4 — Run inference** + +Once weights are downloaded, follow the SGLang, vLLM, or diffusers workflows +documented in the sections below. For a quick smoke-test using the reproducible +768p scripts, set your `SGLANG_DEPLOYMENT_URL` and run: + +```bash +bash scripts/readme/reproducible-768p-t2va-request.sh +``` + + diffusers users do not need a manual download: `ModularPipeline.from_pretrained("MiniMaxAI/MiniMax-H3")` fetches exactly the components it needs. See the [diffusers documentation](https://github.com/huggingface/diffusers/blob/minimax-h3/docs/source/en/api/pipelines/minimax_h3.md) for loading recipes. We recommend the following inference frameworks to serve the model: diff --git a/Ref2VA/audio_vae/__pycache__/dac_alias_free_filter.cpython-314.pyc b/Ref2VA/audio_vae/__pycache__/dac_alias_free_filter.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..be6ff2db1928b547d9fc9aa74a6b8de879980192 GIT binary patch literal 4989 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 literal 0 HcmV?d00001 diff --git a/Ref2VA/audio_vae/__pycache__/dac_audio_vae.cpython-314.pyc b/Ref2VA/audio_vae/__pycache__/dac_audio_vae.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c3b989456baa2ea6b0ab9393a3bfbe27b82a9687 GIT binary patch literal 13429 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 z out_dim: - # assert in_dim // num_heads == out_dim + # Projection compresses in_dim → out_dim after attention. + # QKV operates in in_dim space so head_dim = in_dim // num_heads. self.head_dim = in_dim // num_heads + self.qkv_out_dim = in_dim self.qkv = nn.Linear(in_dim, in_dim * 3, bias=False) self.q_bias = nn.Parameter(torch.zeros(in_dim)) self.v_bias = nn.Parameter(torch.zeros(in_dim)) self.register_buffer("zero_k_bias", torch.zeros(in_dim)) else: - # assert out_dim // num_heads == in_dim + # Projection expands (or keeps) in_dim → out_dim after attention. + # QKV operates in out_dim space so head_dim = out_dim // num_heads. self.head_dim = out_dim // num_heads + self.qkv_out_dim = out_dim self.qkv = nn.Linear(in_dim, out_dim * 3, bias=False) self.q_bias = nn.Parameter(torch.zeros(out_dim)) self.v_bias = nn.Parameter(torch.zeros(out_dim)) @@ -47,21 +51,27 @@ def __init__(self, in_dim, out_dim, num_heads): self.out_dim = out_dim self.num_heads = num_heads self.scale = self.head_dim**-0.5 - self.proj = nn.Linear(out_dim, out_dim) + # Final linear maps from the QKV output space to out_dim. + self.proj = nn.Linear(self.qkv_out_dim, out_dim) def forward(self, x: torch.Tensor) -> torch.Tensor: B, N, C = x.shape - qkv = F.linear(input=x, weight=self.qkv.weight, bias=torch.cat((self.q_bias, self.zero_k_bias, self.v_bias))) - q, k, v = qkv.reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4).unbind(0) + qkv = F.linear( + input=x, + weight=self.qkv.weight, + bias=torch.cat((self.q_bias, self.zero_k_bias, self.v_bias)), + ) + q, k, v = ( + qkv.reshape(B, N, 3, self.num_heads, self.head_dim) + .permute(2, 0, 3, 1, 4) + .unbind(0) + ) x = scaled_dot_product_attention(q, k, v, attn_mask=None, dropout_p=0.0, is_causal=True) - if self.in_dim > self.out_dim: - x = torch.mean(x, dim=1) - if self.in_dim // self.num_heads != self.out_dim: - x = nn.functional.adaptive_avg_pool1d(x, self.out_dim) - else: - x = x.transpose(1, 2).reshape(B, N, -1) + # Always reshape to [B, N, qkv_out_dim] so self.proj receives the + # correct input dimension regardless of whether in_dim > out_dim or not. + x = x.transpose(1, 2).reshape(B, N, self.qkv_out_dim) x = self.proj(x) return x diff --git a/Ref2VA/audio_vae/dac_audio_vae.py b/Ref2VA/audio_vae/dac_audio_vae.py index aebdfb7..d2a9b55 100644 --- a/Ref2VA/audio_vae/dac_audio_vae.py +++ b/Ref2VA/audio_vae/dac_audio_vae.py @@ -43,6 +43,17 @@ def forward(self, x): def init_weights(m): """Initialize Conv1d layers, including those wrapped with ``weight_norm``. + This is the canonical initializer for ``DacAudioVAE`` (encoder + decoder). + It uses ``trunc_normal_`` with ``std=0.02`` and explicitly zeroes biases, + matching the intended training configuration for this model family. + + Note: ``dac_bigvgan.py`` / ``dac_utils.py`` also contain an ``init_weights`` + helper (``std=0.01``, ``normal_``) used by BigVGAN's own module-level + ``apply()`` calls. Because ``DacAudioVAE.__init__`` calls + ``self.apply(init_weights)`` *after* all sub-modules (including BigVGAN) + have been constructed, this function is the one that takes final effect on + every ``nn.Conv1d`` in the whole model graph. + The encoder (``WNConv1d``) and decoder (BigVGAN) both wrap ``nn.Conv1d`` with ``torch.nn.utils.parametrizations.weight_norm``. Under that parametrization ``m.weight`` is computed on access from @@ -74,9 +85,15 @@ def __init__(self, dim: int = 16, dilation: int = 1): def forward(self, x): y = self.block(x) - pad = (x.shape[-1] - y.shape[-1]) // 2 - if pad > 0: - x = x[..., pad:-pad] + diff = x.shape[-1] - y.shape[-1] + if diff > 0: + # Crop the residual path to match the convolved output length. + # Use explicit left/right amounts to handle both even and odd + # differences safely (avoids the x[..., pad:-pad] pattern which + # silently drops an extra sample when diff is odd). + pad_left = diff // 2 + pad_right = diff - pad_left # == pad_left + (diff % 2) + x = x[..., pad_left : x.shape[-1] - pad_right] return x + y @@ -93,7 +110,11 @@ def __init__(self, dim: int = 16, stride: int = 1): dim, kernel_size=2 * stride, stride=stride, - padding=math.ceil(stride / 2), + # For kernel_size = 2*stride the correct "same-length" padding + # is (kernel_size - stride) // 2 = stride // 2. + # The previous math.ceil(stride / 2) was off by 1 for odd + # strides (e.g. stride=5 gave padding=3 instead of 2). + padding=stride // 2, ), ) @@ -209,7 +230,9 @@ def __init__( if self.attn_proj: self.pre_block = AttnProjection(latent_dim, self.attn_proj_dim, num_heads=8) - self.sample_rate = sample_rate + # Apply canonical weight initialization to all Conv1d layers in the + # entire model graph (encoder + BigVGAN decoder). This single pass + # uses trunc_normal_(std=0.02) and is the intended final initializer. self.apply(init_weights) def preprocess(self, audio_data, sample_rate): diff --git a/Ref2VA/transformer/config.json b/Ref2VA/transformer/config.json index 94cc6ca..c7dbf0e 100644 --- a/Ref2VA/transformer/config.json +++ b/Ref2VA/transformer/config.json @@ -4,11 +4,15 @@ "hidden_size": 5376, "num_layers": 50, "token_refiner_num_layers": 2, + "num_refiner_layers": 2, "num_attention_heads": 56, "attention_head_dim": 128, "ffn_hidden_size": 14336, + "ffn_dim": 14336, "latents_dim": 24, + "in_channels": 24, "audio_latents_dim": 32, + "audio_in_channels": 32, "patch_size": [ 1, 2, @@ -16,11 +20,15 @@ ], "text_dim": 5120, "timestep_input_dim": 256, + "freq_dim": 256, "time_embed_hidden_size": 5376, + "time_embed_hidden_dim": 5376, "time_embed_dim": 2688, "adaln_out_features": 96768, "final_adaln_out_features": 10752, "rope_inv_freq_len": 16, + "rope_freq_dim": 16, + "rope_theta": 10000.0, "norm_eps": 1e-05, "qk_norm_eps": 1e-05, "final_norm_eps": 1e-05 diff --git a/audio_vae/config.json b/audio_vae/config.json index 15df6fe..5e90c79 100644 --- a/audio_vae/config.json +++ b/audio_vae/config.json @@ -53,6 +53,7 @@ 5 ] ], + "sample_rate": 32000, "sampling_rate": 32000, "latents_mean": [ -0.020211687488382354, diff --git a/requirements.txt b/requirements.txt index 7f5c20c..8ab7b6e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -47,3 +47,8 @@ soundfile>=0.12.0 imageio>=2.34.0 imageio-ffmpeg>=0.5.0 av>=11.0.0 + +# PyYAML is required at runtime by the audio VAE loader (minimax_h3_audio_vae.py) +# to parse the model config YAML file. Without it, loading the audio VAE raises +# ImportError("MiniMax H3 audio VAE requires PyYAML."). +PyYAML>=6.0 diff --git a/scripts/readme/full-2k-i2va-h3-base.sh b/scripts/readme/full-2k-i2va-h3-base.sh index 37a53d1..cf2e8d4 100755 --- a/scripts/readme/full-2k-i2va-h3-base.sh +++ b/scripts/readme/full-2k-i2va-h3-base.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create the H3-Base request with the expanded prompt and capture the video ID. @@ -23,7 +23,7 @@ video_id=$( }, "seed": 0 }' | - curl --silent --show-error \ + curl --fail-with-body --silent --show-error \ --request POST \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos" \ --header 'Content-Type: application/json' \ @@ -31,12 +31,12 @@ video_id=$( jq -er '.id' ) # Query the generation status. -curl --silent --show-error \ +curl --fail-with-body --silent --show-error \ --request GET \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos/$video_id" | jq '{status}' # Download the local H3-Base MP4 after its status becomes completed. -curl --silent --show-error \ +curl --fail-with-body --silent --show-error \ --request GET \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos/$video_id/content" \ --output i2va.mp4 diff --git a/scripts/readme/full-2k-i2va-h3-context-ir.sh b/scripts/readme/full-2k-i2va-h3-context-ir.sh index c8180c4..1cec904 100755 --- a/scripts/readme/full-2k-i2va-h3-context-ir.sh +++ b/scripts/readme/full-2k-i2va-h3-context-ir.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create the prompt-expansion task and capture its runtime ID. diff --git a/scripts/readme/full-2k-i2va-h3-regenerate-2k.sh b/scripts/readme/full-2k-i2va-h3-regenerate-2k.sh index 45f4b21..6f14127 100755 --- a/scripts/readme/full-2k-i2va-h3-regenerate-2k.sh +++ b/scripts/readme/full-2k-i2va-h3-regenerate-2k.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail H3_BASE_VIDEO='./i2va.mp4' diff --git a/scripts/readme/full-2k-i2va-reference-2k-result-by-directly-calling-open-platform-api.sh b/scripts/readme/full-2k-i2va-reference-2k-result-by-directly-calling-open-platform-api.sh index c04741b..0a9e651 100755 --- a/scripts/readme/full-2k-i2va-reference-2k-result-by-directly-calling-open-platform-api.sh +++ b/scripts/readme/full-2k-i2va-reference-2k-result-by-directly-calling-open-platform-api.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create an 8-second 2K FL2VA video directly and capture its runtime task ID. diff --git a/scripts/readme/full-2k-i2va-reference-768p-result-by-directly-calling-open-platform-api.sh b/scripts/readme/full-2k-i2va-reference-768p-result-by-directly-calling-open-platform-api.sh index c21ee2d..44a2637 100755 --- a/scripts/readme/full-2k-i2va-reference-768p-result-by-directly-calling-open-platform-api.sh +++ b/scripts/readme/full-2k-i2va-reference-768p-result-by-directly-calling-open-platform-api.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create an 8-second 768P FL2VA video directly and capture its runtime task ID. diff --git a/scripts/readme/full-2k-ref2va-h3-api-2k-in-open-platform-for-reference.sh b/scripts/readme/full-2k-ref2va-h3-api-2k-in-open-platform-for-reference.sh index 19b7c65..566cf39 100755 --- a/scripts/readme/full-2k-ref2va-h3-api-2k-in-open-platform-for-reference.sh +++ b/scripts/readme/full-2k-ref2va-h3-api-2k-in-open-platform-for-reference.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create a 5-second 2K Ref2VA video directly and capture its runtime task ID. diff --git a/scripts/readme/full-2k-ref2va-h3-base.sh b/scripts/readme/full-2k-ref2va-h3-base.sh index 6b6f034..ba4b560 100755 --- a/scripts/readme/full-2k-ref2va-h3-base.sh +++ b/scripts/readme/full-2k-ref2va-h3-base.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create the H3-Base request with the expanded prompt and capture the video ID. @@ -27,7 +27,7 @@ video_id=$( }, "seed": 0 }' | - curl --silent --show-error \ + curl --fail-with-body --silent --show-error \ --request POST \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos" \ --header 'Content-Type: application/json' \ @@ -35,12 +35,12 @@ video_id=$( jq -er '.id' ) # Query the generation status. -curl --silent --show-error \ +curl --fail-with-body --silent --show-error \ --request GET \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos/$video_id" | jq '{status}' # Download the local H3-Base MP4 after its status becomes completed. -curl --silent --show-error \ +curl --fail-with-body --silent --show-error \ --request GET \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos/$video_id/content" \ --output r2va.mp4 diff --git a/scripts/readme/full-2k-ref2va-h3-context-ir.sh b/scripts/readme/full-2k-ref2va-h3-context-ir.sh index 6195577..af699e7 100755 --- a/scripts/readme/full-2k-ref2va-h3-context-ir.sh +++ b/scripts/readme/full-2k-ref2va-h3-context-ir.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create the prompt-expansion task and capture its runtime ID. diff --git a/scripts/readme/full-2k-ref2va-reference-2k-result-by-directly-calling-open-platform-api.sh b/scripts/readme/full-2k-ref2va-reference-2k-result-by-directly-calling-open-platform-api.sh index 2ac2aab..ce4e948 100755 --- a/scripts/readme/full-2k-ref2va-reference-2k-result-by-directly-calling-open-platform-api.sh +++ b/scripts/readme/full-2k-ref2va-reference-2k-result-by-directly-calling-open-platform-api.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail H3_BASE_VIDEO='./r2va.mp4' diff --git a/scripts/readme/full-2k-ref2va-reference-768p-result-by-directly-calling-open-platform-api.sh b/scripts/readme/full-2k-ref2va-reference-768p-result-by-directly-calling-open-platform-api.sh index 038b5df..b99f4cd 100755 --- a/scripts/readme/full-2k-ref2va-reference-768p-result-by-directly-calling-open-platform-api.sh +++ b/scripts/readme/full-2k-ref2va-reference-768p-result-by-directly-calling-open-platform-api.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create a 5-second 768P Ref2VA video directly and capture its runtime task ID. diff --git a/scripts/readme/full-2k-t2va-h3-base.sh b/scripts/readme/full-2k-t2va-h3-base.sh index cbdd623..2893bfd 100755 --- a/scripts/readme/full-2k-t2va-h3-base.sh +++ b/scripts/readme/full-2k-t2va-h3-base.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create the H3-Base request with the expanded prompt and capture the video ID. @@ -16,7 +16,7 @@ video_id=$( }, "seed": 0 }' | - curl --silent --show-error \ + curl --fail-with-body --silent --show-error \ --request POST \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos" \ --header 'Content-Type: application/json' \ @@ -24,12 +24,12 @@ video_id=$( jq -er '.id' ) # Query the generation status. -curl --silent --show-error \ +curl --fail-with-body --silent --show-error \ --request GET \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos/$video_id" | jq '{status}' # Download the local H3-Base MP4 after its status becomes completed. -curl --silent --show-error \ +curl --fail-with-body --silent --show-error \ --request GET \ --url "$SGLANG_DEPLOYMENT_URL/v1/videos/$video_id/content" \ --output t2va.mp4 diff --git a/scripts/readme/full-2k-t2va-h3-context-ir.sh b/scripts/readme/full-2k-t2va-h3-context-ir.sh index 6afd3b4..18b88ec 100755 --- a/scripts/readme/full-2k-t2va-h3-context-ir.sh +++ b/scripts/readme/full-2k-t2va-h3-context-ir.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create the prompt-expansion task and capture its runtime ID. diff --git a/scripts/readme/full-2k-t2va-h3-regenerate-2k.sh b/scripts/readme/full-2k-t2va-h3-regenerate-2k.sh index 1d67780..a2649da 100755 --- a/scripts/readme/full-2k-t2va-h3-regenerate-2k.sh +++ b/scripts/readme/full-2k-t2va-h3-regenerate-2k.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail H3_BASE_VIDEO='./t2va.mp4' diff --git a/scripts/readme/full-2k-t2va-reference-2k-result-by-directly-calling-open-platform-api.sh b/scripts/readme/full-2k-t2va-reference-2k-result-by-directly-calling-open-platform-api.sh index 669e10e..cddfc3c 100755 --- a/scripts/readme/full-2k-t2va-reference-2k-result-by-directly-calling-open-platform-api.sh +++ b/scripts/readme/full-2k-t2va-reference-2k-result-by-directly-calling-open-platform-api.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create a 10-second 2K video directly and capture its runtime task ID. diff --git a/scripts/readme/full-2k-t2va-reference-768p-result-by-directly-calling-open-platform-api.sh b/scripts/readme/full-2k-t2va-reference-768p-result-by-directly-calling-open-platform-api.sh index b765671..10eb7db 100755 --- a/scripts/readme/full-2k-t2va-reference-768p-result-by-directly-calling-open-platform-api.sh +++ b/scripts/readme/full-2k-t2va-reference-768p-result-by-directly-calling-open-platform-api.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Create a 10-second 768P video directly and capture its runtime task ID. diff --git a/scripts/readme/reproducible-768p-fl2va-request.sh b/scripts/readme/reproducible-768p-fl2va-request.sh index 1efa6fc..486fd80 100755 --- a/scripts/readme/reproducible-768p-fl2va-request.sh +++ b/scripts/readme/reproducible-768p-fl2va-request.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Submit the FL2VA request with the complete H3-Context-IR prompt. diff --git a/scripts/readme/reproducible-768p-ref2va-request.sh b/scripts/readme/reproducible-768p-ref2va-request.sh index 5f13b14..3e5598e 100755 --- a/scripts/readme/reproducible-768p-ref2va-request.sh +++ b/scripts/readme/reproducible-768p-ref2va-request.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Submit the Ref2VA request with the complete H3-Context-IR prompt. diff --git a/scripts/readme/reproducible-768p-t2va-request.sh b/scripts/readme/reproducible-768p-t2va-request.sh index b23938b..c3e30cd 100755 --- a/scripts/readme/reproducible-768p-t2va-request.sh +++ b/scripts/readme/reproducible-768p-t2va-request.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/usr/bin/env bash set -euo pipefail # Submit the T2VA request with the complete H3-Context-IR prompt. diff --git a/tests/__pycache__/test_regressions.cpython-314-pytest-9.1.1.pyc b/tests/__pycache__/test_regressions.cpython-314-pytest-9.1.1.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7275ea4ef3e0d2274692800c5c35cb0182827b6 GIT binary patch literal 56123 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 literal 0 HcmV?d00001 diff --git a/tests/test_regressions.py b/tests/test_regressions.py new file mode 100644 index 0000000..828d064 --- /dev/null +++ b/tests/test_regressions.py @@ -0,0 +1,338 @@ +""" +MiniMax-H3 Regression Tests — Fixed harness +============================================== +Uses sys.path injection instead of spec_from_file_location so relative +imports inside the audio_vae package resolve correctly. + +Run with: + cd d:\\minimax\\MiniMax-H3 + python -m pytest tests/test_regressions.py -v --tb=short +""" + +import json +import sys +import importlib +from pathlib import Path + +import pytest +import torch +import torch.nn as nn + +PROJECT_ROOT = Path(__file__).parent.parent + + +def _load_audio_vae_package(task: str): + """ + Add the task directory to sys.path so relative imports work, + then import the modules as a flat namespace. + Returns the dac_audio_vae module for that task. + """ + pkg_dir = str(PROJECT_ROOT / task / "audio_vae") + if pkg_dir not in sys.path: + sys.path.insert(0, pkg_dir) + # Force fresh load by removing any cached versions + mods_to_reload = [ + "dac_alias_free_filter", "dac_alias_free_resample", + "dac_alias_free_act", "dac_activations", "dac_utils", + "dac_attn_proj", "dac_bigvgan", "dac_audio_vae", + ] + for m in mods_to_reload: + sys.modules.pop(m, None) + import dac_audio_vae + return dac_audio_vae + + +def _load_filter_module(task: str): + pkg_dir = str(PROJECT_ROOT / task / "audio_vae") + if pkg_dir not in sys.path: + sys.path.insert(0, pkg_dir) + sys.modules.pop("dac_alias_free_filter", None) + import dac_alias_free_filter + return dac_alias_free_filter + + +def _load_attn_proj(task: str): + pkg_dir = str(PROJECT_ROOT / task / "audio_vae") + if pkg_dir not in sys.path: + sys.path.insert(0, pkg_dir) + sys.modules.pop("dac_attn_proj", None) + import dac_attn_proj + return dac_attn_proj + + +# ─── Bug 1 ──────────────────────────────────────────────────────────────────── + +class TestBug1KaiserSincFilter: + + @pytest.fixture(params=["FL2VA", "Ref2VA"]) + def fmod(self, request): + return _load_filter_module(request.param) + + def test_cutoff_zero_no_nameerror(self, fmod): + r = fmod.kaiser_sinc_filter1d(cutoff=0, half_width=0.6, kernel_size=12) + assert r is not None + + def test_cutoff_zero_shape(self, fmod): + r = fmod.kaiser_sinc_filter1d(cutoff=0, half_width=0.6, kernel_size=12) + assert r.shape == (1, 1, 12) + + def test_cutoff_zero_all_zeros(self, fmod): + r = fmod.kaiser_sinc_filter1d(cutoff=0, half_width=0.6, kernel_size=12) + assert torch.all(r == 0) + + def test_cutoff_positive_shape(self, fmod): + for ks in [8, 12, 24]: + r = fmod.kaiser_sinc_filter1d(cutoff=0.3, half_width=0.3, kernel_size=ks) + assert r.shape == (1, 1, ks) + + def test_cutoff_positive_normalized(self, fmod): + r = fmod.kaiser_sinc_filter1d(cutoff=0.5, half_width=0.6, kernel_size=12) + assert abs(r.sum().item() - 1.0) < 1e-5 + + +# ─── Bug 2 ──────────────────────────────────────────────────────────────────── + +class TestBug2DuplicateSampleRate: + + def test_source_has_exactly_one_assignment(self): + for task in ("FL2VA", "Ref2VA"): + src = (PROJECT_ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + count = src.count("self.sample_rate = sample_rate") + assert count == 1, f"{task}: expected 1 assignment, found {count}" + + @pytest.mark.parametrize("task", ["FL2VA", "Ref2VA"]) + def test_sample_rate_attribute_correct(self, task): + vae_mod = _load_audio_vae_package(task) + for sr in (16000, 32000): + vae = vae_mod.DacAudioVAE(sample_rate=sr) + assert vae.sample_rate == sr + + +# ─── Bug 3 ──────────────────────────────────────────────────────────────────── + +class TestBug3InitWeightsConsistency: + + def test_uses_trunc_normal_std02(self): + for task in ("FL2VA", "Ref2VA"): + src = (PROJECT_ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + assert "trunc_normal_" in src + assert "std=0.02" in src + assert "m.bias" in src + + def test_apply_called_once_in_live_code(self): + for task in ("FL2VA", "Ref2VA"): + src = (PROJECT_ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + # Count only real code lines (not comment or docstring lines) + code_apply = sum( + 1 for l in src.splitlines() + if "self.apply(init_weights)" in l + and not l.strip().startswith("#") + and not l.strip().startswith("`") + and not l.strip().startswith("\"\"\"") + ) + assert code_apply == 1, f"{task}: {code_apply} apply calls in live code" + + @pytest.mark.parametrize("task", ["FL2VA", "Ref2VA"]) + def test_conv_biases_zeroed_after_build(self, task): + vae_mod = _load_audio_vae_package(task) + vae = vae_mod.DacAudioVAE(sample_rate=32000) + checked = 0 + for name, param in vae.named_parameters(): + if "bias" in name and param is not None and param.numel() > 0: + assert torch.all(param.data == 0), f"{task}: {name} not zeroed" + checked += 1 + assert checked > 0, "No biases found to check" + + +# ─── Bug 4 ──────────────────────────────────────────────────────────────────── + +class TestBug4CausalAttentionShape: + + @pytest.fixture(params=["FL2VA", "Ref2VA"]) + def amod(self, request): + return _load_attn_proj(request.param) + + def _fwd(self, amod, in_d, out_d, nh, B=2, N=8): + ca = amod.CausalAttention(in_d, out_d, nh) + ca.eval() + with torch.no_grad(): + return ca(torch.randn(B, N, in_d)).shape + + def test_in_eq_out(self, amod): + assert self._fwd(amod, 64, 64, 8) == (2, 8, 64) + + def test_in_less_than_out(self, amod): + assert self._fwd(amod, 32, 64, 8) == (2, 8, 64) + + def test_in_greater_than_out(self, amod): + """This was the broken case — Bug 4.""" + assert self._fwd(amod, 64, 32, 8) == (2, 8, 32) + + def test_large_batch(self, amod): + assert self._fwd(amod, 64, 32, 8, B=4, N=16) == (4, 16, 32) + + def test_attn_projection_end_to_end(self, amod): + proj = amod.AttnProjection(in_dim=64, out_dim=32, num_heads=8) + proj.eval() + with torch.no_grad(): + out = proj(torch.randn(2, 10, 64)) + assert out.shape == (2, 10, 32) + + +# ─── Bug 5 ──────────────────────────────────────────────────────────────────── + +class TestBug5EncoderBlockPadding: + + def test_source_formula_correct(self): + for task in ("FL2VA", "Ref2VA"): + src = (PROJECT_ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + # New formula present + assert "padding=stride // 2" in src, f"{task}: new formula missing" + # Old formula must NOT appear in live code (only in comments) + old_in_live = any( + "padding=math.ceil(stride" in l and not l.strip().startswith("#") + for l in src.splitlines() + ) + assert not old_in_live, f"{task}: old math.ceil formula still in live code" + + @pytest.mark.parametrize("stride", [1, 2, 3, 4, 5, 8]) + def test_output_length(self, stride): + vae_mod = _load_audio_vae_package("FL2VA") + dim = 32 + block = vae_mod.EncoderBlock(dim=dim, stride=stride) + block.eval() + T = stride * 20 + with torch.no_grad(): + out = block(torch.randn(1, dim // 2, T)) + assert out.shape[1] == dim, f"stride={stride}: channels {out.shape[1]}" + assert out.shape[2] == T // stride, f"stride={stride}: T {out.shape[2]} != {T//stride}" + + +# ─── Bug 6 ──────────────────────────────────────────────────────────────────── + +class TestBug6ResidualUnit: + + @pytest.fixture + def ru_mod(self): + return _load_audio_vae_package("FL2VA") + + def test_source_uses_explicit_crop(self): + for task in ("FL2VA", "Ref2VA"): + src = (PROJECT_ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + assert "pad_right = diff - pad_left" in src + + @pytest.mark.parametrize("T", [30, 31, 50, 51, 99, 100, 101]) + def test_no_crash_various_lengths(self, ru_mod, T): + unit = ru_mod.ResidualUnit(dim=16, dilation=1) + unit.eval() + with torch.no_grad(): + _ = unit(torch.randn(2, 16, T)) + + def test_dilation3_no_crash(self, ru_mod): + unit = ru_mod.ResidualUnit(dim=16, dilation=3) + unit.eval() + for T in [31, 33, 47, 51]: + with torch.no_grad(): + _ = unit(torch.randn(1, 16, T)) + + def test_output_is_3d(self, ru_mod): + unit = ru_mod.ResidualUnit(dim=16, dilation=1) + unit.eval() + with torch.no_grad(): + out = unit(torch.randn(2, 16, 51)) + assert out.ndim == 3 + + +# ─── Bug 7 ──────────────────────────────────────────────────────────────────── + +class TestBug7TransformerConfig: + + @pytest.mark.parametrize("task", ["FL2VA", "Ref2VA"]) + def test_ffn_both_keys(self, task): + cfg = json.loads((PROJECT_ROOT / task / "transformer" / "config.json").read_text()) + assert "ffn_hidden_size" in cfg and "ffn_dim" in cfg + assert cfg["ffn_hidden_size"] == cfg["ffn_dim"] + + @pytest.mark.parametrize("task", ["FL2VA", "Ref2VA"]) + def test_rope_both_keys(self, task): + cfg = json.loads((PROJECT_ROOT / task / "transformer" / "config.json").read_text()) + assert "rope_inv_freq_len" in cfg and "rope_freq_dim" in cfg + assert cfg["rope_inv_freq_len"] == cfg["rope_freq_dim"] + + @pytest.mark.parametrize("task", ["FL2VA", "Ref2VA"]) + def test_refiner_both_keys(self, task): + cfg = json.loads((PROJECT_ROOT / task / "transformer" / "config.json").read_text()) + assert "token_refiner_num_layers" in cfg and "num_refiner_layers" in cfg + assert cfg["token_refiner_num_layers"] == cfg["num_refiner_layers"] + + +# ─── Bug 8 ──────────────────────────────────────────────────────────────────── + +class TestBug8DiffusersVersion: + + def test_task_indexes_match(self): + fl = json.loads((PROJECT_ROOT / "FL2VA" / "model_index.json").read_text())["_diffusers_version"] + ref = json.loads((PROJECT_ROOT / "Ref2VA" / "model_index.json").read_text())["_diffusers_version"] + assert fl == ref + + def test_root_indexes_match(self): + root = json.loads((PROJECT_ROOT / "model_index.json").read_text())["_diffusers_version"] + mod = json.loads((PROJECT_ROOT / "modular_model_index.json").read_text())["_diffusers_version"] + assert root == mod + + +# ─── Bug 9 ──────────────────────────────────────────────────────────────────── + +class TestBug9PyYAML: + def test_listed(self): + req = (PROJECT_ROOT / "requirements.txt").read_text(encoding="utf-8") + assert "PyYAML" in req + + +# ─── Bug 10 ─────────────────────────────────────────────────────────────────── + +class TestBug10CRLF: + def test_no_crlf(self): + bad = [f.name for f in (PROJECT_ROOT / "scripts" / "readme").glob("*.sh") + if b"\r\n" in f.read_bytes()] + assert bad == [], f"CRLF found in: {bad}" + + +# ─── Bug 11 ─────────────────────────────────────────────────────────────────── + +class TestBug11CurlFlag: + @pytest.mark.parametrize("script", [ + "full-2k-t2va-h3-base.sh", + "full-2k-i2va-h3-base.sh", + "full-2k-ref2va-h3-base.sh", + ]) + def test_flag_present(self, script): + txt = (PROJECT_ROOT / "scripts" / "readme" / script).read_text(encoding="utf-8") + assert "--fail-with-body" in txt + + +# ─── Bug 12 ─────────────────────────────────────────────────────────────────── + +class TestBug12SampleRate: + def test_both_keys_present_and_equal(self): + cfg = json.loads((PROJECT_ROOT / "audio_vae" / "config.json").read_text()) + assert "sample_rate" in cfg + assert "sampling_rate" in cfg + assert cfg["sample_rate"] == cfg["sampling_rate"] + + def test_fl2va_config_has_sample_rate(self): + cfg = json.loads((PROJECT_ROOT / "FL2VA" / "audio_vae" / "config.json").read_text()) + assert "sample_rate" in cfg + + +# ─── Bug 13 ─────────────────────────────────────────────────────────────────── + +class TestBug13README: + def test_download_steps_present(self): + readme = (PROJECT_ROOT / "README.md").read_text(encoding="utf-8", errors="replace") + assert "Step 1" in readme and "Step 2" in readme and "Step 3" in readme + assert "hf download MiniMaxAI/MiniMax-H3" in readme + + +if __name__ == "__main__": + sys.exit(pytest.main([__file__, "-v", "--tb=short"])) diff --git a/tests/verify_fixes.py b/tests/verify_fixes.py new file mode 100644 index 0000000..061107e --- /dev/null +++ b/tests/verify_fixes.py @@ -0,0 +1,132 @@ +import json, sys, pathlib + +ROOT = pathlib.Path(r"d:\minimax\MiniMax-H3") +results = [] + +def check(num, name, condition, detail=""): + icon = "PASS" if condition else "FAIL" + results.append((num, name, icon, detail)) + tag = "OK" if condition else "!!" + print(f" [{tag}] Bug {num}: {name}" + (f" -> {detail}" if detail else "")) + +# BUG 1 +for task in ("FL2VA", "Ref2VA"): + src = (ROOT / task / "audio_vae" / "dac_alias_free_filter.py").read_text(encoding="utf-8") + lines = src.splitlines() + fix_ok = any(" filter = filter_.view(1, 1, kernel_size)" in l + and not l.startswith(" ") for l in lines) + still_buggy = any(" filter = filter_.view" in l for l in lines) + check(1, f"NameError cutoff==0 [{task}]", fix_ok and not still_buggy) + +# BUG 2 +for task in ("FL2VA", "Ref2VA"): + src = (ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + count = src.count("self.sample_rate = sample_rate") + check(2, f"Duplicate sample_rate [{task}]", count == 1, f"{count} assignment(s)") + +# BUG 3 +for task in ("FL2VA", "Ref2VA"): + src = (ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + has_trunc = "trunc_normal_" in src + has_std = "std=0.02" in src + has_bias = "m.bias" in src + apply_calls = sum(1 for l in src.splitlines() + if "self.apply(init_weights)" in l + and not l.strip().startswith("#") + and not l.strip().startswith("``")) + check(3, f"Conflicting init_weights [{task}]", + has_trunc and has_std and has_bias and apply_calls == 1, + f"trunc={has_trunc} std02={has_std} bias={has_bias} apply={apply_calls}") + +# BUG 4 +for task in ("FL2VA", "Ref2VA"): + src = (ROOT / task / "audio_vae" / "dac_attn_proj.py").read_text(encoding="utf-8") + has_qkv_out = "self.qkv_out_dim" in src + old_mean_gone = "torch.mean(x, dim=1)" not in src + uniform_reshape = "x.transpose(1, 2).reshape(B, N, self.qkv_out_dim)" in src + check(4, f"CausalAttention shape [{task}]", + has_qkv_out and old_mean_gone and uniform_reshape) + +# BUG 5 +for task in ("FL2VA", "Ref2VA"): + src = (ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + new_ok = "padding=stride // 2" in src + old_in_code = any("padding=math.ceil(stride" in l and not l.strip().startswith("#") + for l in src.splitlines()) + check(5, f"EncoderBlock padding [{task}]", new_ok and not old_in_code) + +# BUG 6 +for task in ("FL2VA", "Ref2VA"): + src = (ROOT / task / "audio_vae" / "dac_audio_vae.py").read_text(encoding="utf-8") + has_explicit = "pad_right = diff - pad_left" in src + old_gone = not any("x[..., pad:-pad]" in l and not l.strip().startswith("#") + for l in src.splitlines()) + check(6, f"ResidualUnit odd diff [{task}]", has_explicit and old_gone) + +# BUG 7 +for task in ("FL2VA", "Ref2VA"): + cfg = json.loads((ROOT / task / "transformer" / "config.json").read_text(encoding="utf-8")) + pairs = [("ffn_hidden_size", "ffn_dim"), + ("rope_inv_freq_len", "rope_freq_dim"), + ("token_refiner_num_layers", "num_refiner_layers")] + ok = all(a in cfg and b in cfg and cfg[a] == cfg[b] for a, b in pairs) + check(7, f"Transformer config consistency [{task}]", ok) + +# BUG 8 +fl2va_v = json.loads((ROOT / "FL2VA" / "model_index.json").read_text())["_diffusers_version"] +ref2va_v = json.loads((ROOT / "Ref2VA" / "model_index.json").read_text())["_diffusers_version"] +root_v = json.loads((ROOT / "model_index.json").read_text())["_diffusers_version"] +mod_v = json.loads((ROOT / "modular_model_index.json").read_text())["_diffusers_version"] +check(8, "Diffusers version consistency", + fl2va_v == ref2va_v and root_v == mod_v, + f"FL2VA/Ref2VA={fl2va_v} | Root/Modular={root_v}") + +# BUG 9 +req = (ROOT / "requirements.txt").read_text(encoding="utf-8") +check(9, "PyYAML in requirements.txt", "PyYAML" in req) + +# BUG 10 +crlf_files = [f.name for f in (ROOT / "scripts" / "readme").glob("*.sh") + if b"\r\n" in f.read_bytes()] +check(10, "CRLF in .sh scripts", + len(crlf_files) == 0, + f"CRLF still in: {crlf_files}" if crlf_files else "All 18 scripts are LF-only") + +# BUG 11 +missing = [s for s in ["full-2k-t2va-h3-base.sh", "full-2k-i2va-h3-base.sh", "full-2k-ref2va-h3-base.sh"] + if "--fail-with-body" not in + (ROOT / "scripts" / "readme" / s).read_text(encoding="utf-8")] +check(11, "curl --fail-with-body in h3-base scripts", + len(missing) == 0, + f"Missing in: {missing}" if missing else "All 3 scripts have the flag") + +# BUG 12 +cfg12 = json.loads((ROOT / "audio_vae" / "config.json").read_text(encoding="utf-8")) +both = "sample_rate" in cfg12 and "sampling_rate" in cfg12 +equal = cfg12.get("sample_rate") == cfg12.get("sampling_rate") +check(12, "sampling_rate vs sample_rate", + both and equal, + "sample_rate=32000 & sampling_rate=32000 both present" if (both and equal) else "MISMATCH") + +# BUG 13 +readme = (ROOT / "README.md").read_text(encoding="utf-8", errors="replace") +ok13 = ("Step 1" in readme and "Step 2" in readme and + "Step 3" in readme and "hf download MiniMaxAI/MiniMax-H3" in readme) +check(13, "README weight download docs", + ok13, "4-step guide + hf download command present" if ok13 else "MISSING") + +# SUMMARY +print() +passes = sum(1 for _, _, s, _ in results if s == "PASS") +fails = [r for r in results if r[2] == "FAIL"] +total = len(results) +print("=" * 58) +print(f" RESULT: {passes}/{total} checks PASSED") +if fails: + print(f" FAILED ({len(fails)}):") + for num, name, _, detail in fails: + print(f" Bug {num}: {name} — {detail}") +else: + print(f" ALL {total} CHECKS PASSED — EVERY BUG IS FIXED") +print("=" * 58) +sys.exit(0 if not fails else 1)