Skip to content

feat(benchmark): add Aegis v4 safety evaluator - #3699

Merged
cmunley1 merged 3 commits into
NVIDIA-NeMo:mainfrom
muskank7:feat/aegis-v4-safety
Sep 29, 2026
Merged

cmunley1 merged 3 commits into
NVIDIA-NeMo:mainfrom
muskank7:feat/aegis-v4-safety

Conversation

@muskank7

@muskank7 muskank7 commented Sep 26, 2026 •

Copy link
Copy Markdown
Contributor

What does this PR do?

Adds an Aegis v4 safety-evaluation resources server backed by nvidia/Nemotron-3-Content-Safety and registers it as the manifest-backed aegis_v4_safety benchmark.

The integration supports two workflows:

  • generate responses from a target model and classify the prompt/response pair with Aegis v4;
  • reverify datasets that already contain target-model responses without generating them again.

It accepts text prompts with an optional single image, records structured user/response safety labels and categories, supports final-answer-only or reasoning-plus-final evaluation, and reports unresolved judgments separately from safe/unsafe results. It also includes a dataset converter, example fixtures, documentation, and focused tests.

There is no linked issue; this is a new benchmark integration.

Benchmark metadata and data

  • benchmarks/aegis_v4_safety/manifest.yaml declares the safety-domain benchmark and mirrors its Gym composition.
  • The included five project-authored prompts are an Apache-2.0 smoke dataset for checking the integration, not a comprehensive safety benchmark.
  • The resources server exports a service-free verifier fixture covering full reward, zero reward, and malformed input.
  • A safety-only reward can be maximized by refusing every request. It measures response safety, not helpfulness or task correctness, and should not be used by itself as an RL reward.

Validation

  • venv/bin/pytest -q resources_servers/aegis_v4_safety/tests β€” 23 passed
  • venv/bin/ruff check resources_servers/aegis_v4_safety benchmarks/aegis_v4_safety β€” passed
  • venv/bin/ruff format --check resources_servers/aegis_v4_safety benchmarks/aegis_v4_safety β€” passed
  • pre-commit run --all-files β€” passed
  • gym env test +entrypoint=resources_servers/aegis_v4_safety +should_validate_data=true β€” 23 tests passed and the five-row example data, metrics, and rollouts validated
  • gym env validate aegis_v4_safety --kind benchmark --sync --json β€” passed with 5 benchmark rows, no warnings, and no manifest synchronization drift
  • Publication contract validation β€” benchmark discovered as experimental and all 3 verifier-fixture cases passed

Rollouts

Ran a live five-example end-to-end rollout on Slurm (job 7362340) through:

dataset -> Nemotron 3.5 Super VL EA target endpoint -> Gym -> Aegis v4 endpoint

  • 5/5 rollout records were produced with no transport failures.
  • Both unsafe prompts were classified as unsafe user requests, while the target model's refusals were classified as safe responses.
  • Two completed benign responses were classified safe.
  • One benign prompt exhausted the target model's 1,024-token limit in reasoning without producing a final answer; the environment correctly recorded it as unresolved rather than sending empty text to Aegis or treating it as safe.

The five real rollout records are included in resources_servers/aegis_v4_safety/data/example_rollouts.jsonl.

The benchmark-manifest follow-up is metadata and service-free fixture coverage, so it does not require another model rollout.

Compatibility and benchmark impact

This is additive and does not change existing environments or public APIs. The target model and Aegis model use separate endpoint configurations, so users can replace the target model without modifying the verifier. Existing-response scoring avoids a second target-model inference pass.

The default response_text_mode is final_only; reasoning_plus_final is opt-in. Unresolved results receive the configured unresolved reward and are reported separately from resolved safety rates.

Checklist

  • I have read the contributing guidelines.
  • The change is focused; unrelated "drive-by" edits are tracked as separate issues/PRs.
  • Tests added or updated and pass locally.
  • Documentation and benchmark metadata added.
  • Pre-commit checks pass locally (pre-commit run --all-files).
  • New source files include the required Apache-2.0 SPDX header.
  • All commits have DCO sign-off (git commit -s).

Signed-off-by: Muskan Kumar <muskumar@nvidia.com>
@copy-pr-bot

copy-pr-bot Bot commented Sep 26, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@nemo-automation-bot nemo-automation-bot Bot added the community-request Issue reported or requested by someone from the community label Sep 26, 2026
@yaoyu-33 yaoyu-33 added area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers complexity:medium Single-domain change with interacting parts or a moderate review surface feature New capabilities, enhancements, or enablement work needs-review PR is ready for code review and waiting on a reviewer labels Sep 26, 2026
@svcnvidia-nemo-ci svcnvidia-nemo-ci added the waiting-on-maintainers Waiting on maintainers to respond label Sep 28, 2026
@github-actions github-actions Bot added the sla:triage-overdue Review assignment is over the one-business-day SLA label Sep 28, 2026
@yaoyu-33 yaoyu-33 removed the needs-review PR is ready for code review and waiting on a reviewer label Sep 28, 2026
@cmunley1

Copy link
Copy Markdown
Contributor

/ok to test 64fbf25

@cmunley1

Copy link
Copy Markdown
Contributor

lgtm! do you want to add an entry in environments/ or benchmarks/? If it is eval only, you should put it in benchmarks/.

If for training, it seems a model may be able to reward hack by refusing everything to receive full score? Just a thought!

@muskank7

Copy link
Copy Markdown
Contributor Author

Thanks! Yes, this is evaluation-only at this stage, so I’ll add an entry under benchmarks/ and keep Aegis v4 as the reusable resources server.
Agreed on the reward-hacking risk: the current safety-only reward could encourage blanket refusals, so it should not be used as a standalone training objective. Supporting training would require combining safety with task/helpfulness rewards and appropriate refusal handling.

Signed-off-by: Muskan Kumar <muskumar@nvidia.com>
@muskank7 muskank7 changed the title feat(environment): add Aegis v4 safety evaluator feat(benchmark): add Aegis v4 safety evaluator Sep 28, 2026
@muskank7

Copy link
Copy Markdown
Contributor Author

Added the requested benchmark entry in commit 0e0533c. It includes the benchmark manifest/config, project-authored five-row smoke data and preparation metadata, documentation, and a service-free verifier fixture. I also documented that the safety score is evaluation-only and can be reward-hacked by refusing everything, so it should not be used alone as an RL reward. Local validation passed: 23 Aegis tests, manifest validation with five rows and no warnings, all three verifier-fixture cases, legacy data validation, Ruff, and the full pre-commit suite.

@cmunley1

Copy link
Copy Markdown
Contributor

/ok to test 0e0533c

cmunley1
cmunley1 previously approved these changes Sep 28, 2026
Signed-off-by: Muskan Kumar <muskumar@nvidia.com>
@github-actions github-actions Bot removed the sla:triage-overdue Review assignment is over the one-business-day SLA label Sep 28, 2026
@svcnvidia-nemo-ci svcnvidia-nemo-ci removed the waiting-on-maintainers Waiting on maintainers to respond label Sep 28, 2026
@yaoyu-33 yaoyu-33 added the needs-review PR is ready for code review and waiting on a reviewer label Sep 28, 2026
"sample_id": row["sample_id"],
"dataset_name": "aegis_v4_safety",
"prompt": row["prompt"],
"responses_create_params": {"max_output_tokens": 1024},

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.

is this intentional? 1k output seems small, if reasoning model.

@cmunley1

Copy link
Copy Markdown
Contributor

/ok to test 005c848

@cmunley1
cmunley1 merged commit 1e01443 into NVIDIA-NeMo:main Sep 29, 2026
42 checks passed
cmunley1 added a commit that referenced this pull request Sep 29, 2026
## What does this PR do?

Fixes main. #3699 (Aegis v4) merged about an hour after #3728 added the
audit that every shipped server declares `ray_enabled`, so
`AegisV4SafetyResourcesServer` has no declaration and
`tests/unit_tests/test_ray_opt_out.py::test_shipped_server_classes_declare_ray_usage`
fails on main and on every merge-queue run. The server makes no Ray
calls, so it declares `ray_enabled = False`.

## Validation

- `pytest tests/unit_tests/test_ray_opt_out.py -q`: 5 passed (was
failing on main at 1e01443)

## Rollouts

N/A. Class-level declaration only, no change to requests, verification,
or rewards.

## Compatibility and benchmark impact

None. The Aegis server stops joining the Ray cluster at startup, which
it never used.

## Checklist

- [x] I have read the [contributing
guidelines](https://github.com/NVIDIA-NeMo/Gym/blob/main/CONTRIBUTING.md).
- [x] The change is focused; unrelated "drive-by" edits are tracked as
separate issues/PRs.
- [x] Tests added or updated and pass locally, or N/A for docs-only /
non-code changes (so CI unit/server checks pass when applicable).
- [x] Documentation added or updated, or N/A with justification.
- [x] Pre-commit checks pass locally (`pre-commit run --all-files`) (so
CI lint/format checks pass).
- [x] New source files include the required Apache-2.0 SPDX header.
- [x] All commits have DCO sign-off (`git commit -s`) (so the DCO check
passes).

Signed-off-by: Christian Munley <cmunley@nvidia.com>
cmunley1 pushed a commit that referenced this pull request Sep 30, 2026
## Summary

- Raise the five-row Aegis v4 benchmark target-model output ceiling from
16,384 to 131,072 tokens (128K), and regenerate all five committed
benchmark rows.
- Raise the separate five-row resources-server example input ceiling
from 1,024 to 131,072 tokens and replace its rollouts with a new live
Super β†’ Gym β†’ Aegis run.
- Document an internal Step 25 EA safety result as a **reference
target**, with its dataset, inference settings, score definition, and
unresolved-row caveat.

## Why

Reasoning-capable target models may need more than 16K tokens before
producing a final answer. The new 128K value is a ceiling, not a
required output length; it does not change the Aegis judge limit, the
verifier, or the default final-answer-only judging mode. There is no
linked issue; this is a focused follow-up to #3699 and the review
discussion on this PR.

## Internal reference result (not an official score)

An internal, **non-Gym** run used 5,964 MM-Aegis v3.3 prompts (2,624
with images; input JSONL SHA-256
`d54ed8d391a3e52ca5adc3b4b165ae2cf5d4813d126d3d9421c496c7fc730a62`) with
the Nemotron 3.5 Super VL EA MOPD `large_multi_domain_opd_v1/step_25_hf`
checkpoint. Super used thinking enabled, temperature 1.0, top-p 0.95,
and a **32,768-token** output limit. Only final answers were judged.
Aegis v4 used revision `b47f6f6c18dc7d11a786abbbca2510cba58ede20`,
temperature 0.01, top-p 0.95, 200 output tokens, and category reporting.

The result was **5,795 safe, 168 unsafe, and 1 unresolved** response
judgement. Unsafe rate over all rows is **168 / 5,964 = 2.8169%**; the
Gym resolved-only unsafe-rate target would be **168 / 5,963 = 2.8174%**.
A later retry received a safe judgement for a *different, one-word*
model response; it did not resolve or replace the original row in these
counts. The dataset is not included in this PR, and the five-row
built-in smoke benchmark cannot reproduce this aggregate result. A
strict full-dataset comparison must reuse the data and 32,768-token
generation setting. This is an internal reproduction target, not a score
already reproduced by Gym or an independently reported/official score.

Correction to my earlier comment: the recorded internal Step 25 run used
32,768 `max_tokens`; 16,384 was the previous built-in Gym benchmark
ceiling, not the recorded run's normal generation setting.

## Example rollouts

Both the benchmark rows and the separate resources-server example inputs
now request up to 131,072 target-model output tokens. I regenerated the
committed
`resources_servers/aegis_v4_safety/data/example_rollouts.jsonl` with a
live end-to-end Gym run on Slurm job `7546959`:

`five example inputs β†’ Nemotron 3.5 Super VL EA Step 25 β†’ Gym final-only
verifier β†’ Aegis v4`

All five target responses completed with final answers (195–1,926 actual
output tokens); all five Aegis judgements resolved; no rollout failures.
The two intentionally unsafe user prompts were labelled unsafe, and all
five target responses were labelled safe. The 128K setting is an
available ceiling, not the number of tokens forced or actually
generated. Gym's example metadata collator reported
`example_metrics.json` already up to date, so that file did not change.
These five smoke results are not the 5,964-row reference score.

## Validation

- `venv/bin/python benchmarks/aegis_v4_safety/prepare.py` β€” regenerated
five rows; verified that only their `max_output_tokens` values changed.
- `venv/bin/gym env validate aegis_v4_safety --kind benchmark --sync
--json` β€” five rows, no warnings or manifest drift.
- `venv/bin/pytest -q
tests/unit_tests/test_task_data.py::TestRepoDataMatchesSchemas::test_all_committed_rows_validate`
β€” passed.
- `venv/bin/ruff check benchmarks/aegis_v4_safety/prepare.py` and
`venv/bin/ruff format --check benchmarks/aegis_v4_safety/prepare.py` β€”
passed.
- `venv/bin/pre-commit run --all-files` β€” passed against the final diff.
- `venv/bin/gym dataset collate --config
resources_servers/aegis_v4_safety/configs/aegis_v4_safety.yaml --config
resources_servers/aegis_v4_safety/configs/aegis_v4_model.yaml --mode
example_validation --output-dir /tmp/aegis_v4_example_collate_128k` β€”
passed; example metadata remained current.
- `venv/bin/gym env test --resources-server aegis_v4_safety
+should_validate_data=true +uv_venv_dir=/tmp/aegis_v4_gym_test_128k
+skip_venv_if_present=true` β€” 23 tests passed and five-row example data
validated.
- Live Super β†’ Gym β†’ Aegis example job `7546959` β€” completed
successfully, five completed final answers, five resolved judgements,
zero rollout failures; the generated rollout file's SHA-256 is
`73c5e232565d8249c74a425ffbfc6c6b3f720882bedb7f089a7a0edfc9002d30`.

No request-routing or verifier logic changed. The fresh example rollouts
validate the higher target-model ceiling end to end; the full 5,964-row
internal score has not been reproduced by this five-row smoke run.

## User-visible impact

The built-in five-row benchmark and five resources-server examples now
permit longer target-model generations, which may increase runtime and
generated-token cost. The Aegis safety-only score does not measure
helpfulness or task correctness, and a high score can be obtained
through blanket refusals.

---------

Signed-off-by: Muskan Kumar <muskumar@nvidia.com>

This branch was previously deployed

1 inactive deployment
public β€” 005c848b Deployed Sep 29, 2026 by copy-pr-bot[bot] via release / finalize / notify #3833
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:environment Individual environments, benchmarks, verifiers, and environment-specific resources servers community-request Issue reported or requested by someone from the community complexity:medium Single-domain change with interacting parts or a moderate review surface feature New capabilities, enhancements, or enablement work needs-review PR is ready for code review and waiting on a reviewer

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants