智慧邊緣運算:打造 vad_stt 作為自主語音輸入裝置的調度大腦
從麥克風、Whisper 到 HID 鍵盤的系統級橋接
智慧邊緣運算:打造 vad_stt 作為自主語音輸入裝置的調度大腦
作為一名老派的開發者,我偏好具備確定性(Deterministic)的桌面工作環境,不喜歡操作細節隱藏在現代作業系統的自動化糖衣背後。然而,使用簡化且高度客製化的桌面配置往往需要付出代價:常因桌面元件不完整,遭遇意料之外的整合問題。
幾個月前,當我嘗試在基於 Wayland 的 GNOME 桌面上導入語音轉文字(STT)功能時,撞上了現代 Linux 的安全設計。由於 Wayland 實施了極為嚴格的安全策略,應用程式之間跨視窗的字元注入受到強力限制。嘗試解決問題過程中,激發了一個反向思考:與其在軟體層面苦苦哀求權限,何不直接利用系統授權後的實體層級設備來指揮按鍵?
這成了我「DIY STT Gadget」系列專案的起點。利用先前建置的 dietpi-headless 底層架構,成功將 Raspberry Pi 4(2GB)的 USB-C OTG 接口轉化為硬體 Gadget。透過按鍵與掃描碼(Scancodes)的映射表來模擬鍵盤輸入,成功克服了不同作業系統(Windows, Linux, macOS)對萬國碼(Unicode)輸入機制的底層差異。之後開發的 [rpi-hid-keyboard 核心應用程式](https://medium.com/@breeze833/%E7%A1%AC%E9%AB%94%E4%B9%8B%E6%89%8B-eff4dff90648),運作在 HID 鍵盤輸出裝置節點與輸入 Unix Socket 之間,當它從 Socket 收到一個字串,就會轉化為實體硬體鍵盤的敲擊訊號,注入主機作業系統中,而主機作業系統此時只會把這台 RPi 視為一個隨插即用的實體 USB 鍵盤。
然而,在「雙手(rpi-hid-keyboard)」與「底層環境(dietpi-headless)」就緒後,這個專案還缺少一個關鍵的軟體核心:一個能夠指揮麥克風監聽、智慧語音偵測(VAD)並驅動神經網路語音辨識(Whisper.cpp)的中央橋接調度器。
於是, vad_stt 套件就此誕生。
解耦的異步管線:vad_stt 的雙行程架構
這個程式作為知名開源語音轉譯 whisper.cpp 套件與模擬鍵盤訊號的橋接軟體,架構設計中被拆分為兩個完全獨立的背景行程(Processes),並透過執行緒安全的記憶體佇列並行調度:
- 語音輸入層(監聽麥克風): 我在樹莓派上安裝了 ReSpeaker 2-mic Hat 擴充板。第一個行程會持續監聽麥克風的原始音訊,並透過
webrtcvad-wheel套件即時進行語音活動偵測(VAD)。它會智慧地過濾雜音,並在人類說話的自然停頓點上,將音訊切割成獨立的語音片段,依序推入緩衝佇列中。 - 文字輸出層(驅動轉譯與打字): 第二個行程則是個異步的消費者。它持續監控佇列,一旦有新的音訊片段被推入,就立即將其取出,送往後端的
whisper.cpp引擎進行單次(One-shot)語音辨識,拿到轉譯的 UTF-8 字串後,接著灌入rpi-hid-keyboard的 Unix Socket,讓硬體鍵盤把文字打在主機螢幕上。
整個架構看起來無懈可擊。主機系統只看到一隻實體鍵盤在瘋狂打字,完全不知道背後涉及了如此複雜的音訊採集與神經網路矩陣運算。
然而,當我興高采烈地將所有組件全部跑在 RPi4 上時,現實卻給了我一記沉重的打擊。

撞牆期:低功耗硬體的算力天花板
雖然 whisper.cpp 針對 ARM NEON 指令集進行了極致的優化,特別是對 4-bit 量化模型(Q4_0)的數學查找非常高效。考慮到我經常在句子中混合英文與中文(Code-switching),我特地選用了在準確度與效率上最平衡的 small 尺寸搭配 q4_0 量化模型。
但是,RPi4 的實體算力終究是有極限的。
當真實的測試數據出爐時,我發現整體效能完全無法達到即時(Real-time)的要求。即便我開啟了 VAD 模型進行輔助,在單次直接轉譯一段 20 秒的現成 WAV 語音檔案時,樹莓派 4 竟然需要耗費將近 24 秒的時間才能完成解碼。這種比實際音訊長度還要慢上大約 20% 的嚴重遲滯感,在實際 dictation(語音聽寫)的體驗是相當不好的。
罪魁禍首非常明顯:在樹莓派上,一邊要承擔實體麥克風的即時音訊採集與 VAD 運算,另一邊還要同時並行 whisper.cpp 繁重的 Transformer 矩陣乘法,這對 RPi4 的 CPU 來說實在是超額透支了。
面對這個物理限制,如果我堅持要在邊緣端完成所有事,這隻「硬體之手」就會變成一個反應遲鈍的慢郎中。要作為實用的解方,必須尋找另外一條出路。
逆向思考:透過 NCM 網路 Gadget 實現算力卸載
既然問題卡在樹莓派 4 的 CPU 算力,而又不想放棄這套實體硬體隔離的輸入主權,那該怎麼辦?答案其實早就埋在最初的 dietpi-headless 低底層架構裡了。
在 dietpi-headless 的預設配置中,已經開啟了 NCM 網路裝置 Gadget。這意味著樹莓派與主機電腦之間,除了一條實體鍵盤線之外,還存在著一條高速且穩定的實體 USB 虛擬區域網路(LAN)。
這給我一個靈感:如果樹莓派只負責當「耳朵(麥克風與 VAD 數據切片)」,而將重型的「大腦(Whisper.cpp 轉譯引擎)」卸載(Off-load)到效能強大、效能過剩的主機電腦上呢?
我立刻進行了架構調整:
- 主機電腦在背景執行高效能的
whisper.cpp伺服器。 - 樹莓派透過 USB NCM 網路建立與主機的連線。
- 利用一個非常優雅的網路老把戲 :SSH 遠端連接埠轉發(SSH Remote Forwarding)。
當樹莓派透過 SSH 連線到主機並開啟遠端轉發時,主機端的 Whisper 伺服器連接埠,就會被投射並對應到樹莓派本地端的埠口上。對於 vad_stt 橋接套件而言,程式碼甚至不需要做任何修改,它依然以為自己是在向本地端的 whisper-server 發送請求。但實際上,音訊片段已經透過 USB 網路線送到主機強大的 CPU/GPU 進行轉譯,再將文字回傳給樹莓派,最後由 rpi-hid-keyboard 注入主機。
改用新的配置後,速度明顯提昇。如果我的主機硬體配備再好一些,應該可以再縮短轉譯時間。
結語:工程設計的妥協與彈性
vad_stt 的開發歷程讓我深刻體會到,真正的工程主權(Sovereignty)並不是盲目地在邊緣端硬幹所有運算,而是在遭遇物理瓶頸時,能夠具備動態調整架構的彈性。
雖然 RPi4 面對繁重的神經網路轉譯時露出了疲態,但透過 dietpi-headless 複合 Gadget 的多功能複合設計,我們成功將算力與硬體介面完全解耦。這個專案最終展現了完美的融合,樹莓派安靜地待在桌上捕捉聲音並精準切片,主機默默提供強大算力,而主機作業系統看到的,依然只是那一隻透過實體 USB 線源源不絕、以絕對權威注入文字的「萬能硬體鍵盤」。
本專案開源於 GitHub: https://github.com/breeze833/whispercpp-utils
메타데이터
- post_id
- 63dddb9e38d5
- slug
- 邊緣運算特務的誕生-打造-vad-stt-作為自主語音輸入裝置的調度大腦-63dddb9e38d5
- url
- https://medium.com/@breeze833/%E9%82%8A%E7%B7%A3%E9%81%8B%E7%AE%97%E7%89%B9%E5%8B%99%E7%9A%84%E8%AA%95%E7%94%9F-%E6%89%93%E9%80%A0-vad-stt-%E4%BD%9C%E7%82%BA%E8%87%AA%E4%B8%BB%E8%AA%9E%E9%9F%B3%E8%BC%B8%E5%85%A5%E8%A3%9D%E7%BD%AE%E7%9A%84%E8%AA%BF%E5%BA%A6%E5%A4%A7%E8%85%A6-63dddb9e38d5
- canonical_url
- https://medium.com/@breeze833/%E9%82%8A%E7%B7%A3%E9%81%8B%E7%AE%97%E7%89%B9%E5%8B%99%E7%9A%84%E8%AA%95%E7%94%9F-%E6%89%93%E9%80%A0-vad-stt-%E4%BD%9C%E7%82%BA%E8%87%AA%E4%B8%BB%E8%AA%9E%E9%9F%B3%E8%BC%B8%E5%85%A5%E8%A3%9D%E7%BD%AE%E7%9A%84%E8%AA%BF%E5%BA%A6%E5%A4%A7%E8%85%A6-63dddb9e38d5
- author_url
- https://medium.com/@breeze833
- status
- ok
- fetched_at
- 2026-08-29 01:49:55