feat: add Gemma3 VLM OpenXLA path (#869)#917
Draft
inureyes wants to merge 11 commits into
Draft
Conversation
7 tasks
inureyes
force-pushed
the
feature/issue-869-gemma3-vlm-xla
branch
from
July 27, 2026 00:22
002bb77 to
c4e5d22
Compare
Member
Author
|
Rebased onto Post-rebase validation:
The shared vision runtime inherited #934’s explicit |
Emit the pinned Gemma3 SigLIP tower, average-pool projector, and nested text configuration through native IREE while preserving Gemma3 embedding scaling and authoritative bidirectional padding masks. Route image requests through the filtered host embedding table and resident projector without a duplicate decoder or silent host fallback. Validate prepared-prefill contracts, host/server seams, product feature compilation, and a real CUDA projector execution. Refs #869
Apply configured block prefix and suffix tokens when inserting image blocks into prompts without an existing placeholder, so Gemma3 bare-prompt CLI and server requests match the processor's newline, BOI, image-token, EOI, newline sequence while families with empty wrappers remain unchanged. Include wrapper lengths in checked capacity arithmetic and cover both the Gemma3 insertion sequence and the existing unwrapped insertion behavior. Refs #869
Treat root Gemma3 configurations as nested VLM wrappers only when they also declare a vision_config object. This preserves the existing text-only Gemma3 parser path while retaining nested text defaults and wrapper quantization for actual VLM checkpoints. Add direct-root and nested-wrapper regressions to keep the two configuration shapes distinct. Refs #869
Compare the authoritative Gemma3 VLM additive mask and post-scale embedding boundary against a deterministic Hugging Face eager checkpoint executed through the real IREE local-task graph. Cover logits, selected all-layer KV caches, greedy token parity, and negative causal-mask, multiplicative-mask, double-scale, and image-pre-scale regressions. Validation: gemma3_vlm_mask_check.py passes on llvm-cpu/local-task. Refs #869
Gemma3 eager SigLIP applies post_layernorm before the average-pool projector, but the resident IREE graph omitted those weights and the normalization, causing the first vision-boundary divergence. Add the Gemma3-only post-layernorm schema and artifact generation, plus a CPU/local-task diagnostics feature and pinned ignored gate that compares processor pixels, early and final SigLIP stages, projector rows, one-time embedding scaling, and every additive-mask cell without loading a duplicate decoder. Validation: cargo test -p mlxcel-xla --lib gemma3_ (8 passed); cargo test --features xla-reference-diagnostics --lib comparison_reports_the_first_failed_element (1 passed); cargo clippy --features xla-reference-diagnostics --lib --tests --fix --allow-dirty --allow-staged --no-deps (existing warnings only). The real-checkpoint ignored gate was not run. Refs #869
Bind the authoritative prepared-prefill schema, mask and scaling policies, prompt token IDs, vision config, and sliding attention settings into the single and ragged IREE bundle fingerprints through an explicit stable identity. Preserve the existing dense identity verbatim for text-only Gemma3 sessions. Refs #869
Extract the pinned Gemma3 eager MLX and IREE comparison into a feature-gated library entry point and a dedicated CUDA example that avoids the libtest harness. Keep the existing comparison stages and tolerances while adding flushed stage progress and 60-second heartbeats around long-running model work.
Configure IREE's process-global task topology exactly once before the standalone Gemma3 reference runner creates its first local-task instance, limiting diagnostics to one topology group after the bounded actual reached IREE and failed worker creation with EINVAL. Keep the synthetic flag parser behind mlxcel-xla's diagnostics feature and leave shared xla_aux/xla_iree production startup unchanged. Cache both success and failure, propagate configuration errors before instance creation, and cover ordering, repeated calls, and production-path isolation. Validation: rustfmt check; focused diagnostic runner and topology tests; xla-reference-diagnostics clippy; CUDA standalone example cargo check; linked-symbol inspection and native parser invocation. Refs #869
The bounded standalone run at 3e5edab passed every eager MLX stage but still failed when IREE local-task called pthread_create with EINVAL. The pinned runtime requests a 128 KiB worker stack, exactly this host's PTHREAD_STACK_MIN, through a pthread attribute that the host rejects. Extend the diagnostics-only synthetic argv with `--task_worker_stack_size=0` alongside the existing single-group flag so pthreads use the host-default stack. Rename the one-shot helper for its complete threading role while preserving cached success/failure, error propagation, and production startup isolation. Validation: rustfmt check; five focused threading configuration regressions; native two-flag parser invocation and reuse; linked-symbol inspection; xla-reference-diagnostics Clippy with existing warnings only. Refs #869
Compare the existing eager and IREE hidden-state captures through shared block 6, 13, 20, and final-block descriptors so one bounded run partitions blocks 1 through 26 into four balanced first-failure intervals without changing the production graph, numerical tolerances, or diagnostic worker flags. Emit the ordered checkpoint statuses and inferred inclusive block range, and lock the exact labels, indices, ordering, and interval widths with focused tests. Validated the diagnostics reference-boundary tests, rustfmt, and Clippy with the xla-reference-diagnostics feature. Refs #869
The balanced checkpoint run localized the first post-block-0 divergence to blocks 1 through 6 but could not identify the exact block. Compare block outputs 1 through 5 before the existing block-6 bisection boundary, preserve the later block 13, 20, and final checkpoints, and emit an ordered block-1-through-6 status summary with the exact first failing block. The diagnostic reuses existing eager and IREE captures without changing graph outputs, production behavior, tolerances, worker flags, or artifacts. Validated the complete reference-boundary test group, rustfmt, and Clippy with the xla-reference-diagnostics feature. Refs #869
inureyes
force-pushed
the
feature/issue-869-gemma3-vlm-xla
branch
from
July 27, 2026 04:13
c4e5d22 to
9ab1399
Compare
Member
Author
Rebase and bounded SigLIP evidence — 2026-07-27
|
31 tasks
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
post_layernormafter the final encoder block on the IREE path, matching the eager MLX tower, and version the vision artifact identity for the corrected graph.sqrt(hidden)scaling, and the exact bidirectional padding mask.xla_gemma3_reference_checkCUDA example so it avoids the libtest harness, while retaining the ignored test as a thin wrapper and emitting flushed stage progress plus 60-second heartbeats.local-taskinstance: one topology group and host-default pthread stacks, with cached success/failure and no shared productionxla_aux/xla_ireestartup change.Validation
cargo test -p mlxcel-xla --lib gemma3_(8 passed)cargo test -p mlxcel-xla prepared_gemma3 --lib(7 passed, including stable contract field sensitivity and unchanged text-only identity)cargo test -p mlxcel-xla --features iree gemma3_vlm_compatibility --lib(2 passed: wrapper contract binding and direct-root text-only identity)cargo test -p mlxcel-xla gemma3_avg_pool_projector_binds_pool_and_prompt_contract --lib(1 passed)cargo test -p mlxcel-xla qwen2_vl --libafter rebasing feat(xla): support Qwen2-VL as the representative M-RoPE VLM #865 (4 passed)cargo test --features xla-iree --lib host_preprocessorafter rebasing feat(xla): support Qwen2-VL as the representative M-RoPE VLM #865 (13 passed)cargo test --lib vlm_prompt(16 passed, including bare Gemma3 wrapping and unchanged unwrapped LLaVA insertion)cargo test -p mlxcel-xla gemma3 --lib(52 passed, 2 ignored, including direct-root and nested-wrapper configuration regressions)llama,qwen2_vl, andgemma3capability regression gatecargo check --features xla-iree --lib --binscargo fmt --all -- --checkIREE_DIST=... cargo check --no-default-features --features xla-reference-diagnostics --libIREE_DIST=... cargo clippy --no-default-features --features xla-reference-diagnostics --lib(existing warnings only)xla_gemma3_reference_checkrequires bothcudaandxla-reference-diagnostics./home/inureyes/models/gemma-3-4b-it-4bit: compiled and returned finite[256, 2560]projected features in 32.17 seconds.mlxcel generaterun with the pinned checkpoint and image fixture completed successfully (k, 1 token, exit 0; reported generation time 8.11s).local-taskGemma3 VLM embeddings/mask oracle: logits max absolute difference 0.006675, greedy token exact (14), all-layer K/V within max 0.25, RMS 0.1, and cosine 0.99 envelopes; causal-mask, multiplicative-mask, double-scale, and missing-image-pre-scale negatives all diverged.xla_aux/xla_ireeisolation (5 passed across filtered runs).xla_diagnostics_configure_local_task_threadsandiree_flags_parse; the native reuse test proved the pinned 3.11 parser accepts and consumes both synthetic flags.IREE_DIST=... cargo check --no-default-features --features cuda,xla-reference-diagnostics --example xla_gemma3_reference_checkIREE_DIST=... cargo test --features xla-reference-diagnostics --lib reference_boundary::(10 passed, 1 actual ignored; includes exact balanced descriptors, ordered block-1-through-6 refinement descriptors, interval bounds, and exact-failure selection)c44147f8kept processor pixels,siglip.hidden.embedding, and every block-0 sub-stage passing.siglip.hidden.block6.outputfailed first with 333 failures, max absolute difference1.760086, and first failure at flat index 42197; block 13 failed with 35,808 failures and max absolute difference1.969528, block 20 failed with 489,930 failures and max absolute difference68.06642, andsiglip.hidden.last_pre_layernormfailed with 1,408,110 failures and max absolute difference1302.648. The coarse report resolvedfirst_failing_block_range=1..=6.002bb77ekept the prepared-prefill self/invariant and mask checks passing exactly.siglip.hidden.block1.outputfailed first with 8 failing values, max absolute difference0.6672516, and first failure at flat index 658517; block 2 failed with 18 values and max absolute difference0.7214432, block 3 with 61 and1.209267, block 4 with 73 and1.210052, block 5 with 133 and1.209457, and block 6 with 333 and1.760086.exact_first_failing_block=1. Exit 101 is the diagnostic's intended first-divergence panic atsiglip.hidden.block1.outputflat index 658517, not a worker-creation regression; numeric acceptance remains open. No further actual was run, and graph outputs, production behavior, tolerances, CSV handling, and diagnostic stack flags are unchanged.Runtime notes
xla-ireefeature and rejectsMLXCEL_XLA_VISION_BACKEND=hostexplicitly.local-task; immediately before its first IREE instance it applies--task_topology_group_count=1and--task_worker_stack_size=0once through the diagnostics-only flag parser.Closes #869