Skip to content

test(e2e): don't assert exact image count for duplicate images - #1821

Merged
slin1237 merged 1 commit into
mainfrom
fix/vllm-duplicate-image-collapse
Jun 23, 2026
Merged

test(e2e): don't assert exact image count for duplicate images#1821
slin1237 merged 1 commit into
mainfrom
fix/vllm-duplicate-image-collapse

Conversation

@slin1237

@slin1237 slin1237 commented Jun 23, 2026

Copy link
Copy Markdown
Member

Description

Problem

e2e_test/chat_completions/test_multimodal.py::TestMultimodalQwen3VL::test_multi_images_mixed[grpc] has been failing on main for the vLLM engine (Expected model to count 3 images, got: "two images").

Root cause

Bisected to #1604 (e2e passed on the parent commit, failed on the merge; the test + fixtures + mm_hashes were unchanged across that boundary). #1604 switched the Qwen image resize to a PIL-exact deterministic bicubic for HF/vLLM parity. A side effect: the two byte-identical pug inputs (sent as base64 + URL) now produce byte-identical pixel tensors.

Engines then legitimately differ on byte-identical multimodal inputs:

  • vLLM deduplicates them (encodes the duplicate once) → model sees 2 → "two images, uploaded twice, one unique."
  • sglang keeps both → model sees 3 → "three images, two are duplicates."

So the literal "count 3" assertion is engine-dependent for duplicate inputs. (This is not a gateway bug — the gateway emits 3 distinct image regions; it's vLLM's content-level dedup, which is defensible.)

Fix

Drop the exact-count assertion in test_multi_images_mixed. Keep the duplicate-detection assertion (both engines satisfy it) and the dog/pug content checks, so the test still validates multi-image + mixed base64/URL + duplicate handling without depending on engine-specific dedup of identical images.

Test Plan

  • ruff check + ruff format --check clean.
  • The change makes e2e-1gpu-chat (vllm) test_multi_images_mixed[grpc] pass (it already passes on sglang); verified by this PR's GPU e2e.
Checklist
  • ruff clean
  • (Optional) Documentation updated — n/a (test-only)

Summary by CodeRabbit

  • Tests
    • Updated multimodal image test to account for engine-specific deduplication behavior.

@github-actions github-actions Bot added grpc gRPC client and router changes model-gateway Model gateway crate changes labels Jun 23, 2026
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

In test_multi_images_mixed, the assertion requiring the model response to explicitly mention "3" or "three" images is removed. Comments are added explaining that identical multimodal inputs may be deduplicated differently across engines, while the existing duplicate-detection assertions are retained.

Changes

Multimodal E2E Test Assertion Relaxation

Layer / File(s) Summary
Remove strict image-count assertion
e2e_test/chat_completions/test_multimodal.py
Removes the "3"/"three" image-count check from test_multi_images_mixed, adds comments about engine-dependent deduplication of identical multimodal inputs, and keeps the duplicate-detection assertions.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~2 minutes

Possibly related PRs

  • lightseekorg/smg#931: Originally introduced test_multi_images_mixed with the strict image-count assertion that this PR removes.

Suggested labels

tests, multimodal

Suggested reviewers

  • key4ng

Poem

🐇 Three images walked in, or maybe just two,
The engines disagree on duplicates' view.
No more strict "three!" the test now proclaims,
Dedup behavior differs — we've loosened the chains.
A rabbit approves: flexibility wins the game! 🌸

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: removing exact image count assertions for duplicate images in the test, which aligns with the PR's focus on handling deduplicated multimodal inputs.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/vllm-duplicate-image-collapse

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request introduces a helper function disambiguate_mm_hashes in multimodal.rs to ensure that duplicate images in a request receive distinct hash entries by suffixing repeats (e.g., -dup1). This prevents vLLM from collapsing identical images and losing the user-sent image count, while still allowing the first occurrence to hit the cross-request encoder cache. A corresponding unit test was also added to verify this behavior. There are no review comments to address, and I have no additional feedback to provide.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

@claude

claude Bot commented Jun 23, 2026

Copy link
Copy Markdown

👋 The PR description doesn't fully follow PULL_REQUEST_TEMPLATE.md:

  • Missing header: ### Solution
  • Missing header: ## Changes

Please update the PR description so reviewers have the context they need.

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Clean fix. The disambiguate_mm_hashes approach is sound — keeping the first occurrence's content hash preserves cross-request encoder caching while suffixing repeats ensures vLLM treats each image as distinct. Unit test covers the key cases well.

0 issues found (0 🔴 Important · 0 🟡 Nit · 0 🟣 Pre-existing)

`test_multi_images_mixed` sends the same pug twice (mixed base64 + URL) and
asserted the model counts "3". Engines legitimately differ on byte-identical
multimodal inputs: vLLM deduplicates them (encodes the duplicate once), sglang
keeps both — so the literal count is engine-dependent. This surfaced after
#1604 made image decode bit-deterministic, so identical inputs now produce
identical pixel tensors that vLLM dedups (sglang is unaffected).

Drop the exact-count assertion and keep the duplicate-detection assertion
(which both engines satisfy) plus the dog/pug content checks, so the test still
validates multi-image + mixed base64/URL + duplicate handling.

Signed-off-by: Simo Lin <linsimo.mark@gmail.com>
@slin1237
slin1237 force-pushed the fix/vllm-duplicate-image-collapse branch from be3bd19 to 82ba66d Compare June 23, 2026 15:07
@slin1237
slin1237 requested a review from XinyueZhang369 as a code owner June 23, 2026 15:07
@github-actions github-actions Bot added tests Test changes and removed grpc gRPC client and router changes model-gateway Model gateway crate changes labels Jun 23, 2026
@slin1237 slin1237 changed the title fix(multimodal): keep duplicate images as distinct vLLM items test(e2e): don't assert exact image count for duplicate images Jun 23, 2026
@slin1237

Copy link
Copy Markdown
Member Author

Repurposed this PR: the mm_hashes disambiguation was the wrong lever (vLLM dedups on tensor content, not caller hashes — GPU CI confirmed it didn't help). Reverted it; this PR now just relaxes the engine-dependent count 3 assertion in test_multi_images_mixed. Root cause is #1604's deterministic bicubic resize making byte-identical duplicate images collapse under vLLM's content-dedup (sglang keeps both) — not a gateway bug, so the test shouldn't assert an exact count for duplicate inputs.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 82ba66d907

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +145 to +148
# Don't assert an exact image count: the two pug inputs are byte-identical,
# and engines legitimately differ on whether identical multimodal inputs are
# deduplicated (vLLM encodes the duplicate once; sglang keeps both). The
# duplicate-detection assertion below covers the intent of this test.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep asserting duplicate images remain visible

This test sends three image parts (dog, URL pug, and the same pug as base64), and the documented regression is vLLM collapsing the byte-identical pugs so the model only sees two images. Replacing the count check with this comment makes test_multi_images_mixed accept that exact broken behavior; the later duplicate check can still pass on wording like same/both even when only two images are visible. Please keep an assertion that the response counts all three user-supplied images, or make the expected count engine-specific, so duplicate-image loss is caught.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@e2e_test/chat_completions/test_multimodal.py`:
- Around line 145-148: The image count assertion has been removed in favor of a
comment explaining backend differences, which loses direct regression coverage
for the "duplicate images collapse" case. Restore the image count assertion but
make it backend-aware by conditionally asserting different expected counts based
on the engine being tested: vLLM should show fewer images due to deduplication
while sglang should preserve both copies. This preserves the regression guard
while remaining cross-engine compatible, ensuring the model still receives all
user-sent images regardless of backend.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 1bdfac13-d3eb-4de7-ad8c-c87792f372b2

📥 Commits

Reviewing files that changed from the base of the PR and between be3bd19 and 82ba66d.

📒 Files selected for processing (1)
  • e2e_test/chat_completions/test_multimodal.py

Comment on lines +145 to +148
# Don't assert an exact image count: the two pug inputs are byte-identical,
# and engines legitimately differ on whether identical multimodal inputs are
# deduplicated (vLLM encodes the duplicate once; sglang keeps both). The
# duplicate-detection assertion below covers the intent of this test.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restore a backend-aware image-count assertion to keep regression coverage.

Removing the count assertion drops the only direct guard for the “duplicate images collapse into fewer visible images” regression. The duplicate-language check does not validate that the model still sees all user-sent images. Keep this test cross-engine compatible by asserting count conditionally (or by splitting per-engine expectations) instead of removing the count check entirely.

Suggested direction
-        # Don't assert an exact image count: the two pug inputs are byte-identical,
-        # and engines legitimately differ on whether identical multimodal inputs are
-        # deduplicated (vLLM encodes the duplicate once; sglang keeps both). The
-        # duplicate-detection assertion below covers the intent of this test.
+        # Keep explicit count coverage for the regression where duplicate images were
+        # collapsed on some engines. If behavior differs by engine, assert per-engine
+        # expectations rather than removing count validation.
+        # Example: vLLM path should report 3 after disambiguating duplicate mm_hashes.
+        # (Use the backend selector already available in setup_backend/markers.)
+        assert any(k in text_lower for k in ["3", "three"]), (
+            f"Expected explicit 3-image count, got: {text}"
+        )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@e2e_test/chat_completions/test_multimodal.py` around lines 145 - 148, The
image count assertion has been removed in favor of a comment explaining backend
differences, which loses direct regression coverage for the "duplicate images
collapse" case. Restore the image count assertion but make it backend-aware by
conditionally asserting different expected counts based on the engine being
tested: vLLM should show fewer images due to deduplication while sglang should
preserve both copies. This preserves the regression guard while remaining
cross-engine compatible, ensuring the model still receives all user-sent images
regardless of backend.

@slin1237
slin1237 merged commit d00eb82 into main Jun 23, 2026
39 of 44 checks passed
@slin1237
slin1237 deleted the fix/vllm-duplicate-image-collapse branch June 23, 2026 15:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests Test changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant