Whisper 与 faster-whisper:能力、优缺点及 SmartVoice 接入实践
一句话概述:Whisper 提供多语言语音识别能力,faster-whisper 基于 CTranslate2 提供更适合生产部署的高效推理实现;SmartVoice 将它们封装为独立的 FastAPI ASR 微服务,通过异步任务和 HMAC callback 接入“录音到报告”闭环。
一、背景:语音识别在 SmartVoice 中的位置
语音识别(Automatic Speech Recognition,ASR)负责把录音中的语音转换成文本。对于 SmartVoice,ASR 是“录音到报告”流程的入口:
用户录音
↓
音频文件存储
↓
语音识别
↓
带时间戳的文本分段
↓
LLM 分析
↓
报告生成
如果转写结果不完整、语言选择错误或时间戳不准确,后续摘要、行动项提取和报告生成都会受到影响。因此,ASR 不只是一个文件转换模块,而是整个业务链路的基础能力。
SmartVoice 当前采用 OpenAI Whisper 模型体系,并使用 faster-whisper 作为实际推理引擎。
二、Whisper 是什么
Whisper 是 OpenAI 发布的开源自动语音识别模型。它基于 Transformer 架构,使用大规模多语言音频数据训练,可以完成:
- 语音转文字;
- 多语言识别;
- 语音语言识别;
- 带时间戳的音频分段;
- 跨语言语音识别;
- 对一定程度的口音、噪声和自然表达进行处理。
Whisper 更接近端到端的序列到序列模型,而不是传统的“声学模型 + 发音词典 + 语言模型”组合:
音频
↓
音频编码器
↓
语音特征表示
↓
文本解码器
↓
文字 token 序列
模型会先从音频中提取特征,再由解码器逐步生成文字。生成过程同时参考声音特征和语言上下文,因此可以处理连续语句、停顿以及一定程度的口语表达。
Whisper 的模型规模
Whisper 提供多个模型规模:
| 模型 | 特点 |
|---|---|
tiny |
体积小、速度快,但准确率较低 |
base |
资源消耗较低,适合轻量场景 |
small |
识别质量和速度较均衡 |
medium |
识别效果更好,但资源需求明显增加 |
large-v2 |
较高的多语言识别质量 |
large-v3 |
常用的大型多语言模型,识别质量较高 |
模型越大,通常意味着识别质量越好,但同时也会带来更大的模型文件、更高的内存占用、更长的推理时间和更高的部署成本。SmartVoice 当前使用 large-v3,优先保证转写质量。
三、faster-whisper 是什么
faster-whisper 不是重新训练的语音识别模型,而是 Whisper 的高效推理实现。它使用 CTranslate2 作为底层推理引擎,对 Whisper 模型进行适合部署的转换和优化,重点改善:
- CPU 推理速度;
- GPU 推理速度;
- 内存占用;
- 模型加载和执行效率;
- INT8 等量化计算;
- 批量推理能力。
可以简单理解为:
Whisper
= 提供模型能力
faster-whisper
= 提供更高效的运行方式
使用 faster-whisper 时,项目仍然是在运行 Whisper 模型,只是没有直接采用原始 PyTorch 推理路径。
两者的关系
Whisper 模型
├── 负责语音识别能力
├── 负责多语言建模
└── 负责文本生成
faster-whisper
├── 加载 Whisper 模型
├── 使用 CTranslate2 执行推理
├── 支持量化
└── 提供更适合服务化部署的接口
因此,两者不是竞争关系,而是模型和推理框架的关系。
四、Whisper 和 faster-whisper 的优点
1. 多语言能力较强
Whisper 的核心优势之一是多语言支持。SmartVoice 当前确定的 M1 语言基线为:
zh / yue / en / ja / ko / fr / de / es / pt / ru / ar / it
对应中文、粤语、英语、日语、韩语、法语、德语、西班牙语、葡萄牙语、俄语、阿拉伯语和意大利语。
我们已经在实际运行中的 ASR 容器内检查 faster-whisper 的 tokenizer:
faster-whisper version: 1.2.1
tokenizer language count: 100
project languages missing: []
all_supported: true
这证明当前运行环境可以接受项目承诺的 12 个语言码。但需要注意,语言码被 tokenizer 接受,只能证明接口和模型配置支持这些语言,并不等于每种语言在真实业务音频中的识别质量完全相同。
2. 开源并支持本地部署
Whisper 和 faster-whisper 可以部署在自己的服务器上,SmartVoice 不必将原始音频发送给第三方云端语音服务。本地部署的好处包括:
- 音频不必离开自己的基础设施;
- 减少对第三方 API 的依赖;
- 不按音频时长支付云服务费用;
- 可以根据业务需要调整处理流程;
- 对录音、转写文本和报告数据拥有更直接的控制权。
对于会议、访谈和内部业务录音,本地推理更容易满足数据控制和隐私要求。
3. 对自然语音有较好的适应性
Whisper 不只适合标准播音式语音,对以下场景通常也有一定适应能力:
- 日常对话;
- 会议发言;
- 不同语速;
- 部分地区口音;
- 包含停顿和重复的口语表达;
- 一定程度的背景噪声。
因此,它适合 SmartVoice 这类录音后处理产品,而不只是清晰朗读识别场景。
4. 支持分段和时间戳
Whisper 可以输出多个转写分段,每个分段通常包含开始时间、结束时间和文本:
{
"start": 12.4,
"end": 18.9,
"text": "我们下周需要完成第一版方案。"
}
时间戳可以支持:
- 点击文本跳转到原始音频;
- 定位某一段对话;
- 生成更精确的摘要;
- 关联说话内容和音频时间;
- 对重点内容进行回放。
5. faster-whisper 更适合服务化部署
相比直接使用原始 Whisper 推理实现,faster-whisper 更适合作为后端微服务:
- CTranslate2 推理效率更高;
- 支持 CPU 和 GPU;
- 支持
int8等计算类型; - 可以降低内存占用;
- 可以延迟加载模型;
- 容易封装成 REST 服务;
- 适合 Docker 和任务队列部署。
五、Whisper 和 faster-whisper 的不足
1. 模型资源消耗较高
large-v3 是较大的模型,识别质量较好,但运行成本也较高:
- 模型文件较大;
- 首次加载时间较长;
- 需要较多内存;
- CPU 推理耗时明显;
- 多任务并发时需要更强的机器;
- GPU 部署需要足够的显存。
SmartVoice 当前配置如下:
模型:large-v3
设备:CPU
计算类型:int8
这种配置的部署门槛较低,不强依赖 GPU;代价是长录音处理延迟可能比较明显。
2. 不一定满足严格实时场景
Whisper 更适合“录音完成后转写”,而不是严格意义上的低延迟实时字幕。实时场景还要解决:
- 音频流切片;
- 连续上下文管理;
- 重复文本消除;
- 部分结果和最终结果合并;
- 断句;
- 网络传输;
- 推理排队;
- 延迟与准确率的平衡。
SmartVoice 当前采用异步转写:
录音完成
↓
创建转写任务
↓
后台执行 ASR
↓
callback 写入转写结果
↓
继续生成报告
这更适合会议录音、访谈录音和语音备忘录,而不是要求逐字实时显示的字幕产品。
3. 不同语言的质量并不完全一致
Whisper 支持很多语言,但“支持”不代表每种语言的准确率相同。识别质量会受到以下因素影响:
- 训练数据规模;
- 语言本身的复杂度;
- 地区口音;
- 专业词汇;
- 人名和地名;
- 语音速度;
- 音频清晰度;
- 背景噪声;
- 多人同时说话;
- 语言混杂。
例如,普通话、方言和包含大量专业术语的中文录音可能表现不同;粤语也需要使用真实粤语音频进行独立评估。不能只根据语言码存在与否判断最终质量。
4. 对噪声和多人说话不是万能的
Whisper 可以处理一定程度的噪声,但它不是专业降噪系统,也不是完整的说话人分离系统。以下场景可能明显降低识别质量:
- 多个人同时说话;
- 麦克风距离较远;
- 回声严重;
- 背景音乐较大;
- 电话录音质量较差;
- 说话者频繁打断;
- 语句不完整;
- 持续机械噪声。
高质量会议转写通常还需要结合音频预处理、降噪、语音活动检测、说话人分离、说话人识别、专有名词纠正和领域词典等能力。
5. 专有名词和数字可能出现错误
通用语音识别模型对以下内容可能不够稳定:
- 产品名称;
- 公司名称;
- 人名;
- 地址;
- 邮箱;
- 订单号;
- 金额;
- 日期;
- 缩写;
- 技术术语。
后续可以考虑增加领域词典、关键词纠正、结构化字段提取、数字格式校验、LLM 后处理和用户手动修订能力。
6. 强制语言和自动语言识别各有代价
Whisper 可以自动识别语言,也可以在调用时明确指定语言。SmartVoice 当前允许用户选择转写目标语言,并将语言码明确传给模型,这可以减少自动语言检测错误,让识别路径更确定。
限制是:如果用户选择了中文而实际录音是英文,模型可能仍按中文路径解码,从而影响结果。未来如果支持多语言混合录音,可以增加“自动识别语言”选项,或先进行语言检测再执行转写。
7. 模型更新和部署成本需要管理
生产环境还需要关注:
- 模型版本;
- faster-whisper 版本;
- CTranslate2 兼容性;
- CPU/GPU 运行时;
- 镜像体积;
- 模型缓存;
- 启动时间;
- 模型下载稳定性;
- 版本升级后的识别回归。
正式部署时,应考虑模型缓存、镜像预置或独立模型存储,避免容器启动时临时下载模型受到网络波动影响。
六、SmartVoice 的整体接入架构
SmartVoice 没有把 faster-whisper 直接嵌入主业务服务,而是将 ASR 独立为 Python FastAPI 微服务:
Flutter App
│
│ 选择转写语言、创建录音
▼
Serverpod Backend
│
│ 保存 Recording.language,创建并调度 Job
▼
ASR Adapter
│
│ HMAC REST 请求
▼
FastAPI ASR Service
│
│ 从 MinIO/S3 下载音频
▼
faster-whisper
│
│ large-v3 推理
▼
Transcript Segments
│
│ HMAC Callback
▼
Serverpod Backend
│
▼
LLM 分析与报告生成
这种拆分可以让语音模型和核心业务服务彼此隔离:
- ASR 服务可以独立扩容;
- 模型运行时不影响 Serverpod 主进程;
- 可以单独切换模型;
- 可以将 CPU ASR 和 GPU ASR 分开部署;
- 后续可以支持多个 ASR provider;
- 主业务服务只关心任务状态和转写结果。
七、SmartVoice 的具体数据流
1. App 端选择语言
用户可以在设置页面选择转写语言。默认语言为:
zh
App 端维护支持语言列表并持久化用户选择。首次使用时会展示当前支持的语言数量和默认首选语言。
2. 创建录音时写入语言
用户创建录音草稿时,App 会把当前语言传给后端。后端 Recording 数据模型增加:
language: String
默认值为 zh。每条录音拥有自己的语言配置,因此用户修改默认语言后,历史录音不会跟着变化。
3. 后端校验和持久化
Serverpod 后端验证语言码是否属于允许范围。非法语言会回落到默认语言 zh,避免非法值进入后续任务链路:
收到语言参数
↓
检查是否属于支持列表
├── 是:保存用户选择
└── 否:回落到 zh
4. JobService 调度转写任务
录音创建完成后,JobService 执行转写阶段,读取 Recording.language 并传给 ASR adapter:
Recording.language
↓
JobService.runTranscribeStage()
↓
AsrClient.submit(language)
这一步保证用户选择的语言真正进入任务执行链路,而不是只停留在设置页面。
5. AsrClient 调用 FastAPI
Serverpod 通过内部 REST 请求调用 ASR 服务,请求包含:
{
"audio_key": "recordings/2026/09/example.wav",
"language": "zh",
"callback_url": "...",
"callback_nonce": "..."
}
字段含义如下:
audio_key:对象存储中的音频 key;language:转写语言;callback_url:处理结果回传地址;callback_nonce:防止请求重放的随机值。
Serverpod 与 ASR 服务之间使用 HMAC 进行请求认证,避免客户端伪造内部转写请求。
6. ASR 服务下载音频
FastAPI ASR 服务收到请求后,根据对象存储 key 从 MinIO/S3 下载音频到临时文件,而不是让主业务服务转发整个音频文件:
Serverpod
└── 发送 audio_key
ASR 服务
└── 使用内部存储凭证下载音频到临时文件
这种方式可以减少主服务的内存和网络压力,并方便 ASR 服务独立重试。下载过程包含重试逻辑,应对临时网络异常。
7. faster-whisper 执行推理
模型使用延迟加载方式:
ASR 服务启动
↓
不立即加载 large-v3
↓
收到第一条任务时加载模型
↓
后续任务复用已加载模型
模型加载通过锁保护,避免多个并发请求重复初始化。当前配置为:
ASR_WHISPER_MODEL=large-v3
ASR_WHISPER_DEVICE=cpu
ASR_WHISPER_COMPUTE_TYPE=int8
实际推理时,语言参数会传给 faster-whisper:
segments, info = model.transcribe(
audio_path,
language=request.language,
)
模型输出的分段会转换为 SmartVoice 内部的转写分段结构。
8. Callback 写回 Serverpod
ASR 处理完成后,通过 callback 将结果回传给 Serverpod,而不是让主请求一直等待。
成功结果示例:
{
"status": "succeeded",
"segments": [
{
"start": 0.0,
"end": 4.8,
"text": "今天我们讨论项目进度。"
}
]
}
失败结果包含类型化错误信息:
{
"status": "failed",
"error_code": "ASR_TRANSCRIBE_FAILED",
"message": "转写任务执行失败"
}
Callback 使用时间戳、nonce 和重放保护机制,避免旧请求或重复请求被重复处理。Serverpod 收到成功 callback 后,将分段写入 TranscriptSegment,再进入 LLM 分析和报告生成阶段。
八、当前实现已经验证的内容
当前已经验证:
- ASR 服务可以正常运行;
- 实际运行版本为 faster-whisper
1.2.1; - tokenizer 支持项目当前的 12 个语言码;
- 默认语言
zh有效; - App 到后端的语言参数链路已打通;
Recording.language可以持久化;- JobService 可以将语言传给 ASR;
- ASR REST 请求包含语言参数;
- faster-whisper 推理调用使用该语言;
- HMAC 请求和 callback 机制已接入;
- 后端和 App 相关测试已通过。
九、当前尚未验证的边界
以下内容不能仅凭 tokenizer 和链路测试得出结论:
- 12 种语言在真实业务音频上的准确率;
- 粤语、阿拉伯语、俄语等语言的领域识别质量;
- 多人会议中的说话人区分能力;
- 长录音在 CPU 环境下的平均处理时长;
- 并发任务下的吞吐量;
- 不同录音格式和采样率下的稳定性;
- 专有名词、数字和产品名称的识别准确率。
换句话说,当前已经证明“工程链路和语言接口可用”,但还没有完成“每种语言的真实音频质量基准”。
十、建议的后续评估指标
1. 词错误率
英文等语言通常使用 WER:
$$ WER = \frac{S + D + I}{N} $$
其中:
- $S$:替换数量;
- $D$:删除数量;
- $I$:插入数量;
- $N$:参考文本中的词数。
2. 字错误率
中文通常更适合关注 CER。计算形式与 WER 类似,但以字为基本单位:
$$ CER = \frac{S + D + I}{N} $$
3. SmartVoice 业务指标
除了通用准确率,还应测试:
- 人名识别准确率;
- 数字和金额识别准确率;
- 日期识别准确率;
- 任务和行动项提取准确率;
- 说话人切换位置;
- 时间戳偏差;
- 单位音频处理耗时;
- 失败率和重试成功率。
对 SmartVoice 来说,最终目标不只是“文字看起来正确”,还要看这些文字能否支持后续报告生成。
十一、总结
Whisper 提供了较强的多语言语音识别能力,适合录音转写、会议记录、访谈整理和语音备忘录。它的主要价值包括:
- 开源;
- 支持本地部署;
- 支持多语言;
- 可以输出带时间戳的分段;
- 对自然语音具有较好的适应性;
- 可以作为后续文本分析的输入。
faster-whisper 则解决了 Whisper 原始推理在部署效率方面的问题。它基于 CTranslate2,支持 CPU/GPU 和量化计算,更适合封装为生产级 ASR 服务。
但它并不是没有代价:大模型资源消耗高,CPU 推理延迟明显,不一定适合严格实时场景;不同语言、口音和录音环境的识别质量也会存在差异。
SmartVoice 当前采用的接入方式是:
App 设置语言
→ Recording.language 落库
→ JobService 调度
→ AsrClient HMAC 请求
→ FastAPI ASR 服务
→ MinIO 下载音频
→ faster-whisper large-v3 推理
→ callback 返回分段
→ Serverpod 写入转写结果
→ LLM 生成报告
这套架构将模型推理与主业务服务解耦,同时保留了语言选择、任务重试、内部认证和错误回传能力。当前工程链路已经完成并通过验证,下一步应基于 12 种语言的真实音频,继续评估识别质量、延迟、资源消耗和并发吞吐能力。