fix(moss): align accelerator detection and routing status
This commit is contained in:
@@ -20,6 +20,8 @@ the frozen-backend fallback mirror it for their toolchains.
|
||||
|
||||
### Fixed
|
||||
|
||||
- MOSS accelerator routing now matches runtime device selection, including native XPU and registered NPU detection (#1830) — thanks @li-lizhe!
|
||||
|
||||
|
||||
## [0.5.2] — 2026-09-02
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ def _compute_device_state() -> dict:
|
||||
caps = device_caps.detect_host_caps()
|
||||
env_pin = (os.environ.get("OMNIVOICE_DEVICE") or "").strip().lower()
|
||||
auto_family = next(
|
||||
(f for f in ("cuda", "rocm", "xpu", "mps") if f in caps.available_families),
|
||||
(f for f in device_caps.ACCELERATOR_PRIORITY if f in caps.available_families),
|
||||
"cpu",
|
||||
)
|
||||
value = device_caps.requested_device_override()
|
||||
|
||||
@@ -35,7 +35,8 @@ import sys
|
||||
from dataclasses import dataclass
|
||||
from typing import Literal
|
||||
|
||||
DeviceFamily = Literal["cuda", "rocm", "mps", "xpu", "cpu"]
|
||||
DeviceFamily = Literal["cuda", "rocm", "mps", "xpu", "npu", "cpu"]
|
||||
ACCELERATOR_PRIORITY = ("cuda", "rocm", "xpu", "npu", "mps")
|
||||
|
||||
# Stable substring stamped onto notes that represent a real kernel-launch risk
|
||||
# (arch/driver mismatch) — as opposed to advisory notes (multi-GPU, VRAM query
|
||||
@@ -533,9 +534,12 @@ def _probe() -> HostCaps:
|
||||
# is the whole truth in that case (CodeRabbit, #1425).
|
||||
notes.extend(why_no_gpu(torch))
|
||||
|
||||
# ── Intel XPU via IPEX ───────────────────────────────────────────────
|
||||
# Older builds register XPU through IPEX; modern torch exposes it directly.
|
||||
try:
|
||||
import intel_extension_for_pytorch # noqa: F401
|
||||
except Exception:
|
||||
pass
|
||||
try:
|
||||
if hasattr(torch, "xpu") and torch.xpu.is_available():
|
||||
detected.append("xpu")
|
||||
if not device_name:
|
||||
@@ -546,7 +550,21 @@ def _probe() -> HostCaps:
|
||||
pass
|
||||
notes.append("XPU VRAM not queried (unreliable across IPEX versions)")
|
||||
except Exception:
|
||||
# IPEX absent or XPU probe failed — no XPU on this host.
|
||||
# XPU probe failed — no usable XPU on this host.
|
||||
pass
|
||||
|
||||
# Vendor extensions may register an NPU with torch. Probe only an already
|
||||
# registered backend; never install or import an optional vendor package.
|
||||
try:
|
||||
if hasattr(torch, "npu") and torch.npu.is_available():
|
||||
detected.append("npu")
|
||||
if not device_name:
|
||||
try:
|
||||
device_name = torch.npu.get_device_name(0)
|
||||
except Exception:
|
||||
pass
|
||||
notes.append("NPU VRAM not queried")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# ── Apple Silicon MPS ────────────────────────────────────────────────
|
||||
@@ -579,7 +597,7 @@ def _probe() -> HostCaps:
|
||||
|
||||
# Preferred family by priority; cpu when nothing accelerated was detected.
|
||||
family: DeviceFamily = "cpu"
|
||||
for pref in ("cuda", "rocm", "xpu", "mps"):
|
||||
for pref in ACCELERATOR_PRIORITY:
|
||||
if pref in detected:
|
||||
family = pref # type: ignore[assignment]
|
||||
break
|
||||
|
||||
@@ -29,15 +29,11 @@ Do NOT import ``main.py`` from the parent process — it runs under a
|
||||
different venv (``transformers==5.0.0``) and importing it in-process would
|
||||
re-introduce the exact conflict this isolation exists to avoid.
|
||||
|
||||
Hardware honesty (cross-platform rule): MOSS-TTS-v1.5's upstream documents
|
||||
only CUDA and CPU. There is **no documented or tested MPS path** — the
|
||||
custom ``trust_remote_code`` modelling code and the separate audio
|
||||
tokenizer are unverified on Apple Silicon. We therefore advertise
|
||||
``gpu_compat = ("cuda", "cpu")`` and the sidecar selects ``cuda`` when
|
||||
present else ``cpu`` — it never silently routes to MPS where it might
|
||||
crash. On Apple Silicon the engine honestly resolves to CPU (slow but
|
||||
correct), and the engine is opt-in regardless, so it never becomes a
|
||||
broken default on any platform.
|
||||
Hardware routing follows the sidecar's runtime-available PyTorch accelerator:
|
||||
CUDA/ROCm, XPU, or a registered NPU. MPS remains excluded; CPU is the fallback.
|
||||
XPU/NPU routing is covered with mocked device contracts, not physical-hardware
|
||||
synthesis certification; users need a compatible torch/vendor runtime in the
|
||||
isolated engine venv.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -91,7 +87,7 @@ class MossTTSV15Backend(SubprocessBackend):
|
||||
_DEFAULT_SAMPLE_RATE = 24000
|
||||
# Honest hardware surface: upstream documents CUDA + CPU only. MPS is
|
||||
# undocumented / untested, so we do NOT claim it (cross-platform rule).
|
||||
gpu_compat = ("cuda", "cpu")
|
||||
gpu_compat = ("cuda", "rocm", "xpu", "npu", "cpu")
|
||||
|
||||
# ── availability ───────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -2371,7 +2371,7 @@ def list_backends() -> list[dict]:
|
||||
"one_click_install": bool, # services.sidecar_install can provision it in-app
|
||||
"last_error": Optional[str], # cached most-recent failure
|
||||
"isolation_mode": "in-process" | "subprocess",
|
||||
"gpu_compat": list[str], # subset of {cuda, rocm, mps, xpu, cpu}
|
||||
"gpu_compat": list[str], # subset of {cuda, rocm, mps, xpu, npu, cpu}
|
||||
"supports_cloning": Optional[bool], # True/False from the class attr; None when
|
||||
# model-dependent (property, e.g. mlx-audio)
|
||||
"effective_device": str, # device this engine uses on THIS host
|
||||
|
||||
@@ -23,10 +23,11 @@ interpreter, so MOSS runs behind
|
||||
8 GB GPUs when quantized; the bf16 Transformers path used here is ~16 GB
|
||||
of weights, so a 16 GB+ GPU is the realistic CUDA target. It also runs on
|
||||
**CPU** (fp32) — correct but slow.
|
||||
- **Device:** CUDA when present, else CPU. **There is no MPS path** —
|
||||
upstream documents only CUDA/CPU and the custom modelling code is
|
||||
untested on Apple Silicon, so VoiceStudio never routes MOSS to MPS. On a
|
||||
Mac it runs on CPU.
|
||||
- **Device:** the sidecar uses a runtime-available PyTorch CUDA/ROCm, XPU,
|
||||
or registered NPU backend, otherwise CPU. The isolated engine venv needs the
|
||||
matching torch/vendor integration. MPS still uses CPU. XPU/NPU routing is
|
||||
covered by mocked loader tests; physical-device synthesis has not been
|
||||
validated by this change.
|
||||
|
||||
## Install
|
||||
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "تعذّر تحميل إعداد الجهاز",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Geräteeinstellung konnte nicht geladen werden",
|
||||
|
||||
@@ -934,6 +934,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Failed to load device setting",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "No se pudo cargar el ajuste del dispositivo",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Impossible de charger le réglage du périphérique",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "डिवाइस सेटिंग लोड नहीं हो सकी",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Gagal memuat pengaturan perangkat",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Impossibile caricare l'impostazione del dispositivo",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "デバイス設定を読み込めませんでした",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "장치 설정을 불러오지 못했습니다",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Apparaatinstelling kon niet worden geladen",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Nie udało się wczytać ustawienia urządzenia",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Falha ao carregar a configuração do dispositivo",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Не удалось загрузить настройку устройства",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Kunde inte läsa in enhetsinställningen",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "โหลดการตั้งค่าอุปกรณ์ไม่สำเร็จ",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Aygıt ayarı yüklenemedi",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Не вдалося завантажити налаштування пристрою",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "Không tải được cài đặt thiết bị",
|
||||
|
||||
@@ -586,6 +586,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "无法加载设备设置",
|
||||
|
||||
@@ -334,6 +334,7 @@
|
||||
"device_family_cuda": "NVIDIA GPU (CUDA)",
|
||||
"device_family_rocm": "AMD GPU (ROCm)",
|
||||
"device_family_xpu": "Intel GPU (XPU)",
|
||||
"device_family_npu": "NPU",
|
||||
"device_family_mps": "Apple GPU (MPS)",
|
||||
"device_family_cpu": "CPU",
|
||||
"device_load_failed": "無法載入裝置設定",
|
||||
|
||||
@@ -82,7 +82,7 @@ _REQUIRED_KEYS = {
|
||||
"effective_device", "routing_status", "routing_reason",
|
||||
}
|
||||
_TTS_ASR_STATUSES = {"accelerated", "cpu_fallback", "cpu_only", "unavailable"}
|
||||
_VALID_FAMILIES = {"cuda", "rocm", "mps", "xpu", "cpu"}
|
||||
_VALID_FAMILIES = {"cuda", "rocm", "mps", "xpu", "npu", "cpu"}
|
||||
|
||||
|
||||
def test_engines_response_includes_new_fields(fresh_app):
|
||||
|
||||
@@ -109,3 +109,14 @@ def test_env_pin_is_reported_and_wins(fresh_app, monkeypatch):
|
||||
r = c.put("/api/settings/compute-device", json={"value": "auto"})
|
||||
assert r.status_code == 200
|
||||
assert r.json()["value"] == "cpu"
|
||||
|
||||
|
||||
def test_auto_summary_reports_registered_npu(fresh_app, monkeypatch):
|
||||
from core import device_caps
|
||||
monkeypatch.setattr(device_caps, 'detect_host_caps', lambda: device_caps.HostCaps(
|
||||
family='npu', available_families=('npu', 'cpu'),
|
||||
))
|
||||
body = _client(fresh_app).get('/api/settings/compute-device').json()
|
||||
assert body['auto_family'] == body['effective_family'] == 'npu'
|
||||
# Detection does not globally opt unrelated engines into NPU execution.
|
||||
assert 'npu' not in body['choices']
|
||||
|
||||
@@ -34,7 +34,7 @@ _EXPECTED = {
|
||||
# is_available — e.g. parakeet-mlx gates on Apple Silicon via mlx_supported()).
|
||||
_GPU_ONLY: set[str] = {"parakeet-mlx"}
|
||||
|
||||
_VALID = {"cuda", "rocm", "mps", "xpu", "cpu"}
|
||||
_VALID = {"cuda", "rocm", "mps", "xpu", "npu", "cpu"}
|
||||
|
||||
|
||||
def _cls(engine_id):
|
||||
|
||||
@@ -235,3 +235,24 @@ def test_result_is_cached_until_refresh():
|
||||
def teardown_module(_module):
|
||||
# Drop any cached mock-derived result so other test modules re-probe clean.
|
||||
device_caps.detect_host_caps.cache_clear()
|
||||
|
||||
|
||||
def test_builtin_xpu_does_not_require_ipex():
|
||||
caps = _probe_with({'torch': _torch_mock(xpu_available=True), 'intel_extension_for_pytorch': None})
|
||||
assert caps.family == 'xpu'
|
||||
|
||||
|
||||
def test_registered_npu_is_reported_without_importing_vendor_packages():
|
||||
torch = _torch_mock()
|
||||
torch.npu = types.SimpleNamespace(is_available=lambda: True, get_device_name=lambda i: 'Ascend')
|
||||
caps = _probe_with({'torch': torch, 'intel_extension_for_pytorch': None})
|
||||
assert caps.family == 'npu'
|
||||
assert caps.available_families == ('npu', 'cpu')
|
||||
assert caps.device_name == 'Ascend'
|
||||
|
||||
|
||||
def test_unavailable_npu_does_not_claim_acceleration():
|
||||
torch = _torch_mock()
|
||||
torch.npu = types.SimpleNamespace(is_available=lambda: False)
|
||||
caps = _probe_with({'torch': torch, 'intel_extension_for_pytorch': None})
|
||||
assert caps.family == 'cpu'
|
||||
|
||||
@@ -132,7 +132,7 @@ def test_empty_compat_is_defensive_cpu_only():
|
||||
|
||||
# ── Contract guarantees ───────────────────────────────────────────────────
|
||||
def test_never_emits_n_a():
|
||||
for fam in ("cuda", "rocm", "mps", "xpu", "cpu"):
|
||||
for fam in ("cuda", "rocm", "mps", "xpu", "npu", "cpu"):
|
||||
for compat in ((), ("cpu",), ("cuda",), ("cuda", "cpu"), ("mps", "cpu")):
|
||||
assert resolve_routing(compat, _caps(fam))["routing_status"] != "n/a"
|
||||
|
||||
|
||||
@@ -106,12 +106,12 @@ def test_audited_custom_remote_code_requires_both_opt_ins(monkeypatch):
|
||||
# ── hardware honesty (cross-platform rule) ─────────────────────────────────
|
||||
|
||||
|
||||
def test_gpu_compat_cuda_cpu_no_mps():
|
||||
def test_gpu_compat_matches_accelerator_paths_without_mps():
|
||||
"""MPS is undocumented/untested upstream — we must not claim it."""
|
||||
from engines.moss_tts_v15 import MossTTSV15Backend
|
||||
|
||||
assert MossTTSV15Backend.gpu_compat == ("cuda", "cpu"), (
|
||||
f"expected ('cuda', 'cpu'), got {MossTTSV15Backend.gpu_compat!r}"
|
||||
assert MossTTSV15Backend.gpu_compat == ("cuda", "rocm", "xpu", "npu", "cpu"), (
|
||||
f"unexpected device targets: {MossTTSV15Backend.gpu_compat!r}"
|
||||
)
|
||||
|
||||
|
||||
@@ -199,3 +199,41 @@ def test_generate_without_ref_audio_omits_reference(monkeypatch):
|
||||
MossTTSV15Backend().generate("just text")
|
||||
assert "ref_audio" not in captured
|
||||
assert "tokens" not in captured
|
||||
|
||||
|
||||
@pytest.mark.parametrize('family', [None, 'cuda', 'xpu', 'npu', 'mps'])
|
||||
def test_loader_device_matches_routing(monkeypatch, family):
|
||||
"""Exercise model + tokenizer placement without importing optional weights."""
|
||||
import io
|
||||
from types import SimpleNamespace
|
||||
from unittest.mock import Mock
|
||||
from engines.moss_tts_v15 import main, MossTTSV15Backend
|
||||
from core.device_caps import HostCaps
|
||||
from services.engine_routing import resolve_routing
|
||||
|
||||
expected = family if family not in (None, 'mps') else 'cpu'
|
||||
accelerator = Mock(return_value=SimpleNamespace(type=family) if family else None)
|
||||
monkeypatch.setitem(sys.modules, 'torch', SimpleNamespace(
|
||||
accelerator=SimpleNamespace(current_accelerator=accelerator),
|
||||
bfloat16='bf16', float32='fp32',
|
||||
))
|
||||
processor = Mock()
|
||||
processor.model_config.sampling_rate = 24000
|
||||
tokenizer = processor.audio_tokenizer
|
||||
model = Mock()
|
||||
model.to.return_value = model
|
||||
factory = Mock()
|
||||
factory.from_pretrained.return_value = model
|
||||
monkeypatch.setitem(sys.modules, 'transformers', SimpleNamespace(
|
||||
AutoModel=factory,
|
||||
AutoProcessor=SimpleNamespace(from_pretrained=lambda *a, **kw: processor),
|
||||
))
|
||||
monkeypatch.setattr(main, '_state', None)
|
||||
monkeypatch.setattr(main, '_model_source', lambda: ('local-fixture', 'a' * 40))
|
||||
state = main._load_model(io.BytesIO())
|
||||
accelerator.assert_called_once_with(check_available=True)
|
||||
model.to.assert_called_once_with(expected)
|
||||
tokenizer.to.assert_called_once_with(expected)
|
||||
assert factory.from_pretrained.call_args.kwargs['torch_dtype'] == ('fp32' if expected == 'cpu' else 'bf16')
|
||||
caps = HostCaps(family=family or 'cpu', available_families=(family, 'cpu') if family else ('cpu',))
|
||||
assert resolve_routing(MossTTSV15Backend.gpu_compat, caps)['effective_device'] == state[2]
|
||||
|
||||
@@ -145,7 +145,7 @@ def test_preflight_device_summary(client):
|
||||
assert d["gpu_backend"] in {"cuda", "rocm", "mps", "cpu"}
|
||||
assert d["gpu_vendor"] in {"nvidia", "amd", "apple", "intel", "unknown", "none"}
|
||||
# #21: canonical-probe family + VRAM joined the device summary.
|
||||
assert d["gpu_family"] in {"cuda", "rocm", "mps", "xpu", "cpu"}
|
||||
assert d["gpu_family"] in {"cuda", "rocm", "mps", "xpu", "npu", "cpu"}
|
||||
assert isinstance(d["vram_gb"], (int, float))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user