iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0

https://ithelp.ithome.com.tw/upload/images/20260816/20181284PcGrVXjvJs.png

繼續下一個組件:聽話,講話,創造聲音。

前面那台 amd 雙 GPU,載入 LLM 之後,記憶體就滿了。 所以配置另外一臺 Proxmox,新增個 ubuntu VM :ip: 192.168.0.31,過程都是一樣。就不重述。

網域先確定有設好:
stt.iron30.com
tts1.iron30.com
tts2.iron30.com

npm 分別指向:
stt.iron30.com 指向 192.168.0.31 , 8080
tts1.iron30.com 指向 192.168.0.31 , 8081
tts2.iron30.com 指向 192.168.0.31 , 8082

因為我們要兩個不同版本的 tts, 一個用地端模型,一個用雲端模型。所以弄兩個 tts。
stt 沒有懸念: whisper.

ssh 連到 hq,切換到 /opt/claude-working,執行 claude code:
告訴 claude code :

連接到 192.168.0.31,在.31 執行:
    - 確認:兩張顯示卡都看得到、記憶體容量對。
    - 做完把連線資訊寫進這台虛擬機的 Proxmox 備註欄,
      並且在 machines.md 和 machines/npm.md 補上這台。

install model : use docker

1. stt 語音轉文字
    - whisper.cpp 的 server 版本,用 GPU0。
    - ⛔ 它沒有任何認證,誰打得到誰就能用:只聽本機,不要對外開埠。
      8080 留給等一下要做的那層前台,由前台去打它。
    - 模型用 large-v3-turbo,放資料碟,不要放系統碟。
    - 開 OpenAI 相容的那組路徑,之後接東西進來不用另外寫轉接。
    - 格式轉換交給它自己做,不要求上傳端先轉好檔。
    - ⚠️ 自己編 image 的話:要指定這張卡的運算架構版本,
      而且要把顯示記憶體虛擬管理那個選項關掉 —— 容器裡沒有驅動那顆函式庫,
      沒關的話最後連結會失敗,而錯誤訊息只會說某幾個符號找不到,不會告訴你原因。

2. tts1: 裝文字轉語音,use edge tts , 不用到 gpu
    - 純 CPU,容器跑,綁 8081。
    - 台灣的那幾個語者先固定下來,語速、音高、音量都要能調。
    - ⚠️ 參數格式很挑:不帶正負號的寫法會被整包拒絕,
      預設值要寫成 +0% 這種形式,自己包一層正規化再送出去。
    - 要能輸出字幕檔。
    - 可以設定斷句閥值,預設:0.475s
    - 字典功能:同音字輸出取代。
    - 檔案列表,試聽,下載。
          
3. tts2:裝文字轉語音,use CosyVoice3 use gpu
    - GPU,綁 8082。
    - 合成是長工作:收到請求先回一個工作編號,讓對方自己來問進度,
      不要讓它連著線等到好。前面放一個隊列,不要讓請求直接打進模型。
    - 要支援零樣本克隆:上傳一段十秒左右的參考音檔,加上那段音檔的逐字內容,
      之後就能用那個聲音唸任何一段文字。
    - ⚠️ 模型載入要一到兩分鐘,第一次還要多花約一分鐘暖機,不要以為它掛了就重啟。
    - ⚠️ 這包的相依關係很脆:GPU 版的推論函式庫要跟系統的加速函式庫大版本對得上,
      對不上它不會報錯,會安靜地退回處理器算。
      裝完順便確認數值運算套件沒有被連帶升上去,那會把另一批元件弄壞。
    - ⚠️ 下載完先驗這包真的是第三代:看設定檔的檔名、切分器的版本、
      有沒有那個額外的強化學習權重檔。⛔ 目錄名字不算證據。

三、⛔ 吃顯示卡的那兩個(stt 和 tts2)都要指定GPU0,
    而且指定的方式只有一種算數:在容器的裝置設定裡,讓它只看得到那一張。
     ⚠️ 工作行程要開幾個,得跟你真的給它的卡數一致。
    

規則:
- 3個服務都設成開機自動起來。
- 做完把這台寫進 machines.md 和 machines/voice.md,
  並且在 Proxmox 的備註欄記下連線資訊。

3個服務都起來之後,先不要急著接東西進去。

告訴 claude code:

幫我量這三個服務。
⛔ 不要只確認「有出文字」「有出聲音」就算過。

一、語音轉文字:
    - 找一段真實的錄音,裡面要有人名、公司名這種專有名詞。
      ⛔ 不要用乾淨的示範音檔,那種東西誰跑都會過。
    - 量兩個數字:音檔多長、轉完花多久,算出倍率。
    - 逐字稿裡的專有名詞逐個對一次,錯的抄下來給我。

二、兩個文字轉語音,用同一段文字各跑一次,數字並排給我:
    - 合成一段一分鐘左右的音檔,算「合成花的時間 ÷ 音檔長度」。
      這個值大於一,就是比即時還慢。
    - ⚠️ 地端那個比即時慢,通常不是模型慢,是某個零件掉回處理器在算。
      驗法:合成的時候看那張卡的記憶體和使用率有沒有動,
      沒動就是根本沒在用它。
    - 雲端那個要另外量穩定度:同一段文字連打二十次,
      記失敗幾次、最慢的一次多久。⛔ 它不在我們機房裡,
      穩定度只能量,不能假設。
    - 兩邊都輸出一份字幕檔:檔案大小不可以是 0,
      打開看時間軸切到多細(一句一格,還是一個詞一格)。
    - 音質也記一下:取樣率和位元率各是多少。

三、⚠️ 順便驗一件事:確認跑起來的模型真的是你以為的那一版。
    去看檔案本身 —— 設定檔的名稱、權重檔的清單、下載來源。
    ⛔ 目錄名字不算證據。

回報:語音轉文字的倍率、兩個語音合成的即時率、兩張卡各用掉多少記憶體、
雲端那個失敗幾次、兩份字幕檔的大小與顆粒度、專有名詞錯了哪幾個。

聽的部分,量出來的數字是這樣:
一段 11 秒的錄音,0.4 秒轉完,大約是實際長度的 27 倍速,顯示記憶體只用掉 1.7 GB。
這個數字有個很實際的意義:一小時的會議錄音,兩分鐘就可以出逐字稿。現在,這台在自己家裡的機器就做得到,而且沒有任何一段音檔離開過這個機房。主控權,安全性,全在自家手上。你應該不會想要把內部討論價格,市場競爭策略,人事調整,這種會議錄音,送上雲端或交給外人處理吧!?

說的部份:
用同一段兩百多字的稿子、同一個語者名字,Edge TTS 跟 CosyVoice3 各唸一次:

https://ithelp.ithome.com.tw/upload/images/20260816/20181284y7dhbBPxdt.png

先看生成時間:
本地端這台花了 33.9 秒,即時率 0.65 —— 比當初修好時又好一些,但那三十幾秒是自己的顯示卡被佔住三十幾秒。
雲端只花了 1.03 秒就回來了,即時率 0.021,連打二十次沒有一次失敗,最慢的一次 1.15 秒。差距三十三倍,而且電費是別人付的。

音質的差距比想像中小:兩邊都是 24 kHz,只差在位元率,74 對 48。
真正把兩套分開的是字幕:雲端那份是繁體、標點完整、按句子邊界切;本地端那份送進去是繁體、吐回來是簡體,六格字幕裡有五十八個簡體字,標點全部消失,而且切點是按比例估算的,第一格從零切到十點五秒,橫跨兩句半。簡單講:本地端自己生產的字幕不能用,要加上後續處理。沒辦法,對岸來的模型。

兩套都留著有它的道理:我們的文件內容能不能公開?
可以公開的、要快、要便宜,走雲端;不想被公開的,走自己的機器。

同一張卡上兩個服務可以共存,是因為它們的胃口差很多:聽的那邊只吃 1.7 GB,說的那邊要吃 8 GB 左右。所以規劃的時候不能只數「有幾個服務」,要把每個服務實際吃掉多少寫下來再相加。

地端那個說話的服務,CosyVoice3,發生過一個問題:合成一段音檔要花的時間,是那段音檔本身長度的 1.29 倍。使用者等待的時間,比他要聽的那段音檔還長。而整個過程沒有任何一行錯誤訊息。原因是:幾個做推論的元件因為加速函式庫的版本不對,安靜地,退回用處理器運算,沒用GPU。修好之後是 0.94,終於比即時快。會明顯出現錯誤的問題最便宜,你至少知道要去修哪裡;不會報錯、就只是變慢的那種錯誤,很貴,很麻煩。

修這件事的過程本身也值得記一筆:把推論函式庫換成對得上的版本之後,它順手把數值運算套件升到新的版本,而另一批元件是用舊版編出來的,當場換一個地方壞掉,得再把數值套件壓回去。本地跑 AI 服務最容易被低估的維護成本就在這裡:一個安裝指令會拉動一整排相依套件,而它們彼此的版本要求並不一致。

還有一件事更難發現。那個CosyVoice3的目錄名字寫的是第三代,但下載下來的內容其實是第二代,而且就這樣跑了三個多月沒察覺。載入器讀到舊版的設定檔,優雅地把它載進來,一句話都沒說。版本號在目錄名字上,不在檔案裡面 —— 而那個名字,是我自己打上去的。

測試好了,數字也都對OK,來把它接出去。

告訴 claude code:

 到 NPM 主機:
    - 確認 stt.iron30.com  tts1.iron30.com  tts2.iron30.com從外面解得到 1.2.3.4,解不到就停下來告訴我。
    - 設定: stt.iron30.com,指向 192.168.0.31:8080 
    - 設定: tts1.iron30.com,指向 192.168.0.31:8081
    - 設定: tts2.iron30.com,指向 192.168.0.31:8082
    - 設定 這三個的憑證。
到 192.168.0.31:
語音轉文字服務
 ⛔ 它不可以直接掛上網域。做一層有登入的前台綁在 8080,
只有這層碰得到它,網域指過來的是這層。

前台要有:
    - 上傳音檔,以及瀏覽器直接錄音。
    - 選語言、選輸出格式:純文字或字幕檔。
    - 一個「已知詞彙」欄位,使用者可以自己填,也可以由系統帶進來。

那個欄位是準確率的主要槓桿,流程照這個做:
    - 先不帶任何名單轉一次,拿到一份粗稿。
    - 拿粗稿去跟系統裡已知的名字比對,挑出最像的那幾個,五六個就好。
    - 只把挑出來的那幾個帶進去,重轉第二次。
    - ⚠️ 如果第二次的結果明顯變短或變破碎,就把第一次的還給使用者。
    ⛔ 不要把整份名單倒進去。那個欄位很短,塞爆了它會安靜地壞掉。

另外兩個合成的服務:對外那一層至少要帶一把憑證,沒帶的一律擋掉。

安全與限制:
    - 密碼只存雜湊,不要存明文;產雜湊的時候不要經過命令列參數。
    - ⚠️ 秘密字串放進環境變數檔之前,先確認你的寫法不會被展開;
      放完進容器裡確認那個字串的長度對不對。
    - 上傳大小上限和逾時要一起放大 —— 音檔比網頁大很多,
      預設值會在使用者傳一段會議錄音的時候把他擋下來。
    - 登入失敗同一個來源連續幾次就鎖一段時間。

做完把對外開了什麼寫進 exposure.md,帳號密碼寫進 secrets.md。

做好的樣子如下:沒有加入版面配色控制。
因為基本上,這幾個服務會都是AI在使用,不是人在用,所以介面就不那麼重要了。

STT :

https://ithelp.ithome.com.tw/upload/images/20260816/20181284YPPDLbHpZl.png

TTS1 : Edge TTS
https://ithelp.ithome.com.tw/upload/images/20260816/20181284uMHdkCaud7.png

TTS2:CosyVoice3
https://ithelp.ithome.com.tw/upload/images/20260816/20181284SxttthUms8.png

聽的那一邊,準確率有一個很便宜的槓桿,而且效果大到會讓人以為換了模型。同一段 40 秒的業務口述,不給任何提示的時候,逐字稿是簡體字,而且客戶名稱全部聽成同音字:永盛五金行變成永勝五金行,光華電子變成光華店子,決標變成絕標。把已知的客戶名單先給它之後,同一個音檔,上面那些字全部正確,而且輸出變成繁體。同音字的錯誤事後是救不回來的:那些都是合法的中文詞,拼字檢查看不出來。

但這個槓桿有一個很硬的上限,而且它不會告訴你。名單從 9 個名字加到 15 個之後,同一個音檔的逐字稿當場崩解:句子斷成碎片、詞卡住一直重複,而且退回簡體。它不會回報錯誤,只會給你一份看起來很像逐字稿的東西。所以那個欄位要當成「很短的提示」來用,不是當成「把知識庫倒進去的地方」。

前台那一層自己也踩了一個很經典的坑。密碼的雜湊值裡面有錢字號,而容器的環境變數檔會把錢字號當成變數展開,進到容器裡就只剩前面半截。容器起得來,健康檢查是綠的,所有監控都說一切正常,只有一件事不成立:沒有人登得進去。

語音服務做起來之後有一件事跟預期不一樣:用它的幾乎不是人。翻了幾天的紀錄,使用這台語音服務的,是另外五台機器上的服務 —— 寫作平台把文章唸成語音檔、影片平台配旁白、agent 回訊息的時候順便講一句、還有兩個是自己做的小工具。真人打開網頁,使用服務的次數,反而是裡面最少的。所以這種服務停掉的時候,你不會收到抱怨。你會收到的是五個看起來不相干的功能同時壞掉,而且沒有一個會告訴你原因是這台。內部服務要當成別人的相依套件看待:動它之前先問清楚誰在用,以及它停掉的時候,那五個地方會用什麼姿勢壞掉。

最後是一件跟技術無關的事。現在的合成模型是零樣本克隆:給它十秒鐘的參考音檔,它就能用那個人的聲音唸任何一段文字。不用訓練,不用微調,十秒鐘。所以這件事的門檻已經不在技術那一側了 —— 你能不能用一個聲音,取決於你有沒有那個人的同意,不取決於你做不做得到。

到這裡,這座機房聽得到、也說得出來了。但它還是不知道任何事情:所有的知識都還躺在硬碟裡那一堆檔案裡面。

明天,就從那一堆檔案下手:掃描 PDF,圖檔,讀取檔案,讓機器自己看,變成可以查詢的知識。


上一篇
D09 本地端 LLM Service
系列文
一個人的 IT 部門:用 Claude Code 從裸機到一整座 AI 機房11
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言