Skip to content

QVAC-21841 test: add mobile smoke test for VLM continuous batching#3279

Open
RamazTs wants to merge 2 commits into
tetherto:mainfrom
RamazTs:QVAC-21841-vlm-continuous-batching-mobile-test
Open

QVAC-21841 test: add mobile smoke test for VLM continuous batching#3279
RamazTs wants to merge 2 commits into
tetherto:mainfrom
RamazTs:QVAC-21841-vlm-continuous-batching-mobile-test

Conversation

@RamazTs

@RamazTs RamazTs commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

🎯 What problem does this PR solve?

  • VLM continuous batching has zero mobile coverage. The continuousBatching group is already registered for both ios and android in test/mobile/test-groups.json, but every test in continuous-batching.test.js gates on skipHeavyPlatform (isMobile || isDarwin). Both Device Farm runs currently import the module and execute zero tests.
  • Rolling slot admission is untested on the VLM path. The three MTMD tests added in QVAC-19983: Continuous Batching (Single-job MTMD) #2543 submit 4 image prompts into parallel: '4' slots, so every sequence is admitted in the initial wave and no slot is ever recycled onto a new image.
  • The Android pre-stage would miss the vision models. The runContinuousBatchingTest entry in test/mobile/model-manifest.json listed only Llama-3.2-1B, so SmolVLM2 + mmproj would be downloaded on-device from HuggingFace — the flaky path pre-staging exists to avoid.

Follows #2327 (text) and #2543 (VLM/images). Scope per @Olya's call: mobile coverage only, no extra VLM-Benchmark throughput leg (vision encode is serialized, so single-step encode optimisations carry over to batched inference anyway).

📝 How does it solve it?

  • Mobile smoke test (continuous batching MTMD: mobile smoke — image and text slots decode together): parallel: '2', one elephant.jpg image slot beside one text slot, skipped only on darwin so it runs on the Device Farm pools and on Linux desktop.
    • Image + text rather than two image prompts: vision encode is serialized across slots, so this pairing is what exposes an encode barrier starving the text slot — the regression class that is invisible to every current benchmark and perf test.
    • Asserts both outputs are correct (catches cross-sequence contamination), ids come back in input order, and avgConcurrentSeq > 1.0 (a mean pinned at exactly 1.0 means batching collapsed to serial).
    • parallel: 2 against the default ctx_size: 4096 leaves each slot a 2048-token window — comfortably above SmolVLM2-500M's ~256 vision tokens plus prompt and output, which matters because oversized prompts are rejected rather than truncated.
  • Desktop rolling-admission test (continuous batching MTMD: image prompts outnumber slots and roll through freed slots): reuses the existing 4 IMAGE_CASES but halves the slots to parallel: '2', forcing the second half to wait in pending_ and be admitted into freed slots. This exercises a per-slot MTMD driver resetting its media and vision-encoding a new image while the other slot keeps decoding. IMAGE_CASES asks two questions each about two different images, so a slot that fails to reset media on recycle answers from the wrong image and fails the assertion. Also brackets avgConcurrentSeq at the slot cap to check admission respects n_seq_max.
  • Manifest: added SmolVLM2-500M + its mmproj to runContinuousBatchingTest. Added by hand rather than regenerating with scripts/generate-model-manifest.js, because the generator scrapes through the require('./_image-common.js') and would also stage Qwen3VL-2B + mmproj (~1.5 GB per Android run) that this file never loads.

No new fixtures or wiring needed: elephant.jpg is already used on-device by image-mmproj-gpu.test.js and mrope-sliding-context.test.js via global.assetPaths, and runContinuousBatchingTest is already assigned to a group on both platforms, so test-groups.json and integration.auto.cjs are untouched.

🧪 How was it tested?

  • Prettier + node --check pass locally.
  • Not executed locally: the tests are skipped on darwin by design, and this machine has no native prebuild or cached models. Both need CI.
  • Requesting verified + run-mobile-addon-tests + run-desktop-addon-tests to exercise the Device Farm pools and the Linux leg.
  • ⚠️ The avgConcurrentSeq thresholds (> 1.0 mobile, > 1.2 desktop rolling) are reasoned estimates, not measured. They are the flake risk in this PR and want calibrating against the first green Device Farm run — happy to adjust or drop them to t.comment if they prove noisy on device.

📋 Notes for reviewers

  • Pre-existing, not fixed here: Llama-3.2-1B (~770 MB) is still pre-staged for this group even though its test is skipped on mobile. The manifest is keyed per test-function and can't express "Android only". Worth a follow-up if Device Farm time is tight.

The continuousBatching group is already registered for both ios and android
in test-groups.json, but every test in continuous-batching.test.js gates on
skipHeavyPlatform (isMobile || isDarwin), so both Device Farm runs import the
module and execute zero tests. VLM continuous batching has no mobile coverage.

Add a mobile smoke test at parallel: 2 with one image slot beside one text
slot, skipped only on darwin so it runs on the Device Farm pools and on Linux.
Vision encode is serialized across slots, so pairing an image with a text
prompt is what catches an encode barrier starving the text slot. It asserts
both outputs are correct and that the slots decoded together.

Add a desktop test for rolling admission: the existing MTMD tests submit 4
image prompts into 4 slots, so every sequence is admitted in the initial wave
and no slot is ever recycled. Halving the slots forces the second half of
IMAGE_CASES to wait in pending_ and be admitted into freed slots, exercising a
per-slot MTMD driver resetting its media and vision-encoding a new image while
the other slot keeps decoding.

Stage the SmolVLM2 model and mmproj for runContinuousBatchingTest in
model-manifest.json. The entry listed only Llama-3.2-1B, so the Android
pre-stage would have missed the vision models and downloaded them on-device
from HuggingFace. Entries are added by hand rather than regenerating, since
the generator scrapes through the _image-common.js require and would also
stage Qwen3VL-2B and its mmproj, which this file never loads.
@RamazTs RamazTs requested review from a team as code owners July 15, 2026 06:54
@github-actions

Copy link
Copy Markdown
Contributor

Review Status

Current Status: ❌ PENDING
Approvals so far: none

Pending reviews: Needs 1 Management or Team Lead, and 1 more from Management, Team Lead, or Member.

@RamazTs RamazTs added run-mobile-addon-tests CI: run mobile integration tests (requires verified) run-desktop-addon-tests CI: run desktop integration tests (requires verified) verified Authorize secrets / label-gate in PR workflows labels Jul 15, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Mobile integration tests — @qvac/llm-llamacpp (iOS)

Result: passed

metric value
Devices passed 24
Devices failed 0
Test cases total 72
Test cases passed 72
Test cases failed 0
Test cases skipped 0

View workflow run

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Mobile integration tests — @qvac/llm-llamacpp (Android)

Result: passed

metric value
Devices passed 18
Devices failed 0
Test cases total 54
Test cases passed 54
Test cases failed 0
Test cases skipped 0

View workflow run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run-desktop-addon-tests CI: run desktop integration tests (requires verified) run-mobile-addon-tests CI: run mobile integration tests (requires verified) verified Authorize secrets / label-gate in PR workflows

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant