mirror of
https://github.com/RVC-Boss/GPT-SoVITS.git
synced 2026-07-14 12:13:30 +08:00
Fix Fun-ASR-Nano fallback for GPT-SoVITS ASR (#2801)
Co-authored-by: LauraGPT <LauraGPT@users.noreply.github.com>
This commit is contained in:
parent
bf81cdb14a
commit
551918539c
71
tests/test_funasr_asr.py
Normal file
71
tests/test_funasr_asr.py
Normal file
@ -0,0 +1,71 @@
|
||||
import importlib.util
|
||||
import sys
|
||||
import types
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
MODULE_PATH = ROOT / "tools" / "asr" / "funasr_asr.py"
|
||||
|
||||
|
||||
def load_funasr_asr(monkeypatch, auto_model):
|
||||
funasr = types.ModuleType("funasr")
|
||||
funasr.AutoModel = auto_model
|
||||
monkeypatch.setitem(sys.modules, "funasr", funasr)
|
||||
|
||||
modelscope = types.ModuleType("modelscope")
|
||||
modelscope.snapshot_download = lambda *args, **kwargs: None
|
||||
monkeypatch.setitem(sys.modules, "modelscope", modelscope)
|
||||
|
||||
tqdm = types.ModuleType("tqdm")
|
||||
tqdm.tqdm = lambda iterable: iterable
|
||||
monkeypatch.setitem(sys.modules, "tqdm", tqdm)
|
||||
|
||||
torch = types.ModuleType("torch")
|
||||
torch.cuda = types.SimpleNamespace(is_available=lambda: False)
|
||||
monkeypatch.setitem(sys.modules, "torch", torch)
|
||||
|
||||
module_name = "funasr_asr_under_test"
|
||||
sys.modules.pop(module_name, None)
|
||||
spec = importlib.util.spec_from_file_location(module_name, MODULE_PATH)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def test_fun_asr_nano_falls_back_to_modelscope_when_hf_config_is_not_resolved(monkeypatch):
|
||||
calls = []
|
||||
|
||||
def fake_auto_model(**kwargs):
|
||||
calls.append(kwargs.copy())
|
||||
if kwargs["hub"] == "hf":
|
||||
raise RuntimeError("model 'FunAudioLLM/Fun-ASR-Nano-2512' is not registered.")
|
||||
if kwargs["hub"] == "ms":
|
||||
return types.SimpleNamespace(hub=kwargs["hub"], model_name=kwargs["model"])
|
||||
raise AssertionError(f"unexpected hub {kwargs['hub']}")
|
||||
|
||||
module = load_funasr_asr(monkeypatch, fake_auto_model)
|
||||
|
||||
model = module.create_model("zh", backend="fun-asr-nano")
|
||||
|
||||
assert model.hub == "ms"
|
||||
assert model.model_name == "FunAudioLLM/Fun-ASR-Nano-2512"
|
||||
assert [(call["model"], call["hub"], call["trust_remote_code"]) for call in calls] == [
|
||||
("FunAudioLLM/Fun-ASR-Nano-2512", "hf", True),
|
||||
("FunAudioLLM/Fun-ASR-Nano-2512", "ms", False),
|
||||
]
|
||||
assert all(call["vad_model"] == "fsmn-vad" for call in calls)
|
||||
assert all(call["device"] == "cpu" for call in calls)
|
||||
assert all(call["disable_update"] is True for call in calls)
|
||||
|
||||
|
||||
def test_fun_asr_nano_keeps_non_registration_errors_visible(monkeypatch):
|
||||
def fake_auto_model(**kwargs):
|
||||
raise RuntimeError("network unavailable")
|
||||
|
||||
module = load_funasr_asr(monkeypatch, fake_auto_model)
|
||||
|
||||
with pytest.raises(RuntimeError, match="network unavailable"):
|
||||
module.create_model("zh", backend="fun-asr-nano")
|
||||
@ -9,6 +9,11 @@ from modelscope import snapshot_download
|
||||
from tqdm import tqdm
|
||||
|
||||
funasr_models = {} # 存储模型避免重复加载
|
||||
FUN_ASR_NANO_MODEL_ID = "FunAudioLLM/Fun-ASR-Nano-2512"
|
||||
FUN_ASR_NANO_MODEL_SOURCES = (
|
||||
{"model": FUN_ASR_NANO_MODEL_ID, "hub": "hf", "trust_remote_code": True},
|
||||
{"model": FUN_ASR_NANO_MODEL_ID, "hub": "ms", "trust_remote_code": False},
|
||||
)
|
||||
|
||||
|
||||
def only_asr(input_file, language, backend="fun-asr-nano"):
|
||||
@ -21,6 +26,29 @@ def only_asr(input_file, language, backend="fun-asr-nano"):
|
||||
return text
|
||||
|
||||
|
||||
def is_unregistered_model_error(exc):
|
||||
message = str(exc).lower()
|
||||
return "model" in message and "not registered" in message
|
||||
|
||||
|
||||
def create_fun_asr_nano_model(device):
|
||||
common_kwargs = dict(
|
||||
vad_model="fsmn-vad",
|
||||
device=device,
|
||||
disable_update=True,
|
||||
)
|
||||
last_error = None
|
||||
for model_source in FUN_ASR_NANO_MODEL_SOURCES:
|
||||
try:
|
||||
return AutoModel(**model_source, **common_kwargs)
|
||||
except (KeyError, RuntimeError, ValueError) as exc:
|
||||
if not is_unregistered_model_error(exc):
|
||||
raise
|
||||
last_error = exc
|
||||
|
||||
raise last_error
|
||||
|
||||
|
||||
def create_model(language="zh", **kwargs):
|
||||
backend = kwargs.get("backend", "fun-asr-nano")
|
||||
|
||||
@ -33,14 +61,7 @@ def create_model(language="zh", **kwargs):
|
||||
return funasr_models[cache_key]
|
||||
|
||||
if backend == "fun-asr-nano":
|
||||
model = AutoModel(
|
||||
model="FunAudioLLM/Fun-ASR-Nano-2512",
|
||||
trust_remote_code=True,
|
||||
hub="hf",
|
||||
vad_model="fsmn-vad",
|
||||
device=device,
|
||||
disable_update=True,
|
||||
)
|
||||
model = create_fun_asr_nano_model(device)
|
||||
print(f"FunASR Fun-ASR-Nano 模型加载完成: {language.upper()}")
|
||||
else:
|
||||
model = AutoModel(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user