Repository navigation
Python: Fix media placeholder placement in ONNX Phi-3-vision and Phi-4-multimodal templates - #14737
Open
Qiming Bao (14H034160212) wants to merge 1 commit into
Open
Qiming Bao (14H034160212) wants to merge 1 commit into
Qiming Bao (14H034160212) wants to merge 1 commit into
Conversation
…-vision and Phi-4-multimodal templates phi3v_template and phi4mm_template emitted <|image_N|> / <|audio_N|> outside the <|user|> ... <|end|> turn and opened a separate user turn for every TextContent item. Build one user turn per message instead, with the image placeholders first, then the audio placeholders, then the text, which is the format in the Phi-3-vision, Phi-3.5-vision and Phi-4-multimodal model cards and in the onnxruntime-genai multimodal example.
Qiming Bao (14H034160212)
temporarily deployed
to
github-app-auth
November 7, 2026 04:32 — with
GitHub Actions
Inactive
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues are reported for the multimodal prompt-formatting changes.
No open issues 🎉
What changed in this PR
This PR fixes multimodal prompt formatting in the Python ONNX connector for Phi-3-vision and Phi-4-multimodal, addressing the media-placement portion of #14735.
Changes:
- Places image and supported audio placeholders inside a single user turn, before text.
- Shares content formatting between templates while preserving media numbering across chat history.
- Updates and expands regression tests for content ordering, multiple images, multiple text items, and audio-only messages.
| File | Description |
|---|---|
python/tests/unit/connectors/ai/onnx/services/test_onnx_utils.py |
Corrects expected prompts and adds multimodal formatting regression cases. |
python/semantic_kernel/connectors/ai/onnx/utils.py |
Adds a shared helper and updates both templates to emit one correctly formatted user turn per message. |
Review effort: Balanced
This branch was previously deployed
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.
Motivation and Context
Fixes #14735
ONNXTemplate.PHI3VandONNXTemplate.PHI4MMbuilt prompts that the Phi-3-vision, Phi-3.5-vision and Phi-4-multimodal models were not trained on:<|image_N|>/<|audio_N|>were written outside the<|user|> ... <|end|>turn. With[text, image]the tag came after<|end|>, and with[image, text]it came before<|user|>.TextContentitem opened its own<|user|>turn.The new format is the one given in the Phi-3-vision, Phi-3.5-vision and Phi-4-multimodal model cards, and it is how the onnxruntime-genai multimodal example builds the user content (
get_user_content): image tags, then audio tags, then the text.Description
_multimodal_user_content, inconnectors/ai/onnx/utils.py. For one user message it returns the image placeholders, then the audio placeholders (Phi-4-mm only), each on its own line, then the text items joined with\n, along with the updated image and audio counters. Placeholders are still numbered across the whole chat history, starting at 1. That numbering matches the image and audio lists that_get_images_from_history/_get_audios_from_historypass to the processor, and Phi-3-vision's requirement that image ids be consecutive from 1.phi3v_templateandphi4mm_templatenow emit a single<|user|>\n{content}<|end|>\nper user message. System and assistant turns, and the\nstyle, are unchanged.tests/unit/connectors/ai/onnx/services/test_onnx_utils.py): the two existing multimodal tests asserted the broken format, so I updated them. I also added cases for[image, text], multiple images, image numbering across turns, several text items in one message, text + audio, audio only, and audio listed before images.No public API changes. Only the prompt string produced for multimodal user messages changes.
Verification (from
python/):Contribution Checklist