Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions src/mobius/integrations/ort_genai/auto_export.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,30 +173,49 @@ def _write_processor_config(
model_type = getattr(config, "model_type", "")

if model_type in ("gemma4", "gemma4_text"):
# Gemma4 needs a processor wrapper with model-specific fields
tokens_per_image = (
# Gemma4 needs an onnxruntime-extensions format processor config
# with a transforms pipeline (DecodeImage -> Gemma4ImageTransform).
# The OrtxCreateProcessor API requires this format.
max_soft_tokens = (
Comment thread
justinchuby marked this conversation as resolved.
getattr(vision, "mm_tokens_per_image", None)
or getattr(config, "mm_tokens_per_image", None)
or getattr(vision, "max_soft_tokens", None)
Comment thread
apsonawane marked this conversation as resolved.
Outdated
or 280
)
image_size = getattr(vision, "image_size", None) or 448
patch_size = getattr(vision, "patch_size", None) or 16
processor: dict[str, Any] = {
pooling_kernel_size = getattr(vision, "pooling_kernel_size", None) or 3
processor = {
"processor": {
"name": "gemma4_image_processor",
"image_size": image_size,
"patch_size": patch_size,
"tokens_per_image": tokens_per_image,
"name": "gemma_4_image_processing",
"transforms": [
{
"operation": {
"name": "decode_image",
"type": "DecodeImage",
"attrs": {"color_space": "RGB"},
}
},
{
"operation": {
"name": "gemma4_image_transform",
"type": "Gemma4ImageTransform",
"attrs": {
"patch_size": patch_size,
"max_soft_tokens": max_soft_tokens,
"pooling_kernel_size": pooling_kernel_size,
},
}
},
],
}
}
proc_filename = "image_processor.json"
else:
Comment thread
apsonawane marked this conversation as resolved.
processor = {
"image_size": getattr(vision, "image_size", None) or 448,
"patch_size": getattr(vision, "patch_size", None) or 14,
}

proc_filename = "processor_config.json"
proc_filename = "processor_config.json"

path = os.path.join(output_dir, proc_filename)
with open(path, "w", encoding="utf-8") as f:
Expand Down Expand Up @@ -280,6 +299,7 @@ def _write_genai_config(
vision_cfg = getattr(config, "vision", None)
sms = getattr(vision_cfg, "spatial_merge_size", 2)
vision_kwargs["spatial_merge_size"] = sms
vision_kwargs["config_filename"] = "image_processor.json"

Comment thread
justinchuby marked this conversation as resolved.
if vision_input_mapping is not None:
vision_kwargs["input_names"] = vision_input_mapping
Expand Down
2 changes: 1 addition & 1 deletion src/mobius/integrations/ort_genai/auto_export_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -780,7 +780,7 @@ def test_gemma4_genai_config_from_real_model(self, tmp_path):
# Config-level properties are still present
assert data["model"]["image_token_id"] == 255999
assert data["model"]["vision"]["spatial_merge_size"] == 2
assert data["model"]["vision"]["config_filename"] == "processor_config.json"
assert data["model"]["vision"]["config_filename"] == "image_processor.json"
Comment thread
apsonawane marked this conversation as resolved.

def test_auto_export_produces_genai_config(self, tmp_path):
"""Mock build() to return a tiny package, verify genai_config."""
Expand Down
Loading