Skip to content

Commit ecb103a

Browse files
committed
amend
1 parent f935c0b commit ecb103a

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

src/maxtext/layers/embeddings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ def __call__(
14071407
14081408
Args:
14091409
inputs: Input tensor of shape [B, S, N, head_dim] (batch, sequence, heads, head_dim)
1410-
where T=num_frames, H=height, W=width (all static)
1410+
where sequence length S = num_frames * height * width (static maximum).
14111411
num_frames: Number of temporal frames (static)
14121412
height: Height in patches (static)
14131413
width: Width in patches (static)

tests/unit/qwen3_omni_layers_test.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
Qwen3OmniMoeVisionProjector as JaxQwen3OmniMoeVisionProjector,
5454
)
5555
from maxtext.multimodal import processor as mm_processor
56+
from maxtext.multimodal import utils as mm_utils
5657
from tests.utils.multimodal_test_utils import (
5758
assert_all_close_jax_torch,
5859
copy_attention_weights_to_maxtext,
@@ -869,6 +870,67 @@ def test_padded_video_projected_outputs_match_unpadded_batched(self):
869870
atol=1e-4,
870871
)
871872

873+
# --- Test Merging into Text Sequence ---
874+
emb_dim = config.out_hidden_size_for_vit
875+
876+
# Example 1: 2 placeholders at indices 5, 6.
877+
text_embeddings_1 = jnp.arange(1 * 20 * emb_dim, dtype=jnp.float32).reshape(1, 20, emb_dim)
878+
placeholder_mask_1 = jnp.zeros((1, 20), dtype=jnp.int32)
879+
placeholder_mask_1 = placeholder_mask_1.at[:, 5:7].set(1)
880+
881+
# Example 2: 4 placeholders at indices 5, 6, 7, 8.
882+
text_embeddings_2 = jnp.arange(1 * 20 * emb_dim, dtype=jnp.float32).reshape(1, 20, emb_dim) + 1000.0
883+
placeholder_mask_2 = jnp.zeros((1, 20), dtype=jnp.int32)
884+
placeholder_mask_2 = placeholder_mask_2.at[:, 5:9].set(1)
885+
886+
# Batch text inputs
887+
batched_text_embeddings = jnp.concatenate([text_embeddings_1, text_embeddings_2], axis=0)
888+
batched_placeholder_mask = jnp.concatenate([placeholder_mask_1, placeholder_mask_2], axis=0)
889+
batched_projected_mask = jnp.concatenate([projected_mask_1, projected_mask_2], axis=0)
890+
891+
# Run batched merge
892+
batched_merged = mm_utils.merge_mm_embeddings(
893+
text_embeddings=batched_text_embeddings,
894+
multimodal_embeddings=batched_padded_output,
895+
mask=batched_placeholder_mask,
896+
token_masks=batched_projected_mask,
897+
)
898+
899+
# Run individual unpadded merges
900+
token_mask_1 = jnp.ones((1, 2), dtype=jnp.int32)
901+
merged_1 = mm_utils.merge_mm_embeddings(
902+
text_embeddings=text_embeddings_1,
903+
multimodal_embeddings=raw_output_1,
904+
mask=placeholder_mask_1,
905+
token_masks=token_mask_1,
906+
)
907+
908+
# Example 2 has 4 valid blocks
909+
token_mask_2 = jnp.ones((1, 4), dtype=jnp.int32)
910+
merged_2 = mm_utils.merge_mm_embeddings(
911+
text_embeddings=text_embeddings_2,
912+
multimodal_embeddings=raw_output_2,
913+
mask=placeholder_mask_2,
914+
token_masks=token_mask_2,
915+
)
916+
917+
# Verify that batched merge matches individual unpadded merges
918+
# Batch item 0
919+
np.testing.assert_allclose(
920+
np.asarray(batched_merged[0]),
921+
np.asarray(merged_1[0]),
922+
rtol=1e-4,
923+
atol=1e-4,
924+
)
925+
926+
# Batch item 1
927+
np.testing.assert_allclose(
928+
np.asarray(batched_merged[1]),
929+
np.asarray(merged_2[0]),
930+
rtol=1e-4,
931+
atol=1e-4,
932+
)
933+
872934

873935
class TestDeepstackProcess(unittest.TestCase):
874936
"""Tests for deepstack_process.

0 commit comments

Comments
 (0)