用 FunASR FastAPI 五分钟搭建语音识别 API从一段音频到一行文字只需要一个 POST 请求。本文手把手拆解一个极简但生产可用的 ASR 服务搭建方案。一、先看效果启动服务后一行 curl 即可完成语音转文字curl-XPOST http://localhost:8765/api/asr/recognize\-Ffileyour_audio.wav返回{code:0,msg:success,data:{text:今天天气真不错}}没有多余的依赖没有复杂的部署流程一个 Python 文件搞定。二、为什么选这个技术栈组件选择理由ASR 模型FunASR Paraformer-Large阿里达摩院开源中文识别效果一流内置 VAD 标点恢复长音频友好Web 框架FastAPI异步原生自动生成 OpenAPI 文档写接口极简ASR 框架FunASR AutoModel统一推理接口内置 VAD 等工具链一行代码切换模型这里用的是speech_paraformer-large-vad-punc它是 FunASR 生态中的重磅模型——一个模型 ID 里打包了三件事Paraformer-Large 做语音识别、FSMN-VAD 做语音端点检测、CT-Transformer 做标点恢复。相当于一条龙服务不用再单独挂载 VAD 和标点模型。三、代码逐段拆解3.1 初始化与跨域配置fromfastapiimportFastAPI,UploadFile,Filefromfastapi.middleware.corsimportCORSMiddlewarefromfunasrimportAutoModelimportuvicorn appFastAPI()app.add_middleware(CORSMiddleware,allow_origins[*],allow_credentialsTrue,allow_methods[*],allow_headers[*],)这段做了两件事创建 FastAPI 应用实例——路由、中间件、生命周期都挂在这个对象上。配置 CORS 全放行——开发阶段图方便允许所有来源。上线前记得收紧allow_origins只放行你的前端域名。3.2 加载模型modelAutoModel(modeliic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch,devicemps)这行是整个服务的核心modeliic/speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch从 ModelScope 拉取预训练权重。这个模型 ID 虽然长但每个部分都有含义paraformer-large是主体识别模型vad和punc表示内置了 VAD 和标点恢复子模型16k-common-vocab8404表示 16kHz 采样率、通用中文词表 8404。首次运行会自动下载并缓存后续启动秒级就绪。devicempsMac M 系列芯片的 GPU 加速后端。如果你用的是 Intel Mac改成cpu有 NVIDIA 显卡的 Linux 机器改成cuda。小贴士模型加载放在模块顶层而不是接口内部确保只加载一次。FastAPI 启动时就会完成模型初始化后续请求直接复用。3.3 核心识别接口app.post(/api/asr/recognize)asyncdefrecognize_audio(file:UploadFileFile(...)):FastAPI 的UploadFile会自动处理文件流不需要手动解析 multipart 数据。File(...)表示这个参数是必填的。3.4 临时文件写入audio_bytesawaitfile.read()temp_pathtemp_audio.wavwithopen(temp_path,wb)asf:f.write(audio_bytes)FunASR 的generate方法接受文件路径作为输入所以需要把上传的二进制数据落盘。这里有几个可以优化的点见第四节临时文件名是硬编码的并发场景下会互相覆盖。没有清理临时文件。3.5 调用语音识别resmodel.generate(inputtemp_path,languagezh,use_itnTrue,vad_modelfsmn-vad,vad_kwargs{max_single_segment_time:30000},batch_size_s0,merge_vadTrue,)这几个参数值得展开讲参数值作用languagezh指定中文减少语言检测开销提升准确率use_itnTrue开启逆文本正则化把一千二十三转成1023等vad_modelfsmn-vad加载 FSMN-VAD 模型自动检测语音起止点vad_kwargs{max_single_segment_time: 30000}单段语音最长 30 秒超时截断——防止长时间静音段被误识别为文字batch_size_s0不启用批处理单条推理merge_vadTrueVAD 切分后的多段结果自动合并为一条文本值得一提的是虽然模型 ID 里已经带了vad和punc但代码中仍然通过vad_modelfsmn-vad显式指定了 VAD 模型并设置了max_single_segment_time参数来控制单段语音最大时长。这是为了对 VAD 行为做更精细的调控——默认参数可能把一段长语音切得过于细碎30 秒的上限是一个比较实用的折中。VADVoice Activity Detection是这里的关键。没有 VAD 的话如果音频开头有 5 秒静音模型可能把静音段也识别出乱码。加上 VAD 后模型会先定位有效语音区间只在有声音的地方做识别干净又准确。3.6 后处理与返回textres[0][text]clean_textre.sub(r\|.*?\|,,text).strip()return{code:0,msg:success,data:{text:clean_text}}模型的原始输出可能包含特殊标记如情感标签|HAPPY|或事件标记|Applause|等用正则r\|.*?\|统一清洗掉只保留纯文本。返回结构采用code msg data的经典三段式方便前端统一处理。四、可以改进的地方这段代码作为一个快速验证已经很好但如果要上生产建议做以下优化4.1 并发安全临时文件命名importuuid temp_pathftemp_audio_{uuid.uuid4().hex}.wav用 UUID 生成唯一文件名避免并发请求互相覆盖。4.2 临时文件清理importostry:resmodel.generate(...)finally:ifos.path.exists(temp_path):os.remove(temp_path)用try...finally确保推理完成后一定删掉临时文件不管成功还是失败。4.3 音频格式校验当前代码信任客户端传入的是 16000Hz 单声道 WAV。如果传了个 MP3 或者采样率不对FunASR 可能静默产出错误结果。建议加上importwavewithwave.open(temp_path,rb)aswf:channelswf.getnchannels()frameratewf.getframerate()ifchannels!1orframerate!16000:return{code:1,msg:音频格式错误要求16000Hz单声道WAV}4.4 CORS 收紧上线时把allow_origins[*]改成你的前端域名白名单allow_origins[https://your-app.com]4.5 音频流式处理进阶如果不想落盘可以用soundfile把二进制数据直接加载为 numpy 数组再传给 FunASR。但需要注意 FunASR 的generate对 numpy 输入的支持情况视版本而定。五、启动与部署本地开发pipinstallfastapi uvicorn funasr modelscope python asr_service.py服务会在http://0.0.0.0:8765启动打开http://localhost:8765/docs可以看到自动生成的 Swagger 文档直接在页面上测试接口。Docker 部署FROM python:3.10-slim RUN pip install fastapi uvicorn funasr modelscope WORKDIR /app COPY asr_service.py . EXPOSE 8765 CMD [python, asr_service.py]dockerbuild-tasr-service.dockerrun-p8765:8765 asr-service注意首次启动需要下载模型Paraformer-Large 全套约 1.2GB建议在构建镜像时预下载或者挂载宿主机模型缓存目录。六、性能参考在 Mac M2 Pro 上的粗略测试音频时长识别耗时5 秒~0.3 秒30 秒~1.2 秒60 秒~2.5 秒Paraformer-Large MPS 的组合在 Apple Silicon 上表现不错适合中小规模场景。七、总结做了什么怎么做的选模型FunASR Paraformer-Large中文识别强内置 VAD 标点恢复建接口FastAPI 异步上传 文件接收加速推理Mac 用 MPSNVIDIA 用 CUDA处理静音FSMN-VAD 自动检测有效语音段清洗输出正则去除模型特殊标记整个方案的核心思路用最少的代码把一个开源 SOTA 模型变成一个可调用的 HTTP 接口。不需要 GPU 集群不需要复杂配置一台 Mac 就能跑起来。如果你也在做语音相关的项目FunASR 生态值得深入探索——除了 Paraformer 系列还有 SenseVoice多语言短音频、CT-Transformer标点恢复等一整套工具链可以按需组合。本文代码已验证可运行环境Python 3.10 / Mac M2 Pro / FunASR 1.x。