Repository navigation
FEAT: Report single-trial scorer metrics alongside the majority vote - #4148
Open
WatchTree-19 wants to merge 1 commit into
Open
WatchTree-19 wants to merge 1 commit into
WatchTree-19 wants to merge 1 commit into
Conversation
ScorerEvaluator scores each response num_scorer_trials times, then computes objective metrics on the majority vote of the trials and harm MAE on their median. A scorer in a scenario scores each response once, so the published figures describe a steadier scorer than the one that runs. Add single_trial_accuracy, num_inconsistent_responses and krippendorff_alpha_model to ObjectiveScorerMetrics, and single_trial_mean_absolute_error to HarmScorerMetrics. All are None for a single trial and for results recorded before they existed. The printer and the scorer metrics docs show them.
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain for the added single-trial performance and consistency metrics.
No open issues 🎉
What changed in this PR
This PR adds single-trial performance and consistency metrics to PyRIT’s scorer evaluation, showing how individual scoring runs compare with existing majority-vote and median-based results.
Changes:
- Adds objective single-trial accuracy, inconsistent-response counts, model agreement, and harm single-trial MAE without changing existing metrics.
- Displays the new metrics when present and preserves compatibility with older stored results.
- Adds calculation, serialization, and rendering tests, plus synchronized documentation.
| File | Description |
|---|---|
tests/unit/score/test_scorer_metrics_io.py |
Tests backward-compatible loading and JSON round-trips. |
tests/unit/score/test_scorer_evaluator.py |
Tests trial metrics, agreement values, and single-trial behavior. |
tests/unit/output/scorer/test_pretty.py |
Tests conditional display of the new metrics. |
pyrit/score/scorer_evaluation/scorer_metrics.py |
Defines optional single-trial and consistency fields. |
pyrit/score/scorer_evaluation/scorer_evaluator.py |
Computes the new metrics from individual trials. |
pyrit/output/scorer/pretty.py |
Renders trial metrics when available. |
doc/code/scoring/4_scorer_metrics.py |
Explains the new metrics and when they apply. |
doc/code/scoring/4_scorer_metrics.ipynb |
Mirrors the documentation updates in the notebook. |
Review effort: Balanced
This branch has not been deployed
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
ScorerEvaluatorruns each response through the scorernum_scorer_trialstimes (3 for the published metrics) and the docs describe the trials as a way to measure variance. The metrics then collapse them: objective accuracy, precision, recall and F1 are computed on the majority vote of the trials, and harm MAE on their median. In a scenario a scorer scores each response once, so the published figures describe a steadier scorer than the one that runs. For objective scorers nothing about the trials themselves is reported at all; harm scorers already reportkrippendorff_alpha_model.This adds the trials back to the metrics, alongside the existing fields, which are unchanged:
ObjectiveScorerMetrics.single_trial_accuracy: accuracy of the trials taken one at a time, averaged over the trials. This is the accuracy to expect from a single scoring run.ObjectiveScorerMetrics.num_inconsistent_responses: responses whose trials did not all return the same verdict.ObjectiveScorerMetrics.krippendorff_alpha_model: the scorer's agreement with itself across trials, using the existingkrippendorff_alpha, as harm metrics already do.HarmScorerMetrics.single_trial_mean_absolute_error: MAE of the trials taken one at a time.A small example of the gap: three trials over three true responses, each trial wrong on a different one. The majority vote is right everywhere (accuracy 1.0), but any single run is right two times in three (
single_trial_accuracy0.667), andnum_inconsistent_responsesis 3.All four fields are
Nonewith a single trial, where they would repeat the existing values, and for results recorded before they existed, so stored registry entries load unchanged.PrettyScorerMemoryPrintershows them when present, and the scorer metrics doc page describes them.Tests and Documentation
tests/unit/score/test_scorer_evaluator.py: single-trial accuracy behind a majority vote, the count of inconsistent responses, consistent trials matching the majority vote,Nonefor a single trial, the end-to-end path throughevaluate_dataset_async, and the harm single-trial MAE. Both alpha values are checked against the referencekrippendorffpackage.tests/unit/score/test_scorer_metrics_io.py: entries recorded before these fields load withNone, and the fields round-trip through JSON.tests/unit/output/scorer/test_pretty.py: the printer shows the fields and omits them for a single trial.doc/code/scoring/4_scorer_metrics.pyand.ipynb: the new fields, kept in sync.Twelve of the new tests fail on main and pass with the change; the other two pin that nothing new appears for a single trial.
How it was tested