OpenAI 的神奇 Whisper 語音轉文字模型,可在地端執行,但需有 GPU 才能順跑。先前測過,即便用 32 核 CPU 跑 Medium 也僅 100 WPM,30 分鐘錄音檔需要轉兩小時;有 GPU 就差很多,入門級 RTX 3050 便可達 1594 WPM,快 15 倍,若有 4080 可到幾乎 30 倍。

我的迷你工作機什麼都好,獨缺 Nvidia 獨顯。目前靠雲端 LLM 已可解決工作生活大小事,因偶一為之的逐字稿需求升級電腦是為喝牛奶養一頭牛,不值得。要跑 AI 模型,Mac Mini 或 Project DIGITS 體積小巧耗電又低,感覺性價比更好,未必非得衝 GPU 顯卡,目前無急需,就再觀望一陣子好了。

既然短時間內無 GPU 可用,線上版 Whisper API 感覺是不錯的替代選項。查了定價,Azure Whiper API 處理一小時音檔約 NTD 11.81,大約一顆茶葉蛋的價錢,不算貴,決定玩看看。

我打算用 PowerShell 寫程式,應用起來較方便。MS Learn 有程式範例 但偏簡略,沒提到 Prompt、語系等細節,缺少的參數資訊可以在 OpenAI 技術文件找到。

程式很簡單,給 API Key、指定 Wav/Mp3 檔路徑(、語系及提示詞,用 multipart/form-data 格式呼叫 Transcriptions REST API 就可以了:(這裡以 PowerShell 7.x 為例,PowerShell 5 的 Invoke-RestMethod 不支援 -Form 參數,程式要再調一下)

function Az-WhisperTranscribe($wavPath, $language, $prompt) {
    if (!$prompt) { $prompt = 'Transcribe the audio' }
    if (!$language) { $language = 'zh' }
    $headers = [ordered]@{
        'api-key' = (DecryptApiKey)
    }
    $form = @{ 
        model = 'whisper-1'
        file = (Get-Item -Path $wavPath)
        prompt = $prompt
        language = $language
        # response_format = 'verbose_json'
    }
    Write-Host "Transcribing $wavPath"
    $response = Invoke-RestMethod -Uri $Global:apiUrl -Headers $headers -Form $form -Method Post -ContentType 'multipart/form-data'
    return $response.text
}

Whisper 支援的音檔格式包含 mp3, mp4, mpeg, mpga, m4a, ogg, wav, 或 webm。單一檔案大小上限為 25MB,超過時要降低壓縮率或拆檔。拆檔有可能將一句話截斷而遺漏,我的做法是分割檔彼此重疊一分鐘,使分割點附近內容同時在前後檔都被解析,之後再人工合併校正 😄。(處理大檔的另一種做法是改用 Azure 語音服務的批次轉譯功能)

language 語系參值使用 ISO 936 語系代碼,無法細到 zh-tw。但實測 language 用 zh,提示詞使用繁體中文,輸出會是繁體中文沒有問題。

輸出格式則可選擇 json, text, srt, verbose_json, 或 vtt。

我找了一集李宏毅老師的上課錄音進行實測,長度 38'12",檔案 36.2M。

檔案大小超過 25MB,用 ffmpeg 指定時間範圍分割成兩個檔案,前 20 分鐘與剩餘部分,指令如下:(兩個檔案的 19'00" ~ 20'00" 重疊)

ffmpeg -i .\gpt-4o-audio-tech.m4a -ss 00:00:00 -to 00:20:00 -c copy part1.m4a
ffmpeg -i .\gpt-4o-audio-tech.m4a -ss 00:19:00 -c copy part2.m4a

分割後兩個 .m4a 檔都約 18MB:

寫幾行程式呼叫 Az-WhisperTranscribe 將兩個檔案轉成逐字稿,並記錄花費時間:

$prompt = '以下是台灣大學課程「GPT-4o 背後可能的語音技術猜測」的上課內容,請產生逐字稿'
$sw = New-Object System.Diagnostics.Stopwatch
$sw.Start()
Az-WhisperTranscribe .\part1.m4a 'zh' $prompt | Out-File -FilePath .\part1.txt -Encoding utf8
$sw.Stop()
Write-Host "耗時: $($sw.Elapsed.TotalSeconds) 秒"
$sw.Reset()
$sw.Start()
Az-WhisperTranscribe .\part2.m4a 'zh' $prompt | Out-File -FilePath .\part2.txt -Encoding utf8
Write-Host "耗時: $($sw.Elapsed.TotalSeconds) 秒"

如下圖,20 分鐘跟 19 分鐘的錄音,每次含上傳花一分鐘多一點轉完,約 9300 個中文字,品質維持 Whisper 一貫的高水準。

按此速度,一小時三分鐘可轉完,花不到 12 塊新台幣,挺划算的。未來遇到逐字稿需求,就有更簡單方便的新選擇了。

OpenAI’s Whisper model offers efficient on-premise speech-to-text conversion, but requires a GPU for optimal performance. For occasional transcription needs, the online Whisper API is a cost-effective alternative. This guide demonstrates using PowerShell to call the API, enabling quick and accurate transcriptions.


Comments

# by Hank

不常用的語其實可考慮 SubEasy 免費方案 每日免費轉寫三次

# by 鳥毅

關於斷句的部分,我問了ChatGPT,可以利用 ffmpeg 的 silencedetect 濾鏡偵測音檔中的靜音區段。使用 API 就可以不用 wav,使用 ogg 比較小,可以放入更長的檔案,但要小心 timeout,我自己使用此方法設定25分鐘切一段,但反應時間有點久,在想是否縮更短一點。

# by Jeffrey

to 鳥毅,感謝分享。(已筆記)

Post a comment