mirror of
https://github.com/modelscope/FunASR.git
synced 2026-10-12 02:19:18 +00:00
202 lines
9.6 KiB
Markdown
202 lines
9.6 KiB
Markdown
# FunASR Agent 集成
|
||
|
||
[English](agent_integration.md)
|
||
|
||
按应用需要选择接口:HTTP 文件转写、本地 MCP 工具、桌面录音或本地字幕流水线。
|
||
这些路径的模型、选项和输出字段并不完全相同。直接在进程内推理请使用
|
||
[Python SDK](python_api_zh.md)。
|
||
|
||
## HTTP 服务
|
||
|
||
以下源码安装起点包含本页后续用到的示例脚本,命令使用 POSIX shell。
|
||
使用新目录和虚拟环境;仅安装
|
||
PyPI 包不会安装这些仓库示例。
|
||
|
||
```bash
|
||
git clone https://github.com/modelscope/FunASR.git FunASR-agent
|
||
cd FunASR-agent
|
||
git checkout --detach e19029adca384a06a2f60bd8c18cb98f1a0499aa
|
||
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
|
||
```
|
||
|
||
这只固定源码,不会锁定所有依赖和模型权重。按照[安装指南](installation/installation_zh.md)
|
||
准备 CPU/GPU 环境,记录实际依赖版本和模型版本,再验证真实请求。
|
||
`pip check` 不能代替 CUDA、音频解码或全新环境安装测试。
|
||
|
||
在该环境中选择以下**一条**命令运行。CPU 示例显式选择 SenseVoice;CUDA 方案需要
|
||
可用的 GPU 环境。保持服务终端运行,在另一个已准备好的终端执行客户端命令。
|
||
|
||
```bash
|
||
funasr-server --host 127.0.0.1 --device cpu --model sensevoice --port 8000
|
||
# 备选:使用相同端口前先停止 CPU 服务。
|
||
funasr-server --host 127.0.0.1 --device cuda --model sensevoice --port 8000
|
||
```
|
||
|
||
```bash
|
||
curl -fsS http://localhost:8000/health
|
||
curl -fsS http://localhost:8000/v1/models
|
||
```
|
||
|
||
上传文件使用 `/v1/audio/transcriptions`,运行中服务的 schema 位于 `/openapi.json`,
|
||
Swagger UI 位于 `/docs`。这个服务的 `/docs` 不是 FunASR 官网文档目录。
|
||
健康检查或模型列表返回成功,不能代替目标模型的真实转写验收。
|
||
|
||
打包的 `funasr-server` 与[示例 HTTP 服务](../examples/openai_api/README_zh.md#api-contract)
|
||
具有不同的默认值、别名和响应结构。启动和请求时都应显式指定 `model`。
|
||
`paraformer-en` 是示例服务的注册别名,不是打包服务内置别名。
|
||
SenseVoice 的 HTTP 展示文本已清除富标签,不是专用的情感或事件输出 API。
|
||
Nano 与 MLT-Nano 的语种和时间戳能力应按[模型选择指南](model_selection_zh.md)
|
||
及实际运行路径区分,不能从 HTTP 接口名称推断。打包服务的自定义模型应通过
|
||
`--model-path` 配合正确的 `--hub` 加载,并在请求中指定 `model=custom`;
|
||
任意模型 ID 不会自动成为内置 `--model` 别名。
|
||
|
||
[MOSS-Transcribe-Diarize](moss_transcribe_diarize_zh.md) 是 OpenMOSS 的第三方模型,
|
||
有独立部署要求。其原生匿名说话人标签不需要外接 VAD 或说话人模型,不要叠加这些阶段,
|
||
也不要假设所有客户端都能呈现其全部输出。
|
||
|
||
本地服务不会认证下方 SDK 的占位 key。对外提供网络访问前,按
|
||
[安全指南](../examples/openai_api/SECURITY_zh.md) 配置 TLS、鉴权、上传大小及速率限制。
|
||
CORS 不是身份认证。
|
||
|
||
## SDK 与 curl
|
||
|
||
在客户端环境单独安装 OpenAI HTTP 客户端:
|
||
|
||
```bash
|
||
python -m pip install openai
|
||
```
|
||
|
||
```python
|
||
from openai import OpenAI
|
||
|
||
client = OpenAI(base_url="http://localhost:8000/v1", api_key="local-development")
|
||
with open("meeting.wav", "rb") as audio:
|
||
result = client.audio.transcriptions.create(
|
||
model="sensevoice",
|
||
file=audio,
|
||
response_format="verbose_json",
|
||
)
|
||
print(result.text)
|
||
for segment in getattr(result, "segments", []):
|
||
print(segment)
|
||
```
|
||
|
||
```bash
|
||
curl -fsS http://localhost:8000/v1/audio/transcriptions \
|
||
-F file=@audio.wav \
|
||
-F model=sensevoice \
|
||
-F response_format=verbose_json
|
||
```
|
||
|
||
`verbose_json` 只选择格式,不会开启说话人分离、恢复富标签或保证词级对齐。
|
||
示例服务把已有 `sentence_info` 转为 segments,没有时返回空列表;打包服务可能生成
|
||
粗粒度回退分段。二者的分段时间均为秒,但 `duration` 字段语义不同。
|
||
使用时间戳前请阅读[客户端输出契约](../examples/openai_api/CLIENTS.md#response-formats)。
|
||
`json` 和 `text` 是更简单的响应格式。`spk=true` 的说话人处理属于打包 API,
|
||
不属于示例服务的请求 schema;另见[说话人标签与身份边界](speaker_emotion_zh.md)。
|
||
|
||
## 工作流集成
|
||
|
||
HTTP 节点使用 `POST` 转写端点和 multipart 请求体:二进制文件字段为 `file`,
|
||
文本字段为 `model` 与 `response_format`。把音频 URL 写入 `file` 字段不等于上传音频字节。
|
||
当 Dify/n8n 运行在容器中时,`localhost` 指该容器而非 FunASR 主机,
|
||
应配置经过预期网关、工作流实际可达的服务地址。
|
||
|
||
- [Dify、n8n 与 webhook worker](../examples/openai_api/WORKFLOWS_zh.md) 提供请求连接示例。
|
||
- [JavaScript 和 TypeScript](../examples/openai_api/JAVASCRIPT_zh.md) 提供 SDK 和 multipart 客户端。
|
||
- [Postman](../examples/openai_api/POSTMAN_zh.md) 与[冒烟测试](../examples/openai_api/smoke_test.py) 检查已部署端点。
|
||
- [Gradio](../examples/openai_api/GRADIO_zh.md) 提供浏览器上传及麦克风示例。
|
||
- [OpenAPI](../examples/openai_api/OPENAPI_zh.md) 区分仓库内示例 schema 与已部署打包服务的 schema。
|
||
|
||
在宿主框架中按这些请求和输出边界注册转写工具。URL worker 示例不是完整的安全下载器;
|
||
接受不可信 URL 前,应补充目标白名单、私网阻断、重定向校验、大小限制和超时。
|
||
响应字段以上方客户端契约为准,不要假设工作流字段表适用于两种服务实现。
|
||
这些示例不代表所有框架版本均已完成
|
||
集成验证,也不代表任意不可信下载 URL 都是安全的。
|
||
|
||
## MCP 服务
|
||
|
||
在已准备好的仓库根目录和环境中运行:
|
||
|
||
```bash
|
||
python examples/mcp_server/funasr_mcp.py
|
||
```
|
||
|
||
执行转写前,应按安装指南准备 PyTorch 和兼容的音频特征后端。
|
||
安装工具包或完成 MCP 握手,都不等于模型执行已通过验证;此脚本不需要额外安装 MCP SDK。
|
||
MCP 客户端通过 stdio 启动此脚本,它不是 HTTP 监听服务。
|
||
配置时使用已准备好的 Python 环境与仓库绝对路径:
|
||
|
||
```json
|
||
{
|
||
"mcpServers": {
|
||
"funasr": {
|
||
"command": "/path/to/FunASR-agent/.venv/bin/python",
|
||
"args": ["/path/to/FunASR-agent/examples/mcp_server/funasr_mcp.py"],
|
||
"env": {
|
||
"FUNASR_DEVICE": "cpu",
|
||
"FUNASR_MODEL": "iic/SenseVoiceSmall"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
`transcribe_audio` 接受服务端可见、已存在的本地 `audio_path`,也可以是容器中
|
||
只读挂载的路径,不接受 URL 或实时流。首次调用可能下载并加载权重。
|
||
语种提示为 `auto`、`zh`、`yue`、`en`、`ja`、`ko`;设置 `FUNASR_MODEL` 不会改变
|
||
工具 schema,也不能保证另一模型兼容该工具的 VAD 路径。
|
||
|
||
结果被格式化为 MCP `content` 中的 `type=text`,可包含分段,而不是 HTTP 响应对象。
|
||
顶层转写文本会清除富标签;可选的分段文本来自模型输出。
|
||
`FUNASR_DEVICE` 默认为 `cpu`,`FUNASR_MODEL` 默认为 `iic/SenseVoiceSmall`。
|
||
[MCP 源码与容器说明](../examples/mcp_server/README.md) 提供客户端配置和文件挂载方法。
|
||
控制助手及服务端可访问的文件;本地工具本身不是文件系统权限隔离机制。
|
||
|
||
## 桌面语音输入
|
||
|
||
保持 HTTP 服务运行,在已准备好的仓库内打开另一个终端:
|
||
|
||
```bash
|
||
python -m pip install sounddevice numpy pyperclip openai pynput
|
||
python examples/voice_input/funasr_input.py --server http://localhost:8000/v1 --model sensevoice
|
||
```
|
||
|
||
脚本切换录音状态,将 WAV 上传至 HTTP 服务,再复制转写结果供粘贴。
|
||
需要麦克风权限和音频设备支持;macOS 还可能需要辅助功能权限,Linux 自动粘贴使用
|
||
`xdotool`,剪贴板及粘贴行为随桌面会话而异。当前 `--lang` 虽然被解析,却没有传入
|
||
转写请求,因此在此路径中不是有效的语种控制项。
|
||
|
||
远程 `--server` 会把录音发送给该端点,不能无条件宣称完全离线、音频不离开本机或
|
||
达到固定延迟。部署前请阅读[配置选项](../examples/voice_input/README.md#配置选项)
|
||
及[实现](../examples/voice_input/funasr_input.py)。
|
||
|
||
## 字幕生成
|
||
|
||
这是本地 `AutoModel` 流水线,不是 HTTP 或 MCP 客户端。
|
||
在已准备好的仓库中,使用本地输入文件及适合的推理环境:
|
||
|
||
```bash
|
||
python examples/subtitle/generate_subtitle.py video.mp4
|
||
python examples/subtitle/generate_subtitle.py meeting.wav --spk
|
||
python examples/subtitle/generate_subtitle.py podcast.mp3 --format vtt
|
||
python examples/subtitle/generate_subtitle.py audio.wav --device cpu
|
||
```
|
||
|
||
默认设备为 CUDA,最后一条命令显式选择 CPU。默认模型为 SenseVoiceSmall,并使用
|
||
VAD 和标点模型;这套固定流水线不是任意模型的通用配方。`--spk` 添加 CAM++ 匿名标签,
|
||
不验证真实身份。`--format` 选择 SRT/VTT,`--output` 指定输出路径,已有输出文件会被覆盖;
|
||
需要保留旧字幕时应指定新路径。`--lang` 将非 auto
|
||
语种提示传给推理。`--max-single-segment-time` 的单位是毫秒,当前默认 `60000`。
|
||
|
||
`--segment-mode readable` 对展示字幕分组,不改写识别文本或标点;`sentence` 保留
|
||
原始模型句段分组。两种模式都不修复标点错误,也不保证音素级边界。
|
||
应检查实际时间戳是否可用,并对照原音频回放;缺少时间信息时可能回退到零时长 `(0, 0)`
|
||
区间,这不是经过验证的字幕。输入解码、模型与依赖加载、GPU 容量
|
||
仍需针对环境验证。输出语义见[字幕选项](../examples/subtitle/README.md#options)
|
||
及[说话人指南](speaker_emotion_zh.md)。
|