2024.10 - 2025.03 / 核心全棧開發
離線語音轉錄系統
面向本地音頻轉錄場景的 Web 應用,支持轉寫、熱詞配置、任務追蹤、文本優化與 DOCX 導出。

背景與約束
部分會議錄音與校內音頻數據不適合上傳至在線服務,且使用環境可能沒有穩定網絡,因此需要開發可在本地運行的語音轉錄系統,支持長音頻與會議錄音的轉寫、熱詞配置、任務追蹤、文本優化及 DOCX 導出。部署目標是一般筆記本電腦,GPU 顯存與整體算力有限,無法直接使用大型模型處理完整長音頻,因此選用更適合本地部署的小型 ASR 與 3B 級語言模型。
系統架構
後端以 FastAPI 提供文件上傳、任務查詢、重試與 DOCX 導出 API,並使用 SQLite 保存文件、任務狀態、原始結果、優化結果、熱詞及說話者信息。Redis 作為 Celery broker 接收任務,再由 ASR worker 執行初步轉錄。ASR 完成後會回寫結果並提交文本優化任務,文本優化 worker 再調用 Ollama 上的本地 3B 模型;前端通過 API 查詢每個階段的狀態與結果。上圖只描述任務調度與數據流;音頻前處理、模型選擇和初步分段的細節如下。
ASR pipeline
前處理將多種音頻 / 視頻格式經 ffmpeg 解碼、重採樣為統一格式,再由 torchaudio 加載 waveform。中文路徑接著使用 FSMN-VAD 進行語音端點檢測,依靜音切段並限制單段最長 30 秒。轉錄模型無法穩定承受過長輸入,直接處理長音頻容易佔滿 GPU 顯存並造成 OOM;VAD 因此同時減少無聲計算,也將推理控制在可預期的顯存範圍。
模型選擇經過前期測試,依語言與使用場景分流:中文會議使用 Paraformer,並接 CT-Punc 補全標點與說話者模型;單人語音使用 SenseVoice;中法學院有法語轉錄需求,因此法語使用 faster-whisper。服務層再將各模型的輸出統一為包含文本與時間信息的 sentence blocks,讓前端、文本優化與 DOCX 導出使用同一份數據結構。

文本後處理
初步清理後才進行段落劃分。切分不只受最大長度限制,還需要保留說話者邊界,並優先選擇句末標點和自然語義停頓作為切點,避免將一句話或一段發言從中間截斷。本地部署受限於算力,因此文本後處理通過 Ollama 運行 3B 級語言模型;每個文本塊會連同前文上下文套入 prompt,要求模型校正錯字與同音字、補足標點並輸出可讀段落。原始結果和優化結果分開保存,保留回溯與重試空間。
性能分析與優化
性能分析從一個反常現象開始:通過 top 觀察長音頻轉錄過程時,單個 CPU 核心持續佔滿 100%,但 GPU 推理本應是主要耗時環節。這說明 GPU 在等待一段串行的 CPU 前處理,而不是單純受限於模型推理速度。
接著以 cProfile 對固定音頻和相同配置採樣,分別查看累積耗時與函數自身耗時。結果定位到 VAD 的 ComputeDecibel:它以 Python 循環逐幀切片,反覆執行張量平方、求和與對數運算,將大量時間耗在 CPU 前處理,拖慢後續 GPU 推理。
優化將逐幀循環改為 NumPy 批量索引與向量化計算,一次建立所有 frame、計算能量與分貝值,再回寫結果。這減少了 Python 解釋器與小型張量操作的開銷,並將數值運算交由底層原生實現,以利用 CPU 的向量化 / SIMD 能力。改動後以相同音頻、模型與參數重新執行 cProfile,比較 ComputeDecibel 的耗時和端到端轉錄時間,確認收益來自 VAD 前處理而非測試條件差異。相關改進已提交並合併為 FunASR PR #2174。