mirror of
https://github.com/RVC-Boss/GPT-SoVITS.git
synced 2026-07-24 19:45:42 +08:00
Fix Fun-ASR-Nano fallback for GPT-SoVITS ASR
This commit is contained in:
parent
bf81cdb14a
commit
f301dff24c
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
|
from tqdm import tqdm
|
||||||
|
|
||||||
funasr_models = {} # 存储模型避免重复加载
|
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"):
|
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
|
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):
|
def create_model(language="zh", **kwargs):
|
||||||
backend = kwargs.get("backend", "fun-asr-nano")
|
backend = kwargs.get("backend", "fun-asr-nano")
|
||||||
|
|
||||||
@ -33,14 +61,7 @@ def create_model(language="zh", **kwargs):
|
|||||||
return funasr_models[cache_key]
|
return funasr_models[cache_key]
|
||||||
|
|
||||||
if backend == "fun-asr-nano":
|
if backend == "fun-asr-nano":
|
||||||
model = AutoModel(
|
model = create_fun_asr_nano_model(device)
|
||||||
model="FunAudioLLM/Fun-ASR-Nano-2512",
|
|
||||||
trust_remote_code=True,
|
|
||||||
hub="hf",
|
|
||||||
vad_model="fsmn-vad",
|
|
||||||
device=device,
|
|
||||||
disable_update=True,
|
|
||||||
)
|
|
||||||
print(f"FunASR Fun-ASR-Nano 模型加载完成: {language.upper()}")
|
print(f"FunASR Fun-ASR-Nano 模型加载完成: {language.upper()}")
|
||||||
else:
|
else:
|
||||||
model = AutoModel(
|
model = AutoModel(
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user