Add WebVoyager benchmark and shared web runtime infrastructure - #2295
Add WebVoyager benchmark and shared web runtime infrastructure#2295JeffPengCoder wants to merge 19 commits into
Conversation
4dc5d85 to
ef9a959
Compare
|
FYI @mpatel31415 |
mpatel31415
left a comment
There was a problem hiding this comment.
-
osworld_internalis mentioned in a few files (e.g. `benchmarks/webvoyager/native-v3.md), but actually it's not used and 2 new runtimes are implemented. From discussion with @Glorf i understood that osworld work can be reused here. -
If only WebVoyager is validated we need to keep the changes only related to this benchmarks and add visualwebarena and webarena in the follow-up PRs, once they are validated too. Review done by CC mentioned some correctness issues for webarena, so I think we should be careful about it.
-
Can you clarify difference between 2 implemented runtimes? if legacy WebVoyager with browsergym_web is not validated maybe it's not needed now and we can just drop it? Adding not valdiated code paths to Gym is risky in my opinion.
-
Is it correct to assume that native_web should be used for Super 3.5 VL ? I see in benchmarks/webvoyager/README.md "The maintained 552-task Nano Omni", so it's a bit confusing which version is the one to be used for Super 3.5 VL
-
I think that we should not have versions of the models (v3) used to index markdown files or or e.g. "Native Nano Omni route" comments inside benchmark, they should be model-agnostic.
-
I'm attaching results of review done by CC, I'd be glad to take a deeper dive into the code myself once it contains only validated and needed runtimes and benchmarks.
| @@ -0,0 +1,18 @@ | |||
| # WebVoyager Judge | |||
There was a problem hiding this comment.
Would it be possible to implement the judge call in Gym's standard way, via nemo_gym.judge? Right now verify_webvoyager() calls self.server_client.post(...) directly (app.py:185) with a hand-rolled except Exception and retry loop, instead of using the shared judge-failure abstraction that ~20 other resources servers use (e.g. frontierscience_judge/app.py:287-322, arena_judge/app.py:265-281).
Using the shared helper would get us for free dealing with judge failures and rerunning them and would match this repo's convention for judge-based resources servers.
There was a problem hiding this comment.
Agreed. I will route WebVoyager judging through the standard /verify endpoint and use nemo_gym.judge.call_judge() for the model call. The current custom /verify_webvoyager route and agent-side retry loop will be removed.
Judge transport, timeout, authentication, HTTP, and response-schema failures will then be classified as judge_failed by judge_failsafe, allowing gym eval reverify --judge-failed-only to rerun only the judge.
Captured screenshots, page URLs, and the final answer will be retained in the rollout response so reverification does not repeat live-site interaction. A successfully received but unparseable verdict will remain a benchmark outcome rather than an infrastructure failure
Browsergym is for other models, current native_gym only works for nemotron. legacy webvoyager is for pure omni v3 (without any change toward behavior like super3.5) and I could remove it if it is not needed at all.
Until our tokenizer alike component is stable enough.
|
Could you please point me to any resources so I could understand e. g. "any change toward behavior like super3.5" or "we use customized tokenizer/chat-template, etc to make nano omni behave like super 3.5. ". What is this customised tokenizer? Our goal is to compare Qwen3.5-122B-A10B and Super 3.5 VL and I'm not sure that it's possible to do so with this version of WebVoyager, considering that "Browsergym is for other models" and " current native_gym only works for nemotron". |
There was a problem hiding this comment.
@JeffPengCoder - just to let you know, that there is "Use of AI and LLM Tools" section in contribution guide in Gym's documentation. You might want to look into this section which describes when changes to a PR are required.
“Customized tokenizer” was also an imprecise description. It refers to model-serving assets used by the Nano alignment profile:
For a fair comparison between Qwen3.5-122B-A10B and Super 3.5 VL, both models must use the same:
We have completed an end-to-end Qwen3.5 diagnostic on the BrowserGym path, but we have not yet completed a same-runtime Qwen-versus-Super comparison. The PR also does not currently contain a pinned Super 3.5 VL model profile, but current infrastructure of Omin does apply for Super 3.5 on native web path. |
Get, let me try to use stacked PR |
776a6a6 to
f5677f3
Compare
Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Download the pinned official 643-task source into Gym local ignored data storage, verify its checksum and denominator, and retain explicit source overrides. Add a Fern end-to-end tutorial for both WebVoyager profiles and cover download caching, population validation, and the new navigation entry. Signed-off-by: Jeff Peng <jepeng@nvidia.com>
|
🌿 Preview your docs: https://nvidia-preview-feature-webarena.docs.buildwithfern.com/nemo/gym Here are the markdown pages you've updated: |
Download the pinned 552-task native WebVoyager source directly during preparation, while retaining verified offline-source overrides. Keep the source lock, E2E docs, and regression tests aligned with the executable path. Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Place the informational raw URL after the existing SHA field so the pinned secret-scanner false-positive remains on its baseline line. The exact CI detector then passes without a repository-wide baseline rewrite. Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Install pytest and pytest-asyncio in the native WebVoyager browser component so gym env test executes with the component CPython 3.13 environment instead of falling back to an unrelated global pytest interpreter. Signed-off-by: Jeff Peng <jepeng@nvidia.com>
|
Nice split in You mentioned above that the headed Chromium lifecycle would stay in a shared native layer rather than move into Where it would help: Separately, One thing that would need settling either way: your driver protocol is sync and ours is async, since a CDP connect and a provider call are both I/O. If it's useful I can put up the seam PR against this branch so you can see the shape. No opinions on the benchmark side from us — that's your call, we don't have one here. |
@waple0820 Thank you for your contributions. This PR like you have seen is more geared towards evaluations rather training in mind at the moment. It would be likely that we prioritize this current implementation first and if you can help us improve it for training needs. Sorry for the trouble and not full-filling your request sooner. |
|
Thanks @jayl940712, that's a clear answer and it helps. Should we close #1865? If the plan is to land this implementation first, we'd rather not leave a second browser environment sitting in the queue — happy to close it and bring the remote-CDP backend and the session-provider seam back as a follow-up once this one is in. Just say the word either way. Closing it wouldn't settle the layering question though, which is why I opened #2921. Short version: session lifecycle now has four separate implementations across open PRs and one merged agent, and whichever browser runtime lands first, that piece probably shouldn't live inside a benchmark's package. The one thing worth deciding before this lands rather than after: We're glad to do the training-side work — that's the half we actually have experience with, and Gym needs it eventually if these environments are going to be trained on and not only scored. It's just easier to build if the protocol leaves room for I/O. |
|
@waple0820 Thanks for your input.
[Jeff] understand there is definitely some difference between benchmarking and train, and that difference would impact architecture design. I would leave it to your PR to do such improvement given I get foundation of webbench correctly built up in this PR.
[Jeff] I notice this synchronization issue, it is the same case for other bench package such as osworld. We do have some solution in term of de-lock or parellelism. And now I am using thread to partially cope with the issue and would pursuit more better solution. Thanks for your suggestion.
[Jeff] Thanks and please help review. |
Remove the duplicate BrowserGym path and consolidate WebVoyager on a model-neutral visual_browser resource with shared computer-use actions. Add bounded browser-session provider lifecycle and per-session operation isolation so local Chromium remains serialized per display while remote or AgentEnv-backed providers can be integrated without blocking the async service. Add separate Nano Omni and Qwen 3.5 policy profiles on the shared runtime, consolidate benchmark preparation and judge configuration, and update the Fern runbook and regression coverage. Validation: 250 focused WebVoyager tests passed; pre-commit passed; full 552-task Qwen and Nano Omni rollouts used the matching frozen source snapshot. Signed-off-by: Jeff Peng <jepeng@nvidia.com>
|
The new So the interface question looks settled. What's left is that there are now two copies of it, which is what #2921 was about. That file has nothing benchmark-specific in it — no WebVoyager, no task model, no evaluator — and it is currently sitting inside a 16k-line PR. Could it land on its own first, from either branch? Then this PR and #1865 both build on one copy instead of each shipping their own, and the question of which of the two merges first stops mattering. |
Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Signed-off-by: Jeff Peng <jepeng@nvidia.com> # Conflicts: # .github/workflows/config/.secrets.baseline # nemo_gym/server_utils.py
Treat the configured model-server reasoning and tool parsers as the authoritative output boundary. Remove Gym-side JSON, delimiter, and tool-alias repair, and reject out-of-contract scroll values instead of silently clamping them. Update the Nano Omni profile, documentation, and regression tests accordingly. Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Consolidate dataset and policy provenance into one manifest consumed by prepare.py, and fold the Nano Omni transport override into its main profile without changing sampling or browser behavior. Remove benchmark-local summary and CapSolver account-smoke scripts. Document the generated env.yaml and standard Gym aggregation and health-check workflow in README and Fern. Relocate the existing eight provenance hash findings in the secrets baseline to their new file and line numbers. Preserve the scanner configuration and all unrelated entries; no additional value is allowlisted. Validation: 276 benchmark and CLI tests passed; standard prepare produced 552 tasks; Fern reported zero errors; all-file pre-commit and the targeted secrets hook passed. Signed-off-by: Jeff Peng <jepeng@nvidia.com>
Summary
This PR adds first-class WebVoyager support to NeMo Gym together with the shared web protocol used by the benchmark. It contains only the WebVoyager layer after splitting the former combined WebVoyager, WebArena, and VisualWebArena change into focused stacked follow-ups.
WebVoyager evaluates multimodal browser agents on live public websites and scores the final answer together with browser screenshots. NeMo Gym now exposes one model-neutral browser runtime,
visual_browser, over the maintained 552-task population. Headed Chromium runs under Xvfb; Playwright owns browser lifecycle and navigation; PyAutoGUI performs visible coordinate input. Nano Omni and Qwen3.5 retain separate policy-output adapters but use the same tasks, browser behavior, proxy/CAPTCHA path, action executor, and Gemini judge.The earlier BrowserGym-compatible 643-task route has been removed. The original Selenium runner is not copied into Gym. Large runtime images, model checkpoints, credentials, proxy endpoints, recordings, screenshots, and raw experiment artifacts remain outside this repository.
Scope split and follow-ups
The current dependency chain is:
The follow-up PRs remain drafts until equivalent full-population rollout evidence is attached. PR #2295 originates from a personal fork, so an exact upstream mirror of its head is maintained as the base of #2917 while preserving this PR's review history.
Design
Main changes
nemo_gym.webtask, action, observation, artifact, session, resource-server, failure, task-image, browser-provider, and composed driver/evaluator contracts.visual_browserserver with Playwright lifecycle, PyAutoGUI coordinate actions, Unicode clipboard input, navigation recovery, proxy routing, CAPTCHA handling, redacted logs, recordings, and evidence retention.Standard preparation and execution
From a clean Linux checkout:
From a second terminal in
benchmarks/webvoyager:../../.venv/bin/gym eval run --no-serve --concurrency 1Use
--profile nano_omnifor the Nano Omni policy adapter. Stop the foregroundgym env startprocess with Ctrl-C; Gym currently has no separateenv stopcommand. The Fern WebVoyager tutorial is the single end-to-end guide for external-service preflight, smoke, full-population execution, fixed-denominator reconciliation, and training failure semantics.Validation
main.gym eval prepare --benchmark webvoyagerdownloads the immutable pinned source and produces exactly 552 tasks.gym env validate --benchmark webvoyagerandgym env resolve.detect-secretshook against the committed baseline.uv lock --check, repository-widepre-commit run --all-files, and diff checks pass. This PR does not change.gitignore,.pre-commit-config.yaml, or GitHub workflow definitions.All full runs used the same hash-pinned task population and
visual_browserruntime. The two Nano Omni repetitions used the same frozen source, tuned checkpoint, parser configuration, external services, judge, and generation parameters; their mean was 417.5/552, or 75.63 percent, with a five-task difference. In the parser-faithful profile, Gym validates parser-produced structured calls but does not repair malformed JSON, complete delimiters, infer aliases, or silently clamp action arguments. Because WebVoyager uses live websites and external proxy, CAPTCHA, judge, and policy services, these numbers are integration evidence rather than stable leaderboard guarantees.Operational requirements and non-goals
xclip; live-site access; US egress for proxy-scoped domains; a funded CAPTCHA provider; a configured multimodal judge; and policy-serving assets that match the selected recipe lock.