Skip to content

fix: avoid local STT crash on Apple Silicon - #28624

Closed
AnthonyFrancis wants to merge 1 commit into
NousResearch:mainfrom
AnthonyFrancis:fix/apple-silicon-local-stt-crash
Closed

fix: avoid local STT crash on Apple Silicon#28624
AnthonyFrancis wants to merge 1 commit into
NousResearch:mainfrom
AnthonyFrancis:fix/apple-silicon-local-stt-crash

Conversation

@AnthonyFrancis

Copy link
Copy Markdown

Summary

  • Detect macOS Apple Silicon/Rosetta before loading local faster-whisper
  • Force local STT to CPU/int8 on that path to avoid native device="auto" crashes
  • Set KMP_DUPLICATE_LIB_OK before importing faster_whisper for the affected path because the crash can happen during import via duplicate Intel OpenMP runtimes
  • Relax the voice extra NumPy pin to <2 because the current NumPy 2.x pin emits compatibility warnings with the installed torch/ctranslate2 stack
  • Add regression coverage for Rosetta detection and CPU-only model loading

Fixes #28622

Test Plan

  • python -m pytest tests/tools/test_transcription_tools.py -q -o 'addopts='
  • Manual local transcription on affected Mac/Rosetta environment:
    • force_cpu True
    • Result: {'success': True, 'transcript': 'Hello, one, two, three. Can you hear me?', 'provider': 'local'}
  • Restarted Hermes gateway and confirmed no new Python crash report was created during restart

@AnthonyFrancis
AnthonyFrancis requested a review from a team May 19, 2026 08:27
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists tool/tts Text-to-speech and transcription comp/gateway Gateway runner, session dispatch, delivery labels May 19, 2026
@austinpickett
austinpickett requested a review from Copilot May 19, 2026 10:36

@austinpickett austinpickett left a comment

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.

use PULL_REQUEST_TEMPLATE.md

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR mitigates hard-crash failures in the gateway’s local STT (faster-whisper / ctranslate2) path on macOS Apple Silicon—especially when running under Rosetta—by avoiding native device="auto" autodetection and working around Intel OpenMP duplicate-runtime aborts.

Changes:

  • Add macOS/Rosetta detection and force faster-whisper to load on CPU with compute_type="int8" on affected hosts.
  • Set KMP_DUPLICATE_LIB_OK prior to importing faster_whisper on the affected path to reduce import-time abort risk.
  • Adjust the voice extra’s NumPy requirement from a strict NumPy 2.x pin to numpy<2, and add targeted regression tests around the new CPU-forcing behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
tools/transcription_tools.py Adds Apple Silicon/Rosetta detection and forces CPU/int8 model loading; sets KMP_DUPLICATE_LIB_OK before importing faster-whisper on the affected path.
tests/tools/test_transcription_tools.py Adds regression tests for the CPU-forcing behavior and Rosetta detection; updates existing CUDA fallback tests to explicitly disable the new force-CPU path.
pyproject.toml Relaxes voice extra NumPy constraint to numpy<2 to avoid NumPy 2.x compatibility warnings with the STT stack.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +512 to +516
def test_apple_silicon_forces_cpu_without_auto_probe(self, tmp_path):
"""Apple Silicon/Rosetta should skip device='auto' to avoid SIGABRT."""
audio = tmp_path / "test.ogg"
audio.write_bytes(b"fake")

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the focused fix. The premise still holds on current main: tools/transcription_tools.py:1101-1103 imports faster_whisper and calls WhisperModel(..., device="auto", compute_type="auto"), which matches the crash path described in #28622.

Problems

  • The dependency-pin change is incomplete for Hermes' actual install paths. pyproject.toml's voice extra is one path, but local STT is also lazy-installed via tools/lazy_deps.py:110-114, and that still pins numpy==2.4.3 on current main.
  • The pyproject.toml hunk is stale against current main: gh pr diff 28624 --patch | git apply --check --verbose - fails only for pyproject.toml, while the transcription code and tests apply with offsets.

Suggested changes

  • Update tools/lazy_deps.py:110-114 to match the NumPy constraint chosen for the voice extra, so gateway lazy installs get the same fix.
  • Resolve the pyproject.toml optional-dependency conflict against current main's voice block at pyproject.toml:148-154, and update lock metadata if maintainers require uv.lock to track optional-dependency specifiers.

Automated hermes-sweeper review.

Comment thread pyproject.toml
"numpy==2.4.3",
"numpy<2",
]
pty = [

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This relaxes the voice extra, but local STT is also installed through the lazy dependency table on current main (tools/lazy_deps.py:110-114), which still pins numpy==2.4.3. Please update that sibling install path too so gateway lazy installs receive the same compatibility fix.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused Apple Silicon/Rosetta mitigation. The premise remains present on current main: tools/transcription_tools.py:1102-1104 imports faster_whisper and calls WhisperModel(..., device="auto", compute_type="auto").

Problems

  • The NumPy part of the fix only changes the explicit voice extra. Local STT also lazy-installs through tools/transcription_tools.py:208-229; its actual dependency table at tools/lazy_deps.py:132-136 still requests numpy==2.4.3, so that install path misses the compatibility change.
  • The pyproject.toml hunk is stale: gh pr diff 28624 --patch | git apply --check --verbose - fails for that file, while the code and test hunks apply with offsets. The current voice block is pyproject.toml:173-179.
  • numpy<2 also needs a supported lower bound and a regenerated lockfile under the dependency policy in AGENTS.md:561-576.

Suggested changes

  • Re-resolve the voice extra and uv.lock, and mirror the selected NumPy requirement in tools/lazy_deps.py:132-136.
  • Keep the CPU/int8 loading and Rosetta tests when salvaging the source change.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 13, 2026
teknium1 pushed a commit that referenced this pull request Jul 28, 2026
Force CPU (int8) for faster-whisper on Apple Silicon / Rosetta, where
ctranslate2's device=auto path can hard-abort in native code. Salvaged
from PR #28624 without the numpy pin change (main already moved on).

(cherry picked from commit 7edf2d5, pyproject.toml hunk dropped)
@teknium1

Copy link
Copy Markdown
Contributor

Merged into main via consolidated salvage PR #73510 (merge c0c5dac531). Your Apple Silicon / Rosetta local STT crash guard (CPU int8 + KMP_DUPLICATE_LIB_OK on Darwin arm64) was cherry-picked with your authorship; only the stale numpy-pin hunk was dropped.

Your contribution is credited to you in git history. Thank you! Closing this PR as merged-via-salvage.

@teknium1 teknium1 closed this Jul 29, 2026
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
Force CPU (int8) for faster-whisper on Apple Silicon / Rosetta, where
ctranslate2's device=auto path can hard-abort in native code. Salvaged
from PR NousResearch#28624 without the numpy pin change (main already moved on).

(cherry picked from commit 7edf2d5, pyproject.toml hunk dropped)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/gateway Gateway runner, session dispatch, delivery P2 Medium — degraded but workaround exists sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades tool/tts Text-to-speech and transcription type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gateway voice notes crash Python on Apple Silicon/Rosetta local STT

6 participants