把语音转写接进自己的 API

如果应用只需要上传一段录音、取回文字,先把这一个来回走通。团队可以先在本机核对请求与返回值,再决定怎样承接真实流量,而不是一开始就复制整套云服务。

这里用一份获授权的 audio.wav:客户端把文件发给本机 SenseVoice 服务,再读取 JSON 的 text 字段。示例展示调用路径,不编造转写结果,也不比较速度。

本文使用 FunASR 1.4.15 包内的 funasr-server。它只提供部分 OpenAI 转写接口,不是所有云功能和返回格式的替代品;连通 URL 还不等于迁移完成。

先做一次本地 JSON 转写

前提:已经准备并验证过的独立 FunASR 1.4.15 环境。本段不是从零安装教程。运行下列命令的 Python 和 funasr-server 必须来自同一个已激活环境,且 funasr==1.4.15、PyTorch、音频依赖、FastAPI、Uvicorn、python-multipart、模型权重访问及音频文件均已准备好。平台依赖参见安装指南;其他版本需要重新核对行为。

python -c 'from importlib.metadata import version; assert version("funasr") == "1.4.15", version("funasr")'
python -m pip check

版本检查和 pip check 只检查包元数据,不能证明 CUDA、音频解码或实际转写可用。下方明确选择 SenseVoice CPU 做接入验证,不是性能建议;不要在同一端口同时启动多个服务。另有仓库示例 HTTP 服务指南可作实现对照,但它准备并启动的是 example server,不是本文所要求的包内 1.4.15 环境。

funasr-server --host 127.0.0.1 --port 8000 --model sensevoice --device cpu

在同一主机的另一个终端,上传你有权处理的 audio.wav。命令会输出转写文本,不要把包含私人内容的输出直接贴入公开日志。

curl --fail --show-error --silent --max-time 120 \
  http://127.0.0.1:8000/v1/audio/transcriptions \
  -F "file=@audio.wav" \
  -F "model=sensevoice" \
  -F "response_format=json"

响应是包含 text 的 JSON 对象;具体文本由录音和模型决定。120 秒只是客户端示例超时,不是任意长度音频的处理保证,也不意味着超时会取消后台推理。

OpenAI Python SDK:明确模型和返回格式

在单独安装了 openai 客户端的环境中,可以使用以下基本调用。迁移时仍需检查模型名、参数、响应解析、错误处理和网关认证,不能只检查 URL 是否可连接。

from openai import OpenAI

client = OpenAI(
    base_url="http://127.0.0.1:8000/v1",
    api_key="not-needed",
    timeout=120.0,
    max_retries=0,
)
with open("audio.wav", "rb") as audio:
    result = client.audio.transcriptions.create(
        model="sensevoice", file=audio, response_format="json"
    )
print(result.text)

上面的基本 JSON 调用不是字幕生成器:包内服务不生成 SRT/VTT,text 格式也返回 JSON 字符串而非纯文本。更换应用解析器之前,先核对文末附录中的格式契约。

接入 Open WebUI 或其他应用前

比较的是完整部署方案,不只是 API 单价

自托管需要计算服务器、存储、流量、维护与监控成本。是否留在受控网络,取决于客户端、代理、临时文件、日志和保留策略;不能承诺音频绝不落盘或转写永不泄露。模型权重的许可也需要单独核对,不能由工具包代码许可代替。

根据语言、时延、硬件和说话人需求查看模型选型MOSS 转写与说话人分离部署矩阵。本文不提供新的准确率或性能排名;验收方法见会议录音验收清单

附录:核对返回契约

包内服务的兼容范围

项目当前行为与接入要求
请求multipart 文件上传;路由声明 filemodellanguageresponse_format 和 FunASR 扩展 spk。语言和说话人能力仍受所选模型限制。
json返回带 text 的 JSON 对象,适合先验证基本文本转写。
verbose_json返回结构化 JSON,包括 segmentsduration 等字段;具体时间与说话人信息依赖模型和实际结果。
text当前包内处理器返回 JSON 字符串,不是标准的纯文本响应;不要假设云端客户端的解析方式完全相同。
srt不生成 SRT 字幕,落入 JSON 文本对象分支;HTTP 200 不能证明返回了字幕文件。
vtt不生成 VTT 字幕,同样落入 JSON 文本对象分支。
其他参数与协议prompttemperaturetimestamp_granularities 不是该路由声明的完整能力。不要把它当成流式 WebSocket、翻译或完整云 API;额外字段未报错也不证明生效。

包内服务的字段应通过私有或受限的运维路径访问运行中服务的 /openapi.json,并核对固定版本包内处理器源码示例服务 API schema描述的是另一种实现,不是包内处理器的完整字段说明。包内服务、仓库示例、vLLM 与 llama.cpp 的默认值、参数和响应结构并不通用。

下一步,在让其他用户接入前,按服务安全指南验证网关鉴权和后端不可绕过。在这些部署检查通过前,保留本机私有调用范围。