|
25 | 25 | import jax |
26 | 26 | import jax.numpy as jnp |
27 | 27 | from jax.sharding import Mesh |
| 28 | +import pytest |
28 | 29 | from maxtext.configs import pyconfig |
29 | 30 | from maxtext.common import common_types |
30 | 31 | from maxtext.utils.globals import MAXTEXT_REPO_ROOT |
|
62 | 63 | copy_patch_embed_weights, |
63 | 64 | copy_patch_merger_weights, |
64 | 65 | copy_vision_encoder_weights, |
65 | | - create_block_diagonal_attention_mask, |
66 | 66 | create_random_jax_torch, |
67 | 67 | ) |
68 | 68 | import numpy as np |
@@ -777,6 +777,7 @@ def test_hidden_states_unchanged_without_visual_tokens(self): |
777 | 777 | np.testing.assert_allclose(np.array(result), hidden_np, rtol=1e-6, atol=1e-6) |
778 | 778 |
|
779 | 779 |
|
| 780 | +@pytest.mark.skip(reason="Requires decord, which may not be installed in remote CI runners.") |
780 | 781 | class TestQwen3OmniPreprocessing(unittest.TestCase): |
781 | 782 | """Test MaxText Qwen3 Omni preprocessor against HuggingFace reference.""" |
782 | 783 |
|
@@ -1003,17 +1004,12 @@ def _test_encoder_layer_with_batch_size(self, batch_size): |
1003 | 1004 |
|
1004 | 1005 | jax_input, torch_input_3d = create_random_jax_torch(batch_size, seq_len, hidden_size) |
1005 | 1006 |
|
1006 | | - # PyTorch forward pass - expects 2D input (total_seq_len, hidden_dim) with cu_seqlens |
1007 | | - torch_input_2d = torch_input_3d.reshape(-1, hidden_size) |
1008 | | - |
1009 | | - # Create cu_seqlens for PyTorch (cumulative sequence lengths for each batch) |
1010 | | - # For batch_size=2, seq_len=12: [0, 12, 24] indicates two sequences of length 12 each |
1011 | | - cu_seqlens = torch.tensor([i * seq_len for i in range(batch_size + 1)], dtype=torch.int32) |
1012 | | - |
1013 | | - attention_mask = create_block_diagonal_attention_mask(cu_seqlens, torch_input_2d.dtype) |
1014 | | - |
1015 | | - torch_output_1d = torch_layer(torch_input_2d, cu_seqlens=cu_seqlens, attention_mask=attention_mask)[0] |
1016 | | - torch_output = torch_output_1d.reshape(batch_size, seq_len, hidden_size) |
| 1007 | + # PyTorch audio layers take 2D packed input. Run each batch item separately |
| 1008 | + # to match MaxText's batched attention without relying on HF's old mask API. |
| 1009 | + cu_seqlens = torch.tensor([0, seq_len], dtype=torch.int32) |
| 1010 | + torch_output = torch.stack( |
| 1011 | + [torch_layer(torch_input_3d[i], cu_seqlens=cu_seqlens)[0] for i in range(batch_size)], dim=0 |
| 1012 | + ) |
1017 | 1013 |
|
1018 | 1014 | jax_output = maxtext_layer(jax_input, deterministic=True) |
1019 | 1015 |
|
@@ -1144,18 +1140,15 @@ def test_audio_encoder_matches_torch(self): |
1144 | 1140 | torch_after_pos = torch_conv_out + torch_pos_emb |
1145 | 1141 |
|
1146 | 1142 | # Run through encoder layers + layernorm (but not projector) |
1147 | | - # Process all chunks together |
| 1143 | + # Process chunks separately, matching MaxText's (batch * chunks, seq, hidden) attention shape. |
1148 | 1144 | seq_len_per_chunk = torch_after_pos.shape[1] |
1149 | | - cu_seqlens = torch.tensor([i * seq_len_per_chunk for i in range(num_chunks + 1)], dtype=torch.int32) |
1150 | | - attention_mask = create_block_diagonal_attention_mask(cu_seqlens, torch_after_pos.dtype) |
1151 | | - |
1152 | | - # Flatten: (num_chunks, seq_len_per_chunk, hidden) -> (num_chunks*seq_len_per_chunk, hidden) |
1153 | | - hidden_state = torch_after_pos.reshape(-1, torch_after_pos.shape[-1]) |
| 1145 | + cu_seqlens = torch.tensor([0, seq_len_per_chunk], dtype=torch.int32) |
| 1146 | + hidden_state = torch_after_pos |
1154 | 1147 | for layer in torch_model.layers: |
1155 | | - hidden_state = layer(hidden_state, cu_seqlens=cu_seqlens, attention_mask=attention_mask)[0] |
| 1148 | + hidden_state = torch.stack([layer(chunk, cu_seqlens=cu_seqlens)[0] for chunk in hidden_state], dim=0) |
1156 | 1149 | hidden_state = torch_model.ln_post(hidden_state) |
1157 | 1150 |
|
1158 | | - # Reshape back: (num_chunks*seq_len_per_chunk, hidden) -> (batch=1, num_chunks*seq_len_per_chunk, hidden) |
| 1151 | + # Reshape back: (num_chunks, seq_len_per_chunk, hidden) -> (batch=1, num_chunks*seq_len_per_chunk, hidden) |
1159 | 1152 | torch_output = hidden_state.reshape(1, num_chunks * seq_len_per_chunk, -1) |
1160 | 1153 |
|
1161 | 1154 | # MaxText forward |
|
0 commit comments