open-compass / open-compass/VLMEvalKit

olmOCRBench: `evaluate()` returns `None`, so the score never reaches `status.json`

Open Beginner friendly
#1,690 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
4.4k
Forks
768
Avg merge
1d 10h
Merged PRs (30d)
17

Description

Summary

OlmOCRBench.evaluate() computes its results and writes them to disk, but does
not return them. run.py uses the return value to record the score, so the run
ends with

"skip_reason": "evaluate_returned_none"

while olmOCRBench_eval_summary.csv sits next to the prediction file
containing the correct numbers. The benchmark has effectively run successfully
and reported nothing.

Every other dataset's evaluate() returns a DataFrame or dict; this one is
the exception.

Where

vlmeval/dataset/olmOCRBench/olmocrbench.py:

def evaluate(self, eval_file, **judge_kwargs):
    try:
        from .evaluator import evaluator
    except ImportError as e:
        ...
        raise e
    tsv_path = self.data_path
    evaluator(tsv_path, eval_file)      # <- no return

evaluator() writes the summary as a side effect —
vlmeval/dataset/olmOCRBench/evaluator.py:449:

csv_path = os.path.join(os.path.dirname(eval_file), "olmOCRBench_eval_summary.csv")
rows = [["type", "score"]]
rows.append(["overall", f"{new_overall_score * 100:.1f}"])
for jsonl_file, results in sorted(jsonl_results.items()):
    if results["total"] > 0:
        rows.append([jsonl_file, f"{pass_rate:.1f}"])

Impact

  • status.json records no score for olmOCRBench, so scripts/summarize.py
    reports nothing for it. Its main() returns silently when summary_rows is
    empty, so this presents as an absent dataset rather than an error.
  • Anything that aggregates across datasets treats a completed, correct run as a
    missing one.
  • The failure is easy to misread as an evaluation crash, because the
    skip_reason says the evaluation was skipped when in fact it completed.

Suggested fix

Return the summary that evaluator() already produces. Minimal version, which
re-reads the file the evaluator just wrote:

     def evaluate(self, eval_file, **judge_kwargs):
         try:
             from .evaluator import evaluator
         except ImportError as e:
             ...
             raise e
         tsv_path = self.data_path
-        evaluator(tsv_path, eval_file)
+        evaluator(tsv_path, eval_file)
+        csv_path = osp.join(osp.dirname(eval_file), 'olmOCRBench_eval_summary.csv')
+        if osp.exists(csv_path):
+            df = pd.read_csv(csv_path)
+            # {'overall': 63.4, 'tables': 55.0, ...}
+            return dict(zip(df['type'], df['score']))
+        return None

Cleaner would be for evaluator() to return the rows it writes, and for
evaluate() to pass them through — that avoids the write/read round trip
entirely.

A related naming point

The summary is written as a fixed, unprefixed filename:

olmOCRBench_eval_summary.csv

rather than the <model>_<dataset>_acc.csv convention the other datasets
follow. That means:

  • tooling that locates score files by the usual <model>_<dataset>* pattern
    cannot find it
  • two models evaluated into the same directory would overwrite each other's
    summary

Renaming it to {eval_file_stem}_acc.csv — or using
get_intermediate_file_path(eval_file, '_acc'), as other datasets do — would
make it consistent and collision-free. Happy to include that in the same PR if
it is wanted, or leave it out to keep the change minimal.

Environment

  • VLMEvalKit: main
  • Reproduced with a local model through the --mode eval path; independent of
    model and backend, since it is purely the missing return value.

Happy to open a PR.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in vlmeval/dataset/olmOCRBench/olmocrbench.py and trace how run.py records evaluate() results. Read evaluator.py around line 449 and scripts/summarize.py, then run the --mode eval path and inspect status.json. Done means olmOCRBench reports its computed summary instead of evaluate_returned_none; filename consistency is an optional follow-up.

Written by the indexing model from the issue text.

Assessment

Tech stack
pandas, python
Domain
data, machine-learning, testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.