Skip to content

Improve CPU detection for multiprocessing in scorers - #117

Merged
kahne merged 2 commits into
mainfrom
fix-scorer-multiprocessing
Aug 18, 2026
Merged

Improve CPU detection for multiprocessing in scorers#117
kahne merged 2 commits into
mainfrom
fix-scorer-multiprocessing

Conversation

@kahne

@kahne kahne commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

This PR improves the CPU detection logic for multiprocessing in scorers to properly account for containerized environments (Docker, Kubernetes).

  • Detects CPU limits from cgroup v1 and v2 (common in Docker/Kubernetes)
  • Respects CPU affinity masks (set by taskset, Docker --cpuset-cpus, etc.)
  • Enables multiprocessing by default when multiple CPUs are available
  • Removes hardcoded n_workers = 1 initialization
  • Improves documentation on worker configuration for custom scorers

Testing

The changes enable the multiprocessing optimization to engage automatically based on available CPUs and sample count, while respecting resource limits imposed by containerized environments.

Changhan Wang added 2 commits August 13, 2026 17:01
_update_n_workers() wrote its derived worker count back over the caller's
n_workers=None sentinel. The call from __init__ has no sample count to
derive from, so it pinned n_workers to 1; the later call from score() then
saw a non-None value and left it there. Multi-processing therefore never
engaged unless n_workers was passed explicitly, despite being the
advertised default.

Keep the caller's request in self._requested_n_workers and always
re-derive from it, so _update_n_workers(n_samples) is idempotent and the
existing "call _update_n_workers(n), then read self.n_workers" pattern in
BLEUScorer, BrevityPenaltyScorer, ChrFScorer, CIDErScorer and WERScorer
keeps working unchanged.

Verified on the WMT14 en-de test set (2737 samples -> 3 workers) that all
16 n-gram-based scorers produce corpus and sentence scores identical to a
forced single-process run. This also exercises the corpus-level process
pool in bleu.py and chrf.py for the first time, which was unreachable
before. At 21896 samples on 22 workers: TER 82.3s -> 4.2s, METEOR
10.2s -> 0.7s, RIBES 2.9s -> 0.4s.
Add proper CPU detection that accounts for cgroup limits (common in Docker/Kubernetes
environments) by detecting both cgroup v1 and v2 CPU quotas. This enables multiprocessing
to engage by default when multiple CPUs are available, fixing the issue where scorers
would default to single-worker processing.

- Add _cgroup_cpu_quota() to detect CPU quota limits
- Add _available_cpu_count() to get CPUs considering affinity masks and cgroups
- Remove hardcoded n_workers = 1 initialization
- Update worker count logic to use _available_cpu_count()
- Improve documentation on worker configuration
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Aug 18, 2026
@kahne
kahne merged commit 59e1f05 into main Aug 18, 2026
18 of 21 checks passed
@kahne
kahne deleted the fix-scorer-multiprocessing branch August 18, 2026 17:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant