-
Notifications
You must be signed in to change notification settings - Fork 6
Add finance grounding verification #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,122 @@ | ||
| # GroundingVerifier for finance | ||
|
|
||
| GroundingVerifier evaluates completed `finance_agent` rollouts against the SEC | ||
| evidence preserved in their native tool-call history. It writes a separate | ||
| sidecar and does not modify the original rollout, reward, or training data. | ||
|
|
||
| The evaluator: | ||
|
|
||
| 1. deterministically splits the submitted answer into claims; | ||
| 2. routes each claim to retrieved evidence with | ||
| `sentence-transformers/all-MiniLM-L6-v2`; | ||
| 3. checks entailment with | ||
| `MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli`; and | ||
| 4. verifies SEC attribution, entities, metrics, dates, protected values, | ||
| calculations, comparisons, and evidence-scoped refusals. | ||
|
|
||
| Both public model revisions can be pinned. Incomplete attribution or model | ||
| failure produces `unavailable`; unsupported or conflicting claims are blocked. | ||
| Evidence is limited to `retrieve_information` excerpts retained by the rollout. | ||
|
|
||
| ## Air-gapped setup | ||
|
|
||
| NVFlow workers run with Hugging Face and Transformers offline flags enabled, so | ||
| the two public models must be staged before submitting `evaluate_grounding`. | ||
| From a connected host, download the pinned revisions into the cluster directory | ||
| mounted as `/hf_models`: | ||
|
|
||
| ```bash | ||
| uv run hf download sentence-transformers/all-MiniLM-L6-v2 \ | ||
| config.json model.safetensors special_tokens_map.json \ | ||
| tokenizer.json tokenizer_config.json vocab.txt \ | ||
| --revision 1110a243fdf4706b3f48f1d95db1a4f5529b4d41 \ | ||
| --local-dir /path/to/models/hf_models/sentence-transformers/all-MiniLM-L6-v2 | ||
|
|
||
| uv run hf download MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli \ | ||
| added_tokens.json config.json model.safetensors special_tokens_map.json \ | ||
| spm.model tokenizer.json tokenizer_config.json \ | ||
| --revision 6f5cf0a2b59cabb106aca4c287eed12e357e90eb \ | ||
| --local-dir /path/to/models/hf_models/MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli | ||
| ``` | ||
|
|
||
| The workflow loads `/hf_models/sentence-transformers/all-MiniLM-L6-v2` and | ||
| `/hf_models/MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli`. See [INSTALL.md → | ||
| Download Models](../../../../INSTALL.md#download-models) for the mount | ||
| configuration and general model-staging procedure. | ||
|
|
||
| ## NVFlow integration | ||
|
|
||
| Add `evaluate_grounding` after `collect_rollouts` in a finance GRPO workflow. | ||
| The stage reads completed `output-rs*.jsonl` files and writes matching | ||
| `grounding-verifier-rs*.jsonl` sidecars. | ||
|
|
||
| ```yaml | ||
| pipeline_stages: | ||
| - collect_rollouts | ||
| - evaluate_grounding | ||
| ``` | ||
|
|
||
| ## Repeated feature acceptance | ||
|
|
||
| Every GroundingVerifier feature can define a native acceptance profile with a | ||
| fixed number of finance-agent seeds. The first profile covers the air-gapped | ||
| model setup and runs one prepared `finance_sec_search` task three times: | ||
|
|
||
| ```bash | ||
| uv run nflow run-all \ | ||
| --config nvflow/recipes/finance/workflows/grpo/feature_gates/grounding_airgap.yaml \ | ||
| -e finance_sec_search | ||
| ``` | ||
|
|
||
| Change `feature_runs` in the profile to increase the repetition count. The | ||
| profile always regenerates its dedicated rollouts, evaluates every row, and | ||
| then fails unless all expected files and completion markers exist, every | ||
| sidecar matches its rollout fingerprint, the offline model contract holds, and | ||
| the unavailable rate stays within the configured limit. Its compact summary is | ||
| written beside the sidecars as `feature-gate-grounding_airgap.json`. | ||
|
|
||
| This native profile requires the demo `prepare_data` output and SEC cache from | ||
| the quick-start workflow. Ordinary CI tests validate the gate logic without a | ||
| GPU; executing the finance agent itself requires the configured NVFlow Slurm | ||
| environment. `allow` and `block` are both valid execution outcomes because an | ||
| unsupported agent answer should be blocked. Detection efficacy remains covered | ||
| by the pinned public-model benchmark below. | ||
|
|
||
| ## Public-model benchmark | ||
|
|
||
| The controlled benchmark uses eight FY2024 facts from Amazon, Alphabet, Meta, | ||
| and Tesla, which were held out from the earlier AAPL/MSFT/NVDA development set. | ||
| Each fixed evidence trace is evaluated once with its grounded answer and against | ||
| six mutations: numeric fabrication, entity conflation, metric fabrication, | ||
| temporal conflation, accession conflation, and an unsupported claim. This gives | ||
| eight grounded and 48 adversarial cases. | ||
|
|
||
| ```bash | ||
| uv sync | ||
| uv run python -m nvflow.recipes.finance.utils.rl.grounding_benchmark \ | ||
| --output-dir artifacts/grounding-verifier-benchmark \ | ||
| --routing-model-revision 1110a243fdf4706b3f48f1d95db1a4f5529b4d41 \ | ||
| --nli-model-revision 6f5cf0a2b59cabb106aca4c287eed12e357e90eb | ||
| ``` | ||
|
|
||
| The command writes `cases.jsonl`, `results.jsonl`, and `summary.json`. It also | ||
| records latency, throughput, memory use, model revisions, and host details. | ||
| It succeeds only when grounded acceptance and attack rejection are each at | ||
| least 90% and the unavailable rate is at most 5%. | ||
|
|
||
| The same public-model gate and native rollout-to-sidecar check can be run with: | ||
|
|
||
| ```bash | ||
| GROUNDING_VERIFIER_RUN_MODELS=1 uv run pytest -q \ | ||
| tests/test_grounding_benchmark.py -k pinned_public_models --no-cov | ||
| ``` | ||
|
|
||
| For the native held-out study, see the [frozen evaluation | ||
| protocol](evaluation-protocol.md) and [results](evaluation-results.md). | ||
|
|
||
| ## Scope | ||
|
|
||
| This integration verifies whether a submitted answer is supported by the | ||
| retrieval excerpts and SEC metadata preserved in an NVFlow rollout. It does not | ||
| independently re-verify the complete SEC filing or establish unrestricted | ||
| production hallucination detection. | ||
57 changes: 57 additions & 0 deletions
57
docs/recipes/finance/grounding-verifier/evaluation-protocol.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| # Native finance evaluation protocol | ||
|
psgundecha-nv marked this conversation as resolved.
|
||
|
|
||
| The confirmation protocol was frozen before task generation, rollout | ||
| collection, or GroundingVerifier evaluation. | ||
|
|
||
| ## Separation | ||
|
|
||
| - All 60 issuers were excluded from development and three earlier studies. | ||
| - GroundingVerifier was not used for task generation, rollout collection, | ||
| eligibility, labeling, or adversarial-answer creation. | ||
| - Evaluation inputs and labels were frozen before the one-shot guard run. | ||
|
|
||
| ## Trace generation | ||
|
|
||
| An independent generator used official SEC ticker, submissions, filing, and | ||
| XBRL Company Facts data to select a 10-K and establish its company, metric, | ||
| year, value, and unit. Each task supplied the target filing date, canonical SEC | ||
| URL, and bounded retrieval range. | ||
|
|
||
| A pinned, locally hosted `Qwen3-4B-Instruct-2507` policy then executed the native | ||
| NVFlow `finance_agent` path: | ||
|
|
||
| ```text | ||
| sec_filing_search -> parse_html_page -> retrieve_information -> submit_final_result | ||
| ``` | ||
|
|
||
| The tasks covered year-over-year calculations, cross-issuer comparisons, and | ||
| closed-world evidence-based refusals. This design tests evidence use and answer | ||
| verification, not autonomous discovery of an unknown filing. | ||
|
|
||
| ## Eligibility and freezing | ||
|
|
||
| A calculation or comparison was eligible only when every retrieved | ||
| company/metric/year/value/unit tuple agreed with the independent SEC/XBRL | ||
| reference. A refusal was eligible only when its bounded evidence contained a | ||
| valid coverage fact but omitted the requested metric. | ||
|
|
||
| We collected 180 native rollouts and selected 120 eligible traces by task-ID | ||
| hash, balanced as 40 calculations, 40 comparisons, and 40 refusals. Selection | ||
| did not use GroundingVerifier outcomes. | ||
|
|
||
| Each trace contributed one grounded answer and one independently assigned | ||
| adversarial answer. Attacks covered numeric fabrication; entity, metric, | ||
| temporal, and source conflation; wrong or contradictory comparison winners; | ||
| and unsupported refusal claims. | ||
|
|
||
| ## Success criteria | ||
|
|
||
| The preregistered GO gate required: | ||
|
|
||
| - at least 95% grounded acceptance and attack rejection; | ||
| - Wilson 95% lower bounds of at least 90%; | ||
| - at least 90% accuracy in every task category; and | ||
| - zero adversarial `allow` decisions. | ||
|
|
||
| Intervals used two-sided Wilson estimates and 20,000 issuer-cluster bootstrap | ||
| resamples with seed `26081432`. | ||
58 changes: 58 additions & 0 deletions
58
docs/recipes/finance/grounding-verifier/evaluation-results.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| # Native finance evaluation results | ||
|
|
||
| ## Verdict | ||
|
|
||
| The frozen confirmation passed its preregistered GO criteria. | ||
|
|
||
| | Endpoint | Correct | Rate | Wilson 95% interval | | ||
| |---|---:|---:|---:| | ||
| | Grounded acceptance | 119/120 | 99.17% | 95.43-99.85% | | ||
| | Adversarial rejection | 120/120 | 100% | 96.90-100% | | ||
|
|
||
| - Calculations: 80/80 paired decisions correct. | ||
| - Comparisons: 80/80 paired decisions correct. | ||
| - Refusals: 79/80 paired decisions correct. | ||
| - False allows: 0. | ||
| - Exact two-sided McNemar comparison with an accept-all baseline: | ||
| `p = 9.18e-35`. | ||
|
|
||
| All attacks were blocked. They included numeric fabrication; entity, metric, | ||
| temporal, and source conflation; wrong or contradictory comparison winners; | ||
| and unsupported refusal detail or assertion. | ||
|
|
||
| ## Collection and validation | ||
|
|
||
| - Native collection: 180 rollouts in 1:46:40. | ||
| - Frozen evaluation: 120 independent traces from 60 unseen issuers. | ||
| - Guard evaluation: 240 paired rows in 33.60 seconds. | ||
| - Native exclusions: 40 missing or incorrect source-bound tuples, nine | ||
| unexpected retrieval counts, one unpaired submission, and ten eligible | ||
| reserve traces. Exclusions did not use guard outcomes. | ||
| - Repository tests: 385 passed and one skipped. | ||
| - Pinned-public-model integration test, Ruff, `uv lock --check`, and | ||
| `git diff --check`: passed. | ||
|
|
||
| ## Residual error | ||
|
|
||
| The only false block was a grounded refusal for a company ending in `N.V.`. | ||
| The deterministic decomposer split the legal suffix into an incomplete clause, | ||
| which the NLI model classified as contradiction. The candidate was not changed | ||
| after observing the confirmation result. | ||
|
|
||
| ## Public models | ||
|
|
||
| ```text | ||
| sentence-transformers/all-MiniLM-L6-v2 | ||
| revision 1110a243fdf4706b3f48f1d95db1a4f5529b4d41 | ||
|
|
||
| MoritzLaurer/DeBERTa-v3-base-mnli-fever-anli | ||
| revision 6f5cf0a2b59cabb106aca4c287eed12e357e90eb | ||
| ``` | ||
|
|
||
| ## Claim boundary | ||
|
|
||
| These results demonstrate source-bound detection on controlled, issuer-held-out | ||
| retrieval excerpts preserved in native NVFlow finance traces. They do not | ||
| independently validate complete SEC documents, estimate production failure | ||
| prevalence, prove unrestricted hallucination detection, or demonstrate an | ||
| NVIDIA Slurm deployment. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| # Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
| # | ||
| """Evidence-based provenance decisions for NVFlow agent outputs.""" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.