Add Liger Kernel support for Gemma 4 Unified multimodal (gemma4_unified) - #1312
Draft
lefft wants to merge 2 commits into
Draft
Add Liger Kernel support for Gemma 4 Unified multimodal (gemma4_unified)#1312lefft wants to merge 2 commits into
lefft wants to merge 2 commits into
Conversation
This was referenced Jul 22, 2026
lefft
marked this pull request as ready for review
July 22, 2026 04:27
Mirrors the gemma4_text (omni) support: apply_liger_kernel_to_gemma4_unified_text with an FLCE causal forward for Gemma4UnifiedForCausalLM, RMSNorm/GeGLU class swaps targeting modeling_gemma4_unified (reusing the Gemma4 wrapper classes), the shared LigerGemma4UnifiedCausalLMOutputWithPast output class, a registry entry for model_type gemma4_unified_text, monkey-patch unit tests, and bf16 convergence coverage (FLCE-enabled text rows). Multimodal support (apply_liger_kernel_to_gemma4_unified for Gemma4UnifiedForConditionalGeneration) follows in a stacked PR, mirroring how gemma4 shipped (linkedin#1196 text -> linkedin#1203 multimodal). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stacks on the gemma4_unified_text PR, mirroring how gemma4 shipped (linkedin#1196 text -> linkedin#1203 multimodal): apply_liger_kernel_to_gemma4_unified installs multimodal_forward (FLCE) on Gemma4UnifiedForConditionalGeneration — the class google/gemma-4-12B / gemma-4-12B-it load as — and reuses the text PR's RMSNorm/GeGLU class swaps and shared output class via apply_liger_kernel_to_gemma4_unified_text. Adds the registry entry for model_type gemma4_unified, the conditional-generation monkey-patch test, and bf16/fp32 multimodal convergence coverage (FLCE disabled by design, matching mini_gemma4). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Author
|
Rebased onto current #1313 landed after this PR was opened and gave the
Applied both to the unified rows in the bf16 and fp32 files. With the processor unblocked, the new Re-ran everything on the rebased HEAD at transformers 5.10.1 and 5.14.1 (Modal H100, torch
|
lefft
marked this pull request as draft
July 24, 2026 23:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds Liger Kernel support for Gemma 4 Unified multimodal models
(
Gemma4UnifiedForConditionalGeneration,model_type: gemma4_unified):apply_liger_kernel_to_gemma4_unified, with RMSNorm, GeGLU, CrossEntropyLoss, andFusedLinearCrossEntropy.
Liger Kernel already supports the other Gemma 4 families —
gemma4_text(dense text, #1196) andgemma4(omni multimodal, #1203). Butgoogle/gemma-4-12B/gemma-4-12B-itload asGemma4UnifiedForConditionalGeneration(model_type: gemma4_unified) from their ownmodeling_gemma4_unifiedmodule, which the existing patches don't reach —_apply_liger_kernelno-ops with
no Liger kernels supported for model type: gemma4_unified. This is the PR thatunblocks the 12B checkpoints; text-only fine-tuning of them also lands here, since that's the class
they instantiate as.
Closes #1308.
Details
apply_liger_kernel_to_gemma4_unified_textinternally, then installs the multimodalmultimodal_forwardonGemma4UnifiedForConditionalGeneration.Gemma4UnifiedCausalLMOutputWithPast(extended withliger's
token_accuracy/predicted_tokens), passingshared_kv_statesthrough alongside theimage/audio hidden states.
vocabulary, so the
[B, T, 262144]logits tensor is ~32 GiB in bf16 at T=65,536 (and ~64 GiB oncethe loss path upcasts to fp32), OOMing even 141 GB cards after the forward's activations. Fused CE
materializes only the loss scalar.
final_logit_softcapping(30.0 on the 12B checkpoint) flows through both loss paths.gemma4_unified_assistantmodel_type,LayerNorm kernels for the encoder-free vision embedder, and the audio path in convergence tests.
layer_normis accepted for API compatibility but applies no kernels.mini_gemma4); thefused path through the CondGen class was validated separately — see Testing Done.
main(post-Fix convergence test failures #1313), with the newmini_gemma4_unifiedrows given the sametreatment Fix convergence test failures #1313 gave the
mini_gemma4sibling, since both families hit the same two upstreamissues:
validate_inputsoperator-precedence bug (audio is not None and self.audio_token is None or self.boa_token is None or ...) raises the audioValueErrorwith no audio inputs wheneverboa/eoatokens are unset — fixed the same way, by setting dummy placeholders on the miniprocessor (audio is not exercised in convergence);
the two
mini_gemma4_unifiedrows carry the samexfail(strict=False)as their sibling rows.They will auto-flag
XPASSif a future transformers release realigns the numerics.Testing Done
Environment: Modal H100, torch 2.13.0+cu130, triton 3.7.1; all suites re-run after rebasing onto
main@ ed08f6e, at transformers 5.10.1 and 5.14.1 (current.[dev]resolve). Resultsidentical at both versions: every gemma4-filtered command exits 0.
make checkstyle:test/transformers/test_monkey_patch.py -k gemma4— 4/4 (both new unified instance tests plus bothgemma4 omni sibling tests as regression check):
FLCE-through-
Gemma4UnifiedForConditionalGenerationnumerical check — 20 fp32 optimizer steps, HFvs liger from identical init (the multimodal convergence harness runs with FLCE disabled by design,
so this covers the fused path through the CondGen class):
Text convergence rows (inherited from the stacked text PR, re-run on this branch) pass alongside the
sibling rows:
Multimodal convergence — the new
mini_gemma4_unifiedrows now land asxfailin lockstep with themini_gemma4sibling rows, so both files exit 0:Real-workload validation: a 64k-sequence full fine-tune of
google/gemma-4-12B-it(transformers 5.10.1, torch 2.13.0, FSDP full-shard + flex_attention, 8×H100-class) that OOMs at
step 1 without this port (128.6/139.8 GiB per GPU already used after the forward; the unfused loss
then tries to materialize ~32 GiB of logits) trains cleanly with it — finite, decreasing loss
(1.98 → 0.91 over the first 15 steps).
make testto ensure correctness — on this branch's rebased HEAD (transformers 5.14.1): 3907 passed, 1181 skipped, 14 xfailed in 43:06 — zero failuresmake checkstyleto ensure code stylemake test-convergenceto ensure convergence — gemma4-filtered rows as above; all commands exit 0 at both transformers versions