461 lines
12 KiB
Markdown
461 lines
12 KiB
Markdown
# MOSS-Transcribe-Diarize 转写服务部署
|
||
|
||
基于 [OpenMOSS/MOSS-Transcribe-Diarize](https://github.com/OpenMOSS/MOSS-Transcribe-Diarize)
|
||
0.9B 的端到端语音转写服务。单模型联合完成转写与说话人分离,输出带
|
||
`[S01]`、`[S02]` 等说话人标签和精确时间戳的结构化转写结果,适合多人对话、
|
||
会议、播客、访谈等多说话人场景。
|
||
|
||
与 Whisper 的区别:Whisper 只做语音转文字,不区分说话人;MOSS 在转写的
|
||
同时输出说话人标签,`sentence_api` 无需额外集成即可自动按说话人分句。
|
||
|
||
## 目录结构
|
||
|
||
```text
|
||
moss/
|
||
README.md 本文档
|
||
systemd/moss-transcribe.service systemd 服务模板
|
||
verify.sh 部署验证脚本
|
||
```
|
||
|
||
## 硬件与系统要求
|
||
|
||
| 项目 | 要求 |
|
||
|------|------|
|
||
| GPU | NVIDIA,显存 ≥ 8 GB(推荐 16 GB 以上) |
|
||
| CUDA | 12.9+(vLLM 方案)或 13.0+(SGLang Omni 方案) |
|
||
| 驱动 | ≥ 535(支持 CUDA 12.x)或 ≥ 570(支持 CUDA 13) |
|
||
| 系统 | Ubuntu 22.04 / 24.04 |
|
||
| Python | 3.12 |
|
||
| 其他 | FFmpeg、Git、curl |
|
||
|
||
模型权重约 2 GB(bf16),推理时加上音频编码器和 KV 缓存实际占用约 3–6 GB。
|
||
如果与其他 GPU 服务共存,需确保剩余显存充足。
|
||
|
||
## 推理后端选择
|
||
|
||
MOSS 官方提供两种推理后端,按 CUDA 版本选择:
|
||
|
||
| 后端 | CUDA 要求 | 适用场景 |
|
||
|------|-----------|----------|
|
||
| **SGLang Omni**(推荐) | CUDA 13.0+ | 官方推荐后端,长音频性能更好 |
|
||
| **vLLM** | CUDA 12.x / 13.x | CUDA 12 环境或 SGLang 安装遇到问题时使用 |
|
||
|
||
两者提供相同的 OpenAI 兼容接口(`POST /v1/audio/transcriptions`),
|
||
切换后端不需要改 `sentence_api` 的任何配置。
|
||
|
||
---
|
||
|
||
## 方案 A:SGLang Omni 部署(CUDA 13,推荐)
|
||
|
||
### 前置条件
|
||
|
||
确认驱动支持 CUDA 13:
|
||
|
||
```bash
|
||
nvidia-smi
|
||
# 查看 CUDA Version 列,需 ≥ 13.0
|
||
```
|
||
|
||
### 安装系统依赖
|
||
|
||
```bash
|
||
sudo apt update
|
||
sudo apt install -y ffmpeg git curl
|
||
```
|
||
|
||
### 安装 uv
|
||
|
||
```bash
|
||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||
# 重新加载 shell 或执行 source ~/.bashrc 使 uv 命令生效
|
||
```
|
||
|
||
### 创建目录和虚拟环境
|
||
|
||
```bash
|
||
sudo mkdir -p /opt/moss-transcribe
|
||
sudo chown "$USER":"$USER" /opt/moss-transcribe
|
||
cd /opt/moss-transcribe
|
||
|
||
git clone https://github.com/OpenMOSS/MOSS-Transcribe-Diarize.git
|
||
cd MOSS-Transcribe-Diarize
|
||
|
||
uv venv --python 3.12 .venv
|
||
source .venv/bin/activate
|
||
```
|
||
|
||
### 安装推理框架
|
||
|
||
```bash
|
||
uv pip install -e ".[torch-runtime]" --torch-backend=auto
|
||
uv pip install sglang-omni
|
||
```
|
||
|
||
### 下载模型
|
||
|
||
```bash
|
||
# 国内服务器使用 HF 镜像加速
|
||
export HF_ENDPOINT=https://hf-mirror.com
|
||
|
||
hf download OpenMOSS-Team/MOSS-Transcribe-Diarize
|
||
```
|
||
|
||
模型下载到 `~/.cache/huggingface/hub/`,约 2 GB。
|
||
|
||
### 启动服务
|
||
|
||
```bash
|
||
source /opt/moss-transcribe/MOSS-Transcribe-Diarize/.venv/bin/activate
|
||
|
||
sgl-omni serve \
|
||
--model-path OpenMOSS-Team/MOSS-Transcribe-Diarize \
|
||
--host 127.0.0.1 \
|
||
--port 8001 \
|
||
--max-running-requests 4 \
|
||
--cuda-graph-max-bs 4 \
|
||
--mem-fraction-static 0.35
|
||
```
|
||
|
||
**参数说明:**
|
||
|
||
| 参数 | 默认值 | 说明 |
|
||
|------|--------|------|
|
||
| `--host` | `127.0.0.1` | 只监听本机,不要暴露公网 |
|
||
| `--port` | `8001` | 服务端口(Whisper 用 9000,避免冲突) |
|
||
| `--max-running-requests` | `4` | 最大并发请求数;显存充足可调大 |
|
||
| `--cuda-graph-max-bs` | `4` | CUDA Graph 批大小上限,与并发数一致 |
|
||
| `--mem-fraction-static` | `0.80` | 静态显存分配比例;与其他 GPU 服务共存时调低 |
|
||
|
||
> 与 llama-server、Whisper 等其他 GPU 服务共存时,将
|
||
> `--mem-fraction-static` 设为 `0.30`–`0.40`(约 7–10 GB),避免 OOM。
|
||
> 独占 GPU 时可设为 `0.80` 获得最大并发能力。
|
||
|
||
首次启动会加载模型到 GPU,等待日志出现 `Uvicorn running on ...` 即启动完成。
|
||
|
||
---
|
||
|
||
## 方案 B:vLLM 部署(CUDA 12 / 13 兼容)
|
||
|
||
如果 CUDA 版本低于 13.0 或 SGLang Omni 安装遇到兼容性问题,改用 vLLM。
|
||
|
||
### 前置条件
|
||
|
||
同方案 A,但不要求 CUDA 13。
|
||
|
||
### 安装系统依赖和 uv
|
||
|
||
与方案 A 相同(见上文)。
|
||
|
||
### 创建目录和虚拟环境
|
||
|
||
```bash
|
||
sudo mkdir -p /opt/moss-transcribe
|
||
sudo chown "$USER":"$USER" /opt/moss-transcribe
|
||
cd /opt/moss-transcribe
|
||
|
||
uv venv --python 3.12 .venv
|
||
source .venv/bin/activate
|
||
```
|
||
|
||
### 安装 vLLM
|
||
|
||
vLLM 从 0.27.1 起包含 MOSS-Transcribe-Diarize 的模型注册。
|
||
|
||
```bash
|
||
# CUDA 13 环境
|
||
uv pip install -U "vllm[audio]" --torch-backend=auto
|
||
```
|
||
|
||
如果安装的 vLLM 版本不支持 MOSS 模型(启动时报 `model not found`),
|
||
需要使用官方指定的 pinned nightly 构建:
|
||
|
||
```bash
|
||
# CUDA 12 环境(cu129)
|
||
uv pip install -U vllm \
|
||
--torch-backend=auto \
|
||
--extra-index-url https://wheels.vllm.ai/68b4a1d582818e67adc903bf1b8fc5a5447da2fa/cu129
|
||
```
|
||
|
||
> 上游构建地址可能随版本更新,正式部署前对照
|
||
> [MOSS 官方仓库](https://github.com/OpenMOSS/MOSS-Transcribe-Diarize) Quickstart。
|
||
|
||
### 启动服务
|
||
|
||
```bash
|
||
source /opt/moss-transcribe/.venv/bin/activate
|
||
|
||
vllm serve OpenMOSS-Team/MOSS-Transcribe-Diarize \
|
||
--host 127.0.0.1 \
|
||
--port 8001 \
|
||
--trust-remote-code
|
||
```
|
||
|
||
> `--trust-remote-code` 是必需的:模型使用自定义 HuggingFace processor 代码。
|
||
|
||
首次启动会自动从 HuggingFace 下载模型权重。国内服务器建议在启动前设置:
|
||
|
||
```bash
|
||
export HF_ENDPOINT=https://hf-mirror.com
|
||
```
|
||
|
||
---
|
||
|
||
## 注册为 systemd 服务
|
||
|
||
### SGLang Omni 版本
|
||
|
||
复制服务文件到系统目录并修改实际路径:
|
||
|
||
```bash
|
||
sudo cp /path/to/repo/moss/systemd/moss-transcribe.service /etc/systemd/system/
|
||
```
|
||
|
||
确认 `ExecStart` 路径与实际安装位置一致:
|
||
|
||
```ini
|
||
ExecStart=/opt/moss-transcribe/MOSS-Transcribe-Diarize/.venv/bin/sgl-omni serve ...
|
||
```
|
||
|
||
### vLLM 版本
|
||
|
||
将 `ExecStart` 改为:
|
||
|
||
```ini
|
||
ExecStart=/opt/moss-transcribe/.venv/bin/vllm serve OpenMOSS-Team/MOSS-Transcribe-Diarize --host 127.0.0.1 --port 8001 --trust-remote-code
|
||
```
|
||
|
||
并删除 `Environment=HF_ENDPOINT=...` 以外的 SGLang 特有参数。
|
||
|
||
### 启用并启动
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable --now moss-transcribe
|
||
sudo journalctl -u moss-transcribe -f # 观察启动日志
|
||
```
|
||
|
||
首次启动会下载模型权重,看到 `running on ...` 表示服务就绪。
|
||
|
||
---
|
||
|
||
## 验证部署
|
||
|
||
使用仓库自带的验证脚本:
|
||
|
||
```bash
|
||
cd /opt/moss-transcribe
|
||
bash verify.sh
|
||
|
||
# 用真实语音文件验证(推荐)
|
||
bash verify.sh --file /path/to/multi-speaker.wav
|
||
|
||
# 同时检查 sentence_api 集成状态
|
||
bash verify.sh --api-url http://127.0.0.1:8000
|
||
```
|
||
|
||
或手动发起转写请求:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:8001/v1/audio/transcriptions \
|
||
-F model=OpenMOSS-Team/MOSS-Transcribe-Diarize \
|
||
-F file=@/path/to/test.wav \
|
||
-F response_format=verbose_json \
|
||
-F temperature=0 \
|
||
-F max_new_tokens=65536
|
||
```
|
||
|
||
**正常响应**应包含:
|
||
|
||
- `text`:完整转写文本
|
||
- `segments`:分段数组,每段包含 `start`、`end`、`text`、`speaker`
|
||
|
||
```json
|
||
{
|
||
"text": "大家好,今天我们讨论项目进度。 好的,我先汇报我这边的进展。",
|
||
"segments": [
|
||
{"start": 0.48, "end": 2.12, "text": "大家好,今天我们讨论项目进度。", "speaker": "S01"},
|
||
{"start": 2.55, "end": 5.80, "text": "好的,我先汇报我这边的进展。", "speaker": "S02"}
|
||
]
|
||
}
|
||
```
|
||
|
||
**说话人标签说明:** `S01`、`S02` 等由模型自动分配,是匿名编号。
|
||
同一说话人在同一段音频中标签一致;不同音频之间标签无关联。
|
||
|
||
---
|
||
|
||
## 接入 sentence_api
|
||
|
||
在 `sentence_api/.env` 中确认以下配置:
|
||
|
||
```dotenv
|
||
MOSS_TRANSCRIBE_URL=http://127.0.0.1:8001/v1/audio/transcriptions
|
||
MOSS_MODEL=OpenMOSS-Team/MOSS-Transcribe-Diarize
|
||
```
|
||
|
||
然后重建 API 容器:
|
||
|
||
```bash
|
||
cd /opt/oral-trainer/sentence_api
|
||
docker compose up -d --build
|
||
curl http://127.0.0.1:8000/healthz # 确认 moss_configured 为 true
|
||
```
|
||
|
||
已上传的视频可在管理后台点击"重新处理",重新转写后会带上说话人标签。
|
||
|
||
---
|
||
|
||
## 从 Whisper 切换到 MOSS
|
||
|
||
如果服务器上同时部署了 Whisper(Speaches)和 MOSS,切换步骤:
|
||
|
||
1. **停止 Whisper 服务**(释放约 4 GB 显存):
|
||
|
||
```bash
|
||
cd /opt/whisper
|
||
docker compose down
|
||
sudo systemctl disable --now whisper-transcribe # 如果注册了 systemd
|
||
```
|
||
|
||
2. **修改 `sentence_api/.env`**:
|
||
|
||
```dotenv
|
||
MOSS_TRANSCRIBE_URL=http://127.0.0.1:8001/v1/audio/transcriptions
|
||
MOSS_MODEL=OpenMOSS-Team/MOSS-Transcribe-Diarize
|
||
```
|
||
|
||
3. **重建 API**:
|
||
|
||
```bash
|
||
cd /opt/oral-trainer/sentence_api
|
||
docker compose up -d --build
|
||
```
|
||
|
||
4. **验证**:
|
||
|
||
```bash
|
||
curl http://127.0.0.1:8000/healthz
|
||
```
|
||
|
||
不需要删除 Whisper 的部署文件,后续切回只需恢复 `.env` 并重新启动。
|
||
|
||
---
|
||
|
||
## 显存分配参考
|
||
|
||
以 NVIDIA L4(24 GB)为例,MOSS 与其他服务共存的显存分配:
|
||
|
||
| 服务 | 显存占用 | 说明 |
|
||
|------|----------|------|
|
||
| llama-server | 8.4 GB | 保留 |
|
||
| MOSS (SGLang, mem-fraction=0.35) | ~8 GB | 新增 |
|
||
| Speaches (Whisper) | 4 GB | 停掉后释放 |
|
||
| **MOSS + llama-server** | ~16 GB / 24 GB | 安全 |
|
||
|
||
独占 GPU 时可将 `--mem-fraction-static` 调到 `0.80`(约 19 GB),
|
||
`--max-running-requests` 调到 `16`,支持更多并发。
|
||
|
||
---
|
||
|
||
## API 参数
|
||
|
||
| 参数 | 类型 | 默认值 | 说明 |
|
||
|------|------|--------|------|
|
||
| `file` | file | 必填 | 上传的音频/视频文件 |
|
||
| `model` | string | 服务端默认 | 模型标识符 |
|
||
| `language` | string | 未设置 | 可选的语言提示(如 `zh`、`en`) |
|
||
| `response_format` | string | `json` | `json`(原始文本)、`verbose_json`(分段)或 `text` |
|
||
| `temperature` | float | `0.0` | 采样温度,转写建议保持 `0` |
|
||
| `max_new_tokens` | int | `5120` | 最大生成 token 数;长音频/多人对话调大到 `65536` |
|
||
| `prompt` | string | 未设置 | 可选的自定义指令或热词提示 |
|
||
|
||
### 热词提示
|
||
|
||
通过 `prompt` 参数为专有名词、人名、产品名等提供提示,可提高识别准确率:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:8001/v1/audio/transcriptions \
|
||
-F model=OpenMOSS-Team/MOSS-Transcribe-Diarize \
|
||
-F file=@meeting.wav \
|
||
-F response_format=verbose_json \
|
||
-F prompt="热词提示:MOSS, Transcribe, Diarize, vLLM" \
|
||
-F temperature=0
|
||
```
|
||
|
||
---
|
||
|
||
## 常见问题
|
||
|
||
### 模型下载慢或失败
|
||
|
||
```bash
|
||
# 方法一:使用 HF 镜像
|
||
export HF_ENDPOINT=https://hf-mirror.com
|
||
hf download OpenMOSS-Team/MOSS-Transcribe-Diarize
|
||
|
||
# 方法二:配置 HTTP 代理
|
||
export HTTP_PROXY=http://your-proxy:port
|
||
export HTTPS_PROXY=http://your-proxy:port
|
||
```
|
||
|
||
### 启动报 CUDA out of memory
|
||
|
||
与其他 GPU 服务共存时,降低 `--mem-fraction-static`(如 `0.30`);
|
||
或停掉暂时不需要的服务(如 Whisper)释放显存。
|
||
|
||
### 启动报 model not found
|
||
|
||
vLLM 版本过低,不包含 MOSS 模型注册。使用官方指定的 pinned nightly
|
||
(见方案 B 安装部分),或升级到 vLLM ≥ 0.27.1。
|
||
|
||
### 长音频转写截断
|
||
|
||
请求时添加 `-F max_new_tokens=65536`,确保解码器能完整生成整段转写。
|
||
|
||
### 说话人标签偶尔混淆
|
||
|
||
多人重叠说话(同时说话)时 0.9B 模型可能偶尔混淆,这是模型本身的局限。
|
||
MOSS 采用端到端 joint diarization,比 Whisper + pyannote 拼接方案更稳定,
|
||
但如果场景对说话人准确率要求极高,可以考虑使用在线的 MOSS Pro 版本。
|
||
|
||
### 服务只监听 127.0.0.1,外部怎么访问
|
||
|
||
这是有意设计——转写服务不应暴露公网。`sentence_api` 通过 Docker 内部
|
||
网络或宿主机 `127.0.0.1` 访问即可。如果 `sentence_api` 运行在 Docker
|
||
容器里且无法访问宿主机的 `127.0.0.1:8001`,将 `MOSS_TRANSCRIBE_URL` 改为
|
||
`http://host.docker.internal:8001/v1/audio/transcriptions`(Linux 需在
|
||
`docker-compose.yml` 中添加 `extra_hosts: ["host.docker.internal:host-gateway"]`)。
|
||
|
||
---
|
||
|
||
## 更新与回滚
|
||
|
||
### 更新模型
|
||
|
||
```bash
|
||
export HF_ENDPOINT=https://hf-mirror.com
|
||
hf download OpenMOSS-Team/MOSS-Transcribe-Diarize
|
||
sudo systemctl restart moss-transcribe
|
||
```
|
||
|
||
### 更新推理框架
|
||
|
||
```bash
|
||
cd /opt/moss-transcribe/MOSS-Transcribe-Diarize
|
||
source .venv/bin/activate
|
||
uv pip install -U sglang-omni # 或 vllm
|
||
sudo systemctl restart moss-transcribe
|
||
```
|
||
|
||
### 回滚
|
||
|
||
```bash
|
||
# 回滚到上一个 systemd 配置
|
||
sudo systemctl revert moss-transcribe
|
||
|
||
# 或手动恢复备份的服务文件
|
||
sudo cp /path/to/backup/moss-transcribe.service.bak /etc/systemd/system/moss-transcribe.service
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl restart moss-transcribe
|
||
```
|