Skip to content

Commit abeba51

Browse files
fix(models): Fix Gemma3n TF backend .fit() crash with GQA (#2712)
* fix: Use ops.shape() for dynamic dims * refactor: Use run_task_test()
1 parent 47c2871 commit abeba51

2 files changed

Lines changed: 54 additions & 1 deletion

File tree

keras_hub/src/models/gemma3n/gemma3n_attention.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def repeat_kv(self, hidden_states):
365365
for grouped-query attention."""
366366
if self.num_key_value_groups == 1:
367367
return hidden_states
368-
batch, num_key_value_heads, slen, head_dim = hidden_states.shape
368+
batch, num_key_value_heads, slen, head_dim = ops.shape(hidden_states)
369369
hidden_states = ops.expand_dims(hidden_states, 2)
370370
hidden_states = ops.repeat(
371371
hidden_states, self.num_key_value_groups, axis=2

keras_hub/src/models/gemma3n/gemma3n_causal_lm_test.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,3 +377,56 @@ def test_multimodal_generate(self):
377377
}
378378
output = causal_lm.generate(inputs)
379379
self.assertIsInstance(output, str)
380+
381+
def test_gqa_fit(self):
382+
# Test fit() with GQA (num_heads != num_kv_heads).
383+
preprocessor = Gemma3nCausalLMPreprocessor(
384+
tokenizer=self.tokenizer,
385+
image_converter=None,
386+
audio_converter=None,
387+
sequence_length=20,
388+
max_images_per_prompt=0,
389+
num_vision_tokens_per_image=0,
390+
max_audios_per_prompt=0,
391+
num_audio_tokens_per_audio=0,
392+
)
393+
backbone = Gemma3nBackbone(
394+
text_vocab_size=preprocessor.tokenizer.vocabulary_size(),
395+
text_hidden_size=8,
396+
num_hidden_layers=1,
397+
pad_token_id=0,
398+
num_attention_heads=4,
399+
num_key_value_heads=2,
400+
head_dim=2,
401+
intermediate_size=[16],
402+
hidden_activation="gelu_approximate",
403+
layer_types=["full_attention"],
404+
sliding_window=4,
405+
rope_theta=10000.0,
406+
max_position_embeddings=20,
407+
vocab_size_per_layer_input=10,
408+
hidden_size_per_layer_input=2,
409+
altup_num_inputs=2,
410+
laurel_rank=1,
411+
)
412+
self.run_task_test(
413+
cls=Gemma3nCausalLM,
414+
init_kwargs={
415+
"preprocessor": preprocessor,
416+
"backbone": backbone,
417+
},
418+
train_data=(
419+
{
420+
"prompts": ["the quick brown fox", "the quick brown fox"],
421+
"responses": [
422+
"the earth is round",
423+
"the earth is round",
424+
],
425+
},
426+
),
427+
expected_output_shape=(
428+
2,
429+
20,
430+
preprocessor.tokenizer.vocabulary_size(),
431+
),
432+
)

0 commit comments

Comments
 (0)