Repository navigation
fix(genrm_compare): name output-budget exhaustion (max_output_tokens) in the judge failure - #3303
Conversation
3980bdc to
d9baf0f
Compare
When every attempt comes back incomplete with incomplete_details.reason=
max_output_tokens, the judge spent its whole output budget (typically on
reasoning) and never emitted a verdict. The retry path already raises
JudgeError("no completed answer") for this; the message now says how many
attempts exhausted the budget and at what max_output_tokens, and each such
attempt logs a warning, so operators can tell a budget problem from a
transport or parsing one.
Co-Authored-By: Balaji Ganesan <bganesan@nvidia.com>
Signed-off-by: Balaji Ganesan <bganesan@nvidia.com>
d9baf0f to
e71b081
Compare
|
Agreed, and done. Rebased onto main and trimmed to exactly that: the existing retry-then- |
yaoyu-33
left a comment
There was a problem hiding this comment.
LGTM. The escalation knobs are removed, and this now only clarifies output-budget exhaustion while preserving the existing retry and JudgeError behavior.
|
/ok to test daf175a |
|
🔄 Merge queue validation started! You can track the progress here: https://github.com/NVIDIA-NeMo/Gym/actions/runs/37048033494 |
What does this PR do?
Names GenRM output-budget exhaustion in the judge failure instead of reporting it as a generic "no completed answer", in
resources_servers/genrm_compare. No behaviour change: same retries, sameJudgeError, only the message and a per-attempt warning.Why
When the GenRM model spends its whole
max_output_tokenson reasoning, the model server returns HTTP 200 with a complete envelope and no verdict:status: "incomplete",incomplete_details.reason: "max_output_tokens". Since #2814 and #3351 the retry path already handles this correctly (retry, thenJudgeError), but the error reads the same as an empty or garbled answer, so an operator cannot tell a budget problem from a transport or parsing one without opening the raw response.Measured against a hosted GenRM endpoint with the candidates delivered as
response_1/response_2roles, temperature 0.6, same input each time:max_output_tokensstatus: completed)status: incomplete,reason: max_output_tokens, no verdict)The outcome is bimodal: the same input either converges at roughly 8 to 10k output tokens or runs away and consumes whatever budget it is given (4 of 4 still exhausted at 49,152), so the fix belongs with the judge's prompt or reasoning budget, and the message now points there.
How
_output_budget_exhausted(raw_response): true when the Responses object isincompletewith reasonmax_output_tokens.GenRM output budget exhausted for pair (i, j) (attempt a/n, max_output_tokens=N).JudgeErrormessage gains(k of them exhausted max_output_tokens=N without emitting a verdict; raise the budget or constrain the judge's reasoning). Completed-but-empty answers keep the unchanged generic message.resources_servers/genrm_compare/tests: 35 passed.Per review, the earlier opt-in budget escalation (
genrm_budget_exhausted_retry_multiplier,genrm_max_output_tokens_cap) is dropped.Checklist
resources_servers/genrm_compare/tests, 35 passed).pre-commit run --files ...: all Passed).git commit -s).