From d06a93f4f9f11d91b68e40795dec5482c17c20b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B8=B8=E9=9B=81?= Date: Tue, 26 May 2026 23:11:51 +0800 Subject: [PATCH] fix: add try-import guards for optional deps (fastapi, humanfriendly, transformers) - funasr/bin/_server_app.py: wrap fastapi import with helpful error message - funasr/bin/tokenize_text.py: guard cli_utils import - funasr/utils/type_utils.py: guard humanfriendly import - funasr/frontends/s3prl.py: guard humanfriendly import - funasr/utils/types.py: add compat shim (types -> type_utils) - funasr/frontends/abs_frontend.py: add missing abstract class - funasr/models/fun_asr_nano/model.py: guard transformers import Fixes #2937 - users seeing import errors on fresh pip install --- funasr/bin/_server_app.py | 9 +++++++-- funasr/bin/tokenize_text.py | 6 +++++- funasr/frontends/abs_frontend.py | 12 ++++++++++++ funasr/frontends/s3prl.py | 10 ++++++++-- funasr/models/fun_asr_nano/model.py | 6 +++++- funasr/utils/type_utils.py | 7 ++++++- funasr/utils/types.py | 2 ++ 7 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 funasr/frontends/abs_frontend.py create mode 100644 funasr/utils/types.py diff --git a/funasr/bin/_server_app.py b/funasr/bin/_server_app.py index 0e1357d3e..03a659d9f 100644 --- a/funasr/bin/_server_app.py +++ b/funasr/bin/_server_app.py @@ -7,8 +7,13 @@ import re import logging from typing import Optional -from fastapi import FastAPI, UploadFile, File, Form, HTTPException -from fastapi.responses import JSONResponse +try: + from fastapi import FastAPI, UploadFile, File, Form, HTTPException + from fastapi.responses import JSONResponse +except ImportError: + raise ImportError( + "funasr-server requires fastapi. Install with: pip install fastapi uvicorn python-multipart" + ) logger = logging.getLogger("funasr.server") diff --git a/funasr/bin/tokenize_text.py b/funasr/bin/tokenize_text.py index e127e1234..de15cb7c6 100755 --- a/funasr/bin/tokenize_text.py +++ b/funasr/bin/tokenize_text.py @@ -8,7 +8,11 @@ from typing import List from typing import Optional -from funasr.utils.cli_utils import get_commandline_args +try: + from funasr.utils.cli_utils import get_commandline_args +except ImportError: + def get_commandline_args(): + return {} from funasr.tokenizer.build_tokenizer import build_tokenizer from funasr.tokenizer.cleaner import TextCleaner from funasr.tokenizer.phoneme_tokenizer import g2p_classes diff --git a/funasr/frontends/abs_frontend.py b/funasr/frontends/abs_frontend.py new file mode 100644 index 000000000..c0089dcfe --- /dev/null +++ b/funasr/frontends/abs_frontend.py @@ -0,0 +1,12 @@ +from abc import ABC, abstractmethod +import torch + + +class AbsFrontend(ABC, torch.nn.Module): + @abstractmethod + def output_size(self) -> int: + raise NotImplementedError + + @abstractmethod + def forward(self, input, input_lengths): + raise NotImplementedError diff --git a/funasr/frontends/s3prl.py b/funasr/frontends/s3prl.py index 36f1dc7a9..dcf06f351 100644 --- a/funasr/frontends/s3prl.py +++ b/funasr/frontends/s3prl.py @@ -6,7 +6,10 @@ from typing import Optional from typing import Tuple from typing import Union -import humanfriendly +try: + import humanfriendly +except ImportError: + humanfriendly = None import torch import torch.nn as nn @@ -50,7 +53,10 @@ class S3prlFrontend(nn.Module): """ super().__init__() if isinstance(fs, str): - fs = humanfriendly.parse_size(fs) + if humanfriendly is not None: + fs = humanfriendly.parse_size(fs) + else: + fs = int(fs) if download_dir is not None: torch.hub.set_dir(download_dir) diff --git a/funasr/models/fun_asr_nano/model.py b/funasr/models/fun_asr_nano/model.py index b7e6ad5de..d5d61cd37 100644 --- a/funasr/models/fun_asr_nano/model.py +++ b/funasr/models/fun_asr_nano/model.py @@ -15,7 +15,11 @@ from funasr.register import tables from funasr.train_utils.device_funcs import force_gatherable, to_device from funasr.utils.datadir_writer import DatadirWriter from funasr.utils.load_utils import extract_fbank, load_audio_text_image_video -from transformers import AutoConfig, AutoModelForCausalLM +try: + from transformers import AutoConfig, AutoModelForCausalLM +except ImportError: + AutoConfig = None + AutoModelForCausalLM = None from .ctc import CTC from .tools.utils import forced_align diff --git a/funasr/utils/type_utils.py b/funasr/utils/type_utils.py index fe99013be..0731e46f8 100644 --- a/funasr/utils/type_utils.py +++ b/funasr/utils/type_utils.py @@ -3,7 +3,10 @@ from typing import Optional from typing import Tuple from typing import Union -import humanfriendly +try: + import humanfriendly +except ImportError: + humanfriendly = None def str2bool(value: str) -> bool: @@ -95,6 +98,8 @@ def humanfriendly_parse_size_or_none(value) -> Optional[float]: """ if value.strip().lower() in ("none", "null", "nil"): return None + if humanfriendly is None: + raise ImportError("humanfriendly is required for parse_size. Install with: pip install humanfriendly") return humanfriendly.parse_size(value) diff --git a/funasr/utils/types.py b/funasr/utils/types.py new file mode 100644 index 000000000..9fb3dbe21 --- /dev/null +++ b/funasr/utils/types.py @@ -0,0 +1,2 @@ +# Compatibility shim: types was renamed to type_utils +from funasr.utils.type_utils import *