faster-whisper:更快的 Whisper 转写引擎

faster-whisper 基于 CTranslate2 重新实现 Whisper 推理,适合在本地或服务器上做更快、更省显存的语音转文字。

faster-whisper 是 SYSTRAN 维护的 Whisper 推理实现。它用 CTranslate2 作为后端,在保持 Whisper 使用方式接近的同时,把推理速度、显存占用和部署灵活性做得更适合工程场景。

如果你已经用过 openai/whisper,可以把 faster-whisper 理解成一个更偏生产环境的替代方案:接口仍然围绕模型加载、音频转写、分段结果展开,但底层执行效率更高,也更容易按 CPU、GPU、量化和批处理策略做取舍。

它解决什么问题

Whisper 的效果很好,但原版实现直接部署时经常会遇到几个问题:

  1. 长音频转写耗时明显。
  2. GPU 显存占用偏高。
  3. CPU 环境可用,但速度不一定理想。
  4. 批量处理大量音视频时,吞吐不容易压上去。

faster-whisper 主要就是围绕这些问题做优化。项目 README 中说明,在相同精度下,它可以比 openai/whisper 快到 4 倍,并且内存占用更低;如果使用 8-bit 量化,速度还可以进一步提升。

安装

常规 Python 环境里可以直接安装:

1
pip install faster-whisper

如果要使用 GPU,需要确认本机 CUDA、cuDNN 与 CTranslate2 版本匹配。这里最容易踩坑的是显卡驱动和 CUDA 运行时版本不一致:代码本身可能没问题,但运行时会在加载模型或首次推理时失败。

基本用法

最小示例很直接:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from faster_whisper import WhisperModel

model_size = "large-v3"

model = WhisperModel(model_size, device="cuda", compute_type="float16")

segments, info = model.transcribe("audio.mp3", beam_size=5)

print("Detected language '%s' with probability %f" % (info.language, info.language_probability))

for segment in segments:
    print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))

这里有几个关键参数:

参数 作用
model_size 选择 Whisper 模型规格,例如 smallmediumlarge-v3
device 推理设备,常见值是 cudacpu
compute_type 计算精度,例如 float16int8_float16int8
beam_size 解码搜索宽度,通常越大越稳,但速度越慢

如果你的目标是本地快速转写,通常可以先从 mediumlarge-v3 开始测试。显存紧张时,再考虑量化。

CPU 和 GPU 怎么选

有 NVIDIA GPU 时,优先用:

1
model = WhisperModel("large-v3", device="cuda", compute_type="float16")

显存不够时可以换成:

1
model = WhisperModel("large-v3", device="cuda", compute_type="int8_float16")

没有 GPU 时,可以在 CPU 上跑:

1
model = WhisperModel("small", device="cpu", compute_type="int8")

CPU 模式更适合轻量任务、后台低频任务,或者没有显卡的服务器。要处理大量长音频,GPU 仍然更合适。

批量转写

faster-whisper 也提供批量转写能力。批处理适合大量短音频,或者需要提升 GPU 吞吐的场景:

1
2
3
4
5
6
7
8
from faster_whisper import WhisperModel, BatchedInferencePipeline

model = WhisperModel("turbo", device="cuda", compute_type="float16")
batched_model = BatchedInferencePipeline(model=model)
segments, info = batched_model.transcribe("audio.mp3", batch_size=16)

for segment in segments:
    print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))

batch_size 不是越大越好。它会提高吞吐,但也会增加显存压力。实际部署时建议从 4、8、16 这样的值逐步测试,找到机器能稳定承受的点。

VAD 和词级时间戳

语音转文字经常会遇到长静音、背景噪声和字幕对齐问题。faster-whisper 内置了一些实用参数,可以直接在转写时启用。

启用 VAD:

1
segments, info = model.transcribe("audio.mp3", vad_filter=True)

获取词级时间戳:

1
2
3
4
5
segments, info = model.transcribe("audio.mp3", word_timestamps=True)

for segment in segments:
    for word in segment.words:
        print("[%.2fs -> %.2fs] %s" % (word.start, word.end, word.word))

VAD 适合处理会议录音、播客、直播回放这类包含长静音的音频。词级时间戳则适合生成字幕、做逐字稿校对,或者后续接入播放器高亮。

模型怎么选

模型选择主要看三件事:准确率、速度、机器资源。

场景 建议
快速测试 smallmedium
中文内容质量优先 large-v3
GPU 显存紧张 int8_float16 或更小模型
CPU 跑后台任务 小模型加 int8
批量短音频 尝试 BatchedInferencePipeline

如果是中文语音,建议优先测试 large-v3。如果机器压力太大,再降模型规格或使用量化。不要一开始就只看速度,转写质量下降后,人工校对时间可能会把省下来的推理时间抵消掉。

适合的使用场景

faster-whisper 很适合这些任务:

  1. 视频字幕生成。
  2. 播客、会议、课程录音转文字。
  3. Bilibili、YouTube 等视频的本地转写流程。
  4. 批量音频归档和检索。
  5. 把语音内容接入 RAG、知识库或搜索系统。

它不直接解决说话人分离、摘要、章节切分这些上层问题,但可以作为稳定的转写层。后面可以再接 pyannote 做说话人分离,接 LLM 做摘要和结构化整理。

部署建议

实际使用时,可以按这个顺序调试:

  1. 先用一段 1 到 3 分钟的音频确认环境能跑通。
  2. 再换成目标语言和目标音质的样本测试准确率。
  3. 确认显存占用,再决定是否启用量化。
  4. 长音频先切分,避免一次性任务失败后重跑成本过高。
  5. 输出结果同时保存 TXT 和 SRT,后续校对更方便。

如果是服务器任务,最好把模型加载放在服务启动阶段,不要每次请求都重新加载模型。模型加载本身会消耗时间,频繁加载也容易让显存管理变得不稳定。

OpenAI Whisper 的模型定位与使用边界

openai/whisper 是 OpenAI 开源的语音识别项目,论文方向是 Robust Speech Recognition via Large-Scale Weak Supervision。它让很多人第一次低门槛获得了可本地运行的多语言语音转写能力。

今天虽然有 faster-whisper、whisper.cpp、各种云端 ASR 和新一代语音模型,但原版 Whisper 仍然是理解开源 ASR 生态的起点。

它适合做什么

Whisper 常见用途包括:

  • 音频转文字;
  • 视频字幕生成;
  • 播客转写;
  • 会议记录;
  • 多语言语音识别;
  • 语音翻译到英文;
  • 字幕草稿和内容检索。

它的优势是鲁棒、多语言、开源、生态成熟。很多后续工具都是围绕 Whisper 模型或接口做优化。

使用边界

Whisper 不是万能听写员:

  • 噪音、口音、多人重叠会影响结果;
  • 专业术语和人名需要后处理;
  • 长音频要分段;
  • 时间戳不一定总是完美;
  • 原版推理速度和资源占用不一定适合生产;
  • 隐私音频要注意本地处理和存储。

如果你需要高吞吐生产服务,可能要看 faster-whisper、whisper.cpp、批处理、量化和 GPU 部署。

适合谁用

适合:

  • 做字幕和转写工具;
  • 处理播客、课程、会议录音;
  • 研究 ASR 模型;
  • 搭建本地语音转文字服务;
  • 做多语言内容整理。

如果只是偶尔转写一段音频,托管服务可能更省事;如果你在意隐私和成本,本地部署更有吸引力。

参考来源

在 NAS 上部署 faster-whisper

把 Whisper 部署到 NAS,最适合的场景不是追求“实时会议字幕”,而是把家庭录像、访谈、课程录音、播客和会议文件放进一个私有目录后,按需或批量生成文字稿和 SRT 字幕。

对大多数 NAS,推荐从 faster-whisper 开始。它使用 CTranslate2 推理引擎,能使用 CPU 或 CUDA GPU,并支持量化、VAD 静音过滤和词级时间戳。先用小模型跑通流程,再按准确率和等待时间决定是否升级模型。

先说结论

NAS 本地语音识别的最稳妥路线是:

1
2
3
4
5
6
准备输入 / 输出目录
-> 安装 ffmpeg 与 faster-whisper
-> 用短音频跑 small 或 base
-> 检查 TXT 和 SRT
-> 开启 VAD 过滤
-> 再做批量任务、GPU 加速或 Docker 封装

没有独显的 NAS 也能转写,但应把它当成离线任务。若要频繁转写长视频、多人录音或追求更快响应,GPU 的作用通常比单纯增加硬盘容量更明显。

模型怎么选

Whisper 有不同大小的模型。模型越大,通常越能处理口音、噪声和复杂语境,但推理更慢、内存需求也更高。

模型 NAS 上的建议 适合场景
tiny / base 测试流程、低功耗 NAS 清晰短音频、快速预览
small 多数家庭 NAS 的起点 普通中文会议、课程、视频字幕
medium CPU NAS 通常较慢;有 GPU 再尝试 噪声较多、专业术语较多的音频
large-v3 / turbo 更适合显存充足的 GPU 主机 高质量离线转写、长音频批处理

不要只以模型名判断效果。录音清晰度、说话人重叠、背景音乐、麦克风距离和专有名词,往往比从 small 升到更大模型更影响最终文字稿。

目录规划:输入、输出和模型缓存分开

以 Linux NAS 为例:

1
2
3
mkdir -p ~/asr/inbox
mkdir -p ~/asr/out
mkdir -p ~/asr/models

建议约定:

1
2
3
~/asr/inbox/   放 MP3、M4A、WAV、MP4 等输入文件
~/asr/out/     放 TXT、SRT、JSON 等结果
~/asr/models/  放下载的模型缓存

批量任务最怕输入、输出和模型缓存混在同一个目录里。分开后,备份、清理和权限控制都更简单。

安装环境

在 Debian/Ubuntu 类 NAS 或 Linux 容器内,先安装基础工具:

1
2
sudo apt update
sudo apt install -y python3 python3-venv ffmpeg

创建独立虚拟环境:

1
2
3
4
python3 -m venv ~/asr/.venv
source ~/asr/.venv/bin/activate
pip install --upgrade pip
pip install faster-whisper

ffmpeg 用来读取常见音视频格式。没有它时,MP4、M4A 或某些编码格式可能无法正常转码或读取。

最小转写脚本

~/asr/transcribe.py 写入下面代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
from pathlib import Path
from faster_whisper import WhisperModel

input_file = Path("/home/USER/asr/inbox/sample.mp3")
output_dir = Path("/home/USER/asr/out")
output_dir.mkdir(parents=True, exist_ok=True)

model = WhisperModel(
    "small",
    device="cpu",
    compute_type="int8",
    download_root="/home/USER/asr/models",
)

segments, info = model.transcribe(
    str(input_file),
    language="zh",
    vad_filter=True,
    word_timestamps=True,
)

segments = list(segments)

lines = []
for segment in segments:
    text = segment.text.strip()
    lines.append(text)
    print(f"[{segment.start:.2f} -> {segment.end:.2f}] {text}")

(output_dir / f"{input_file.stem}.txt").write_text(
    "\n".join(lines), encoding="utf-8"
)

把代码中的 /home/USER 改成你的实际 Linux 用户目录,然后运行:

1
2
source ~/asr/.venv/bin/activate
python ~/asr/transcribe.py

第一次运行时,faster-whisper 会下载对应模型。模型下载成功后会保存在你指定的 download_root,以后不需要重复下载。

CPU NAS 推荐参数

没有 GPU 时,优先控制模型大小和计算精度:

1
2
3
4
5
6
model = WhisperModel(
    "small",
    device="cpu",
    compute_type="int8",
    download_root="/home/USER/asr/models",
)

int8 通常适合作为 CPU 推理的起点。若 NAS 同时还承担文件同步、照片索引、下载或媒体服务,建议:

  • 先从 basesmall 开始;
  • 避免同时跑多个转写任务;
  • 长视频安排在低峰时段;
  • 观察系统内存、CPU 温度和 swap;
  • 不要在同一时段让 NAS 大量转码、校验和转写同时进行。

CPU NAS 的目标应是“稳定完成”,而不是实时追赶音频播放进度。

有 NVIDIA GPU 时怎么配置

NAS 或 Linux 主机有可用 NVIDIA GPU 时,可尝试:

1
2
3
4
5
6
model = WhisperModel(
    "small",
    device="cuda",
    compute_type="float16",
    download_root="/home/USER/asr/models",
)

显存紧张时可以尝试:

1
2
3
4
5
6
model = WhisperModel(
    "small",
    device="cuda",
    compute_type="int8_float16",
    download_root="/home/USER/asr/models",
)

实际可用的 compute_type 取决于 CTranslate2、CUDA、驱动和 GPU。先用短音频验证,再处理长文件。若放进 Docker,还需要先确认容器能看到 GPU;容器内 nvidia-smi 都不可用时,转写程序也不会获得 CUDA 加速。

为什么建议开启 VAD 过滤

VAD(语音活动检测)会跳过明显无语音的片段。对会议录像、长暂停、背景音乐或录音头尾空白较多的文件,通常有两点好处:

  • 减少无意义的推理时间;
  • 降低静音段被识别成无关文字的概率。

在 faster-whisper 中启用:

1
2
3
4
segments, info = model.transcribe(
    "input.mp3",
    vad_filter=True,
)

但 VAD 不是“绝不出错”的开关。说话声音很轻、音乐与人声混杂、电话录音断续时,应抽样检查 VAD 是否误切掉了有效内容。

生成 SRT 字幕

Whisper 的每个 segment 都带有起止时间。可以在上述脚本基础上输出简单 SRT:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
def srt_time(seconds: float) -> str:
    milliseconds = round(seconds * 1000)
    hours, milliseconds = divmod(milliseconds, 3_600_000)
    minutes, milliseconds = divmod(milliseconds, 60_000)
    seconds, milliseconds = divmod(milliseconds, 1000)
    return f"{hours:02}:{minutes:02}:{seconds:02},{milliseconds:03}"

blocks = []
for index, segment in enumerate(segments, start=1):
    blocks.append(
        f"{index}\n"
        f"{srt_time(segment.start)} --> {srt_time(segment.end)}\n"
        f"{segment.text.strip()}\n"
    )

(output_dir / f"{input_file.stem}.srt").write_text(
    "\n".join(blocks), encoding="utf-8"
)

如果要做逐词高亮或更精细剪辑,可以读取 word_timestamps=True 后的词级时间戳。但词级结果也需要人工抽查,尤其是中英混说、人名、地名和缩写。

批量转写不要一口气并发跑满

批量文件建议按队列串行或低并发处理:

1
2
3
for file in ~/asr/inbox/*; do
  python ~/asr/transcribe.py "$file"
done

实际脚本中应补上扩展名过滤、成功/失败记录和跳过已完成文件的逻辑。最重要的是:先处理 5 个样本,确认输出目录、语言、模型和字幕时间轴都正确,再启动整批任务。

NAS 上盲目并发多个 large-v3 转写任务,很容易让内存、GPU 显存或散热成为瓶颈。转写服务如果还要和相册、备份、下载器共用资源,更应限制队列。

Docker 怎么用才稳

许多 NAS 更适合用 Container Manager 或 Docker 管理服务。建议先在宿主机或普通 Linux 容器里跑通 Python 版本,再封装容器。容器化时至少要做到:

  • 将输入目录只读挂载;
  • 将输出目录单独可写挂载;
  • 将模型缓存目录持久化挂载;
  • 固定 faster-whisper、CTranslate2 和 Python 版本;
  • 若使用 GPU,先验证容器运行时和设备透传。

不要把整个 NAS 的共享目录以读写方式挂入转写容器。语音识别任务只需要读取音视频和写入文字结果,权限越小,误操作影响越小。

准确率与隐私边界

本地部署的优势是音频不必上传到第三方服务,但这不代表输出天然准确。Whisper 可能听错人名、专业术语、数字和静音段,也可能在噪声或长空白时出现不可靠文本。

以下内容应人工复核:

  • 医疗、法律、财务和安全记录;
  • 对外发布的字幕;
  • 访谈引用和会议决议;
  • 人名、金额、日期、电话号码和产品型号。

保留原始音频,并把文字稿视为初稿,是比“转写后立刻删除原文件”更稳妥的流程。

一套适合 NAS 的默认配置

如果你没有独显:

1
2
3
4
5
model: base 或 small
device: cpu
compute_type: int8
vad_filter: true
并发: 1

如果你有可用 NVIDIA GPU:

1
2
3
4
5
model: small 起步,按效果再试 medium
device: cuda
compute_type: float16 或 int8_float16
vad_filter: true
并发: 从 1 开始压测

先用同一段 10 到 30 分钟的真实录音比较耗时、漏字、错字和字幕时间轴,再决定是否升级模型。不要只用几秒钟的清晰样本来判断 NAS 是否适合长期转写。

小结

faster-whisper 的价值在于把 Whisper 变成更适合长期使用的转写组件。它不是换一个模型,而是换一套更高效的推理后端和工程接口。

对于个人工作流,可以用它快速把视频、会议、课程音频变成文本。对于服务端任务,可以通过 GPU、量化、批处理和 VAD 做性能调优。只要机器环境配置正确,它会比原版 Whisper 更适合承担稳定、批量的语音转文字工作。

项目地址:https://github.com/SYSTRAN/faster-whisper