SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

VPS 自架 Whisper 語音轉文字與 Piper TTS

在沒有 GPU 的 VPS 上執行 Whisper 與 Piper,了解 CPU 時間、磁碟需求,以及如何建立相容 OpenAI API 的 endpoint,讓現有 client 只需更換 base URL。

簡述自架語音轉文字與 TTS

自架語音轉文字與 TTS(文字轉語音)是最便宜的伺服器端 AI。轉錄透過 faster-whisper runtime 執行 Whisper。語音合成則使用 Piper。兩者都能在完全沒有 GPU 的一般 CPU VPS 上運作。較小的 Whisper 模型約需 484 MB 磁碟空間,而 Piper 語音模型是單一檔案,大小遠低於 150 MB。

因此,音訊是適合開始的項目。自架影像產生器自架影片產生 在實際使用前都需要 GPU。音訊則不需要。

本指南涵蓋語音轉文字、文字轉語音,以及連接兩者的服務層。Whisper 將音訊轉換為文字。Piper 將文字轉換為音訊。在兩者前方加入相容 OpenAI API 的 HTTP server,現有 client 只需改用 base URL,即可指向你的伺服器,其他設定無須變更。

本文提到的所有版本截至 August 2026 均為當時的最新版本。

為什麼選 faster-whisper,而不是官方 Whisper 套件

OpenAI 的 whisper 套件使用 PyTorch 執行模型。faster-whisper 則使用專為 transformer 模型設計的推論引擎 CTranslate2,執行相同的模型權重。兩者的權重完全相同,因此產生的逐字稿也相同。差異完全在執行環境。

CTranslate2 載入權重時會進行量化,因此 compute_type="int8" 只需一個引數,不需要另外執行轉換步驟。它也不相依於 PyTorch。pip install faster-whisper 會安裝 CTranslate2、tokenizer 和用於音訊解碼的 PyAV,因此虛擬環境的大小是數百 MB,而不是數 GB。在磁碟容量為 40 GB 的 VPS 上,這項差異會直接影響可用空間是否充裕。

以下是該專案針對 CPU 上 small 模型發布的數據。基準測試使用 Intel Core i7-12700K 的 8 個執行緒,轉錄 13 分鐘的音訊。x_realtime 欄位是 13 分鐘除以實際測得的執行時間:7.6 表示 13 分鐘的錄音在略多於 1 分 40 秒內完成。

ChartWhisper small on CPU, 13 minutes of audio (published project figures)
The data behind this chart
[
  {
    "label": "openai/whisper, fp32",
    "x_realtime": 1.9,
    "seconds": 418,
    "memory_mb": "2,335"
  },
  {
    "label": "whisper.cpp, fp32",
    "x_realtime": 6.2,
    "seconds": 125,
    "memory_mb": "1,049"
  },
  {
    "label": "faster-whisper, fp32",
    "x_realtime": 5.0,
    "seconds": 157,
    "memory_mb": "2,257"
  },
  {
    "label": "faster-whisper, int8",
    "x_realtime": 7.6,
    "seconds": 102,
    "memory_mb": "1,477"
  },
  {
    "label": "faster-whisper, int8, batch 8",
    "x_realtime": 15.3,
    "seconds": 51,
    "memory_mb": "3,608"
  }
]

請如實解讀第二列。在此 CPU 上,fp32 模式的 whisper.cpp 比 faster-whisper 快,速度分別為 6.2x 與 5.0x,而且記憶體用量不到後者的一半。它使用的就是支援 本機 LLM 堆疊中 llama.cpp 部分的同一個 ggml 系列。啟用 int8 與批次處理後,faster-whisper 會領先,達到 15.3x,但需要 3,608 MB RAM。因此,如果需要 Python API 和批次處理,請選擇 faster-whisper;如果 RAM 是無法增加的限制,請選擇 whisper.cpp。

第一列就是本節的重點。在同一台機器上,官方套件的速度是即時速度的 1.9x,表示 1 小時的音訊需要使用 CPU 處理半小時。

Whisper 模型權重需要多少磁碟空間?

Chartfaster-whisper model weights on disk (Systran CTranslate2 conversions, float16)
The data behind this chart
[
  {
    "label": "tiny",
    "weights_mb": 75.5
  },
  {
    "label": "base",
    "weights_mb": 145
  },
  {
    "label": "small",
    "weights_mb": 484
  },
  {
    "label": "medium",
    "weights_mb": "1,530"
  },
  {
    "label": "large-v3",
    "weights_mb": "3,090"
  }
]

以下是已發布的 CTranslate2 float16 轉換版本。請注意,compute_type="int8"不會縮小下載檔案。權重會以 float16 形式下載,CTranslate2 在載入時於記憶體中進行量化。因此,無論以 float16 或 int8 執行,large-v3 在磁碟上都需要 3,090 MB。int8 可節省 RAM 並提升速度,但不會節省磁碟空間。

模型會在首次使用時下載至 ~/.cache/huggingface/hub。如果 VPS 的根磁碟區容量較小,請使用 download_root 引數或 HF_HOME 環境變數,將下載位置指定到有足夠空間的路徑。否則首次執行時可能會填滿磁碟,導致程序在下載途中終止。

安裝 faster-whisper,避免破壞系統 Python

Ubuntu 24.04 和 Debian 13 會將系統 Python 標記為由外部管理。在虛擬環境外執行 pip install faster-whisper 會立即停止,並顯示:

error: externally-managed-environment

這是套件管理系統在保護由 apt 所管理檔案。請使用虛擬環境。

sudo apt update
sudo apt install -y python3-venv ffmpeg
python3 -m venv ~/stt
~/stt/bin/pip install --upgrade pip
~/stt/bin/pip install faster-whisper==1.2.1

版本 1.2.1 是目前版本,於 October 2025 發布。faster-whisper 透過 PyAV 解碼音訊。PyAV 內含自己的 ffmpeg 程式庫,因此不需要另外安裝 ffmpeg binary,就能讀取 mp3 或 m4a。上方的 ffmpeg package 是本指南後續影片處理所需。

下載三 gigabytes 的權重前,先確認安裝是否成功:

~/stt/bin/python -c "from faster_whisper import WhisperModel; print('ok')"

若顯示 ok,表示 wheels 已成功安裝。若出現名為 ImportErrorctranslate2,表示未安裝適用於目前架構的 wheel。這種情況會發生在 32-bit ARM 映像檔上。

轉錄會議錄音或語音備忘錄

將以下內容儲存為 transcribe.py

from faster_whisper import WhisperModel

model = WhisperModel("small", device="cpu", compute_type="int8", cpu_threads=4)
segments, info = model.transcribe("meeting.m4a", beam_size=5, vad_filter=True)

print("language: %s (%.2f)" % (info.language, info.language_probability))
for segment in segments:
    print("[%.2fs -> %.2fs] %s" % (segment.start, segment.end, segment.text))

使用 ~/stt/bin/python transcribe.py 執行。第一次執行會下載權重,因此一段時間內不會輸出任何內容。之後模型會從快取載入,幾秒內即可完成。

segments 是產生器,因此必須對其進行迭代,轉錄才會開始。有些人計算 transcribe() 呼叫所需的時間,看到它立即返回,就以為發生問題。實際上沒有問題。工作是在迴圈中執行。

vad_filter=True 會先執行 Silero VAD(語音活動偵測),在 Whisper 處理音訊前移除無聲片段。對於有長時間停頓的會議錄音,這是可用的最大單項加速方式,因為 Whisper 完全不必處理沒有語音的音訊。這也能抑制 Whisper 在收到無聲音訊後,試圖從中辨識文字而產生的重複句迴圈。

cpu_threads 設為實際擁有的核心數。若設定值高於 vCPU 數量,轉錄速度會變慢,因為額外執行緒會爭用相同的核心,而排程器也必須承擔每次執行緒切換的成本。

Jellyfin 媒體庫的字幕

Jellyfin 會讀取放在影片旁邊、且檔名相同的外部字幕檔,因此將 Movie (2019).en.srt 放在 Movie (2019).mkv 旁邊後,Jellyfin 會將其顯示為英文音軌,不需轉碼,也不需重建媒體庫。

先擷取音訊。Whisper 內部會將所有音訊重新取樣為 16 kHz 單聲道,因此先提供 16 kHz 單聲道音訊,可減少兩端的處理工作:

ffmpeg -i "Movie (2019).mkv" -vn -ac 1 -ar 16000 -c:a pcm_s16le "Movie (2019).wav"

faster-whisper 沒有 SRT 寫入器,因此請自行格式化各個片段。將以下內容儲存為 srt.py

import sys
from faster_whisper import WhisperModel

def ts(seconds):
    ms = int(round(seconds * 1000))
    hours, ms = divmod(ms, 3600000)
    minutes, ms = divmod(ms, 60000)
    secs, ms = divmod(ms, 1000)
    return "%02d:%02d:%02d,%03d" % (hours, minutes, secs, ms)

model = WhisperModel("small", device="cpu", compute_type="int8")
segments, info = model.transcribe(sys.argv[1], vad_filter=True)

with open(sys.argv[2], "w", encoding="utf-8") as out:
    for index, segment in enumerate(segments, start=1):
        out.write("%d\n" % index)
        out.write("%s --> %s\n" % (ts(segment.start), ts(segment.end)))
        out.write("%s\n\n" % segment.text.strip())

接著遍歷媒體庫:

for f in /srv/media/films/*.mkv; do
  ffmpeg -nostdin -y -i "$f" -vn -ac 1 -ar 16000 -c:a pcm_s16le "${f%.mkv}.wav"
  nice -n 15 ~/stt/bin/python srt.py "${f%.mkv}.wav" "${f%.mkv}.en.srt"
  rm -f "${f%.mkv}.wav"
done

-nostdin 並非裝飾用途。沒有它時,ffmpeg 會從迴圈的標準輸入讀取資料,吞掉檔案清單的其餘內容,導致迴圈在處理一部影片後停止,而且不會顯示錯誤訊息。

開始前先估算所需時間。以上述 7.6x 速度計算,一部 100 分鐘的影片約需 13 分鐘的 CPU 時間,因此 50 部影片的媒體庫需要執行一整晚。在共用 vCPU 方案上,速度會更慢;這正是 nice 的用途:字幕處理工作會讓出資源,讓伺服器能繼續執行其他工作。

使用 Piper 進行文字轉語音

Piper 是在 CPU 上執行 ONNX 語音模型的神經網路文字轉語音引擎。它內嵌 espeak-ng,會將文字轉換為音素,因此不需要另外安裝音素轉換器。目前版本為 1.6.0,發布於 July 2026。

python3 -m venv ~/tts
~/tts/bin/pip install piper-tts==1.6.0
~/tts/bin/python -m piper.download_voices en_US-lessac-medium
~/tts/bin/python -m piper -m en_US-lessac-medium -f test.wav -- 'This is a test.'

download_voices 會在工作目錄中寫入 2 個檔案:.onnx 權重檔案,以及包含取樣率與說話者清單的 .onnx.json 設定檔。這 2 個檔案必須放在一起。如果將語音檔案存放在固定位置,請對這 2 個命令都傳入 --data-dir,因為播放器預設會在工作目錄中尋找語音檔案,找不到不在該目錄中的語音。

文字前的 -- 也很重要。沒有它時,任何以連字號開頭的句子都會被解析為命令列選項。

語音檔案提供數種品質等級。中等品質的英文語音約為 60 MB,高品質語音約為其 2 倍。較高的品質代表模型較大,且每秒語音需要更多 CPU,不代表使用不同的說話者。

不要在迴圈中呼叫 CLI。每次呼叫都會載入模型,而對短句而言,載入模型的成本通常占大部分。請改為執行 HTTP server:

~/tts/bin/pip install 'piper-tts[http]==1.6.0'
~/tts/bin/python -m piper.http_server -m en_US-lessac-medium --host 127.0.0.1 --port 5000
curl -X POST -H 'Content-Type: application/json' \
  -d '{ "text": "This is a test." }' \
  -o test.wav localhost:5000/synthesize

只要能播放 test.wav,就表示運作正常。該端點採用 Piper 自有的格式,不是 OpenAI 的格式,因此預期使用 /v1/audio/speech 的用戶端無法與它通訊。下一節會修正這個問題。

請使用 unit file 讓它持續執行,不要依賴即將關閉的終端機:

[Unit]
Description=Piper text to speech HTTP server
After=network-online.target

[Service]
User=piper
ExecStart=/home/piper/tts/bin/python -m piper.http_server -m en_US-lessac-medium --data-dir /home/piper/voices --host 127.0.0.1 --port 5000
Restart=on-failure

[Install]
WantedBy=multi-user.target

sudo systemctl enable --now piper 會啟動它,並在重新開機後重新啟動。如果上方的 curl 沒有回傳任何內容,journalctl -u piper -n 50 會記錄原因;最常見的原因是缺少語音檔案。

OpenAI 相容伺服器的形式

大多數處理音訊的軟體已經支援 OpenAI audio API:對 /v1/audio/transcriptions 傳送包含檔案的 multipart POST,對 /v1/audio/speech 傳送包含句子的 JSON POST。自行提供這兩個路徑後,客戶端只需修改 base URL。

Speaches 是一個同時支援兩個方向的伺服器。它在 OpenAI 路徑後方使用 faster-whisper 進行轉錄,並使用 Piper 或 Kokoro 產生語音。目前版本是 2025 年 12 月發布的 v0.9.0-rc.3,仍未達到 1.0,因此請固定映像標籤,並在升級前閱讀 release notes。

curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.yaml
curl --silent --remote-name https://raw.githubusercontent.com/speaches-ai/speaches/master/compose.cpu.yaml
export COMPOSE_FILE=compose.cpu.yaml
docker compose up --detach

如果不想維護 compose 檔案,也可以使用單一容器形式:

docker run --rm --detach --publish 8000:8000 --name speaches \
  --volume hf-hub-cache:/home/ubuntu/.cache/huggingface/hub \
  ghcr.io/speaches-ai/speaches:latest-cpu

具名 volume 是最容易被省略的部分。沒有它,模型快取會儲存在容器內,因此每次重新啟動都會重新下載數 GB 的權重,第一個請求也必須等到下載完成後才會收到回應。

語音功能需要先下載 voice,/v1/audio/speech 才會回應:

uvx speaches-cli model download speaches-ai/Kokoro-82M-v1.0-ONNX

完成後,任何 OpenAI 客戶端都能使用,只需修改 base URL:

from pathlib import Path
from openai import OpenAI

openai = OpenAI(base_url="http://localhost:8000/v1", api_key="cant-be-empty")
res = openai.audio.speech.create(
    model="speaches-ai/Kokoro-82M-v1.0-ONNX",
    voice="af_heart",
    input="Hello, world!",
    response_format="mp3",
    speed=1,
)
with Path("output.mp3").open("wb") as f:
    f.write(res.response.read())

之所以需要佔位符 api_key,是因為 OpenAI 客戶端函式庫沒有它就不會傳送請求。在設定真正的 key 前,伺服器會忽略其值。

vox-box 是另一個值得介紹的專案。它是 Python package,不是容器,並使用 Whisper、FunASR、Bark、Dia 或 CosyVoice 提供相同的路徑。當前版本是 2025 年 12 月發布的 0.0.21,且需要 Python 3.10 或更新版本。

python3 -m venv ~/voice
~/voice/bin/pip install vox-box==0.0.21
~/voice/bin/vox-box start --huggingface-repo-id Systran/faster-whisper-small \
  --data-dir ~/voice/data --host 127.0.0.1 --port 8010

該專案提供的範例會繫結 port 80,因此需要 root。在還執行其他服務的伺服器上,讓 reverse proxy 代理較高的 port 是更好的做法。vox-box start 一次只能載入一個模型,因此若要同時支援兩個方向,需在第二個 port 上啟動第二個執行個體,並指定語音模型的 repo id。

先詢問伺服器已載入哪些內容,再將該 id 填入 model 欄位:

curl http://127.0.0.1:8010/v1/models
curl http://127.0.0.1:8010/v1/audio/transcriptions \
  -H "Content-Type: multipart/form-data" \
  -F file="@voice-note.m4a" \
  -F model="faster-whisper-small"

格式為 {"text": "..."} 的 JSON body 代表整個路徑可正常運作。若模型名稱得到 404,表示你是自行猜測,而不是讀取 /v1/models 的輸出。

這些伺服器都不會預設啟用驗證。請將它們繫結至 127.0.0.1,並透過 VPN 或要求輸入認證資訊的 reverse proxy 存取。公開 IP 上開放的 /v1/audio/transcriptions 等於為找到它的人免費提供 CPU,而他們一定找得到。

自行託管助理的語音前端

當雙向都能透過 OpenAI 路徑回應後,聊天前端就能驅動這兩個方向。Open WebUI 及其替代方案可在設定中接受與 OpenAI 相容的音訊 base URL,因此單一主機即可使用 Ollama 執行本機 LLM,在兩端完成語音迴路。

請如實估算延遲,因為這 3 個步驟會在相同的 CPU core 上依序執行。以上述 7.6x 的速度計算,10 秒的問題約需 1.3 秒才能完成轉錄,而且這還是在模型讀取第一個 token 之前。再加上 CPU token 生成時間後,整個往返速度會慢到讓測試人員以為服務已當機。批次轉錄在 CPU 上尚可接受,但對話則不然。此時,使用配備 GPU 的 VPS才開始值得其價格。

GPU 何時才真正值得使用?

ChartWhisper large-v2 on an RTX 3070 Ti, 13 minutes of audio (published project figures)
The data behind this chart
[
  {
    "label": "openai/whisper, fp16",
    "x_realtime": 5.5,
    "seconds": 143,
    "memory_mb": "4,708"
  },
  {
    "label": "faster-whisper, fp16",
    "x_realtime": 12.4,
    "seconds": 63,
    "memory_mb": "4,525"
  },
  {
    "label": "faster-whisper, int8",
    "x_realtime": 13.2,
    "seconds": 59,
    "memory_mb": "2,926"
  },
  {
    "label": "faster-whisper, int8, batch 8",
    "x_realtime": 48.8,
    "seconds": 16,
    "memory_mb": "4,500"
  }
]

在 GPU 上,int8 的 large model 會以 13.2 倍即時速度執行,使用 2,926 MB VRAM;啟用批次處理後可達 48.8 倍。請特別注意兩個圖表未說明的事項。它們使用不同的模型:GPU 列使用 large-v2,CPU 列使用 small。GPU 不會讓 small model 快 6 倍,而是讓高準確度模型變得可用。

這些數字的來源

兩個圖表都重現 faster-whisper README 發布的基準測試結果。音訊是單一 13 分鐘檔案。CPU 列在 Intel Core i7-12700K 上使用 8 個執行緒,GPU 列則在配備 8 GB VRAM 的 NVIDIA RTX 3070 Ti 上使用 CUDA 12.4。秒數與記憶體欄位是已發布的數值。x_realtime 欄位是在此基礎上計算而得:以 780 秒的音訊長度除以測得的執行時間,再四捨五入至小數點後 1 位。CPU 圖表的記憶體欄位代表系統 RAM,GPU 圖表則代表 VRAM。

共享 vCPU 方案無法達到 CPU 圖表中的數值。該基準測試獨占一台高效能桌上型處理器的 8 個執行緒。請將 7.6 倍視為上限,並先使用 time 在實際錄音上測試自己的主機,再據此規劃。

以下 4 項經驗法則在實務上可靠:

  • 偶爾轉錄自己的錄音:使用 CPU、small、int8。2 個專用 vCPU 已足夠。
  • 例如整晚批次處理字幕:使用 CPU、small 或 medium、int8,並以 nice 執行。
  • 需要互動式處理,或希望在一個晚上處理完整個人媒體庫:使用 GPU。
  • Piper:一律使用 CPU。這種大小的語音模型幾乎無法從 GPU 獲得效能提升。

如果你正在評估同一套硬體還能執行哪些工作,哪些 AI 模型適合自行代管的更廣泛問題會說明哪些模型大小能夠或無法容納。

錯誤情況與對應訊息

error: externally-managed-environment 在安裝時出現。發行版會保護系統 Python。請依照上述方式建立虛擬環境。

GPU 主機上的 cuDNN 不相容。 錯誤訊息如下:

Unable to load any of {libcudnn_ops.so.9.1.0, libcudnn_ops.so.9.1, libcudnn_ops.so.9, libcudnn_ops.so}
Invalid handle. Cannot load symbol cudnnCreateTensorDescriptor

CTranslate2 4.5.0 及後續版本在 CUDA 12 上需要 cuDNN 9,但主機使用的是 cuDNN 8。請安裝 cuDNN 9,或使用 pip install --force-reinstall ctranslate2==4.4.0 鎖定較舊的執行環境。兩者擇一即可。同時執行兩者會回到原本的問題。

This CTranslate2 package was not compiled with CUDA support 是另一種故障,但表現類似。已安裝的 wheel 是僅支援 CPU 的版本。請在 GPU 主機上重新建立虛擬環境,讓 pip 再次選取 wheel。

轉錄文字重複出現相同句子。 某個句子重複 10 次,幾乎都是因為靜音或音樂被誤解碼為語音。請先啟用 vad_filter=True。如果問題仍存在,請聆聽該片段:接近靜音的音訊無法提供 Whisper 足夠的依據,因此它會重複最後一次有信心的猜測。

偵測到錯誤的語言。 Whisper 只會根據前 30 秒進行猜測。info.language_probability 明顯低於 1.0,表示模型無法確定;錄音開頭是音樂或多人同時說話時,就可能發生這種情況。如果已知語言,請傳入 language="en"

程序輸出 Killed 後停止。 這是核心的 out-of-memory killer,dmesg 會顯示相符的 oom-kill 訊息。large-v3 光是載入權重就需要超過 3 GB,還不包含工作記憶體。在 2 GB VPS 上,int8 的 small 是能夠容納的最大模型。

Piper 找不到語音。 除非傳入 --data-dir,否則播放器會在工作目錄中尋找。請對預期的目錄執行 ls,並確認 .onnx.onnx.json 都存在,因為只存在其中一個會失敗,兩者都不存在也一樣。

FAQ

我可以在僅有 CPU 的 VPS 上執行語音轉文字嗎?

可以,對批次處理而言,這是合理的選擇。使用 int8 的 small 模型搭配 faster-whisper 時,該專案公布的基準測試顯示,在桌上型 i7 的 8 個執行緒上,將 13 分鐘的音訊轉錄為文字需要 102 秒,速度約為即時的 7.6 倍,使用 1,477 MB 記憶體。共享 vCPU 方案的速度會比這項結果慢,因此請測量自己的伺服器。Piper 的文字轉語音更容易執行,在任何情況下都不需要 GPU。

我應該使用哪種 Whisper 模型大小?

請從 int8 的 small 模型開始。該模型佔用 484 MB 磁碟空間,處理清晰的錄音語音效果良好。若口音或背景噪音造成無法接受的錯誤,再升級至 medium。只有在準確度比其他因素都重要時,才使用 large-v3,因為它需要 3,090 MB 磁碟空間及超過 3 GB 記憶體。反過來說,大小為 75.5 MB 的 tiny 適合語言偵測與測試處理流程,不適合產生供人閱讀的轉錄文字。

為什麼 faster-whisper 比原始的 Whisper 套件快?

模型相同,但執行環境不同。參考套件在 PyTorch 中執行 Whisper;faster-whisper 則在 CTranslate2 上使用相同的權重。CTranslate2 是專為 transformer 推論設計的引擎,會在載入時量化權重,且不需要安裝 PyTorch。在公布的 CPU 基準測試中,參考套件的速度為即時的 1.9 倍;faster-whisper 使用 int8 時則為 7.6 倍,且記憶體用量較低。

為什麼我的轉錄文字會不斷重複相同的句子?

Whisper 將靜音或音樂解碼為語音,並反覆使用最近一次有信心的猜測。請在 transcribe() 呼叫中設定 vad_filter=True。該設定會先執行 Silero voice activity detection,並在模型處理音訊前移除靜音片段。若仍然重複,請檢查音訊音量,因為幾乎全程無聲的錄音無法提供模型足夠的資訊。

如何在自己的伺服器上取得與 OpenAI 相容的音訊端點?

執行實作 POST /v1/audio/transcriptionsPOST /v1/audio/speech 的伺服器,然後透過新的 base URL 將用戶端指向該伺服器。Speaches 是其中一個選項,提供容器映像檔與 CPU build,使用 faster-whisper 進行轉錄,並使用 Piper 或 Kokoro 進行語音處理。另一個選項是 vox-box,可使用 pip install vox-box 安裝,再以 vox-box start --huggingface-repo-id 啟動;每個程序會提供一個模型。這兩者預設都不啟用驗證,因此請繫結至 localhost,並在前方配置 proxy 或 VPN。

#whisper#tts#piper#speech-to-text#self-hosted-ai