Skip to content

Fix CharacterErrorRate checkpoint and distributed state - #3829

Open
aswanth-07 wants to merge 2 commits into
pytorch:masterfrom
aswanth-07:fix/cer-distributed-state
Open

Fix CharacterErrorRate checkpoint and distributed state#3829
aswanth-07 wants to merge 2 commits into
pytorch:masterfrom
aswanth-07:fix/cer-distributed-state

Conversation

@aswanth-07

Copy link
Copy Markdown

What does this PR do?

Fixes #3828.

CharacterErrorRate was missing two pieces of standard Ignite metric bookkeeping:

  • it declared no _state_dict_all_req_keys, so metric checkpoint round-trips discarded all accumulated errors, reference characters, and update state;
  • it reduced errors and reference characters across ranks but left _num_examples local, causing ranks with no local batches to raise NotComputableError even when other ranks had valid input.

This PR declares the three existing accumulators as the metric state and includes _num_examples in the existing distributed sum. It does not change CER calculation or the public API.

The tests cover both failure modes: a state-dict round trip retains a CER of 0.2, and a distributed test updates only rank 0 before computing collectively.

Validation

  • pytest tests/ignite/metrics/nlp/test_character_error_rate.py -q -m "not distributed" — 18 passed
  • pytest tests/ignite/metrics/nlp/test_character_error_rate.py -q -m distributed -k gloo_cpu — passed locally; the multi-rank CI configuration exercises the empty-rank branch
  • pre-commit run --files ignite/metrics/nlp/character_error_rate.py tests/ignite/metrics/nlp/test_character_error_rate.py — passed
  • pyrefly check ignite/metrics/nlp/character_error_rate.py — 0 errors
  • git diff --check — passed

Checklist

  • This PR does one thing.
  • The bug and proposed fix are documented in the linked issue.
  • Necessary regression tests are included.
  • Existing focused tests and code-style checks pass locally.
  • No public API or breaking behavior is introduced.

Disclosure: I used OpenAI Codex to assist with auditing the accumulator protocol, reproducing the state loss, and running validation. I reviewed the complete diff against the conventions used by Ignite's other accumulating metrics.

@github-actions github-actions Bot added the module: metrics Metrics module label Aug 23, 2026
@aswanth-07
aswanth-07 force-pushed the fix/cer-distributed-state branch from ad71802 to 63c494b Compare August 23, 2026 13:18
Comment thread ignite/metrics/nlp/character_error_rate.py Outdated
Comment on lines +127 to +134
@pytest.mark.skipif(not idist.has_native_dist_support, reason="Skip if no native dist support")
@pytest.mark.usefixtures("distributed")
def test_distributed_with_empty_rank():
cer = CharacterErrorRate()
if idist.get_rank() == 0:
cer.update((["bat"], ["cat"]))

assert cer.compute() == pytest.approx(1 / 3)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we do. The regression is not only that an empty rank should avoid raising. _num_errors, _num_refs, and _num_examples must all reduce to the same global state. Checking 1 / 3 verifies that the numerator and denominator remain correct on every rank, so I kept this assertion.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vfdev-5 thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

module: metrics Metrics module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CharacterErrorRate drops checkpoint state and fails on empty distributed ranks

2 participants