MOSS-Transcribe-Diarize 转写服务部署
基于 OpenMOSS/MOSS-Transcribe-Diarize
0.9B 的端到端语音转写服务。单模型联合完成转写与说话人分离,输出带
[S01]、[S02] 等说话人标签和精确时间戳的结构化转写结果,适合多人对话、
会议、播客、访谈等多说话人场景。
与 Whisper 的区别:Whisper 只做语音转文字,不区分说话人;MOSS 在转写的
同时输出说话人标签,sentence_api 无需额外集成即可自动按说话人分句。
目录结构
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:
nvidia-smi
# 查看 CUDA Version 列,需 ≥ 13.0
安装系统依赖
sudo apt update
sudo apt install -y ffmpeg git curl
sudo apt install -y ninja-build
安装 uv
curl -LsSf https://astral.sh/uv/install.sh | sh
# 重新加载 shell 或执行 source ~/.bashrc 使 uv 命令生效
创建目录和虚拟环境
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
安装推理框架
uv pip install -e ".[torch-runtime]" --torch-backend=auto
uv pip install sglang-omni
uv pip install ninja
ninja是 FlashInfer JIT 编译 CUDA kernel 所需的构建工具,缺少它会在启动时 报FileNotFoundError: 'ninja'。必须用
apt install ninja-build安装系统级 ninja(/usr/bin/ninja)。uv pip install ninja只安装到虚拟环境.venv/bin/,systemd 服务的 PATH 不包含它。如果只能用 venv 里的 ninja,在 systemd 服务的[Service]段加:Environment=PATH=/opt/moss-transcribe/MOSS-Transcribe-Diarize/.venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
下载模型
# 国内服务器使用 HF 镜像加速
export HF_ENDPOINT=https://hf-mirror.com
hf download OpenMOSS-Team/MOSS-Transcribe-Diarize
模型下载到 ~/.cache/huggingface/hub/,约 2 GB。
启动服务
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 \
--mem-fraction-static 0.35
参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
--host |
127.0.0.1 |
只监听本机,不要暴露公网 |
--port |
8001 |
服务端口(Whisper 用 9000,避免冲突) |
--mem-fraction-static |
自动 | 静态显存分配比例(作用于所有 SGLang engine stage);与其他 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 相同(见上文)。
创建目录和虚拟环境
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 的模型注册。
# CUDA 13 环境
uv pip install -U "vllm[audio]" --torch-backend=auto
如果安装的 vLLM 版本不支持 MOSS 模型(启动时报 model not found),
需要使用官方指定的 pinned nightly 构建:
# CUDA 12 环境(cu129)
uv pip install -U vllm \
--torch-backend=auto \
--extra-index-url https://wheels.vllm.ai/68b4a1d582818e67adc903bf1b8fc5a5447da2fa/cu129
上游构建地址可能随版本更新,正式部署前对照 MOSS 官方仓库 Quickstart。
启动服务
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 下载模型权重。国内服务器建议在启动前设置:
export HF_ENDPOINT=https://hf-mirror.com
注册为 systemd 服务
SGLang Omni 版本
复制服务文件到系统目录并修改实际路径:
sudo cp /path/to/repo/moss/systemd/moss-transcribe.service /etc/systemd/system/
确认 ExecStart 路径与实际安装位置一致:
ExecStart=/opt/moss-transcribe/MOSS-Transcribe-Diarize/.venv/bin/sgl-omni serve ...
vLLM 版本
将 ExecStart 改为:
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 特有参数。
启用并启动
sudo systemctl daemon-reload
sudo systemctl enable --now moss-transcribe
sudo journalctl -u moss-transcribe -f # 观察启动日志
首次启动会下载模型权重,看到 running on ... 表示服务就绪。
验证部署
使用仓库自带的验证脚本:
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
或手动发起转写请求:
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
{
"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 中确认以下配置:
MOSS_TRANSCRIBE_URL=http://127.0.0.1:8001/v1/audio/transcriptions
MOSS_MODEL=OpenMOSS-Team/MOSS-Transcribe-Diarize
然后重建 API 容器:
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,切换步骤:
-
停止 Whisper 服务(释放约 4 GB 显存):
cd /opt/whisper docker compose down sudo systemctl disable --now whisper-transcribe # 如果注册了 systemd -
修改
sentence_api/.env:MOSS_TRANSCRIBE_URL=http://127.0.0.1:8001/v1/audio/transcriptions MOSS_MODEL=OpenMOSS-Team/MOSS-Transcribe-Diarize -
重建 API:
cd /opt/oral-trainer/sentence_api docker compose up -d --build -
验证:
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),支持更多并发。
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 参数为专有名词、人名、产品名等提供提示,可提高识别准确率:
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
常见问题
模型下载慢或失败
# 方法一:使用 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"])。
更新与回滚
更新模型
export HF_ENDPOINT=https://hf-mirror.com
hf download OpenMOSS-Team/MOSS-Transcribe-Diarize
sudo systemctl restart moss-transcribe
更新推理框架
cd /opt/moss-transcribe/MOSS-Transcribe-Diarize
source .venv/bin/activate
uv pip install -U sglang-omni # 或 vllm
sudo systemctl restart moss-transcribe
回滚
# 回滚到上一个 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