FunASR OpenAI 兼容 API 浏览器演示:Gradio UI 部署、三大后端 Profile 与安全边界全指南

FunASR OpenAI 兼容 API 浏览器演示:Gradio UI 部署、三大后端 Profile 与安全边界全指南 FunASR OpenAI 兼容 API 浏览器演示Gradio UI 部署、三大后端 Profile 与安全边界全指南【免费下载链接】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导读本篇技术指南围绕 examples/openai_api/GRADIO_zh.md 展开系统讲解如何为 FunASR OpenAI 兼容 API 搭建一个可上传文件、可录制麦克风音频的 Gradio 浏览器界面并打通funasr、vllm、sglang-omni三类后端 Profile 的完整调用链。读完本文你将掌握如何隔离安装客户端与服务端两套 Python 环境、如何按 Profile 与模型别名正确启动 UI、如何用curl/smoke_test.py验证后端就绪、三个 Profile 在默认模型与响应格式上的差异以及把该演示当作私有操作台时必须落实的安全边界与生产注意事项。需要强调的是这个 Gradio 应用是纯 HTTP 客户端它不加载任何模型、不安装服务端声学依赖、也不做流式识别或实时唤醒——录音完成后按完整文件提交转写请求。1. 架构定位一个不加载模型的浏览器客户端先厘清这个 Demo 在 FunASR 生态中的位置。仓库中 examples/openai_api/gradio_app.py 通过标准库urllib.request直接构造 multipart/form-data 请求把音频文件连同model、response_format字段发送到后端的/v1/audio/transcriptions端点这与 OpenAI SDK 的调用形态完全一致。从源码可以确认几个关键架构事实请求由 Gradio 进程发起而不是浏览器直接发起。API base URL 文本框可编辑但实际网络请求由 Python 进程发出浏览器只与 Gradio 页面交互Gradio 客户端不依赖 FunASR、Torch、CUDA也不需要下载任何模型权重——它只需要gradio这一个第三方包以及 Python 标准库。后端服务则自行负责加载模型与声学推理不是鉴权网关Demo 本身没有配置 UI 鉴权也不向后端发送Authorization凭据。两个服务都应保持私有不要把这个操作界面分享给不可信用户不是流式服务录音完成后按完整文件提交不存在流式识别或实时唤醒链路。examples/openai_api/gradio_app.py 中request_json()仅携带Accept: application/json头访问/health与/v1/models而transcribe_audio()L71-L92用uuid生成 multipart boundary、按文件名推断 MIME 类型、将整个音频文件读入内存后 POST 到{base_url}/v1/audio/transcriptions。这正是后续理解其安全边界的关键线索整文件进内存是源码级事实不是宣传话术。2. 第一步启动 OpenAI 兼容 API 服务UI 需要一个可用的后端。仓库提供了示例服务 examples/openai_api/server.py它实现了 OpenAI 风格/v1/audio/transcriptions接口。按 HTTP 服务指南 准备同一份 checkout在已安装 Python 3.11 的 POSIX shell 中执行git clone https://github.com/modelscope/FunASR.git FunASR-api cd FunASR-api git checkout --detach d91d961e37a005837b1523bcc6b09f087877be54 python3.11 -m venv .venv source .venv/bin/activate python -m pip install -e . python -m pip install fastapi uvicorn python-multipart python -m pip check cd examples/openai_api python server.py --host 127.0.0.1 --model sensevoice --device cpu --port 8000关于这段安装配方的边界原文档与 examples/openai_api/README_zh.md 表述一致值得重申只固定源码 revision不固定依赖、模型权重、解码器或 CUDA。这是安装操作说明不是全新安装或声学验证结果模型加载完成后再检查服务GET /health下载与启动耗时取决于 checkpoint、缓存、网络和硬件准备好 GPU 依赖后可改用 HTTP 指南中的 CUDA 替代命令--device cuda但不要在 8000 端口再启动第二个服务。2.1 MOSS 场景需要专用环境与固定 revision如果要用 MOSSmoss-transcribe-diarize别名必须按 MOSS 部署指南 准备专用环境以及固定的服务端和模型 revision。在 examples/openai_api/server.py 的MODEL_CONFIGS中可以看到MOSS 条目固定了model_revisione8681d68e7042738ffca8ac8212bc8fcb1131ab8、hubhf、backendhf、trust_remote_codeTrue。MOSS 在专用环境中联合完成离线转写与说话人分离无需外部 VAD 或说话人模型。部署时先选择其中的 FunASR 服务、原生 vLLM 或原生 SGLang Omni 路径——UI profile 不会启动、转换或重新配置后端它只是一个面向已就绪服务的客户端。不要把 MOSS 的 GPU 环境安装到轻量 Gradio 客户端环境中。2.2 Docker / Kubernetes 作为后端替代部署容器 8000 端口只发布到主机 loopback127.0.0.1:8000:8000或使用私有kubectl port-forward容器内部监听0.0.0.0与主机端口暴露是不同边界。ClusterIP本身不是网络隔离。只有 Gradio 进程能解析并访问集群 DNS 时才能使用该地址在笔记本上应使用本地转发地址而不是无法解析的*.svc.cluster.localURL。详细方案见 Docker 部署 和 Kubernetes 部署。3. 第二步安装并启动浏览器 UI打开新终端从包含FunASR-api的目录开始。使用独立的 Python 3.12 环境.venv-gradio不要使用服务端.venv或原生后端环境cd FunASR-api python3.12 -m venv .venv-gradio source .venv-gradio/bin/activate python -m pip install gradio6.26.0 python -m pip check cd examples/openai_api python gradio_app.py --backend funasr --model sensevoice --base-url http://127.0.0.1:8000 --host 127.0.0.1 --port 7860从 examples/openai_api/gradio_app.py 的parse_args()可以看到全部 CLI 参数及默认值参数默认值说明--base-urlBASE_URL环境变量或http://localhost:8000后端地址不带/v1与 OpenAI SDK 的 base URL 不同客户端会自行追加/v1/audio/transcriptions--backendfunasr客户端 Profilefunasr/vllm/sglang-omni--modelProfile 默认模型精确的 served-model ID 覆盖值--hostGRADIO_HOST或127.0.0.1Gradio 绑定地址--portGRADIO_PORT或7860Gradio 绑定端口--timeoutTIMEOUT或300HTTP 超时秒--share关闭创建临时 Gradio share 链接启动后打开命令行输出的本地 URL只在需要时允许麦克风访问上传或录制音频选择Model alias和Response format再点击Transcribe。UI 使用 7860 端口与后端端口分开。需要提醒的是浏览器麦克风依赖权限和安全上下文HTTPS 或 localhost远程普通 HTTP UI 不是可通用的麦克风配方。3.1 三条后端 Profile 启动配方以下是替代选项都在同一已激活的客户端环境和examples/openai_api目录中执行。复用 7860 端口前先停止旧 UI并另行启动匹配的后端。--backend显式选择客户端 profile不会探测或切换运行中的服务。连接已为 MOSS 准备好的 FunASR example 或 packaged 服务python gradio_app.py --backend funasr --model moss-transcribe-diarize --base-url http://127.0.0.1:8000 --host 127.0.0.1 --port 7860连接固定 revision 的原生 vLLM 配方后端使用--served-model-name moss-transcribe-diarizepython gradio_app.py --backend vllm --model moss-transcribe-diarize --base-url http://127.0.0.1:8898 --host 127.0.0.1 --port 7860连接使用完整模型 ID 的原生 SGLang Omni 配方下拉框显示较短标签MOSS-Transcribe-Diarize请求仍发送完整 IDpython gradio_app.py --backend sglang-omni --model OpenMOSS-Team/MOSS-Transcribe-Diarize --base-url http://127.0.0.1:8898 --host 127.0.0.1 --port 78603.2 显式--model覆盖语义显式--model是操作人员配置的覆盖值会加入下拉选项并作为请求的model原样发送不会注册服务端 alias也不会更换 checkpoint。在 gradio_app.py 的build_app()中可以看到如果selected_model不在 Profile 的模型列表里它会被追加进下拉选项models.append(selected_model)并且完整 IDOpenMOSS-Team/MOSS-Transcribe-Diarize在 UI 上显示为短标签MOSS-Transcribe-Diarize、请求时仍回传完整 ID——这正是model_choices使用(label, value)元组对的原因。例如只有先把 vLLM 服务配置为接受 served namemeeting-asr后才使用python gradio_app.py --backend vllm --model meeting-asr --base-url http://127.0.0.1:8898 --host 127.0.0.1 --port 7860反向的坑也要避免不要用完整 Hugging Face ID 替换 FunASR 请求 alias。example API 校验其五个 alias见 server.py未知模型直接抛 400HTTPExceptionpackaged 服务的--model-path/--hub部署使用请求模型custom。UI 的覆盖值不会绕过任何一类服务的模型校验。发送音频前务必检查当前 profile、model 和格式。4. 第三步先验证后端服务再点 TranscribeCheck service按钮会请求/health和/v1/models源码见 gradio_app.py 的check_service()。注意这是metadata 检查不是声学测试也不代表模型就绪。不同服务的 schema 和路由策略不同——原生服务或网关可能拒绝某个 metadata 路由但允许转写。不要为了让按钮成功而公开私有 metadata 或移除鉴权。对于无鉴权、仅监听 loopback 的 FunASR example 服务在已激活的客户端环境及examples/openai_api目录中执行curl --fail --silent --show-error http://127.0.0.1:8000/health curl --fail --silent --show-error http://127.0.0.1:8000/v1/models python smoke_test.py --base-url http://127.0.0.1:8000 --model sensevoice前两条命令只检查 metadata。/health响应包含status、device、models_loaded和models_available字段见 server.py/v1/models返回别名列表其中ready字段标明该模型是否已加载进注册表server.py。可选的smoke_test.py命令行为不同见 examples/openai_api/smoke_test.py若默认的sample.wav不存在它会从公开中文样本 URL 下载写入当前目录然后依次打印 health、models 和转写 JSON。它不是多语言准确率 benchmark也不是仅检查 metadata。使用受控音频并保护诊断输出smoke 脚本的模型也必须与已准备的服务匹配这条命令不验证 MOSS/native 部署。UI timeout 默认为 300 秒并传给 HTTP 客户端。它不是整个任务的截止时间客户端超时不会取消后端推理也不能据此确定安全并发上限。5. 模型别名与三个 Profile 的默认契约funasrprofile 提供五个请求 alias与 server.py 的MODEL_CONFIGS一一对应。列出 alias不代表 checkpoint 已加载、已缓存或被当前安装的依赖支持选择其他模型可能触发 example API 按需加载load_model()会在MODEL_REGISTRY未命中时动态加载并缓存。sensevoice通过 FunASR 进行 SenseVoice 转写SenseVoiceSmall FSMN-VAD。HTTP text 已移除语言、情绪和事件标签clean_text()用正则剥掉|...|富文本标签见 server.pyUI 的原始响应不是 SDK 的原始标签输出paraformer通过已配置的 FunASR pipeline 进行中文转写paraformer-zh FSMN-VAD CT 标点不保证吞吐或生产容量paraformer-en通过已配置的 FunASR pipeline 进行英文转写paraformer-en FSMN-VAD示例服务专有别名无标点组件fun-asr-nano基础 Fun-ASR-Nano 模型HF 平台 FSMN-VAD。它不是独立的 31 语言 Fun-ASR-MLT-Nano checkpoint不应假定支持韩语。在 exampleserver.py中选择此 alias不会启动原生 vLLM示例始终走AutoModelmoss-transcribe-diarize第三方 OpenMOSS在专用环境中联合完成离线转写和说话人分离。录音内的匿名说话人标签不是身份认定它不是实时麦克风模型。使用verbose_json检查 FunASR 服务的 segments。5.1 funasr profilejson 与 verbose_jsonfunasr默认sensevoice和verbose_json也可选json。example API 的json只包含{text: ...}其verbose_json将模型返回的sentence_info映射为segments毫秒坐标除以 1000 转换为秒见 server.pystart/end单位为秒speaker取决于模型。segments 可以为空——请求 verbose 输出不会创建说话人分离能力。example 的duration是generate()调用耗时不含首次模型加载不是音频时长packaged FunASR 则报告音频时长。字段语义差异详见 API 边界。5.2 vllm profilediarized_json 与 jsonvllm默认moss-transcribe-diarize和diarized_json也可选json。在固定 revision 的 MOSS 部署路径中diarized_json包含结构化说话人片段json保留紧凑标签文本。这不是对任意 vLLM 模型或发布版的承诺也不要向 FunASR profile 发送diarized_json并期待同样的结果。5.3 sglang-omni profile仅 verbose_jsonsglang-omni默认OpenMOSS-Team/MOSS-Transcribe-Diarize仅提供verbose_json。在文档记录的原生契约中[Sxx]标签保留于segments[].text不是独立的speaker字段。Gradio 客户端只展示返回的text和 JSON不剥离标签、不生成说话人标签也不归一化这些后端差异。协议、版本限制和长音频控制参见固定 revision 的 MOSS 部署指南此 UI 没有暴露后端特定的 token 预算参数。5.4 源码级佐证BACKEND_PROFILES 与测试契约三个 Profile 的差异在 gradio_app.py 的BACKEND_PROFILES字典中硬编码BACKEND_PROFILES { funasr: { models: (sensevoice, paraformer, paraformer-en, fun-asr-nano, moss-transcribe-diarize), formats: (json, verbose_json), default_format: verbose_json, }, vllm: { models: (moss-transcribe-diarize,), formats: (json, diarized_json), default_format: diarized_json, }, sglang-omni: { models: (OpenMOSS-Team/MOSS-Transcribe-Diarize,), formats: (verbose_json,), default_format: verbose_json, }, }仓库的模型无关测试 tests/test_gradio_app.py 对这套契约做了参数化验证每个 profile 的下拉模型、格式选项、默认格式必须与上表一致sglang-omni 的下拉显示为短标签MOSS-Transcribe-Diarize而 value 是完整 ID。另有测试L173-L187验证客户端不编造说话人或分段无论后端返回什么 payload客户端都原样透传metadata 路由 404 也不会阻断转写test_optional_metadata_failure_does_not_gate_transcription。更完整的模型对比见模型选择指南。6. 生产注意事项安全边界与数据流把它当作私有操作 demo而不是公网生产前端。敏感音频不要启用--share。UI 监听 loopback 不会让另行暴露的后端变成私有服务可编辑 API URL 控制服务端请求。应用没有目标 allowlist 或重定向限制HTTP 客户端可以跟随重定向。应限制 UI 使用者和 Gradio 进程的网络访问范围不要把密码或访问 token 放进 URLDemo 没有配置 Basic、Bearer、OIDC 或 mTLS 后端凭据。TLS、鉴权、上传及响应大小限制、限流、并发准入和网络隔离都需要另行设计部署。OpenAI SDK 的api_key示例不会为此 Gradio 客户端增加鉴权api_keynot-needed只是占位符examples/openai_api/README_zh.md 明确说明它不提供鉴权音频从浏览器传到 Gradio再传到 API。Gradio 使用文件路径输入gr.Audio(typefilepath)见 gradio_app.pymultipart builder 会将整文件读入内存example API 也会缓冲并写入临时文件NamedTemporaryFileserver.py。不能承诺无落盘、立即删除或安全地无限上传。需核验所选 Gradio 版本的缓存和保留行为准备私有临时存储、请求大小和时长限制UI 显示服务端响应也可能显示上游错误正文、URL 或异常详情。safe_transcribe()/safe_check()gradio_app.py会把HTTPError的响应体原文拼进 UI 展示。分享诊断信息前先脱敏不要默认记录原始错误文本、音频或转写正文为两类服务制定访问、保留和删除规则成功显示 JSON 不能证明说话人分离准确率、身份识别、吞吐、取消能力、公网隔离或兼容所有原生服务版本。请用受控文件和真实网关策略验证准确的客户端及后端 revision。首次启动前务必阅读安全与网关指南——其中的 Basic 网关不能直接接收此客户端的无鉴权请求需要在网关处配置匹配的认证客户端并遵循该指南中的上线检查清单逐项验收。7. 快速排障速查现象处理方式8000 端口被占用改用--port 9000并运行python smoke_test.py --base-url http://localhost:9000首次请求很慢模型可能在按需加载用--model sensevoice在启动时预加载CUDA 不可用先用--device cpu跑通 smoke test再修 GPU 驱动/runtime请求超时增大 UI 的 Timeout seconds 或拆分超长录音客户端超时不会取消后端推理下拉里找不到目标模型用--model exact-served-id显式覆盖它是原样发送的 served model ID不是 checkpoint 下载器响应中没有segmentsverbose_json只选响应格式不启用说话人分离或强制时间戳数组可能为空8. 总结Gradio 浏览器 Demo 是 FunASR OpenAI 兼容 API 生态中的一块「轻客户端拼图」它用独立环境、纯 HTTP 方式把文件上传/麦克风录音与funasr、vllm、sglang-omni三类后端连接起来。理解它的关键是分清三层边界——UI 不加载模型、Profile 不切换后端、verbose_json 不创造声学能力。将本文的启动配方、模型别名契约与安全与网关指南结合使用即可在私有网络内搭建一个可靠、可审计的语音转写操作台后续接入更多客户端形态可继续参考客户端配方与工作流配方。【免费下载链接】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),仅供参考