Skip to content

[Fix] MMMU-Pro cot_postproc: robustly extract the option letter (handles "Answer: $LETTER" echoes)#1591

Merged
kennymckormick merged 1 commit into
open-compass:mainfrom
sseanliu:fix/mmmu-pro-cot-answer-extraction
Jul 3, 2026
Merged

[Fix] MMMU-Pro cot_postproc: robustly extract the option letter (handles "Answer: $LETTER" echoes)#1591
kennymckormick merged 1 commit into
open-compass:mainfrom
sseanliu:fix/mmmu-pro-cot-answer-extraction

Conversation

@sseanliu

@sseanliu sseanliu commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

MMMUProDataset.cot_postproc mis-extracts the predicted option in two common cases, causing correct answers to be scored as wrong on the CoT settings of MMMU-Pro:

  1. It counts uppercase letters across the entire Answer: line. The capital A in the word "Answer" is always counted, so len(counter) == 1 almost never holds and the clean-letter fast-path rarely fires.
  2. When a model echoes the prompt's 'Answer: $LETTER' template literally — e.g. Answer: $B — the fallback returns the raw text " $B", which the downstream option matcher (exact_matching) cannot parse, so the item is scored incorrect.

build_prompt explicitly instructs "...format: 'Answer: $LETTER'...", and several models reproduce the $ literally, so this is hit frequently — especially in the Vision setting (MMMU_Pro_V), where the options live inside the image.

Fix

Inspect only the text after the last Answer: marker (and take the last Answer: line, in case the model emits more than one). This removes the spurious A from "Answer" and makes Answer: $B resolve to B.

if len(cands) >= 1:
    tail = cands[-1][len('Answer:'):]
    counter = defaultdict(lambda: 0)
    for ch in tail:
        if ch in string.ascii_uppercase:
            counter[ch] += 1
    if len(counter) == 1:
        return list(counter.keys())[0]
    else:
        return tail
return response

Validation

Eval-only rescoring of identical saved predictions (a 31B open model, greedy, --judge exact_matching), with only cot_postproc changed:

Setting before after
MMMU_Pro_V (COT) 18.55% 67.92%
MMMU_Pro_10c (COT) ~56% ~74%

In this run 77% of MMMU_Pro_V answers were written as Answer: $X (literal $). The fixed values match both the reference evaluate.py extraction (rfind("Answer:")) and the models' own stated answers, and are consistent with the public MMMU-Pro leaderboard for this model.

Single-function change, no new dependencies.

cot_postproc counted uppercase letters across the whole 'Answer:' line, so the
capital 'A' in the word 'Answer' always added a spurious letter and the
single-letter fast-path almost never fired. Models that echo the prompt's
'$LETTER' template literally (e.g. 'Answer: $B') then fell through to returning
raw text that the downstream option matcher cannot parse, scoring correct
answers as wrong.

Fix: inspect only the text after the last 'Answer:' marker (also handles
multiple 'Answer:' lines by taking the last one).

Validation (eval-only rescoring of identical predictions, gemma-4-31b):
MMMU_Pro_V COT 18.55%->67.92%, MMMU_Pro_10c COT ~56%->~74%, matching the
reference evaluate.py extraction (rfind('Answer:')).
@kennymckormick kennymckormick added this pull request to the merge queue Jul 3, 2026
Merged via the queue into open-compass:main with commit 944ee12 Jul 3, 2026
10 of 11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants