你想替一段影片做旁白,找到了「CPU 就能跑」的 KittenTTS,卻看到 V0.8、KittenTTS 2、GGUF 與 MLX。名字很像,下載的東西卻可能差了一整代。這篇 KittenTTS 2 本機配音教學,從選對檔案開始,帶你走到一份可逐字核對的繁中 WAV。
專為第一次接觸本機語音合成的讀者寫:先選電腦適合的路徑,再做一句旁白,最後才換成自己的聲音。你會用到終端機與一小段 Python;每段指令都說明用途,成果是音檔、逐字稿與版本紀錄。
先說結論:可用配音=正確版本+可控逐字稿+逐段驗收
把模型想成配音員,權重是同一位配音員的不同訓練版本,runtime 則是錄音室設備。換了設備,不能假設讀音完全相同;裝了同名套件,也要查實際載入的模型。
- 先明確指定
KittenML/kitten-tts-2,不要靠預設值判斷代數。 - 一般 CPU 先看官方 C++ 路徑;Apple silicon Mac 可選 MLX。兩條路分開安裝、分開記錄。
- 繁中稿使用
normalize=False,日期與金額先改成你想聽到的口語。 - 先用內建聲音完成短句;複製自己的聲音放在第二輪,並確認該 runtime 的輸入方式。
一、KittenTTS 2 本機配音教學:先分清三個零件
截至 2026 年 10 月 24 日,官方程式庫同時維護輕量 ONNX 的 V0.8 家族,以及 KittenTTS 2 語音語言模型。這裡的 TTS 是 text-to-speech,也就是「文字變語音」;它和把錄音轉成文字的語音辨識,方向正好相反。若你要的是對電腦口述輸入,先看 Whisper Local 與 open-wispr 的選擇教學。
第一個零件是套件,負責提供 generate() 等操作。第二個是 checkpoint(模型權重快照),決定這次使用哪份訓練結果。第三個是 runtime(執行方式),把權重真的跑起來。GGUF 是權重檔案格式,MLX 是 Apple silicon 上的運算框架,兩者不是模型世代的名稱。
本篇固定 Python 套件 kittenml==0.9.6、CPU 綁定 kitten_tts_cpp==0.2.0,主模型 revision 為 c93cb7c271baa51d9ae8204d5277988906f235a2。可把 revision 當成食譜的版本號:往後再做同一道菜,先確定拿到同一頁。這份設定檔的 type 是 KITTEN2,並列出對應的 C++ 資產。

二、第一步「備好錄音桌」:選路、隔離環境、核對授權
不知道該裝哪個?Windows/Linux 的一般 CPU 使用者先試 C++ 綁定;Apple silicon Mac 先試 MLX。Intel Mac 請從官方 C++ 建置文件核對環境;不要直接套用 MLX。MLX 官方指南明確要求 Apple silicon,並要求 weights="packed"。先保留預設解碼器,之後要換小型解碼器時再重新聽品質。
先開一個空資料夾。在已備有 Python 3.12 的 macOS/Linux,可依序執行 python3.12 -m venv .venv 與 source .venv/bin/activate。Windows PowerShell 則用 py -3.12 -m venv .venv,再執行 .venv\Scripts\Activate.ps1。虛擬環境就像獨立抽屜,讓這篇的依賴和其他專案分開。先用 python --version 確認目前進的是哪個抽屜。
雖然 README 部分段落仍寫 Python 3.9,這次核對的 0.9.6 套件宣告要求 3.10 以上,因此本篇採 3.12。只選下面一條安裝指令;CPU wheel 若顯示平台不相容,先到 0.2.0 官方發布檔核對作業系統、處理器與 Python 版本,不要拿不明轉檔補上。
# CPU C++ 路徑
python -m pip install "kitten_tts_cpp==0.2.0" soundfile
# Apple silicon Mac 路徑:在另一個獨立環境選用這行
python -m pip install "kittenml[mlx]==0.9.6" soundfile
# 安裝完成後保存依賴版本
python -m pip freeze > requirements-lock.txt
做私人練習和替公司接案,要先分開。程式碼採 Apache 2.0;KittenTTS 2 權重採 Stellon Labs Community License。官方商用說明要求商業使用先登記;年營收與累計募資都低於一百萬美元的範圍可申請免費商用,任一達一百萬美元的情境應先走付費授權確認。範圍還會合併關係企業,不是只看這支配音賺了多少。散布模型或建於模型的產品,另有附授權、Notice 與署名義務。
三、第二步「寫成要聽到的話」:繁中日期與金額先消歧義
文字看得懂,不等於配音會照你想的方式念。這個 revision 的模型卡要求非英文輸入關閉英文導向的正規化,因此以下範例都用 normalize=False。這個開關是「別替我用英文規則展開文字」,不是「自動修好中文發音」。
先把 10/24,NT$1,280,KittenTTS 2 改成「十月二十四日,費用是一千兩百八十元。這是 Kitten T T S 第二版。」這是你替本次作品指定的念法。若要念年份,也寫清楚「二零二六年」;「一二八零」和「一千兩百八十」有不同用途,別讓模型猜。
建立 script.txt,第一輪只放一句:「十月二十四日,這堂課的費用是一千兩百八十元。」第二輪再加一句專有名詞,第三輪才加語氣。每次只改一項,你才聽得出是哪個改動有效。先保留原稿和口語稿兩份,之後剪片時可以回查。

四、KittenTTS 2 本機配音教學:兩條路產出第一份 WAV
①「CPU 錄音室」:指定 revision,再檢查可用聲音
把下面存為 cpu_voice.py,再執行 python cpu_voice.py。threads=8 是起始設定,並非每台電腦的最佳值;先讓同一段稿件完整念完,再試其他執行緒數。C++ 會依固定 revision 的 manifest 取回 GGUF、解碼器與聲音資料;首次載入含下載,和之後的等待要分開記。
from pathlib import Path
from time import perf_counter
import json
import soundfile as sf
from kitten_tts_cpp import KittenTTS
revision = "c93cb7c271baa51d9ae8204d5277988906f235a2"
t0 = perf_counter()
m = KittenTTS("KittenML/kitten-tts-2", revision=revision,
decoder="default", threads=8)
load_s = perf_counter() - t0
print(m.available_voices)
if "Chinese" not in m.available_voices:
raise RuntimeError("此原生資產未列出 Chinese,先核對版本與聲音清單")
text = Path("script.txt").read_text(encoding="utf-8").strip()
for run in (1, 2):
t1 = perf_counter()
audio = m.generate(text, voice="Chinese", normalize=False,
preset="stable", advanced={"seed": 1234})
generation_s = perf_counter() - t1
if len(audio) == 0:
raise RuntimeError("音訊為空,先檢查生成紀錄")
sf.write(f"cpu-{run}.wav", audio, m.sample_rate)
seconds = len(audio) / m.sample_rate
report = {"revision": revision, "backend": "cpp",
"voice": "Chinese", "decoder": "default", "threads": 8,
"text": text, "load_s": load_s,
"generation_s": generation_s, "audio_s": seconds,
"rtf": generation_s / seconds,
"native_report": m.last_report}
Path(f"cpu-{run}.json").write_text(
json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
m.close()
這份程式會保存兩個 WAV 和兩份 JSON。先打開聲音清單;若沒有 Chinese,程式會停下,讓你先查配套資產。同一個品牌、相同檔名,不足以證明轉檔來自同一個 checkpoint。改用第三方 GGUF 時,要能追到來源 revision 與轉檔方式,否則先回到官方配套。上面介面已逐項核對官方 0.2.0 發布 wheel 的 Python 原始碼;它仍是官方標記的 beta 路徑。
②「Mac 錄音室」:先下載固定快照,再交給 MLX
MLX 這條路先把主模型下載到固定目錄,再由本機目錄載入。把下面存為 mac_voice.py,執行 python mac_voice.py。這段只下載 packed 語言模型及配套設定,不把其他重量格式一起拉下來。主權重之外,這版音訊解碼還會取用 ResembleAI/chatterbox-turbo 的 s3gen 資產;固定主模型不等於封存整套依賴,交付時也要記錄實際下載檔案的快取快照與雜湊。
from pathlib import Path
from time import perf_counter
import json
import soundfile as sf
from huggingface_hub import snapshot_download
from kittenml import KittenTTS
revision = "c93cb7c271baa51d9ae8204d5277988906f235a2"
folder = snapshot_download(
"KittenML/kitten-tts-2", revision=revision,
allow_patterns=["config.json", "LICENSE.md", "README.md",
"lm/*.json", "lm/*.txt", "lm/model-ternary.safetensors",
"speaker/*", "voices/*"],
local_dir="model-kitttentts2-pinned")
t0 = perf_counter()
m = KittenTTS(folder, backend="mlx", weights="packed")
load_s = perf_counter() - t0
text = Path("script.txt").read_text(encoding="utf-8").strip()
for run in (1, 2):
t1 = perf_counter()
audio = m.generate(text, voice="Chinese", normalize=False,
preset="stable", advanced={"seed": 1234})
generation_s = perf_counter() - t1
if len(audio) == 0:
raise RuntimeError("音訊為空,先檢查生成紀錄")
sf.write(f"mac-{run}.wav", audio, m.sample_rate)
seconds = len(audio) / m.sample_rate
report = {"revision": revision, "backend": "mlx", "weights": "packed",
"voice": "Chinese", "decoder": "default", "text": text,
"load_s": load_s, "generation_s": generation_s,
"audio_s": seconds, "rtf": generation_s / seconds}
Path(f"mac-{run}.json").write_text(
json.dumps(report, ensure_ascii=False, indent=2), encoding="utf-8")
檔案生成後,先聽 mac-1.wav,再聽第二份。官方指南指出首輪會編譯 Metal 核心,因此首輪與後續生成要各記一筆。相同 seed(抽樣亂數的起點)也不保證跨 C++、PyTorch、MLX 得到相同波形;官方相容性說明明確區分權重一致與生成結果逐樣本一致。
五、第三步「換成自己的聲音」:錄音與逐字稿成對保存
先完成內建聲音,再錄一段你自己的乾淨聲音。官方建議單一說話者的五到三十秒錄音;選沒有背景音樂、沒有另一個人插話的片段,存成 my_voice.wav。本次練習只用自己的錄音;若要換別人的聲音,先取得涵蓋這次合成與發布用途的同意,並把用途與允許期限和檔案一起保存。
在 Mac 範例建立好 m 之後,用下面這一行替換 m.generate(...),並把後續輸出檔名另存為 my-voice-1.wav 等新名稱。reference_text 必須是參考錄音真的說過的話,不是你這次要生成的旁白。官方 API 說明把這兩份文字分開;提供正確逐字稿也能略過自動轉錄那一輪。
audio = m.generate(text, reference="my_voice.wav",
reference_text="這裡逐字填入我在參考錄音中實際說的話。",
normalize=False, preset="stable",
advanced={"seed": 1234})
C++ 0.2.0 綁定不能把原始 WAV 直接丟進 reference= 完成聲音複製。該版介面會直接拋出 NotImplementedError;官方C++ 範圍說明要求先用離線 Python 準備參考聲音,再以聲音名稱選取。新手先完成內建 Chinese;想直接用自己的短錄音,採上面的 MLX 路徑,或依 Python 主套件文件選擇相容的 PyTorch 環境。不要把兩套匯入名稱視為完全可互換。
六、第四步「交出作品」:速度、讀音與漏字各有一張成績單
先聽完整,再看快慢。把稿件分成日期、金額、專有名詞、句尾四個核對點:日期是否念成你指定的月份與日子?一千兩百八十是否漏了八十?英文縮寫是否變成另一個詞?最後一個字是否被截斷?發現錯誤先縮短句子、改口語稿,再重生成該段。
速度用 RTF=生成秒數÷音訊秒數 判讀。假設生成花十二秒、音檔長二十秒,RTF 就是 0.6;這是算式示例。低於 1 代表該段生成比播放快,但不代表按下按鈕立刻有聲音。下載、載入、首輪暖機、檔案寫入及串流第一段延遲,都是另外的時間。上面的 generation_s 量的是呼叫生成到回傳音訊,不含後面的寫檔。
為什麼不直接承諾 CPU 即時?原始 tts-bench 測試紀錄在 2026 年 10 月 22 日回報:Windows、9950X3D、C++ 0.2.0 與權重 1f00fee5 的組合未達即時,且作者明說尚未嘗試原生 SIMD 建置。那是另一份設定與權重的觀察,不能直接預測你這次固定快照的速度,更不能拿來排名繁中音質。

最後建立一個交付資料夾:收進確認過的 WAV、原稿、口語稿、JSON 紀錄、requirements-lock.txt,另記作業系統、處理器、參考錄音與使用同意。若要接到影片,VoiceStudio 本機配音流程補上翻譯與影片的後續工作;若要做雙人對話,Gemini 繁中雙人 WAV 教學提供另一種創作方式。
常見問題:八個直接答案
1. V0.8 是不是 KittenTTS 2 的小檔案版?
不是。官方把兩個模型家族分開描述。先看完整 repo ID 和 config 類型,別用下載大小判斷世代。
2. 看到支援 Chinese,就等於繁中口音一定符合我的需求?
不等於。Chinese 是語言/聲音選項,這份作品的地名、日期與口音仍要拿自己的稿件逐句試聽。
3. 非英文也開著 normalize,會更自然嗎?
先關閉。這個 revision 的模型卡明確要求非英文使用 normalize=False;數字與日期由你在口語稿寫清楚。
4. CPU 一定比 MLX 慢嗎?
不能只看名稱下結論。電腦、執行緒、解碼器、版本與稿件一起決定等待時間;先在自己的機器保存同條件紀錄。
5. 固定 revision,就完全能重現別人的聲音?
不夠。還要對上套件、解碼器、參考檔、生成設定與執行環境;主套件另取的音訊資產也要留存身份。
6. 同一個 seed,換 runtime 會完全一樣嗎?
不會有這項保證。官方明列跨後端浮點運算與抽樣差異,應比較讀音與完整度,不要要求 WAV 位元組相同。
7. 我可以直接把 C++ 範例改成 reference=my_voice.wav 嗎?
0.2.0 這個介面不行。先完成官方離線參考聲音準備;直接短錄音的操作則採主套件路徑。
8. 程式免費,就可以直接替公司接案嗎?
先核對權重商用資格與登記。程式碼的 Apache 2.0 並未替你完成 Community License 的商用與散布條件。
給新手的三個重點
- 版本先對齊:明確指定模型與 revision,記錄執行路徑和解碼器。
- 稿件先消歧義:關閉英文正規化,把數字、日期與名稱寫成要聽到的念法。
- 作品先驗收:完整、念對、可用的旁白,比單一速度數字更接近創作目標。
接著閱讀
左右滑動查看更多推薦
下一步:今天只交出一句念對的旁白
先把「十月二十四日,費用是一千兩百八十元」做成一個 WAV,關掉畫面聽一次,再看著稿件聽一次。日期、金額和句尾都對上,才換自己的聲音、加語氣或擴成一分鐘作品。記住正確版本+可控逐字稿+逐段驗收,你就有了下一支旁白可以沿用的工作方法。更多創作與 AI 工作流,可從 AlphaLab AI 專區與 AI 系統課程接著練習。






