Repository navigation
feat(evals): optional QualityWindow frame selection for VQA generate - #4566
moshiii-wei wants to merge 7 commits into
Conversation
Keep uniform start/stop/stride anchors, then pick the sharpest nearby color_image in a stride-aware neighborhood so motion-blurred samples are less likely to enter deterministic VQA cases.
There was a problem hiding this comment.
go2 replay realtime (arm64)
Details
| Benchmark suite | Current: ce0d609 | Previous: 3faae1f | Ratio |
|---|---|---|---|
peak memory |
1585.992 MB |
1589.676 MB |
1.00 |
peak threads |
356 threads |
360 threads |
0.99 |
network (transport) |
2722.098 MB |
2722.636 MB |
1.00 |
disk write |
1.461 MB |
1.734 MB |
0.84 |
instructions |
115.648 G |
115.588 G |
1.00 |
This comment was automatically generated by workflow using github-action-benchmark.
❌ 1 Tests Failed:
View the top 1 failed test(s) by shortest run time
To view more test analytics, go to the Test Analytics Dashboard |
|
| lo = max(0, anchor - half_width) | ||
| hi = min(image_count - 1, anchor + half_width) |
There was a problem hiding this comment.
Frames escape the requested range
--sharp-stride clips its search only to the recording, not to start and the exclusive stop. For example, start=100, stop=101, stride=10 searches frames 96–104 and forwards frame 104 to generation if it has the highest sharpness. A sharper frame before start can also be selected. Users can therefore get images and questions from outside their requested range. Pass the requested bounds into the selector and clip each neighborhood to them before merging.
Artifacts
Scoped generation reproduction script
- Executes real generation selection and consumes its frame iterator with fake supporting services, asserting the exact selected indices at both request boundaries.
Commands and output capture script
- Runs the reproduction with sharp-stride disabled and enabled and records each command, working directory, exit code, and observed output for comparison.
Generation output with sharp-stride disabled
- Captured the baseline generation runs for both score profiles; only frame 100 was loaded and forwarded, respecting the requested range.
Generation output with sharp-stride enabled
- Captured generation selecting and forwarding frames 104 and 96 in the respective score profiles, confirming that both request boundaries can be violated.
There was a problem hiding this comment.
Fixed in 0a0038a: neighborhoods are clipped to [start, stop); added resolve/generate forwarding tests and CLI option coverage.
| def test_select_sharp_stride_indices_picks_neighborhood_max_and_dedupes() -> None: | ||
| scores = {i: float(i) for i in range(30)} | ||
| scores[12] = 100.0 | ||
| scores[22] = 100.0 | ||
| selected = select_sharp_stride_indices( | ||
| anchors=(10, 20), | ||
| image_count=30, | ||
| half_width=4, | ||
| score_at=scores.__getitem__, | ||
| ) | ||
| assert selected == (12, 22) |
There was a problem hiding this comment.
Generation path remains untested
The new tests exercise the selector and request checks, but do not verify that generate_dataset consumes the sharp-selected indices. Replacing its frame loop with the original anchors left all seven new sharp-stride cases passing and the existing test outcomes unchanged, even though generation then emitted the wrong frames. This is a non-blocking regression-coverage gap. Add a test with a fake loader and models that checks which indices reach generation, plus a CLI test that passes both new options.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Artifacts
Executable baseline and mutation harness
- This executed Python harness applies the in-memory mutation, runs the existing tests, and probes generation with deterministic doubles, making the coverage comparison reproducible.
Executed commands and evidence capture script
- This executed driver records command, working directory, exit code, and observed output for inspection and the single before/after pair.
Scoped selector, generation, and CLI test inspection
- Numbered source excerpts and search output show direct selector tests and CLI tests without sharp-option checks, locating the coverage gap.
Tests and generation probe before mutation
- The unmodified run records 83 passes and two failures while the separate generation probe emits selected indices (12, 22), establishing the baseline.
Tests and generation probe after disconnecting selected indices
- The mutated run records the same test outcomes while generation emits anchors (10, 20), showing that the existing tests do not detect the disconnection.
Tracked source status after validation
- The final git diff check exits successfully with no diff, confirming that validation left tracked sources unchanged.
There was a problem hiding this comment.
Fixed in 0a0038a: neighborhoods are clipped to [start, stop); added resolve/generate forwarding tests and CLI option coverage.
Keep sharpness search inside the requested generation range, and cover the generate/CLI path so selected indices are asserted end-to-end.
Drop custom sharp-stride neighborhoods; reuse Image.sharpness + QualityWindow (and optional brightness floor) the same way loop-closure / semantic peaks do.
|
Reworked per review: dropped the custom sharp-stride / k-neighborhood path. Range mode now uses mem `QualityWindow(lambda img: img.sharpness, window=...)` (optional `--min-brightness` first), matching the loop-closure / semantic-peak docs. |
|
Added a Comparison experiment section to the PR description with the go2_short A/B:
|
Restore Sequence import in generate.py and cast QualityWindow outputs so lint mypy passes.
|
Fixed CI mypy failures: restored |
What is this feature?
Adds optional quality-based frame picking for
dimos evals vqa generatein range mode. Instead of a custom sharp-stride neighborhood, generation reuses memQualityWindowonImage.sharpness(same path as loop-closure / semantic-peak picking), with an optional brightness floor.Uniform
--strideremains available;--quality-windowreplaces stride when you want frequency-preserving sharpest-frame selection.Why do we need this?
Blind stride can land on blurry frames. The platform already measures sharpness/brightness and keeps update frequency via
QualityWindow/sharpness_barrier— VQA generate should use that instead of a parallel selection algorithm.Comparison experiment (go2_short)
A/B on
go2_shortcolor_image[0, 855)(~60s @ ~14 Hz). QualityWindow usedwindow=1.0s,min_brightness=0.1; uniform stride was matched to the same count (stride=15, n=57).Frame selection
Eval-case yield (image-only families)
Ran the real
_generate_framepath (OpenAI author → Moondream GT) on 12 evenly spaced frames per arm. Families:presence,horizontal_direction,object_count(no masks / pointcloud —go2_shorthas nocamera_info/tf).By family (answered / rejected):
Takeaway: sharper picks cut family rejects (~3× lower reject rate) and increased kept eval cases on this sample. Mask / LiDAR families not measured here.
How to Test
Which issue(s) does this PR close?
NA
Checklist