Skip to content

ort_genai: native processor configs for gemma-4-12B unified - #391

Merged
titaiwangms merged 7 commits into
mainfrom
gemma4-unified-native-processor
Sep 18, 2026
Merged

titaiwangms merged 7 commits into
mainfrom
gemma4-unified-native-processor

Conversation

@justinchuby

Copy link
Copy Markdown
Member

Problem

For the encoder-free gemma-4-12B "unified" model, mobius deliberately did not emit image_processor.json or audio_feature_extraction.json, and its genai_config.json mapped model.type to gemma4. The unified model's inputs (48px merged pixel patches / raw 640-sample waveform frames) had no native ORT GenAI preprocessing, so the only way to run it was HuggingFace AutoProcessor + Generator.set_inputs. The emitted genai_config referenced processor files that were never written (a dangling reference; harmless for set_inputs but broken for MultiModalProcessor).

Change

With native ORT GenAI support now available (companion PRs below), emit the correct processor configs:

  • model.type: gemma4_unified → dedicated gemma4_unified ORT GenAI type (was gemma4).
  • image_processor.json: DecodeImage → Gemma4ImageTransform at patch_size=48, pooling_kernel_size=1 (patch_dim 6912). HF produces the merged patches via 16px patchify + 3×3 patches_merge, which is provably identical to a direct 48px patchify, so the existing op is reused with merged geometry.
  • audio_feature_extraction.json: AudioDecoder → Gemma4UnifiedAudioFrames (raw 640-sample framing) instead of the 128-dim log-mel op.

The text-only unified backbone (gemma4_unified_text) still resolves to gemma4_text (unchanged).

Dependencies

Testing

auto_export_test.py + genai_config_test.py: 115 passed. Updated the three unified tests to assert the emitted configs (48/1 image transform, raw-frame audio op, gemma4_unified type). ruff, ruff format, and mypy clean on the changed source.

The encoder-free gemma-4-12B "unified" model can now be preprocessed
natively by ORT GenAI (no HuggingFace processor / set_inputs needed), so
stop skipping its processor artifacts and emit the correct configs:

* model.type: gemma4_unified now maps to the dedicated "gemma4_unified"
  ORT GenAI multimodal type (was reusing "gemma4").
* image_processor.json: DecodeImage -> Gemma4ImageTransform configured
  for the 48px merged-patch contract (patch_size=48, pooling_kernel_size=1,
  patch_dim=6912). HF builds these via 16px patchify + 3x3 patches_merge,
  which is identical to a direct 48px patchify, so the existing op is
  reused with merged geometry.
* audio_feature_extraction.json: AudioDecoder -> Gemma4UnifiedAudioFrames
  (raw 640-sample waveform framing) instead of the 128-dim log-mel op.

Requires the companion onnxruntime-extensions (Gemma4UnifiedAudioFrames)
and onnxruntime-genai (gemma4_unified processor) support. Updates the
unified auto_export tests to assert the emitted configs.

Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
@justinchuby
justinchuby requested review from a team and a lite review from Copilot July 9, 2026 18:11
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

🏗️ Architecture Diff

Comparing 223b438ee003de74

Model Sub-model Changes Status

No architecture changes detected.


Legend: ⚪ No change · 🔵 Minor (attrs/inits) · 🟡 Moderate (nodes added/removed) · 🔴 Major (interface changed)

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

Performance Comparison

Comparing 223b438ee003de74

Model Metric Baseline Current Delta
bert (feature-extraction) model_size_bytes 359 KB 359 KB +0.0%
bert (feature-extraction) num_nodes 68 68 +0.0%
falcon model_size_bytes 364 KB 364 KB +0.0%
falcon num_nodes 66 66 +0.0%
gemma2 model_size_bytes 428 KB 428 KB +0.0%
gemma2 num_nodes 105 105 +0.0%
gpt2 model_size_bytes 324 KB 324 KB +0.0%
gpt2 num_nodes 54 54 +0.0%
llama model_size_bytes 425 KB 425 KB +0.0%
llama num_nodes 60 60 +0.0%
llama (static-cache) model_size_bytes 425 KB 425 KB +0.0%
llama (static-cache) num_nodes 56 56 +0.0%
mamba (ssm-text-generation) model_size_bytes 296 KB 296 KB +0.0%
mamba (ssm-text-generation) num_nodes 94 94 +0.0%
phi3 model_size_bytes 421 KB 421 KB +0.0%
phi3 num_nodes 58 58 +0.0%
phi3 (static-cache) model_size_bytes 421 KB 421 KB +0.0%
phi3 (static-cache) num_nodes 54 54 +0.0%
qwen2 model_size_bytes 425 KB 425 KB +0.0%
qwen2 num_nodes 60 60 +0.0%
qwen2 (static-cache) model_size_bytes 425 KB 425 KB +0.0%
qwen2 (static-cache) num_nodes 56 56 +0.0%
qwen3_5_moe (hybrid-text-generation) model_size_bytes 506 KB 506 KB +0.0%
qwen3_5_moe (hybrid-text-generation) num_nodes 265 265 +0.0%
qwen3_5_text (hybrid-text-generation) model_size_bytes 458 KB 458 KB +0.0%
qwen3_5_text (hybrid-text-generation) num_nodes 127 127 +0.0%
qwen3_5_vl (hybrid-qwen-vl) model_size_bytes 977 KB 977 KB +0.0%
qwen3_5_vl (hybrid-qwen-vl) num_nodes 450 450 +0.0%
t5 (seq2seq) model_size_bytes 836 KB 836 KB +0.0%
t5 (seq2seq) num_nodes 176 176 +0.0%
whisper (speech-to-text) model_size_bytes 1008 KB 1008 KB +0.0%
whisper (speech-to-text) num_nodes 128 128 +0.0%

No performance regressions.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates Mobius’ ORT GenAI auto-export integration to emit native processor configs for the encoder-free Gemma-4-12B “unified” model, aligning exported artifacts with newly available ORT GenAI + ort-extensions preprocessing support.

Changes:

  • Map HF model_type="gemma4_unified" to ORT GenAI model.type="gemma4_unified" (instead of reusing gemma4).
  • Emit image_processor.json for unified models using DecodeImage → Gemma4ImageTransform with patch_size=48 and pooling_kernel_size=1.
  • Emit audio_feature_extraction.json for unified models using AudioDecoder → Gemma4UnifiedAudioFrames (raw 640-sample framing), and update tests to assert these outputs.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
src/mobius/integrations/ort_genai/auto_export.py Updates ORT GenAI model-type mapping and writes unified-specific image/audio processor configs.
src/mobius/integrations/ort_genai/auto_export_test.py Adjusts expectations and adds assertions for unified processor config emission and attributes.

@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Follow the onnxruntime-extensions consolidation: both gemma4 audio configs
now use the single Gemma4Audio op with an explicit type attribute instead of
two separate op types.

* gemma4 / gemma4_text  -> Gemma4Audio type="log_mel"  (128-dim USM log-mel)
* gemma4_unified*       -> Gemma4Audio type="raw_frames" (raw 640-sample frames)

Updates the auto_export audio-config tests accordingly. 115 tests pass.

Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
…-processor

# Conflicts:
#	src/mobius/integrations/ort_genai/auto_export.py
Copilot AI review requested due to automatic review settings August 4, 2026 04:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/mobius/integrations/ort_genai/auto_export.py:783

  • PR description (and the earlier module-level comment) refer to a Gemma4UnifiedAudioFrames ort-extensions op for unified audio framing, but the emitted processor config here uses Gemma4Audio with attrs.type="raw_frames". If ORT GenAI / ort-extensions expects the dedicated Gemma4UnifiedAudioFrames op name, this config will fail to load at runtime; if Gemma4Audio(raw_frames) is the intended API, the PR description (and any related docs) should be updated for consistency.
                        "operation": {
                            "name": "gemma4_audio",
                            "type": "Gemma4Audio",
                            "attrs": {
                                "type": "raw_frames",
                                "audio_samples_per_token": samples_per_token,
                                "sampling_rate": 16000,
                                "padding_value": 0.0,
                            },

src/mobius/integrations/ort_genai/auto_export.py:109

  • The comment describing the unified Gemma4 audio preprocessing mentions a Gemma4UnifiedAudioFrames op, but this PR’s emitted audio processor config uses the Gemma4Audio op with attrs.type="raw_frames" (and there are no other references to Gemma4UnifiedAudioFrames in the repo). This comment should be updated to match the actual emitted config to avoid misleading future readers.

This issue also appears on line 775 of the same file.

# These are produced natively by ort-extensions: ``Gemma4ImageTransform`` with
# patch_size=48 / pooling_kernel_size=1 (the 48px merged patch is identical to a
# direct 48px patchify) and the ``Gemma4UnifiedAudioFrames`` raw-framing op. The
# genai ``gemma4_unified`` processor consumes both (see the companion
# onnxruntime-genai / onnxruntime-extensions support).

@rui-ren

rui-ren commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

…-processor

Signed-off-by: GitHub <noreply@github.com>

# Conflicts:
#	src/mobius/integrations/ort_genai/auto_export.py
#	src/mobius/integrations/ort_genai/auto_export_test.py

Co-authored-by: rui-ren <15321482+rui-ren@users.noreply.github.com>

Copilot AI commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merged origin/main and resolved the conflicts in 01cd63c:

  • auto_export.py: kept main's new MiniCPM / LFM2-VL image-processor skips and dropped the now-obsolete gemma4_unified skip, so the unified model keeps emitting the 48px merged-patch Gemma4ImageTransform config.
  • auto_export_test.py: kept main's new Qwen2.5/Mage-VL packed-patch tests alongside test_gemma4_unified_image_processor, and adopted main's generic "decoder" ORT type assertion for the text-only unified backbone (main normalizes decoder-only packages to decoder).

auto_export_test.py + genai_config_test.py: 288 passed; the only 2 failures are network-dependent HuggingFace downloads in this sandbox.

Lock the exported vision and audio graph ABI, processor attributes, runtime model type, semantic input mappings, and multimodal token metadata to the Extensions and GenAI consumer contracts.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e64e522-b07f-4c1c-abf1-3985268beb7e
Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
@CLAassistant

CLAassistant commented Sep 15, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.
2 out of 3 committers have signed the CLA.

✅ titaiwangms
✅ justinchuby
❌ Copilot
You have signed the CLA already but the status is still pending? Let us recheck it.

justinchuby and others added 2 commits September 15, 2026 11:41
Bring the PR onto origin/main at 8c1bf54 without rebasing while preserving the native Gemma4 unified preprocessing contract.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 6e64e522-b07f-4c1c-abf1-3985268beb7e
Signed-off-by: Justin Chu <justinchuby@users.noreply.github.com>
@titaiwangms
titaiwangms enabled auto-merge (squash) September 18, 2026 18:11
@titaiwangms
titaiwangms merged commit 6b27a3f into main Sep 18, 2026
22 of 25 checks passed
@titaiwangms
titaiwangms deleted the gemma4-unified-native-processor branch September 18, 2026 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants