Skip to content

Commit a712df4

Browse files
committed
Apply cross-model review fixes to T5Gemma2 layout-map tests
- Make the Tier-3 memory-budget cap tunable via the KERAS_HUB_DISTRIBUTION_TEST_MEM_BUDGET env var instead of a hardcoded 300MB, which no real preset in this series can ever fit under. - Correct the memory-estimate formula to cover every weight class T5Gemma2 actually has: separate encoder/decoder embedding tables, the untied reverse_embeddings output projection (always built here since the sweep forces tie_word_embeddings=False), GQA-scaled encoder self-attention QKVO, the decoder's merged self+cross attention QKVO (with cross K/V projected from cross_attention_hidden_size), and both towers' FFNs. - Reword comments and skip-reason strings to be environment-neutral instead of referencing this specific dev machine.
1 parent a73d297 commit a712df4

2 files changed

Lines changed: 661 additions & 79 deletions

File tree

keras_hub/src/models/t5gemma2/t5gemma2_backbone.py

Lines changed: 56 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -544,9 +544,15 @@ def get_layout_map(
544544
cross-attention are fused into a single `merged_attention` layer
545545
(see `T5Gemma2MergedAttention`), which shares the same
546546
query/key/value/attention_output naming as the encoder's
547-
self-attention and is covered by the same rules. Vision/interleave/
548-
EOI-embedding weights are left replicated for now -- see Limitations
549-
in the PR description.
547+
self-attention and is covered by the same rules.
548+
549+
When a `Gemma3VisionEncoder` is attached, its transformer weights are
550+
also sharded (2-D `(in, out)` Dense kernels, following the Megatron
551+
column-/row-parallel convention). Weights that are intentionally left
552+
replicated -- the patch `embedding_conv`, `position_embedding`,
553+
pooling, all vision norms/biases, and the interleave/EOI embeddings --
554+
are small and do not benefit from sharding; see the vision-encoder
555+
rules below.
550556
551557
Args:
552558
device_mesh: keras.distribution.DeviceMesh. The device mesh
@@ -587,26 +593,37 @@ def get_layout_map(
587593
model_dim,
588594
data_dim,
589595
)
596+
# reverse_embeddings is the output-projection tensor of shape
597+
# (hidden, vocab); the vocab-parallel output projection wants vocab on
598+
# the model axis, mirroring token_embedding's (vocab, hidden) =
599+
# (model_dim, data_dim). Only untied embeddings materialize this
600+
# tensor, but tie_word_embeddings is a real constructor arg propagated
601+
# from HF configs, so it must not be left silently replicated.
590602
layout_map["decoder_token_embedding/reverse_embeddings"] = (
591-
model_dim,
592603
data_dim,
604+
model_dim,
593605
)
594-
# Key/value kernels are sized by num_key_value_heads (GQA), which is
595-
# independent of and typically much smaller than num_query_heads --
596-
# sharding that small axis would raise an IndivisibleError whenever
597-
# the mesh dimension doesn't evenly divide it, so that axis is left
598-
# replicated; the large hidden_dim axis is still sharded via
599-
# model_dim. The broad "attention" wildcard covers both the
600-
# encoder's self_attention and the decoder's merged (self+cross)
601-
# attention, which share the same
606+
# QKV kernels are (hidden, num_heads, head_dim) (einsum btd,dnh->btnh):
607+
# the query kernel shards the contracting hidden dim on data_dim and
608+
# the head dim on model_dim (Megatron column-parallel), and its
609+
# attention_output (num_heads, head_dim, hidden) shards heads on
610+
# model_dim to match -- so the two collectives cancel into one
611+
# all-reduce per attention block. Key/value kernels are sized by
612+
# num_key_value_heads (GQA), which is independent of and typically much
613+
# smaller than num_query_heads -- sharding that small head axis on
614+
# model_dim would raise an IndivisibleError whenever the mesh dimension
615+
# doesn't evenly divide it, so it is left replicated; the large hidden
616+
# dim is still sharded on data_dim for memory. The broad "attention"
617+
# wildcard covers both the encoder's self_attention and the decoder's
618+
# merged (self+cross) attention, which share the same
602619
# query/key/value/attention_output naming.
603620
layout_map["encoder_layer.*attention.*query.kernel"] = (
604-
model_dim,
605621
data_dim,
622+
model_dim,
606623
None,
607624
)
608625
layout_map["encoder_layer.*attention.*(key|value).kernel"] = (
609-
model_dim,
626+
data_dim,
610627
None,
611628
None,
612629
)
@@ -616,12 +633,12 @@ def get_layout_map(
616633
data_dim,
617634
)
618635
layout_map["decoder_layer.*attention.*query.kernel"] = (
619-
model_dim,
620636
data_dim,
637+
model_dim,
621638
None,
622639
)
623640
layout_map["decoder_layer.*attention.*(key|value).kernel"] = (
624-
model_dim,
641+
data_dim,
625642
None,
626643
None,
627644
)
@@ -636,6 +653,29 @@ def get_layout_map(
636653
layout_map["decoder_layer.*gate_proj.kernel"] = (data_dim, model_dim)
637654
layout_map["decoder_layer.*up_proj.kernel"] = (data_dim, model_dim)
638655
layout_map["decoder_layer.*down_proj.kernel"] = (model_dim, data_dim)
656+
657+
# Vision encoder (Gemma3VisionEncoder), present only for multimodal
658+
# variants. All 2-D Dense kernels `(in, out)`: qkv/mlp_dense_1 are
659+
# column-parallel (fused output on model_dim), out_proj/mlp_dense_2 and
660+
# the vision_input_projection are row-parallel. The patch
661+
# `embedding_conv`, `position_embedding`, pooling, all vision
662+
# norms/biases, and the interleave/EOI embeddings are intentionally
663+
# left replicated (small; sharding them adds divisibility risk for no
664+
# memory benefit). These rules are inert when `vision_encoder=None`.
665+
layout_map[
666+
"image_encoder.*multi_head_attention.*"
667+
"(query_proj|key_proj|value_proj).kernel"
668+
] = (data_dim, model_dim)
669+
layout_map["image_encoder.*multi_head_attention.*out_proj.kernel"] = (
670+
model_dim,
671+
data_dim,
672+
)
673+
layout_map["image_encoder.*mlp_dense_1.kernel"] = (data_dim, model_dim)
674+
layout_map["image_encoder.*mlp_dense_2.kernel"] = (model_dim, data_dim)
675+
layout_map["vision_output_encoder.*vision_input_projection.kernel"] = (
676+
model_dim,
677+
data_dim,
678+
)
639679
return layout_map
640680

641681
@classmethod

0 commit comments

Comments
 (0)