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 runtime 版本不一致:程式碼本身可能沒問題,但執行時會在載入模型或首次推理時失敗。

基本用法

最小範例很直接:

 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 適合處理會議錄音、Podcast、直播回放這類包含長靜音的音訊。詞級時間戳則適合生成字幕、做逐字稿校對,或者後續接入播放器高亮。

模型怎麼選

模型選擇主要看三件事:準確率、速度、機器資源。

場景 建議
快速測試 smallmedium
中文內容品質優先 large-v3
GPU 顯存緊張 int8_float16 或更小模型
CPU 跑後台任務 小模型加 int8
批次短音訊 嘗試 BatchedInferencePipeline

如果是中文語音,建議優先測試 large-v3。如果機器壓力太大,再降低模型規格或使用量化。不要一開始就只看速度,轉寫品質下降後,人工校對時間可能會把省下來的推理時間抵消掉。

適合的使用場景

faster-whisper 很適合這些任務:

  1. 影片字幕生成。
  2. Podcast、會議、課程錄音轉文字。
  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