FunASR 部署与故障排查指南:从安装选择、模型下载到 OpenAI 兼容服务的问题定位手册
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
FunASR 是一个开源的语音识别工具包,覆盖训练、推理、流式 ASR、VAD(语音活动检测)、标点、说话人分离(diarization)以及 OpenAI 兼容/MCP 服务等完整链路。本文是官方 FAQ 与故障排查手册,围绕开发者最常遇到的部署与运行问题展开:安装命令怎么选、Python/PyTorch 版本如何搭配、模型下载失败如何定位、funasr-server起不来怎么办、长音频与说话人分离结果异常如何分析,以及提 issue 时需要准备哪些信息。读完本文,你将掌握一套"先选模型与运行时、再对症下药"的排查方法论,并能用仓库源码佐证每一步判断。
说明:本文以 docs/reference/FQA.md 为核心骨架,并结合仓库内更详细的 docs/troubleshooting.md、docs/installation/installation.md、docs/python_api.md、examples/openai_api/README.md 以及 funasr/bin/_server_app.py 等源码展开。FAQ 页面本身是兼容页,保留早期 FAQ 链接可用性,详细诊断与现行命令以 troubleshooting 文档为准。
排查的前提:先分清运行时,再动手
FQA 页面开篇就强调了一个核心原则:在应用任何 workaround 之前,先选择模型和运行时。FunASR 的 Python SDK、Python HTTP 服务、原生 vLLM 与 C++ WebSocket 是四套截然不同的运行时,它们的依赖、参数与输出契约互不通用:
| 运行时 | 入口 | 适用场景 |
|---|---|---|
| Python SDK | from funasr import AutoModel,见 docs/python_api.md | 进程内推理、波形输入、流式 cache 字典 |
| Python HTTP | funasr-server(打包服务)或 examples/openai_api/server.py(示例服务) | OpenAI 风格/v1/audio/transcriptions接口 |
| 原生 vLLM | AutoModelVLLM、funasr-server的 vLLM 引擎、vllm serve | 高吞吐、需要 vLLM 调度器 |
| C++ WebSocket | runtime/websocket 等 runtime 目录 | 实时/近实时流式场景 |
从源码看,打包服务funasr-server由 funasr/bin/server.py 启动,实际应用逻辑在 funasr/bin/_server_app.py 的create_app中:--model auto时,设备字符串以cuda开头选择fun-asr-nano(走 vLLM 引擎),否则选择sensevoice;请求中省略 multipartmodel字段则独立默认fun-asr-nano。启动预加载与请求默认是两个不同的设置,排查时务必分开核对。
我应该用哪条安装命令?
官方建议严格遵循 docs/installation/installation.md,核心要点是二选一:
- PyPI 发布包:
python -m pip install --upgrade funasr,安装的是你配置的索引源中的版本,不是当前 Git checkout。本文档或仓库中记录的功能可能不在该发布版本里;追求可复现应改为固定版本号安装。 - 源码 checkout:在仓库根目录执行
python -m pip install -e .并记录git rev-parse HEAD。可编辑安装直接从该目录导入代码,并非独立副本。
需要特别注意:仓库中的examples/、runtime/和文档并不全被 PyPI 作为包数据安装。也就是说,"我装了 funasr" 不等于"我有示例服务脚本或运行时工具"。当前 checkout 中modelscope和huggingface_hub是核心依赖而非可选后续安装,但模型专属 extras 是分开的:knfextra 提供kaldi-native-fbank(无 torchaudio 的路径),silero提供 Silero VAD,标准首个示例均不需要。可在 setup.py 中核对依赖声明。
推荐哪些 Python 和 PyTorch 版本?
FunASR 官方不承诺普适的版本组合,原则是"以所选模型/后端的 requirements 为准"。setup.py 声明python_requires=">=3.7.0",但解析后的依赖和具体模型可能要求更新的 Python;pyproject.toml 只定义构建后端,不是锁定推理环境的依据。
安装指南以 Python 3.11 作为环境示例(Linux/macOS 用python3.11 -m venv .venv,Windows PowerShell 用py -3.11 -m venv .venv),并明确区分"包元数据"与"解析后的依赖 requirements"两种概念。关键建议:
- 先装匹配的
torch/torchaudio/torchvision(同一安装通道、兼容版本),再装 FunASR;python -m pip install -U torch torchaudio之后python -m pip install -U "funasr==1.3.26"是 docs/troubleshooting.md 给出的标准顺序。 - MOSS 与 vLLM 有各自独立的依赖栈,不要让冲突的栈共存于同一环境。例如 MOSS 需要 Transformers 5.6+,vLLM 需要匹配 CUDA 的 wheel,混合安装会互相污染。
- 安装后在实际用于推理的同一环境里验证导入:
python -c "import funasr, torch, torchaudio; from funasr import AutoModel; print(funasr.__version__, torch.__version__, torchaudio.__version__)",并确认funasr.__file__指向预期安装位置。
模型下载慢或失败,该检查什么?
这是出现频率最高的一类问题。官方排查顺序是:
- Hub 选择:中国大陆建议优先 ModelScope(使用
iic/...模型名),海外可尝试 Hugging Face 镜像;GGUF / 边缘运行时模型使用 Hugging Face 上的公共 FunAudioLLM 仓库。 - 完整模型 ID 与 revision:别名是 hub 特有的,不是版本钉住;要复现就记录完整 ID 与上游 revision。
- 缓存权限与磁盘空间:模型文件与 Python 包分开下载,走 hub 客户端的缓存目录。务必保证足够的可写磁盘空间,并保留完整目录(配置、tokenizer、前端资源、权重都要)。
- 下载中断处理:只清理该模型的部分缓存再重试,不要无差别删除共享模型缓存卷。
从源码看,hub 解析逻辑在 funasr/download/download_model_from_hub.py:download_from_ms走 ModelScope 的snapshot_download(model, revision=model_revision, ...),会转发 revision;而get_or_download_model_dir_hf目前调用的是snapshot_download(model),没有转发 revision、local_files_only或check_latest。因此文档明确警告:不要依赖AutoModel(..., hub="hf", model_revision=...)做钉住;应使用 hub 客户端获取固定快照后传入本地目录。
离线推理还有一个易误解点:disable_update=True只跳过 FunASR 包版本检查,不是 hub 客户端、模型代码或缺失资源的离线开关。URL 形式的音频输入、热词输入仍需要网络;缓存的 hub 别名也可能触发 hub 请求。真正的离线需要"在线时准备好完整快照 + 依赖,断网后验证"。
funasr-server报 FastAPI 或 multipart 缺失
打包服务依赖额外的包。从 funasr/bin/server.py 的入口代码可以看到:
try: import uvicorn import fastapi except ImportError: print("Error: funasr-server requires additional packages.") print("Install with: pip install vllm fastapi uvicorn python-multipart") sys.exit(1)而 funasr/bin/_server_app.py 顶部同样会因缺少 fastapi 抛出ImportError,提示安装pip install vllm fastapi uvicorn python-multipart。
排查要点:
- 用启动服务的同一个解释器安装 examples/openai_api/README.md 中记录的依赖(
python -m pip install fastapi uvicorn python-multipart)。 - 仅安装 SDK 不等于 HTTP 服务就绪。SDK-only 安装不能证明 HTTP 服务器或某个模型专属后端可用——这是 FAQ 反复强调的边界:
AutoModel.generate()是进程内推理,与funasr-server的/v1/audio/transcriptions是两个契约,详见 docs/python_api.md 的 "SDK and Service Boundaries" 一节。
端口 8000 已被占用
默认端口冲突时:
- 用服务的
--port选一个新端口(如funasr-server --host 127.0.0.1 --device cpu --port 9000),并同步更新客户端base_url。 - 用 Docker Compose 时,改其文档记录的 host-port 设置(见 examples/openai_api/docker-compose.yml 的
FUNASR_HOST_PORT环境变量)。 - 提交音频前先验证目标进程的 health 端点——health 只证明服务就绪,不代表转写准确或所有可选输出字段可用。
示例服务还支持通过python smoke_test.py --base-url http://localhost:9000或BASE_URL=http://localhost:9000 bash smoke_test.sh(见 examples/openai_api/smoke_test.py)在自定义端口上做冒烟验证。
如何快速验证 OpenAI 兼容 API?
官方推荐流程:
- 启动服务(示例:
python server.py --host 127.0.0.1 --model sensevoice --device cpu --port 8000,注意等待模型加载完成再查 health)。 - 用 examples/openai_api/smoke_test.sh 或 examples/openai_api/smoke_test.py 做健康检查与转写检查。
- 手工 curl 验证核心端点:
curl http://localhost:8000/health curl http://localhost:8000/v1/models curl http://localhost:8000/v1/audio/transcriptions \ -F file=@sample.wav \ -F model=sensevoice \ -F response_format=verbose_json- 将响应与 examples/openai_api/OPENAPI.md 的 HTTP schema 对照;更严谨的做法是查询已部署服务的实时
/openapi.json,而不是只信仓库里检入的 schema 文件。
易混淆点(源自 examples/openai_api/README.md 的 API Contract):
response_format=verbose_json只选择响应形态,不会启用说话人分离,也不会强制生成时间戳。示例服务若sentence_info存在则拷贝进segments,否则返回segments=[]。- 示例服务的
duration是generate()周边的耗时(秒,不含模型加载),不是音频时长;打包服务 verbose 响应里的duration才是音频时长(秒)。 - 示例服务接受 multipart
file、model、language、response_format;SDK 的use_itn、热词、原始数组、spk不是它的表单字段。
如何用 Docker Compose 运行 OpenAI 兼容 API?
遵循 examples/openai_api/README.md 的 Compose 说明与 docs/installation/docker.md 的容器选择指南,核心命令:
cd examples/openai_api cp .env.example .env FUNASR_HOST_PORT=127.0.0.1:8000 docker compose up --build或等效的docker run:
docker build -t funasr-api . docker run --rm -p 127.0.0.1:8000:8000 \ -e FUNASR_DEVICE=cpu \ -e FUNASR_MODEL=sensevoice \ funasr-api排查时应整体核对:镜像依赖、设备、缓存与端口。FAQ 特别提醒:"改变设备环境变量不会给镜像添加 CUDA 支持"。FUNASR_DEVICE=cuda只有在镜像本身具备 CUDA 能力的依赖时才有意义;GPU 主机还需要 NVIDIA Container Toolkit(docker run --rm --gpus all ...)。另外注意,默认示例镜像启动的是 CPU 模式的示例server.py,并非打包的funasr-server;当前 Dockerfile 安装的是未钉版本的 PyPI FunASR/依赖,因此它既不是上面源码钉住的环境,也不是可复现的声学环境——这是文档明确写出的限制。
Docker 起来了但/health或转写失败
按顺序检查:
- 启动日志与模型加载状态:下载和启动时间取决于 checkpoint、缓存、网络与硬件,health 前先等模型加载完。
- 依赖完整性:确认镜像内是否安装了 fastapi、uvicorn、python-multipart 以及所选模型需要的解码器(soundfile/librosa 等)。
- host-port 映射:
-p 127.0.0.1:8000:8000与容器内监听端口是否一致;默认示例服务仍监听0.0.0.0,只是 host 发布端口绑定到回环地址。 - 设备可用性:
--gpus all与 CUDA 镜像是否匹配。 - 保留失败配置与相关日志,脱敏密钥与私人音频。
FAQ 特别强调:不要第一步就把共享模型缓存卷删掉;应只在识别出某个未完成下载并保留所需本地产物之后,才做隔离清理。这与 docs/troubleshooting.md 中"只清理该模型的部分缓存"的建议一致。
长音频慢、切分错误或内存不足
长音频问题最常见的根源是没有为所选模型/管线选择正确的工作流。官方建议:
- 先在 docs/python_api.md 中选定 Python SDK 工作流:Paraformer 风格管线可用 VAD 与 batch-size 控制。
- 更短的分块也可能引入边界错误(切断词、丢失上下文);在改变分段方式之前,先分别识别"识别错误、标点错误、时间戳错误",不要把所有问题都归咎于分段。
- 没有任何单一的分段长度是普适的准确率修复。
从 SDK 实现看,VAD 路径的批处理参数值得区分(均出自 docs/python_api.md):
| 参数 | 默认值 | 含义 |
|---|---|---|
batch_size | 1 | 每次直接推理的输入数,模型实际批支持各异 |
batch_size_s | 300 | VAD 路径按"最长填充段 × 段数"估算的批预算(秒),不是硬性的文件时长上限;CPU VAD 用单段批 |
batch_size_threshold_s | 60 | VAD 批处理的段时长阈值,不是 VAD 切分设置 |
merge_vad | False | 本次调用合并检测到的 VAD 区域 |
merge_length_s | 15 | VAD 合并目标时长;本 checkout 中应在构造时设置,调用期覆盖会被并入 ASR 配置 |
VAD 检测出的区域会按时长排序做 ASR 批处理、恢复原始顺序并偏移时间戳到原录音;VAD 边界是语音区域边界,不一定是说话人切换点。
MOSS 路线:联合转写 + 说话人分离
对于超长音频,FAQ 指向 MOSS-Transcribe-Diarize 路线(详见 docs/moss_transcribe_diarize.md):这是 OpenMOSS 发布的第三方模型(Apache-2.0),在一次生成中联合产出转写、时间戳与匿名说话人标签(如[S01]),应用无需自行拼装外部 VAD+ASR+diarization 管线。
关键约束:不要给它的 adapter 传外部的vad_model或spk_model——独立的块处理会破坏整段录音的说话人一致性。应检查其自身的上下文长度、输出 token 与设备需求。例如本地 Transformers 后端:
from funasr import AutoModel model = AutoModel( model="OpenMOSS-Team/MOSS-Transcribe-Diarize", model_revision="e8681d68e7042738ffca8ac8212bc8fcb1131ab8", backend="hf", device="cuda:0", dtype="bf16", attn_implementation="sdpa", disable_update=True, ) result = model.generate("audio.wav", max_new_tokens=5120)[0] print(result["text"]) for segment in result["sentence_info"]: print(segment["start"], segment["end"], segment["spk"], segment["text"])长录音测试max_completion_tokens时注意:FunASR 的 vLLM adapter 同时接受 OpenAI 兼容的max_completion_tokens与兼容别名max_new_tokens,两者同时出现时原生名称优先;更大的限制可能增加显存占用与尾部延迟。文档记录的真实案例显示:约 379.7 秒的双说话人中文录音在默认 5120 token 限制下被截断于 354.98 秒并导致diarized_json标签不完整(HTTP 400),改为max_completion_tokens=8192后输出 224 个段直至 378.55 秒——这说明存在精确的输入完整性边界,需要在部署前针对最长的预期会议实测。
说话人分离结果没有说话人标签
两条不同的路线,对应不同的检查方式:
- Paraformer 风格 VAD/ASR/标点/说话人嵌入管线:检查
sentence_info与 SDK 说话人契约(docs/python_api.md)。只有spk_model并不会给直接推理附加 diarization——说话人聚类运行在 VAD 路径中;punc_segment需要可用的标点与时间戳,缺失时会回退到vad_segment。 - MOSS-Transcribe-Diarize:使用其原生标签,不要再叠加第二个 VAD 或说话人模型。adapter 会把结构化输出规范化为
sentence_info;畸形/未标记输出不得凭空捏造标签——如果解析器无法证明带标签结构,它会把模型文本留在text与raw_text中,返回空的 timestamp/segment 数组,而不是伪造说话人元数据。
另一层重要语义:录音内的说话人标签是匿名的。spk=0或[S01]不代表已登记的某人,也不保证与另一段录音中的相同标签对应——它不是跨录音的说话人识别。
能否用 cam++ 以外的说话人模型?
对于嵌入(embedding)类管线:
- 使用已注册且推理输出含
spk_embedding的兼容说话人模型,然后在所选 ASR/VAD 管线上实测聚类效果。注册机制见 docs/model_registration.md:@tables.register("model_classes", "YourUniqueModelName")把 Python 实现与配置名连接起来,注册本身不下载权重、不保证质量。 - 直接输出分离片段的模型(diarized segments)不能与说话人嵌入模型互换。
- MOSS 走专用 adapter,不用
spk_model。
打包服务的说话人路径可作为参考实现:_server_app.py中的attach_speaker_labels在收到spk=true时惰性加载--spk-model(默认cam++),对每个带时间戳的段切出音频,调用说话人模型generate得到spk_embedding,再经ClusterBackend(merge_thr=0.78)聚类、postprocess时间线化、distribute_spk分配标签,最终以SPK{n}形式写入段的speaker字段。这印证了嵌入模型的输出契约(spk_embedding+ 聚类)是替换的前提。
同一命令 CPU 能跑、CUDA 失败
FAQ 的结论:CPU 成功并不能证明 GPU wheel 或模型的兼容性。排查步骤:
- 记录完整环境:驱动、GPU、Python、PyTorch、torchaudio、CUDA build 版本。
- 从 docs/installation/installation.md 的环境检查与 docs/troubleshooting.md 开始。
- 检查该模型在目标设备上的支持情况与峰值显存。
打包服务里有一个可佐证的实现细节:fun-asr-nano的 vLLM 引擎加载失败时会回退到 AutoModel(_load_vllm_engine捕获异常后打印 warning 并加载 fallback),并在/health中如实反映实际加载的模型。因此看到 "fun-asr-nano (vLLM)" 与 "fallback AutoModel" 的区别,本身就是一条诊断线索。另注意 vLLM 引擎的repetition_penalty被固定在 1.0(prompt-embeds 模式下其他值会使 CUDA kernel 崩溃,见 issue #2948 与fun_asr_nano.vllm_utils)。
提 issue 时应该包含什么信息
FAQ 与 docs/troubleshooting.md 给出了可照抄的清单:
- 操作系统、Python 版本、安装命令、虚拟环境工具;
torch、torchaudio、CUDA、驱动与 GPU 详情;- FunASR 版本、模型 ID、hub(
ModelScope或Hugging Face)、部署模式; - 最小可复现的命令或脚本,预期输出 vs 实际输出;
- 包与源码版本、模型 ID/revision、运行时/设备细节、相关日志;
- 音频时长、格式、采样率;许可时可提供可分享的复现样本;
- 发布前移除凭证、私有端点与私人音频;
- 在建议的修复被验证期间保持 issue 打开。
历史 ModelScope pipeline 示例的取舍
FQA 末尾列出了若干历史社区讨论(涉及 VAD 模型、标点模型、Paraformer 流式、VAD+ASR+标点、VAD+ASR+标点+NNLM、时间戳预测、UniASR 在线/离线解码切换等场景)。这些是历史社区讨论:复用其中代码前必须先核对它们的源码/包版本,新集成应以维护中的 SDK 指南(docs/python_api.md)与模型选择指南(docs/model_selection.md)为起点,避免把旧版本 API 行为当作当前实现。
附:一次完整的快速诊断路径
把上面的排查方法论串成一条可执行的路径:
- 确认运行时:SDK / HTTP / vLLM / WebSocket?对应读 docs/python_api.md 或 examples/openai_api/README.md。
- 确认安装:
python -m pip check+ 导入验证(import funasr, torch, torchaudio; from funasr import AutoModel),funasr.__file__指向预期位置。 - 确认模型:hub、完整 ID、revision、缓存目录权限、磁盘空间;ModelScope 走
iic/...,海外优先 HF 镜像。 - 确认服务:依赖(
fastapi uvicorn python-multipart)、端口(--port+ 客户端base_url)、/health、/v1/models、/openapi.json。 - 用小而已知的音频做冒烟(
curl -F file=@...),再上长音频;长音频分别隔离"识别/标点/时间戳/分段"四类错误。 - 说话人相关先区分管线(嵌入聚类 vs MOSS 原生标签)再排查
sentence_info与spk字段。 - 仍然失败,就按上述 issue 清单整理信息提交 Deployment Help 类 issue。
这条路径覆盖了 docs/reference/FQA.md 的全部主题,也与 docs/troubleshooting.md 归纳的三大首次使用拦路虎(安装/hub 路径、运行时包选择、服务输出异常)一一对应,可作为团队内部的知识库条目复用。
【免费下载链接】FunASROpen-source speech recognition toolkit for training, inference, streaming ASR, VAD, punctuation, speaker diarization pipelines, and OpenAI-compatible/MCP serving.项目地址: https://gitcode.com/GitHub_Trending/fun/FunASR
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考