Repository navigation
[Bugfix] Bound Omni-DuplexEval judge frame resolution - #9038
armaanamatya wants to merge 2 commits into
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
|
This PR appears to belong to: docs/design/module/benchmarking.md. Module owners: @alex-jw-brooks @Bounty-hunter @NickCao Routing: @alex-jw-brooks via module of the changed files, CODEOWNERS; @Bounty-hunter via module of the changed files, CODEOWNERS; @NickCao via CODEOWNERS @armaanamatya, please review your own changes and leave a short self-review comment describing what you checked. PRs without author self-review may not be assigned a reviewer. Please take a look when you have a chance. If you would like an automated review, mention @vllm-omni-review-bot in a comment. |
|
Rechecked on current main ( @alex-jw-brooks @Bounty-hunter @yenuo26 @NickCao could one of you review? It caps judge frame resolution (default 1920 on the long side, @vllm-omni-review-bot please review. |
c1b49de to
05d6a4f
Compare
|
Rebased onto main Beyond moving the PR onto the new code, the fallback's frame extraction now also gets
|
|
@alex-jw-brooks @Bounty-hunter @yenuo26 @NickCao this is rebased onto today's main ( @vllm-omni-review-bot please review. |
Judge frames were extracted at source resolution, so on 4K clips about ten frames already exceeded a 64K-token judge context and the request failed with HTTP 500 every time. extract_jpeg now takes max_side and scales larger frames down while keeping the aspect ratio. evaluate uses it for both the temporal frames and the frame-sample content frames, via --judge-frame-max-side (default 1920, so 1080p and smaller clips are unchanged; 0 disables). The value is recorded in each score file. Fixes vllm-project#7375 Signed-off-by: Armaan Amatya <armaanamatya2014@gmail.com>
05d6a4f to
1008060
Compare
|
Rebased onto main
@alex-jw-brooks @Bounty-hunter @yenuo26 @NickCao could one of you review? It is one @vllm-omni-review-bot please review. |
| "response_meta": meta, | ||
| "judge_model": getattr(judge, "model", None), | ||
| "judge_video_mode": judge_video_mode, | ||
| "judge_frame_max_side": judge_frame_max_side, |
There was a problem hiding this comment.
Individual scores record judge_frame_max_side, but summaries neither retain nor validate it. Partial reruns with different caps can silently mix different judge inputs. Preserve a uniform setting or explicitly group/reject mixed settings.
There was a problem hiding this comment.
Fixed in c679762e3. summarize now reports judge_frame_max_side and raises a ValueError if the score root mixes values, naming them and pointing at --overwrite. Scores from before this PR have no field and used source resolution, so they count as None. The serving path always scores into a fresh root, so only the CLI can hit this.
The same commit renames the max_side test and covers both the equal and larger cases, per the nit from yenuo26. 478 passed (CPU), also on a trial merge with main 456030431.
yenuo26
left a comment
There was a problem hiding this comment.
Reviewed 1008060d (static; duplex unit/CLI suites not re-run here).
Looks good / CLEAN for self-approve. Bounding judge JPEG longer-side via extract_jpeg(..., max_side=) + evaluate_sample/CLI plumbing addresses #7375 without touching generate-side iter_jpegs (default None). Cap applied on temporal, frame-sample content, and the #9101 context-overflow fallback — the important coverage set. Score files record judge_frame_max_side, and --judge-frame-max-side 0 restores source resolution.
Tests: scale-down aspect (320×180 → 160×90), leave-unchanged at equal max_side, CLI default/768/0 + negative reject, and fallback max_side assertion all look right. _extract_frames keyword form is what production uses.
Soft nits (non-blocking):
test_max_side_leaves_smaller_frames_unchangedactually covers “not larger than” (max(size) > max_sideis false for equal sides too). A one-line rename/comment would match the predicate.- Protocol note for
video_urlon >1080p clips is already in the PR body + score field — good; no further ask.
No helper-reuse or redundant Buildkite concerns. Fine once CI is green.
Record judge_frame_max_side in the summary. evaluate skips samples that already have a score, so a rerun with another cap would otherwise average different judge inputs without any sign of it. Scores without the field used source resolution and count as None. Rename the max_side test to match the predicate, which also covers frames equal to the cap. Signed-off-by: Armaan Amatya <armaanamatya2014@gmail.com>
yenuo26
left a comment
There was a problem hiding this comment.
Re-reviewed tip c679762e (static; duplex suites not re-run here).
Looks good / CLEAN for self-approve. Tip addresses both open threads:
- jiangmengyu18 —
summarize_scoresnow records a uniformjudge_frame_max_sideand raises on mixed caps (legacy missing field ≡None/ source resolution). Covered bytest_summary_records_a_uniform_judge_frame_max_side,test_summary_rejects_mixed_judge_frame_max_side, andtest_summary_treats_a_score_without_the_field_as_source_resolution. - Prior soft nit — leave-unchanged test renamed to
test_max_side_leaves_frames_within_limit_unchangedwithequal|largercases matchingmax(size) > max_side.
Production path unchanged in spirit: extract_jpeg(..., max_side=) + evaluate/CLI plumbing; #9101 fallback still capped. _extract_frames stub accepts **kwargs. No new helper-reuse or Buildkite concerns. Fine once CI is green.
Purpose
Fixes #7375.
vllm bench omni-duplex-eval evaluatesends judge frames at source resolution. Image tokens grow with pixel count, so on 4K clips (3734x2100 in the report, ~7.7k tokens per frame) 10-13 frames already exceed a 64K-token judge, and those samples fail with HTTP 500 every time (77k-101k token prompts in the report, 5 of 660 samples dropped).This bounds frame resolution before JPEG encoding:
extract_jpeg(..., max_side=None): if the longer side is larger thanmax_side, scale the frame down with the aspect ratio kept. Smaller frames are unchanged. The default isNone, so the generate-side runner (iter_jpegs) is not affected.evaluate_sample(..., judge_frame_max_side=1920): applied to the temporal-window frames, the frame-sample content frames, and the frame-sample fallback that [Bugfix][Benchmark][Duplex] Fall back to frame-sample judging when the video exceeds the judge context #9101 added for judge context overflow invideo_urlmode. Without the cap that fallback's 16 frames of a 4K clip would still be ~123k tokens.--judge-frame-max-side(default 1920,0keeps source resolution, negative is rejected).judge_frame_max_side, andsummarizereports it.evaluateskips samples that already have a score, so a rerun with another cap would otherwise average different judge inputs;summarizenow raises aValueErrorfor a mixed score root. Scores written before this PR have no field and used source resolution, so they count asNone.With the 1920 cap, the reported clip goes to 1920x1080, ~2k tokens per frame, so the 16-frame content prompt is ~33k tokens.
What changes and what doesn't:
video_urlmode too. For those clips this departs from the pinned protocol, which is why the value is written to the score file.--judge-frame-max-side 0restores the old behavior.window length x judge_fpswith no cap, and there is no token-budget pre-check or skip/degrade path (items 1-2 in the issue). This PR only fixes the resolution part, which is what the reported failures come from.Related: #9101 (merged) retries the content prompt with at most 16 sampled frames when the judge rejects the full video for context length; this PR bounds the resolution of those frames as well. #7387 (draft) handles the frame-count side with an opt-in retry using fewer frames after a context-length error. The two don't overlap in behavior and can land in either order, but they touch the same files (
omni_duplex_eval_eval.py, the CLI,test_omni_duplex_eval_cli.py), so whichever lands second will need a rebase.Test Plan
CUDA_VISIBLE_DEVICES="" python -m pytest -q tests/benchmarks/duplex \ tests/e2e/features/fullduplex/test_omni_duplex_eval_cli.py \ tests/e2e/accuracy/omni_duplex_eval/test_omni_duplex_eval_ci.pyNew tests:
test_max_side_scales_down_keeping_aspect_ratio: a 320x180 clip withmax_side=160gives 160x90.test_max_side_leaves_frames_within_limit_unchanged[equal|larger]: same bytes as withoutmax_side.test_frame_sample_content_passes_frames: both temporal and content extraction receive the default max side, and the score file records it.test_cli_evaluate_forwards_judge_frame_max_side(default / 768 / 0 -> None) andtest_cli_evaluate_rejects_negative_judge_frame_max_side.test_summary_records_a_uniform_judge_frame_max_side[source|capped],test_summary_rejects_mixed_judge_frame_max_sideandtest_summary_treats_a_score_without_the_field_as_source_resolution.test_content_prompt_falls_back_to_frame_sample_on_judge_context_overflow(from [Bugfix][Benchmark][Duplex] Fall back to frame-sample judging when the video exceeds the judge context #9101) now also checks that the fallback frames get the default max side.vLLM Version: 0.32.0
vLLM-Omni Commit: c679762 (on main d6bd0fd)
Test Result
478 passed (CPU, WSL2 Ubuntu 24.04, Python 3.12, vLLM 0.32.0), both at c679762 and on a trial merge with main 4560304.
ruff check/ruff format(0.14.10) clean.The PR also passes
max_side=judge_frame_max_sideon the #9101 fallback's frame extraction, checked by the assertion above. The rebase onto d6bd0fd resolved conflicts with #9390 (judge_resultwrapper) and #9056 (GT references) inomni_duplex_eval_eval.py, keeping main's code; the_extract_framesstub in #9390'stest_rtd_requires_complete_scores_before_publishingnow accepts themax_sidekeyword.