MOOSSin
選單

全部文章 · 開源工具

Qwen3-TTS:在自己的顯卡上跑它之前,值得先量的幾個數字

Qwen 的 Qwen3-TTS-12Hz-1.7B-Base 是能在八 GB 顯卡上跑的開源語音合成模型。這篇講我在它身上量到的:注意力核心換一下快一成,四句一批快近兩倍,八句就爆顯存,鎖高 GPU 時脈反而更慢,以及批次會不會改變輸出。也講一講「量測」這件事為什麼比工具本身重要。

我高中的物理老師有一句口頭禪:「你覺得不算,量了才算。」當時覺得很煩,每次實驗都要量三次取平均。後來在自己的顯卡上跑語音模型,這句話每天都在我腦中重播,因為在那張卡上,我「覺得」的事情大概有一半是錯的。

Qwen3-TTS-12Hz-1.7B-Base 是 Qwen 團隊釋出的語音合成基礎模型,十七億參數,語音以每秒十二個 token 表示,支援音色複製,權重放在 Hugging Face,Python 套件叫 qwen-tts。我在一張 RTX 2070 SUPER 上用了它一段時間,後來換了別的引擎,但當初在它身上建立的量測方法一直沿用。這篇寫那些數字,給想在中階顯卡上跑它的人參考,也給任何想在自己電腦上跑模型的人一點關於「怎麼量」的想法。

起點:每秒語音要四點四秒

一句一句生成、eager 注意力、fp16:RTF 4.40,也就是每一秒語音要 4.4 秒牆鐘。RTF 是 real-time factor,數字越小越快,小於 1 表示比即時還快。4.4 的意思是你唸一分鐘的稿,它要算四分多鐘。成本幾乎全在自迴歸解碼,載模型約五十秒、寫檔可以忽略。

安裝時上游會提醒沒有 FlashAttention 和 SoX,前者 Turing 架構裝不了,後者只有 25 Hz 的 tokenizer 用得到,12 Hz 模型不需要,兩個警告都可以放著。第一次看到警告我很緊張,以為裝壞了,查了半小時才確定那是「你可以更快但你的卡不行」的意思。

兩個值得改的設定

注意力換成 SDPA,RTF 從 4.73 降到 4.01,快 11.7%。SDPA 是 PyTorch 內建的,不用裝任何東西,改一個字串就有一成的速度,這種便宜的事不撿白不撿。

每次生成四句,總時間從 390 秒變 204 秒,1.91 倍。八句一批是 2.46 倍,但顯存峰值 10.18 GB 超過這張卡的 8.6 GB,只靠 Windows 驅動程式退到系統記憶體才沒有爆。看起來能跑,數字不能信,不採用。四句的峰值是 7.21 GB,留了一點餘裕給其他東西。

兩個設定都會改變輸出的波形。如果你有「同樣輸入就重用舊音檔」的機制,這兩個值要進重用的身分,改了就重生全部。這聽起來很浪費,但另一個選項是一半的音檔用舊設定、一半用新設定,聽起來會像兩個人在輪流講話。

批次會不會改變輸出

這個問題我原本用猜的。我猜「同一批裡的鄰居會影響輸出」,因為感覺上它們一起經過模型,應該會互相干擾。猜錯代價很大,所以直接量。

同一句用兩組完全不同的鄰居各生一次,逐個取樣比對,差異是零。零,不是很小,是零。但單獨生成和在批次裡生成不一樣,長度 3.68 秒對 3.84 秒。結論:「跟誰同批」不是輸入,「有沒有批次、批次多大」才是。

這個結論決定了重用機制該記什麼,也決定了缺一句時要整批重做而不是單獨補一句。我原本的猜測如果直接寫進程式,會多出一堆沒必要的重算,而且我永遠不會發現,因為結果看起來都對。物理老師,你是對的。

三個實測後否決的做法

鎖高 GPU 時脈。生成時卡片看起來被限制住了,2145 MHz 只跑約 500 MHz,215 W 只吃 39 W,風扇安靜得像沒開機。我很得意地想「這一定是省電策略在拖」,鎖到 1800 MHz。同一句從 71.9 秒變 82.0 秒,慢 14%,GPU 使用率反而從 33% 掉到 14%。瓶頸在每個 token 的 CPU 側開銷:Python、kernel 啟動、Windows 的顯示驅動排程。GPU 大部分時間在等,你讓它跑更快只是讓它等得更快。這是我做過最反直覺的實驗,也是我最常拿出來講的一個。

把段落接成一長串生成再切開。比一句一句快,比四句一批慢,而且 422 個字只產出 79.9 秒音訊,同樣的字分開唸是 100.0 秒,少了五分之一。不是唸快了就是漏了內容,而且你聽不出來是哪一種,因為它唸得很流暢。流暢地漏內容,比結巴地唸完更可怕。

請雲端的文字模型分擔。語音的成本是 GPU 音訊解碼,沒有一部分是文字工作,這個想法在算之前就該否決。但我還是算了,因為那時候我什麼都想試。

小劇場:那我要不要買新顯卡

「你這張卡這麼舊,換一張不就都解決了?」

「換一張會快,但不會解決『你不知道哪裡慢』這個問題。」

「可是至少會快。」

「會。但我在這張卡上學會的量測方法,換卡之後還在。如果我一開始就用快的卡,我大概永遠不會發現鎖時脈會變慢。」

「所以舊卡是一種教育。」

「昂貴的教育,用時間付費。」

我對它的看法

它是一個認真的開源模型,在中階顯卡上跑得動,音色複製穩定,文件也算清楚。我後來換掉它是因為另一個模型用循序生成就比它批次化之後還快,不是因為它有什麼問題。

留下來的是方法:任何「應該會快」的改動都要量,在這種顯卡上直覺錯的比對的多。你覺得不算,量了才算。老師,我終於懂了,只是晚了好幾年。

那個 12Hz 是什麼

模型名字裡的 12Hz 是語音 tokenizer 的頻率:一秒鐘的聲音被表示成十二個 token。這個數字決定了很多事。頻率越低,一句話的 token 越少,自迴歸解碼的步數越少,速度越快;但頻率太低會丟掉細節。12 Hz 是這個模型選的平衡點,同系列還有 25 Hz 的版本,細節多一點、慢一倍。

Qwen 是阿里巴巴的模型家族,語言模型、視覺模型、語音模型都用這個名字。它們的開源策略很積極,權重放 Hugging Face、套件放 PyPI,文件是中英雙語。對中文使用者來說,這幾年最好用的開源模型有一大部分來自這個家族,這件事在幾年前大概沒有人想得到。

RTF 這個指標值得多解釋一句。real-time factor,生成時間除以音訊長度。RTF 1 表示唸一分鐘的稿要算一分鐘,剛好即時;RTF 0.1 表示算六秒就有一分鐘的音;RTF 4.4 表示要算四分多鐘。做離線內容的人 RTF 大於 1 沒關係,只是等;做即時對話的人 RTF 必須遠小於 1,不然使用者會覺得對方在思考人生。

常見的三個誤會

第一個誤會是「量測就是跑一次記時間」。第一次跑有冷啟動,最後一次跑有快取,中間的那幾次才是常態。至少跑三次,看中間值,我的物理老師會這樣說。

第二個誤會是「顯示卡使用率低就是沒在工作」。前面那個鎖時脈的實驗就是這個誤會的代價。使用率低可能是它在等 CPU,這時候讓它更快只是讓它等更久。要看的是整條鏈路的瓶頸在哪,不是某一個零件的儀表板。

第三個誤會是「批次越大越好」。到顯存上限之前是,超過之後 Windows 的驅動會默默借系統記憶體,速度掉下來但不報錯。批次大小要跟峰值顯存一起看,兩個數字放在同一張表上,不要分開看。

一個週末可以試的小練習

不一定要用這個模型,任何一個你手上能跑的模型都行。寫一個十行的量測腳本:記開始時間、跑一次、記結束時間、用 torch.cuda.max_memory_allocated() 讀峰值顯存、印出來。跑五次,把五組數字貼進試算表。

然後改一個參數,隨便一個,再跑五次。比較兩組的中間值和峰值。這半小時的重點不是那個參數改了有沒有比較快,是你會建立一個「改任何東西都量五次」的習慣。有了這個習慣之後,你會發現網路上很多「這樣改快三倍」的文章,作者大概只跑了一次,而且是第二次。

後記

物理老師如果知道她的口頭禪被我拿來寫語音模型的文章,大概會覺得很莫名其妙。但我後來想,實驗課教的從來不是那些公式,是「不要相信你覺得」這件事。這句話在寫程式、跑模型、甚至決定要不要買一張新顯卡的時候,都一樣有用。你覺得不算,量了才算。

模型頁面:huggingface.co/Qwen/Qwen3-TTS-12Hz-1.7B-Base

閱讀偏好

返回全部文章作者與內容更正

留言(0)

還沒有留言。讀完有想法,歡迎留下第一則。

留言經站長審核後才會顯示。暱稱和留言會公開,請不要寫下電話、地址等個人資料;資料怎麼處理,請見隱私權政策。