The TRANSFORMERS_IMPORT hint and the ASR pipeline error told users to reinstall torch + torchaudio + transformers. torchvision — the package whose ABI mismatch actually produces this exact lazy-import wording (#1357's torchvision::nms, wrapped into "Could not import module 'AutoFeatureExtractor'") — was the one package the advice omitted. Following it to the letter left the broken package untouched (#1376). Both surfaces now name the mismatch as a cause and prescribe the pinned reinstall with literal versions (desktop installs ship no deploy/, so the constraint-file form fails there) targeting the venv explicitly. A lockstep test asserts the exact command on every advice surface against deploy/torch-constraints.txt, so a pin bump stays red until the advice matches. Docs gain the same-wording-different-cause section (1a-bis).
This commit is contained in:
@@ -31,6 +31,7 @@ The bundled TTS model package (`pyproject.toml`) is versioned independently.
|
||||
|
||||
- Every subprocess TTS engine would have turned a stereo render into noise: the mono downmix always averaged axis 0, which is time rather than channels for channels-last audio. Unreachable today since every engine returns mono, fixed in all five before it isn't. (#1328)
|
||||
- A generation that hits its time limit now says so, instead of "an error OmniVoice doesn't recognize" followed by an empty `TimeoutError:`. It names the likely causes and the setting that raises the limit. (#1368)
|
||||
- The "transformers install is incomplete" advice now names torchvision — the package whose version mismatch actually produces that error — and points at the pinned reinstall that repairs it, instead of a reinstall that left the broken package untouched. (#1376, #1357)
|
||||
- A model download cut off mid-request is no longer reported as a broken transformers install — reinstalling could never have fixed a dropped connection. (#1347)
|
||||
- A TLS connection cut during generation is explained as the dropped download it is, instead of falling through as an unrecognized error carrying `_ssl.c:1016`. (#1335)
|
||||
- Windows "paging file is too small" no longer suggests the Flush button, which cannot help. It now names the virtual-memory setting to change, and says plainly that it is not a network problem. (#1334)
|
||||
|
||||
@@ -40,7 +40,13 @@ _HINTS: dict[str, str] = {
|
||||
"HF_AUTH_FAILED": "Set a valid HF_TOKEN in Settings → Hugging Face and retry.",
|
||||
"PYANNOTE_LICENSE_REQUIRED": "Accept the pyannote model licenses on Hugging Face, then retry.",
|
||||
"COMPUTE_TYPE_UNSUPPORTED": "Your GPU doesn't support float16 — OmniVoice retried on int8. If transcription still fails, set OMNIVOICE/ASR_COMPUTE_TYPE=int8 or use CPU.",
|
||||
"TRANSFORMERS_IMPORT": "Your transformers install is incomplete, or a package it loads models through (torchaudio) is missing or mismatched with your torch. Reinstall them together (`uv pip install --reinstall torch torchaudio transformers`), then restart the backend. If only transcription is affected, switching ASR to faster-whisper (Settings → Models) also works around it.",
|
||||
# Literal versions, not `--constraint deploy/torch-constraints.txt`:
|
||||
# desktop installs don't ship deploy/ (tauri.conf.json bundles only
|
||||
# pyproject/uv.lock/backend/omnivoice), so the file-based command would
|
||||
# fail with "file not found" for exactly the users most likely to need it
|
||||
# (greptile on #1377). tests/test_failure_classify.py pins these literals
|
||||
# to the constraint file so they cannot drift when the pins bump.
|
||||
"TRANSFORMERS_IMPORT": "Your transformers install is incomplete, or a package it loads models through (torchaudio, torchvision) is missing or mismatched with your torch — a torch/torchvision version mismatch fails with exactly this wording. Reinstall them together at the pinned versions (`uv pip install --python .venv --reinstall torch==2.8.0 torchaudio==2.8.0 torchvision==0.23.0 transformers` in the project folder), then restart the backend. If only transcription is affected, switching ASR to faster-whisper (Settings → Models) also works around it.",
|
||||
"WINDOWS_APP_CONTROL_BLOCKED": "Windows refused to load a file OmniVoice needs — an Application Control policy (Smart App Control, WDAC, or AppLocker) blocked it. On a personal PC: Windows Security → App & browser control → Smart App Control → Off (Windows only lets you turn it off once — re-enabling requires a Windows reset), then restart OmniVoice. On a managed/work PC, ask IT to allow the OmniVoice install folder.",
|
||||
"WINDOWS_PAGING_FILE_TOO_SMALL": "Windows ran out of virtual memory while mapping the model into memory — its paging file is smaller than the model needs. This is not the same as your RAM being full, and closing other apps usually won't fix it: Windows has to be allowed to back the mapping. Set a bigger paging file — Settings → System → About → Advanced system settings → Performance → Settings → Advanced → Virtual memory → Change: untick \"Automatically manage\", pick your system drive, choose \"Custom size\" and set both Initial and Maximum to at least 32768 MB (more than the model's size), then OK and restart Windows. A smaller/quantized engine (OmniVoice GGUF, Supertonic-3) also avoids the large mapping entirely.",
|
||||
"MEDIA_TOOL_MISSING": "OmniVoice's media engine (ffmpeg/ffprobe) wasn't on the system path when a component went looking for it. Open Settings → Audio tools and use Download/Repair to fetch the bundled copy, then retry — a restart picks it up for everything. If you'd rather use a system install, install ffmpeg (macOS: `brew install ffmpeg`; Windows: `winget install Gyan.FFmpeg`; Linux: your package manager) and restart OmniVoice, or point FFMPEG_PATH / OMNIVOICE_FFPROBE_PATH at the binaries in Settings.",
|
||||
|
||||
@@ -1239,11 +1239,24 @@ class PyTorchWhisperBackend(ASRBackend):
|
||||
# pipeline (e.g. "Could not import module 'AutoFeatureExtractor'").
|
||||
# The raw error is opaque; re-raise with an actionable next step so
|
||||
# the toast tells the user how to recover instead of "no segments".
|
||||
# #1376: "install is incomplete" is only ONE of the causes. A
|
||||
# torch/torchvision version mismatch fails with the same lazy-import
|
||||
# wording (transformers' __getattr__ wraps the real error), and for
|
||||
# that cause reinstalling transformers alone fixes nothing — the
|
||||
# trio has to move together, at the pinned versions, or the
|
||||
# reinstall can itself resolve a drifted pair (#1357).
|
||||
# Literal versions rather than the constraint file: desktop
|
||||
# installs don't ship deploy/ (greptile on #1377); the lockstep
|
||||
# test in tests/test_failure_classify.py keeps them current.
|
||||
raise RuntimeError(
|
||||
"transformers ASR pipeline failed to import (AutoFeatureExtractor) "
|
||||
"— your transformers install is incomplete; reinstall with "
|
||||
"`uv pip install --reinstall transformers`, or use faster-whisper "
|
||||
"(OmniVoice's default ASR) which avoids the transformers pipeline. "
|
||||
"— either your transformers install is incomplete, or torch and "
|
||||
"torchvision are mismatched (which fails with this exact wording). "
|
||||
"Reinstall them together at the pinned versions: `uv pip install "
|
||||
"--python .venv --reinstall torch==2.8.0 torchaudio==2.8.0 "
|
||||
"torchvision==0.23.0 transformers` in the project folder — or use faster-whisper "
|
||||
"(OmniVoice's default ASR), which avoids the transformers "
|
||||
"pipeline. "
|
||||
f"Underlying: {e}"
|
||||
) from e
|
||||
|
||||
|
||||
@@ -84,6 +84,35 @@ Or, as a quick workaround, switch ASR to **faster-whisper** in
|
||||
antivirus exclusions (see §1). Newer builds classify this error and show the
|
||||
reinstall hint directly instead of a bare path + "try restarting".
|
||||
|
||||
### 1a-bis. Same wording, different cause: torch ↔ torchvision mismatch
|
||||
|
||||
**Symptom:** identical `Could not import module 'AutoFeatureExtractor'` /
|
||||
`'GenerationMixin'` errors — but reinstalling transformers alone changes
|
||||
nothing.
|
||||
|
||||
**Cause:** transformers' lazy importer wraps whatever really failed in that
|
||||
generic message. When the real failure is
|
||||
`RuntimeError: operator torchvision::nms does not exist`, the problem is a
|
||||
**torch/torchvision version mismatch** (one was upgraded without the other),
|
||||
and transformers itself is fine.
|
||||
|
||||
**Fix:** reinstall the trio **together, at the pinned versions** — a plain
|
||||
unpinned reinstall can itself resolve a drifted pair
|
||||
([#1357](https://github.com/debpalash/OmniVoice-Studio/issues/1357)):
|
||||
|
||||
```
|
||||
uv pip install --python .venv --reinstall torch==2.8.0 torchaudio==2.8.0 torchvision==0.23.0 transformers
|
||||
```
|
||||
|
||||
run in the project folder. The versions mirror `deploy/torch-constraints.txt`
|
||||
(source checkouts can pass `--constraint deploy/torch-constraints.txt` instead;
|
||||
desktop installs don't ship that file, which is why the literal pins are shown).
|
||||
They carry no `+cu128`/`+rocm` suffix on purpose — vendor GPU builds match the
|
||||
pins rather than being replaced.
|
||||
|
||||
**Linked issues:** [#1357](https://github.com/debpalash/OmniVoice-Studio/issues/1357),
|
||||
[#1376](https://github.com/debpalash/OmniVoice-Studio/issues/1376)
|
||||
|
||||
### 1b. Dubbing: `ASR backend initialization failed: No module named 'lightning_fabric'`
|
||||
|
||||
**Symptom:** transcription/dubbing fails at the start with
|
||||
|
||||
@@ -177,3 +177,64 @@ def test_classify_ssl_handshake_failure():
|
||||
def test_classify_generic_still_empty():
|
||||
# A genuinely unknown reason must still classify to "" (no false hint).
|
||||
assert failure.classify("some totally unrelated failure") == ""
|
||||
|
||||
|
||||
def test_transformers_import_hint_names_the_package_that_actually_breaks():
|
||||
"""#1376: the hint told users to reinstall torch+torchaudio+transformers —
|
||||
omitting torchvision, the package whose ABI mismatch produces this exact
|
||||
lazy-import wording (#1357's `torchvision::nms`). Following the advice to
|
||||
the letter left the broken package untouched.
|
||||
|
||||
It must also point at the pinned constraint file: an unpinned reinstall of
|
||||
the trio can itself resolve a drifted pair, which is the bug the pins
|
||||
exist to prevent.
|
||||
"""
|
||||
hint = failure._HINTS["TRANSFORMERS_IMPORT"]
|
||||
assert "torchvision" in hint
|
||||
|
||||
|
||||
def test_transformers_import_hint_versions_match_the_constraint_file():
|
||||
"""The hint carries LITERAL pins — desktop installs don't ship deploy/, so
|
||||
a `--constraint deploy/torch-constraints.txt` command fails with "file not
|
||||
found" for exactly the users most likely to need it (greptile on #1377).
|
||||
Literals drift, so this locks them to the constraint file: bump the pins,
|
||||
and this fails until every advice surface says the new versions."""
|
||||
import os
|
||||
import re
|
||||
|
||||
root = os.path.join(os.path.dirname(__file__), "..")
|
||||
with open(os.path.join(root, "deploy", "torch-constraints.txt")) as fh:
|
||||
pins = dict(
|
||||
re.fullmatch(r"([A-Za-z0-9_.\-]+)==([^\s;]+)", ln.split("#")[0].strip()).groups()
|
||||
for ln in fh
|
||||
if re.fullmatch(r"([A-Za-z0-9_.\-]+)==([^\s;]+)", ln.split("#")[0].strip())
|
||||
)
|
||||
|
||||
surfaces = {
|
||||
"core/failure.py hint": failure._HINTS["TRANSFORMERS_IMPORT"],
|
||||
}
|
||||
with open(os.path.join(root, "backend", "services", "asr_backend.py")) as fh:
|
||||
surfaces["asr_backend.py error"] = fh.read()
|
||||
with open(os.path.join(root, "docs", "install", "troubleshooting.md")) as fh:
|
||||
surfaces["troubleshooting.md"] = fh.read()
|
||||
|
||||
# The COMMAND, not isolated substrings (CodeRabbit): a surface could carry
|
||||
# the right pin in a comment while its actual reinstall line says something
|
||||
# else. Normalizing collapses the asr_backend source's string-literal line
|
||||
# breaks so the assertion sees what the user sees.
|
||||
command = (
|
||||
f"uv pip install --python .venv --reinstall torch=={pins['torch']} "
|
||||
f"torchaudio=={pins['torchaudio']} torchvision=={pins['torchvision']} "
|
||||
f"transformers"
|
||||
)
|
||||
|
||||
def _normalize(text):
|
||||
return re.sub(r"[\s\"\\]+", " ", text)
|
||||
|
||||
for name, text in surfaces.items():
|
||||
assert command in _normalize(text), (
|
||||
f"{name} does not carry the exact pinned reinstall command "
|
||||
f"({command!r}) — either a pin drifted from "
|
||||
f"deploy/torch-constraints.txt or the command was reworded; "
|
||||
f"following stale advice would recreate the mismatch it fixes"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user