在单台 VPS 上搭建中英日会议转写服务:Whisper + LLM 纠错
需求
手头有一台 VPS,配置是 5.8Gi 内存、无 GPU。想要一个能整理会议记录的服务,需要支持:
- 中文、日文、英文三种语言
- 上传音频,自动出文字
- 文字要能读,不是一堆同音字错误
技术选型
视频会议:Jitsi vs 录音上传
一开始考虑过部署 Jitsi Meet,但它的完整栈(JVB + Jicofo + Prosody + Web + HAProxy)对单台 VPS 来说太重。而且“视频会议整理”的核心价值在”整理”,不在”开会”。
所以先用最简单的路径:手机录音 → 上传到 VPS → 转写。跑通后再考虑是否接实时会议。
转写:为什么选 faster-whisper
对比了几个方案:
| 方案 | CPU 可行性 | 特点 |
|---|---|---|
| faster-whisper | ✅ 支持 CPU INT8 | 生产级,有 VAD,OpenAI 兼容 API |
| whisper.cpp | ✅ 原生 CPU | 最轻量,但需要自己封装 API |
| WhisperX | ⚠️ 内存需求更高 | 支持说话人分离,适合多人会议 |
选 faster-whisper,因为它有现成的 Docker 镜像,直接暴露 OpenAI 兼容的 /v1/audio/transcriptions 接口,调用方式和其他 API 一致。
LLM:用已有的 One API
VPS 上已经有一个 Docker 版的 One API,统一管理 LLM 渠道。转写后的纠错直接复用这个网关,调用 NVIDIA 的 nemotron-3-ultra。
部署 faster-whisper
启动容器
bash
docker run -d \ --name whisper-server \ -p 9000:8000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ -e WHISPER__MODEL=Systran/faster-whisper-small \ fedirz/faster-whisper-server:latest-cpu
注意端口冲突:VPS 上的 8000 和 8080 都被占用了,所以映射到宿主机的 9000。
首次启动会自动下载模型(约 500MB),日志里出现 Application startup complete 就说明就绪。
模型选择
Whisper 的模型尺寸和内存需求:
| 模型 | 内存需求 | 中日英准确率 |
|---|---|---|
| base | ~1 GB | 一般 |
| small | ~2 GB | 较好 |
| medium | ~5 GB | 很好 |
| large | ~10 GB | 最好 |
关键:VPS 可用内存只有约 2Gi,只能跑 small。medium 及以上需要 5GB+ 内存,跑不了。
必须用多语言版本:不带 .en 后缀的模型(如 small、medium)才支持中文和日文。.en 模型只支持英文。
实测:small 模型的中文识别效果
用一段 AI 视频的配音文件测试:
原文:
text
开场:作业还在愁?AI秒批、个性化推题!正文:1.智能批改释放老师时间;2.自适应路径让每个孩子按节奏进步;3.虚拟导师24h陪伴,打破时空限制。结尾:关注我,获取更多AI教育黑科技!
Whisper 转写结果:
text
台厂,作业还在愁, AI 秒批,个性化推提,证闻,一致能批改释放老师时间,二,自适应路径,让每个孩子按节奏进步,三,虚拟导师 24H 陪伴,打破时空限制。结尾,关注我,获取更多 AI 教育非科技,警号...
对比:
| 原文 | 转写 | 问题 |
|---|---|---|
| 开场 | 台厂 | 同音字错误 |
| 推题 | 推提 | 同音字错误 |
| 正文 | 证闻 | 同音字错误 |
| 1. 智能批改 | 一致能批改 | 数字识别错误 |
| 2. 自适应 | 二,自适应 | 数字识别错误 |
| 黑科技 | 非科技 | 同音字错误 |
| #AI教育 | 警号 AI 教育 | 符号识别错误 |
结论:small 模型能抓住大意,但同音字、数字、标点错误较多。这是模型尺寸的限制,不是参数问题——加 language=zh 参数也没明显改善。
LLM 纠错:用上下文修正同音字
Whisper 的”听写”能力有限,但 LLM 能根据上下文推断出正确的字。
纠错 prompt
text
以下是一段语音转写的文字,包含同音字错误。请纠正错误。
规则:
1. 只纠正同音字和明显错别字
2. 不要改变标点、格式或措辞
3. 不要添加原文没有的内容
4. 直接输出纠正后的文字,不要解释
原文:
{text}
纠正后:
纠错效果
| 转写(错) | LLM 纠错(对) |
|---|---|
| 台厂 | 台上(接近,但还不是”开场”) |
| 推提 | 推题 ✅ |
| 证闻 | 作文(不对,应该是”正文”) |
| 一致能批改 | AI智能批改 ✅ |
| 非科技 | 黑科技 ✅ |
| 警号 | 账号(部分正确) |
部分修正成功,部分失败。原因在于 LLM 没有音频上下文,只能根据文字猜。有些错误它猜不到,因为”台上””作文”也是合理的词。
完整脚本
把 Whisper 和 LLM 纠错串起来:
python
import sys
import requests
from pathlib import Path
WHISPER_URL = "http://localhost:9000/v1/audio/transcriptions"
WHISPER_MODEL = "Systran/faster-whisper-small"
LLM_URL = "http://172.17.0.1:3000/v1/chat/completions"
LLM_TOKEN = "sk-你的OneAPI令牌"
LLM_MODEL = "nvidia/nemotron-3-ultra-550b-a55b"
CORRECTION_PROMPT = """以下是一段语音转写的文字,包含同音字错误。请纠正错误。
规则:
1. 只纠正同音字和明显错别字
2. 不要改变标点、格式或措辞
3. 不要添加原文没有的内容
4. 直接输出纠正后的文字,不要解释
原文:
{text}
纠正后:"""
def transcribe(audio_path):
with open(audio_path, "rb") as f:
r = requests.post(
WHISPER_URL,
files={"file": f},
data={"model": WHISPER_MODEL},
timeout=600,
)
r.raise_for_status()
return r.json()["text"]
def correct(text):
body = {
"model": LLM_MODEL,
"messages": [
{"role": "user", "content": CORRECTION_PROMPT.format(text=text)}
],
"max_tokens": 4096,
"temperature": 0.1,
"stream": False,
}
headers = {
"Authorization": f"Bearer {LLM_TOKEN}",
"Content-Type": "application/json",
}
r = requests.post(LLM_URL, headers=headers, json=body, timeout=300)
r.raise_for_status()
return r.json()["choices"][0]["message"]["content"]
if __name__ == "__main__":
audio_path = sys.argv[1]
raw = transcribe(audio_path)
corrected = correct(raw)
print(corrected)
Path(audio_path).with_suffix(".txt").write_text(corrected, encoding="utf-8")
运行
bash
cd /opt/rag-nvidia source venv/bin/activate python transcribe.py 会议录音.mp3
输出会保存到同名的 .txt 文件。
踩坑记录
1. 端口冲突
faster-whisper 默认映射到 8000,但 VPS 上 8000 被 nginx 占用,8080 也被占用。最终用 9000。
2. small 模型的中文准确率有限
同音字错误是模型尺寸决定的,不是参数问题。加 language=zh 也没明显改善。想要更好的中文识别,需要 medium 或 large,但内存需求超出 VPS 能力。
3. LLM 纠错不稳定
LLM 能修正部分同音字,但有些错误它猜不到(比如”台厂→开场”)。原因是缺少音频上下文。
4. LLM 会擅自改格式
如果不加严格约束,LLM 会自己加”首先””一是””二是”这类结构词。prompt 里必须明确说”不要改变标点、格式或措辞”。
5. 数字识别错误
Whisper 会把”1.”听成”一致”,把”2.”听成”二”。这是 Whisper 的已知问题,LLM 纠错能部分修复。
当前状态
| 环节 | 状态 |
|---|---|
| faster-whisper 服务 | ✅ 运行在 9000 端口 |
| small 模型 | ✅ 内存可承受 |
| 中文/日文/英文 | ✅ 自动检测 |
| LLM 纠错 | ✅ 部分修正成功 |
| 端到端脚本 | ✅ 一个命令跑完 |
下一步
Part 2 会做:
- 优化纠错 prompt:告诉 LLM 这是”视频脚本”或”会议记录”,让它有更多上下文
- 接入 n8n:上传音频自动出会议记录,发到 Telegram 或存入 WordPress
- 加摘要和待办事项:会议记录的最终价值不只是逐字稿
- 考虑升级 VPS 内存:如果要中英日三语都准确,
medium模型是必要的
