Skip to content

macOS Python 3.14 CPU backend: intra_threads=0 aborts on 4.7.2 and oversubscribes on 4.8.0 #2063

Description

@jmpnop

Summary

On macOS arm64 with Python 3.14.5, the no-OpenMP CTranslate2 CPU backend behaves poorly when intra_threads=0 is used through Argos Translate. In 4.7.2 it produced a native abort during a sustained translation workload. In 4.8.0 the same workload no longer aborted in my test, but the automatic backend threading path was still pathologically slow and CPU-heavy compared with intra_threads=1.

Environment

macOS 26.5.1 arm64
Python 3.14.5
CTranslate2 4.7.2 and 4.8.0 wheels
Argos Translate / argostranslate-lt 1.12.1
English -> Russian Argos model

4.7.2 crash

With CTranslate2 4.7.2 and Argos' default ARGOS_INTRA_THREADS=0, a sustained Markdown translation workload aborted after several hundred translation calls:

libc++abi: terminating due to uncaught exception of type std::__1::system_error:
condition_variable wait failed: Invalid argument

Crash report showed the faulting thread inside the vendored CPU backend thread pool:

BS::thread_pool_light::worker()
std::__1::condition_variable::wait(...)

The main thread was waiting in:

ctranslate2::python::wait_on_futures<ctranslate2::TranslationResult>(...)
ctranslate2::python::TranslatorWrapper::translate_batch(...)

4.8.0 performance problem

I upgraded the same environment to CTranslate2 4.8.0. The crash-adjacent segment completed, and a full sustained run completed when using intra_threads=1.

However, with the unpatched default intra_threads=0, the process became extremely CPU-heavy and slow:

CPU: ~1470%
Hot path: ctranslate2::TranslatorWrapper::translate_batch
          ctranslate2::ops::Gemm::compute
          ruy::ThreadPool::ExecuteImpl
          ruy::BlockingCounter::Wait
          BS::thread_pool...

Benchmark on the same 30-unit Markdown slice with CTranslate2 4.8.0:

intra=0  TIMEOUT >60s
intra=1  elapsed=31.012s user=36.103s  sys=0.120s
intra=2  elapsed=48.529s user=84.297s  sys=19.564s
intra=4  elapsed=38.526s user=139.771s sys=28.153s
intra=8  elapsed=37.895s user=275.805s sys=28.084s

For this workload, intra_threads=1 is both fastest and most stable.

Notes

Argos Translate is mitigating this by defaulting ARGOS_INTRA_THREADS to 1 on Darwin while preserving explicit user overrides:

argosopentech/argos-translate#528

I am filing this here because the 4.7.2 abort and 4.8.0 oversubscription both appear to originate in the CTranslate2 macOS no-OpenMP CPU backend path when the backend default thread count is selected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions