fix: lazy load top-level AutoModel exports

Fix fresh-install import behavior when torch has not been installed yet, and prepare funasr 1.3.21.
This commit is contained in:
zhifu gao
2026-07-19 18:27:49 +08:00
committed by GitHub
parent f2122795a4
commit ac07ca2616
5 changed files with 83 additions and 4 deletions
+1
View File
@@ -288,6 +288,7 @@ hf download FunAudioLLM/fsmn-vad-GGUF fsmn-vad.gguf --local-dir .\gguf
## What's new
- 2026/07/19: **v1.3.21 on PyPI** — fixes first-import onboarding in fresh environments where users install `funasr` before choosing a platform-specific PyTorch build. `import funasr` and `funasr.__version__` now work without torch; accessing `AutoModel` still requires PyTorch and raises a clear install hint. Install with `python -m pip install -U "funasr==1.3.21"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.3.21)
- 2026/07/19: **v1.3.20 on PyPI** — PyPI metadata and install guidance now point at the current FunASR docs, community integrations, and quoted `python -m pip install -U "funasr>=1.3.19"` commands for Fun-ASR-Nano deployment paths. This is a documentation/packaging sync; runtime code remains unchanged from v1.3.19. Install with `python -m pip install -U "funasr==1.3.20"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.3.20)
- 2026/07/19: **v1.3.19 on PyPI** — realtime WebSocket long-session troubleshooting docs are now shipped with the package. Run the server with `--enable-spk --log-session-stats-interval 30` and attach the emitted `Session stats:` lines when reporting disconnects or memory growth. Install with `python -m pip install -U "funasr==1.3.19"`. [Long-session guide ->](docs/vllm_guide.md#long-session-diagnostics) · [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.3.19)
- 2026/07/19: **v1.3.18 on PyPI** — CLI SRT/TSV subtitle output now requests sentence timestamps and loads punctuation when needed, so `funasr audio.wav --output-format srt --output-dir ./subs` writes segmented subtitle cues instead of one full-text block. Install with `python -m pip install -U "funasr==1.3.18"`. [Release ->](https://github.com/modelscope/FunASR/releases/tag/v1.3.18)
+1
View File
@@ -132,6 +132,7 @@ Whisper 是单个模型,**FunASR 是一个工具箱**——按场景挑模型
## 最新动态
- 2026/07/19:**v1.3.21 已发布到 PyPI** — 修复全新环境里先安装 `funasr`、尚未选择平台对应 PyTorch 版本时的首次导入阻塞。现在 `import funasr` 和 `funasr.__version__` 不再因为缺少 torch 失败;真正访问 `AutoModel` 时仍会要求安装 PyTorch,并给出明确安装提示。安装命令:`python -m pip install -U "funasr==1.3.21"`。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.3.21)
- 2026/07/19:**v1.3.20 已发布到 PyPI** — PyPI 项目页和安装引导已同步到当前 FunASR 文档、社区集成列表,以及 Fun-ASR-Nano 部署路径中带引号的 `python -m pip install -U "funasr>=1.3.19"` 命令。本版本是文档/打包元数据同步,运行时代码与 v1.3.19 保持一致。安装命令:`python -m pip install -U "funasr==1.3.20"`。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.3.20)
- 2026/07/19:**v1.3.19 已发布到 PyPI** — 实时 WebSocket 长会话排障文档已随包发布。启动服务时加上 `--enable-spk --log-session-stats-interval 30`,如果仍遇到断连或内存增长,请在 issue 中附上输出的 `Session stats:` 日志。安装命令:`python -m pip install -U "funasr==1.3.19"`。[长会话诊断 →](docs/vllm_guide_zh.md#长会话诊断) · [发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.3.19)
- 2026/07/19:**v1.3.18 已发布到 PyPI** — CLI 的 SRT/TSV 字幕输出现在会请求句级时间戳,并在需要时加载标点模型;`funasr audio.wav --output-format srt --output-dir ./subs` 会输出分句字幕,不再退化成一个全文字幕块。安装命令:`python -m pip install -U "funasr==1.3.18"`。[发布页 →](https://github.com/modelscope/FunASR/releases/tag/v1.3.18)
+31 -3
View File
@@ -16,6 +16,10 @@ _IMPORT_ERRORS = {}
_IMPORT_ERROR_TRACEBACKS = {}
_IMPORT_DEBUG = os.environ.get("FUNASR_IMPORT_DEBUG") == "1"
_STRICT_IMPORT = os.environ.get("FUNASR_STRICT_IMPORT") == "1"
_LAZY_EXPORTS = {
"AutoModel": ("funasr.auto.auto_model", "AutoModel"),
"AutoFrontend": ("funasr.auto.auto_frontend", "AutoFrontend"),
}
def _record_import_error(name, error):
@@ -73,7 +77,31 @@ def import_submodules(package, recursive=True):
import_submodules(__name__)
from funasr.auto.auto_model import AutoModel
from funasr.auto.auto_frontend import AutoFrontend
os.environ["HYDRA_FULL_ERROR"] = "1"
def __getattr__(name):
if name not in _LAZY_EXPORTS:
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
module_name, attr_name = _LAZY_EXPORTS[name]
try:
module = importlib.import_module(module_name)
except ModuleNotFoundError as error:
if error.name == "torch":
raise ModuleNotFoundError(
"FunASR requires PyTorch before using AutoModel. Install a "
"platform-appropriate torch build first, for example: "
"`python -m pip install torch torchaudio --index-url "
"https://download.pytorch.org/whl/cu126` for CUDA 12.6, "
"or follow https://pytorch.org/get-started/locally/.",
name="torch",
) from error
raise
value = getattr(module, attr_name)
globals()[name] = value
return value
__all__ = ["AutoModel", "AutoFrontend", "__version__", "get_import_errors", "get_import_error_tracebacks"]
+1 -1
View File
@@ -1 +1 @@
1.3.20
1.3.21
+49
View File
@@ -0,0 +1,49 @@
import os
import subprocess
import sys
from pathlib import Path
def test_top_level_import_without_torch_succeeds():
repo_root = Path(__file__).resolve().parents[1]
script = r"""
import importlib.abc
import sys
class BlockTorch(importlib.abc.MetaPathFinder):
def find_spec(self, fullname, path=None, target=None):
if fullname == "torch" or fullname.startswith("torch."):
raise ModuleNotFoundError("No module named 'torch'", name="torch")
return None
sys.meta_path.insert(0, BlockTorch())
import funasr
print(funasr.__version__)
assert isinstance(funasr.get_import_errors(), dict)
try:
from funasr import AutoModel # noqa: F401
except ModuleNotFoundError as error:
assert error.name == "torch"
assert "requires PyTorch before using AutoModel" in str(error)
else:
raise AssertionError("AutoModel import should fail clearly when torch is missing")
"""
env = os.environ.copy()
env["PYTHONPATH"] = str(repo_root)
env.pop("FUNASR_STRICT_IMPORT", None)
result = subprocess.run(
[sys.executable, "-c", script],
cwd=repo_root,
env=env,
text=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=False,
)
assert result.returncode == 0, result.stdout + result.stderr