Files
mediaplayer/moss/README.md
2026-09-11 12:15:51 +08:00

13 KiB
Raw Blame History

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,切换步骤:

  1. 停止 Whisper 服务(释放约 4 GB 显存):

    cd /opt/whisper
    docker compose down
    sudo systemctl disable --now whisper-transcribe   # 如果注册了 systemd
    
  2. 修改 sentence_api/.env:

    MOSS_TRANSCRIBE_URL=http://127.0.0.1:8001/v1/audio/transcriptions
    MOSS_MODEL=OpenMOSS-Team/MOSS-Transcribe-Diarize
    
  3. 重建 API:

    cd /opt/oral-trainer/sentence_api
    docker compose up -d --build
    
  4. 验证:

    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