[Mistral3] Add VLM support with multi-image inference - #2077
Merged
Conversation
titaiwangms
marked this pull request as draft
April 8, 2026 23:17
titaiwangms
force-pushed
the
pr/mistral3-vlm-support
branch
from
April 8, 2026 23:41
09b475c to
accc0ee
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adds end-to-end support for Pixtral/Ministral-3 (Mistral3ForConditionalGeneration) vision-language models across the C++ runtime (VLM registration + image processor) and the Python ModelBuilder (architecture dispatch + FP8 weight handling) so the text decoder and vision inputs can be exported/consumed by ORT GenAI.
Changes:
- Register
mistral3as a VLM type and wire up aMistral3ImageProcessorin the C++ processor factory. - Implement Pixtral-specific prompt/image preprocessing (special token expansion, NHWC→NCHW transpose, spatial-merge-aware token counting).
- Add Python ModelBuilder support for
Mistral3ForConditionalGenerationviaMistral3TextModeland builder dispatch/config flattening.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/models/model_type.h | Adds mistral3 to the VLM type set so it routes through multimodal model codepaths. |
| src/models/model.cpp | Registers Mistral3ImageProcessor in MultiModalProcessor factory. |
| src/models/mistral3_image_processor.h | Declares the Pixtral image processor used by the runtime. |
| src/models/mistral3_image_processor.cpp | Implements Pixtral prompt expansion, pixel preprocessing, and NHWC→NCHW transpose. |
| src/python/py/models/builder.py | Adds architecture dispatch for Mistral3ForConditionalGeneration and config adjustments for text-only export. |
| src/python/py/models/builders/mistral.py | Introduces Mistral3TextModel with FP8 linear weight dequantization when loading HF weights. |
| src/python/py/models/builders/init.py | Exports Mistral3TextModel for builder imports. |
titaiwangms
force-pushed
the
pr/fix-yarn-config-resolution
branch
from
April 9, 2026 20:28
dbb6147 to
d786f35
Compare
titaiwangms
force-pushed
the
pr/mistral3-vlm-support
branch
10 times, most recently
from
April 10, 2026 00:03
3600ddf to
ffae0a0
Compare
titaiwangms
force-pushed
the
pr/fix-yarn-config-resolution
branch
from
April 10, 2026 21:10
d786f35 to
216066d
Compare
titaiwangms
marked this pull request as ready for review
April 10, 2026 21:15
titaiwangms
force-pushed
the
pr/mistral3-vlm-support
branch
from
April 10, 2026 21:46
ffae0a0 to
078d398
Compare
titaiwangms
requested review from
baijumeswani,
kunal-vaishnavi,
tianleiwu and
xadupre
April 10, 2026 21:51
Contributor
Author
This was referenced Apr 10, 2026
Add full Mistral3/Pixtral VLM support to onnxruntime-genai: Model builder (src/python/py/models/builders/mistral.py): - Mistral3TextModel builder with FP8 dequantization for quantized checkpoints - image_token_id injection into genai_config.json Image preprocessor (src/models/mistral3_image_processor.cpp): - ProcessPixtralPrompt: per-image token sequence with [IMG], [IMG_BREAK], [IMG_END] - Smart resize dimensions from image_sizes tensor with shape validation - NCHW transpose for ort-extensions NHWC output Multi-image vision loop (src/models/multi_modal.cpp): - PixtralVisionState: per-image vision.onnx execution with zero-padded slicing - SetExtraInputs override reads image_sizes for per-image dimensions - Uses actual tensor memory info for GPU-safe sub-tensor views - Explicit rejection of multi-image without image_sizes metadata - Overflow guard on feature buffer offsets Factory and config: - IsPixtralFamily() in model_type.h for vision state dispatch - YaRN RoPE parity test with GPT-OSS-20B config - Simplified type hierarchy test (compile-time static_asserts) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
titaiwangms
force-pushed
the
pr/mistral3-vlm-support
branch
from
April 20, 2026 20:49
b9bd58f to
f84c0f6
Compare
…ment cleanup - multi_modal.cpp: Add image_widths_ size validation matching heights check - multi_modal.cpp: Add h_i/w_i bounds checks before memcpy (0 < h_i <= h_max) - common.py: Add mistral3 model_type elif for multi-image [IMG] tags - test_mistral3_tokens.py: Clarify token IDs are test-only, add del generator comment - test_yarn_rope_parity.py: Remove duplicate comment header Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ral config Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kunal-vaishnavi
previously approved these changes
Apr 21, 2026
…mpty stub - mistral3_image_processor.cpp: Keep soft if/null fallback for image_sizes tensor. PixtralImageSizes step is not yet in processor_config.json (olive-recipes needs updating), so CheckResult would break single-image inference. Added clarifying comment explaining the dependency. - builders/base.py: Add pass to empty update_genai_config() method stub. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
titaiwangms
force-pushed
the
pr/mistral3-vlm-support
branch
from
April 21, 2026 22:50
a6f120e to
84978b2
Compare
The runtime should crash on misconfigured models (missing PixtralImageSizes) rather than silently producing wrong multi-image results. Models must be exported with PixtralImageSizes in processor_config.json. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
titaiwangms
enabled auto-merge (squash)
April 23, 2026 18:06
Add comment noting opportunity to explore batched image processing for improved throughput in PixtralVisionState. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
kunal-vaishnavi
approved these changes
Apr 24, 2026
titaiwangms
added a commit
to onnxruntime/mobius
that referenced
this pull request
Apr 30, 2026
…161) ## Summary Add an end-to-end olive-recipe demo for Ministral-3-3B VLM and enhance the mobius genai integration with Pixtral processor config support and tokenizer class remapping. ## Changes ### Core: genai integration enhancements (`src/mobius/integrations/ort_genai/`) - **`_write_processor_config`**: Enhanced to generate full ORT-extensions image transform pipeline for VL models. Dispatches by model type (Pixtral: longest_edge resize; generic: smart_resize). Derives normalization params from HF processor config. - **`_fix_tokenizer_config`**: New function with `_TOKENIZER_CLASS_REMAP` dict to remap unsupported tokenizer classes (e.g. `TokenizersBackend` → `LlamaTokenizer`). Called automatically from `write_ort_genai_config()`. - 4 new tests (31 total passing) ### Example: olive-recipe demo (`examples/olive/ministral-3-3b-vlm/`) - **optimize.py**: Pure mobius export (`build()` → `save()` → `write_ort_genai_config()`) with optional Olive quantization via `--olive-config` - **inference.py**: ORT GenAI multimodal inference (text-only, image+text, interactive) - **eval.py**: AI2D benchmark evaluation (ONNX vs PyTorch comparison) - Olive configs for CPU (INT4) and CUDA (FP16) quantization - README with setup, export, inference, and evaluation instructions ### Skills - New `olive-recipe` skill documenting the mobius + Olive hybrid pipeline pattern - Updated `ort-genai-config` skill with Pixtral processor config and tokenizer remap info ## References - [Issue #158](#158) - [PR #130](#130) (Pixtral/Ministral3 VLM support) - [olive-recipes PR #352](microsoft/olive-recipes#352) - [onnxruntime-genai PR #2077](microsoft/onnxruntime-genai#2077) Closes #158 --------- Signed-off-by: Ti-Tai Wang <titaiwang@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 Mistral3/Pixtral VLM support to onnxruntime-genai with multi-image inference. Includes C++ image processor, PixtralVisionState for per-image vision processing, Python export support, and comprehensive tests.
Changes
C++ Runtime
[IMG]/[IMG_BREAK]/[IMG_END]token expansion based on image resolution and patch geometry, multi-image supportimage_sizesmetadata from ort-extensionsPixtralImageSizesopSetExtraInputs— proper polymorphic dispatch for vision state subclassesIsPixtralFamily()model type detection — enables Pixtral-specific codepathprocessor_config.json— withPixtralImageSizespreprocessing stepcontext_length/max_lengthseparation —context_lengthcontrols KV cache allocation whilemax_lengthcontrols generation stopping, preventing premature EOS with large image token countsinput_ids— token IDs above 32767 (Pixtral[IMG]=128011) require int32Python Export Support
Mistral3Config,Mistral3ForConditionalGeneration)get_user_content()handler for Mistral3 prompt formattingMulti-Image Architecture
Pixtral uses dynamic image sizes (28×28 to 1540×1540) so images can't be batched in the vision encoder.
PixtralVisionStateprocesses each image individually by:image_sizestensor from ort-extensionsPixtralImageSizesop (provides per-image H×W)[N, C, max_H, max_W]batch tensor to extract each image's actual pixelsDependencies
PixtralImageSizescustom op for image size metadataTesting
SetExtraInputs