先算一笔账:在线转写服务按音频时长计费,一小时的会议录音或播客动辄几十元,而且音频要完整上传到对方服务器,隐私敏感的内容未必敢传。换一条路:在同一台电脑的显卡上,13 分钟音频 59 秒转完,不联网、不按分钟付费——这是 faster-whisper 的官方基准数字(int8 精度),开批量推理还能压到 16 秒。
这个工具是开源的,地址 https://github.com/SYSTRAN/faster-whisper ,本质是基于 CTranslate2 对 OpenAI Whisper 的重实现:同精度下比 openai/whisper 快至多 4 倍、更省内存,CPU 与 GPU 上都能再做 8-bit 量化进一步提效。它解决的是最普遍的那类需求:会议录音出纪要底稿、播客与访谈出文字稿、视频出字幕源文件,这些都只要「把语音变成带时间戳的原文」,不联网、不付费、不传第三方,本地一张消费级显卡就够。本篇按「选型、安装、最小脚本、调参提速、进阶玩法」五步把它部署到你自己机器上。
先交代两件事,省得读歪。其一,口径:本文的速度与显存数字,凡未单独说明,均出自 faster-whisper 官方 README 基准表,条件是 large-v2 模型、beam_size=5、转写 13 分钟音频、NVIDIA RTX 3070 Ti 8GB 显卡、CUDA 12.4;CPU 基准则为 small 模型、Intel Core i7-12700K 8 线程、同一段 13 分钟音频。其二,分工:本篇讲的是本地转写(听写),输入语音、输出原文文字;「边听边译」的同声传译是另一条技术线,站内有专文,别拿本篇当同传教程。
一、选型:先看显存,再挑模型
动手前回答三个问题:有没有 NVIDIA 显卡?显存几 GB?要不要实时出字?三个问题各对应一条分支:有卡看显存决定模型档位与精度;没卡直接走 CPU 路线,模型与精度都要降档;要实时出字的,选型时就要留好 VAD 与小模型的组合,本篇第五步会展开。答案决定整套配置,先别急着复制命令。
先看模型档位(OpenAI README 口径):large 共 1550M 参数,OpenAI 称约需 10GB 显存;large-v3 的 fp16 权重约 3.1GB,int8 量化后约 1.55GB;turbo 809M 参数、约 6GB,速度约 8 倍但不支持翻译任务;medium 769M、约 5GB;small 244M、约 2GB。模型名传给 WhisperModel 就会自动从 Hugging Face 下载现成的 CTranslate2 格式权重(Systran/faster-whisper-large-v3 等各档位都有),无需手动转换。
按显存对号入座:
- 24GB 显存:large-v3 + float16 + beam_size=5,质量优先,这是实测文公认的上限配置。
- 8GB 显存:large-v3 + int8_float16;实测仍不够就把模型降到 medium。
- 纯 CPU:small 或 base + int8。
两个提醒。第一,GPU 上不要写纯 int8——那是 CPU 档位。CTranslate2 文档写明,int8 量化在 NVIDIA GPU 上需要计算能力 7.0 以上或等于 6.1;计算能力 6.0 及以下的老卡(Maxwell、Pascal 一代)请求 int8 或 float16 都会静默回退 float32,不报错、只变慢变吃显存,这种卡不如直接走 CPU int8 路线。6.1 这档(GTX 10 系一代对应的架构)可用 int8_float32。第二,想核实精度是否真生效,加载模型时看日志,或设环境变量 CT2_VERBOSE=1,也可以调 ctranslate2.get_supported_compute_types("cuda") 查当前卡支持哪些计算类型——老卡的降级是静默的,不查不知道。
顺带交代一个新选项,一段带过:2026 年 10 月,NVIDIA 开放了 Nemotron 3.5 Transcribe 的权重,支持 40 语言转写,约 4.3B 激活的 MoE 架构,GGUF 权重已发布,可在 RTX Spark 类设备上本地跑;其工具链尚在演进早期,想换新引擎的读者看本批开源列那篇的跑分与部署细节,本篇仍以 faster-whisper 为主线。
选型时还会撞上 compute_type 这个参数,可选值按 CTranslate2 文档有十个:default、auto、int8、int8_float32、int8_float16、int8_bfloat16、int16、float16、float32、bfloat16。不用背,传 auto 会自动选当前系统支持的最快类型;int16 只有 Intel CPU 配 MKL 后端才支持,bfloat16 要计算能力 8.0 以上。量化也直接作用在磁盘体积上:CTranslate2 以 base Transformer 为例,float32 权重 364MB,int8_float16 压到 95MB,文档原话是模型在磁盘上小 4 倍、精度损失极小——这也是 8GB 卡能装下 large-v3 int8 版的原因。
二、安装:一行 pip 与 GPU 两件套
CPU 用户一行搞定:
pip install faster-whisperGPU 用户要补两件套:CUDA 12 版 cuBLAS 与 CUDA 12 版 cuDNN 9。最新版 ctranslate2 只认 CUDA 12 加 cuDNN 9 的组合,装了 cuDNN 8 会初始化 GPU 失败。Linux 上可以 pip 直接装 NVIDIA 库:
pip install nvidia-cublas-cu12 nvidia-cudnn-cu12==9.*
export LD_LIBRARY_PATH=$(python3 -c 'import os, nvidia.cublas, nvidia.cudnn; print(os.path.dirname(nvidia.cublas.__path__[0]) + "/cublas/lib:" + os.path.dirname(nvidia.cudnn.__path__[0]) + "/cudnn/lib")')注意先设 LD_LIBRARY_PATH 再启动 Python。不想折腾本地环境,直接用官方 NVIDIA 镜像 nvidia/cuda:12.3.2-cudnn9-runtime-ubuntu22.04,cuBLAS 与 cuDNN 都已内置。旧环境实在动不了也有退路:CUDA 11 加 cuDNN 8 组合降级 ctranslate2==3.24.0,CUDA 12 加 cuDNN 8 降级 ctranslate2==4.4.0。
装完验证 GPU 是否真被认到:
python -c "import ctranslate2; print(ctranslate2.get_cuda_device_count())"返回 0 说明在走 CPU。这一步别省——后面所有「显存不够」的排障,前提都是显卡真的在干活。
补一句给爱折腾的读者:PyPI 上还有装主分支的写法(从 GitHub master 归档强制重装),能第一时间拿到未发布修复,但普通读者不推荐,稳定版足够。为什么 CPU 用户也能开箱即用?底层 CTranslate2 是多后端推理引擎,支持 x86-64 与 ARM64,会自动探测运行时分发 AVX、AVX2 指令集,无需手动选编译版本——这些脏活它都替你做了。
三、最小脚本:十行跑通,小心生成器陷阱
README 的最小示例就是可用的起点(large-v3、GPU fp16、beam_size=5):
from faster_whisper import WhisperModel
model_size = "large-v3"
model = WhisperModel(model_size, device="cuda", compute_type="float16")
# 显存不够换:compute_type="int8_float16"
# 无显卡用:WhisperModel(model_size, device="cpu", compute_type="int8")
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))设备与精度必须配对:cuda 配 float16 或 int8_float16;cpu 配 int8——faster-whisper 的命令行封装 whisper-ctranslate2 的文档原话是「On CPU int8 will give the best performance」。
这里埋着本篇最大的坑:transcribe 返回的 segments 是生成器(generator),不遍历它,转写根本没有开始。README 特别警告,segments = list(segments) 这一行才是真正执行转写的地方。网上流传「一秒转完 13 分钟」的假测试,全部源于此——创建生成器是零成本的,真正计算发生在遍历。自己掐表测速时,表必须掐在遍历完成之后,否则测出来是零秒。
四、提速省显存:三大杠杆按序拧
先把官方基准表摊开(口径再报一次:large-v2、beam_size=5、13 分钟音频、RTX 3070 Ti 8GB):
| 实现 | 精度 | 耗时 | 显存 |
|---|---|---|---|
| openai/whisper | fp16 | 2m23s | 4708MB |
| whisper.cpp | fp16 | 1m05s | 4127MB |
| faster-whisper | fp16 | 1m03s | 4525MB |
| faster-whisper | fp16,batch=8 | 17s | 6090MB |
| faster-whisper | int8 | 59s | 2926MB |
| faster-whisper | int8,batch=8 | 16s | 4500MB |
表中略去了 transformers 一行:同一口径下它 fp16 耗时 1m52s、显存 4960MB,两项都不占优,且 README 脚注写明 batch 大于 1 时会显存溢出,本地部署场景不如 faster-whisper,故不展开。
三个提速杠杆,按收益从大到小排序拧。
第一杠杆是精度。fp16 降到 int8,显存从 4525MB 降到 2926MB,省约 1.6GB,耗时只从 1m03s 小幅到 59s——但别小看这一步,8GB 卡上它的真正价值是给下一杠杆腾地方。
第二杠杆是批量。faster-whisper 提供 BatchedInferencePipeline,是 WhisperModel.transcribe 的直接替代:
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))README 示例用 batch_size=16,官方基准表用 8,8GB 卡建议从 batch_size=8 起试:int8 加 batch=8 多花约 1.5GB 显存(2926MB 到 4500MB),换来 59 秒到 16 秒,约 3.7 倍提速;显存吃紧就降到 4。别把两组数记混:fp16 加 batch=8 是 17 秒、6090MB,8GB 卡根本装不下,能装下的是 int8 的 16 秒、4500MB。另外批量模式会忽略部分逐段参数——whisper-ctranslate2 文档列明 compression_ratio_threshold、logprob_threshold、no_speech_threshold、condition_on_previous_text 等在批量模式下无效,调了也白调。
第三杠杆才是 beam。降 beam_size 收益最小,前两个杠杆用尽不够再动它。还有一条纪律:对比测速必须对齐 beam_size,官方基准全部锁 beam_size=5,复现时也要锁 5,否则数字失真。
质量侧也有证据:在 distil-whisper-large-v3 的官方基准里(batch_size=16、beam_size=5、YT Commons 语料),faster-whisper 用 25m50s 跑出词错率 13.527,transformers 用 46m12s 得到 14.801——该口径下更快的同时也更准。
纯 CPU 用户要如实分开说:CPU 档位上 fp32 的 whisper.cpp(2m05s/1049MB)其实比 faster-whisper fp32(2m37s/2257MB)更快更省,faster-whisper 在 CPU 的优势要靠 int8 量化兑现——int8 1m42s/1477MB,开 batch=8 再到 51s/3608MB。所以纯 CPU 有两条路:faster-whisper 加 small 或 base 加 int8,或者干脆用 whisper.cpp(其 OpenVINO 后端在 CPU 上更快)。别默认配置硬上,然后抱怨「比官方说的慢」。
没有 Python 环境也不想装的读者还有第三层选择:Windows 与 macOS 用户可以用 whisper-standalone-win 项目提供的独立 CLI 可执行文件,下载即用;要给多台设备共用转写能力的,speaches 项目提供 OpenAI 兼容 API 服务器,Docker 部署、支持流式与实时转写,把本地转写包装成局域网服务。
五、进阶:VAD、词级时间戳、SRT 字幕与说话人分离
长音频先开 VAD。faster-whisper 内置 Silero VAD 模型剔除无语音片段,默认保守策略只移除长于 2 秒的静音,可调参数:
segments, _ = model.transcribe(
"audio.mp3",
vad_filter=True,
vad_parameters=dict(min_silence_duration_ms=500),
)一个行为差异必须记住:逐段路径 vad_filter 默认关闭,批量路径默认开启——做对比实验时显式传参,别被默认值坑了。
要词级时间戳,加 word_timestamps=True:
segments, _ = 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))出 SRT 字幕要自己动手:库本体不含 SRT 写出器,通用做法是遍历 segments 自拼时间轴,格式为 HH:MM:SS,mmm 连接 HH:MM:SS,mmm,每段一个字幕块——segment 的 start 与 end 秒数除以 3600、60 取整换算即可,字幕序号从 1 递增;不想写代码,用 whisper-ctranslate2 命令行,它兼容 openai/whisper 的 CLI 参数,--output_format 可选 txt、vtt、srt 等。
说话人分离不是 faster-whisper 本体的活,用 WhisperX,仓库 https://github.com/m-bain/whisperX :v3 版起 70 倍实时(large-v2 批量推理口径),faster-whisper 后端 large-v2 加 beam_size=5 显存小于 8GB,wav2vec2 对齐做词级时间戳,pyannote-audio 做多说话人分离。安装 pip install whisperx,命令行一条:
whisperx path/to/audio.wav --model large-v2 --diarize --highlight_words True已知说话人数加 --min_speakers 2 --max_speakers 2。前置条件别漏:需要 Hugging Face read token(--hf_token),并且先在 HF 上接受 speaker-diarization-community-1 模型的用户协议,否则 --diarize 直接报错。显存紧就 --batch_size 4,或分两段跑:先转写对齐、再分离。对齐速度本身也有加速件:pip install "whisperx[fast]" 会装上 Numba,长音频对齐提速 30-100 倍。WhisperX 与 openai/whisper 还有几处行为差异值得知道:批量单遍推理要传 --without_timestamps True;按 VAD 分段转写(论文口径可降词错率);condition_on_prev_text 默认 False 以减少幻觉。对齐模型按语言自动从 torchaudio 或 Hugging Face 选取,英语、法语、德语、西班牙语、意大利语内置,中文等其他语言会自动拉对应模型,具体清单查仓库 alignment.py 的 DEFAULT_ALIGN_MODELS_HF。
实时转写作第三条线,先说清边界:本篇主线是离线文件转写,实时只点到为止,不做流式架构展开。whisper.cpp 的 stream 示例按 3 秒块出字,small 模型延迟约 0.5-1.5s;faster-whisper 侧配合 vad_filter=True 按静音切段,small/medium 延迟约 0.5-2s,tiny 小于 0.5 秒但词错率明显更高,对字幕场景建议宁可慢一点选 small;不想写代码,whisper-ctranslate2 的 --live_transcribe True 可直接从麦克风实时转写。
六、陷阱清单:十个坑逐条过
以上是顺路能讲清的,下面把全文的坑集中收口,部署前扫一遍:
- 生成器不遍历不执行。transcribe 返回生成器,
segments = list(segments)才真算;假测速全部源于此。 - GPU 用纯 int8。GPU 档位用 int8_float16;纯 int8 是 CPU 档位,跑不满显卡。
- 老卡静默降级。计算能力 6.0 及以下的卡请求 int8、float16 会回退 float32,不报错只变慢;用 CT2_VERBOSE=1 或 get_supported_compute_types 核实。
- 设备与精度不配对。cpu 配 int8,cuda 配 float16 或 int8_float16,混着写就踩上面两坑。
- cuDNN 版本错配。最新 ctranslate2 只要 CUDA 12 加 cuDNN 9;cuDNN 8 会初始化 GPU 失败,按版本降级 ctranslate2(3.24.0 或 4.4.0)解决。
- 测速不对齐 beam_size。官方基准全部 beam_size=5,对比前先锁齐。
- 批量模式忽略逐段参数。compression_ratio_threshold 等阈值参数在批量路径无效。
- 说话人分离非开箱即用。先到 Hugging Face 接受 diarization 模型协议并配 read token,否则 whisperx --diarize 报错。
- 显存不够的三连降。先降 batch_size,再降模型(large 换 base),最后降精度(int8);前两档可能影响质量,按顺序试。
- turbo 不做翻译。速度约 8 倍但只管转写,要 task=translate 的别选 turbo。
常见问题
Q1: 没有 NVIDIA 显卡,纯笔记本能跑吗?
能,但选对档位。纯 CPU 用 small 或 base 模型加 int8:i7-12700K 8 线程转写 13 分钟音频,faster-whisper int8 耗时 1m42s、内存 1477MB,开 batch=8 到 51s。也可以选 CPU 上更省内存的 whisper.cpp(fp32 全程 1049MB,OpenVINO 后端更快)。large 档位纯 CPU 硬跑会非常慢,不建议。
Q2: 脚本「瞬间跑完」却没有任何输出,为什么?
transcribe 返回的是生成器,不遍历就不执行。你看到的秒数只是创建生成器的时间,真正的转写发生在 for 循环里。想一次性拿到全部结果,写 segments = list(segments);想测速,表掐在遍历结束之后。
Q3: 8GB 显存跑 large-v3 爆显存怎么办?
三连降:先把 batch_size 从 8 降到 4;再降模型到 medium;最后降精度到 int8。按官方基准,8GB 卡的正确起点本来就是 large-v3 加 int8_float16,fp16 的 large-v3 在这张卡上并不稳妥。
Q4: 能直接导出 SRT 字幕文件吗?
库本体没有 SRT 写出器,要自己遍历 segments 拼时间轴(HH:MM:SS,mmm 格式,逗号接毫秒,别写成点号,否则部分播放器读不出),或改用 whisper-ctranslate2 命令行,--output_format srt 直接输出,兼容 openai/whisper 的 CLI 参数。
Q5: 它能边转写边把中文翻成英文吗?
不能当同传用。Whisper 的 translate 任务只译英语且是离线整段翻译,不是边听边译;turbo 模型干脆不支持翻译任务。本篇与站内同传专题是两条技术线:转写输出原文,同传边听边输出译文,要真同传看后者。