音訊課程文件
文字轉語音的預訓練模型
並獲得增強的文件體驗
開始使用
文字轉語音的預訓練模型
與 ASR(自動語音識別)和音訊分類任務相比,可用的預訓練模型檢查點明顯較少。在 🤗 Hub 上,你會發現將近 300 個合適的檢查點。在這些預訓練模型中,我們將重點關注 🤗 Transformers 庫中現成的兩種架構——SpeechT5 和 Massive Multilingual Speech (MMS)。在本節中,我們將探討如何在 Transformers 庫中使用這些預訓練模型進行 TTS。
SpeechT5
SpeechT5 是微軟的 Junyi Ao 等人釋出的一個模型,能夠處理一系列語音任務。雖然在本單元中,我們側重於文字轉語音方面,但該模型可以用於語音轉文字任務(自動語音識別或說話人識別),以及語音轉語音任務(例如語音增強或不同聲音之間的轉換)。這得益於模型的設計和預訓練方式。
SpeechT5 的核心是一個常規的 Transformer 編碼器-解碼器模型。與其他 Transformer 一樣,編碼器-解碼器網路使用隱藏表示對序列到序列的轉換進行建模。這個 Transformer 主幹對於 SpeechT5 支援的所有任務都是相同的。
這個 Transformer 輔以六個特定於模態(語音/文字)的 pre-nets 和 post-nets。輸入語音或文字(取決於任務)透過相應的 pre-net 進行預處理,以獲得 Transformer 可以使用的隱藏表示。然後,Transformer 的輸出被傳遞到 post-net,後者將使用它在目標模態中生成輸出。
這就是該架構的樣子(圖片來自原始論文)

SpeechT5 首先使用大規模的未標記語音和文字資料進行預訓練,以獲得不同模態的統一表示。在預訓練階段,所有 pre-nets 和 post-nets 同時使用。
預訓練後,整個編碼器-解碼器主幹針對每個單獨的任務進行微調。在此步驟中,僅使用與特定任務相關的 pre-nets 和 post-nets。例如,要將 SpeechT5 用於文字轉語音,您需要用於文字輸入的文字編碼器 pre-net 和用於語音輸出的語音解碼器 pre-net 和 post-net。
這種方法可以獲得針對不同語音任務進行微調的多個模型,所有這些模型都受益於對未標記資料的初始預訓練。
儘管微調模型最初使用來自共享預訓練模型的相同權重集,但最終版本都大相徑庭。例如,您不能拿一個微調過的 ASR 模型,然後替換掉 pre-nets 和 post-net 來獲得一個可用的 TTS 模型。SpeechT5 很靈活,但沒那麼靈活;)
讓我們看看 SpeechT5 專門用於 TTS 任務的 pre-nets 和 post-nets 是什麼樣子的
- 文字編碼器前置網路:一個文字嵌入層,將文字標記對映到編碼器期望的隱藏表示。這類似於 BERT 等 NLP 模型中發生的情況。
- 語音解碼器前置網路:它將對數梅爾譜圖作為輸入,並使用一系列線性層將譜圖壓縮成隱藏表示。
- 語音解碼器後置網路:它預測要新增到輸出譜圖的殘差,並用於最佳化結果。
結合起來,這就是 SpeechT5 文字轉語音架構的樣子

如您所見,輸出是對數梅爾譜圖,而不是最終的波形。如果您還記得,我們在第 3 單元中簡要提到了這個主題。生成音訊的模型通常會生成對數梅爾譜圖,需要使用稱為聲碼器的額外神經網路將其轉換為波形。
讓我們看看如何做到這一點。
首先,讓我們從 🤗 Hub 載入經過微調的 TTS SpeechT5 模型,以及用於分詞和特徵提取的處理器物件
from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech
processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")
接下來,對輸入文字進行分詞。
inputs = processor(text="Don't count the days, make the days count.", return_tensors="pt")
SpeechT5 TTS 模型不僅限於為單個說話人建立語音。相反,它使用所謂的說話人嵌入來捕捉特定說話人的聲音特徵。
說話人嵌入是一種以緊湊方式表示說話人身份的方法,無論語音長度如何,都以固定大小的向量表示。這些嵌入捕捉了說話人聲音、口音、語調和其他區分不同說話人的獨特特徵的基本資訊。此類嵌入可用於說話人驗證、說話人識別、說話人分離等。生成說話人嵌入的最常用技術包括:
- I-Vectors(身份向量):I-Vectors 基於高斯混合模型(GMM)。它們將說話人表示為從說話人特定 GMM 的統計資料派生的低維固定長度向量,並以無監督方式獲得。
- X-Vectors:X-Vectors 是使用深度神經網路(DNN)派生的,透過結合時間上下文來捕獲幀級說話人資訊。
X-Vectors 是一種最先進的方法,與 I-Vectors 相比,在評估資料集上表現出卓越的效能。深度神經網路用於獲取 X-Vectors:它訓練以區分說話人,並將可變長度的語音對映到固定維度的嵌入。您還可以載入預先計算的 X-Vector 說話人嵌入,它將封裝特定說話人的說話特徵。
讓我們從 Hub 上的資料集中載入這樣的說話人嵌入。這些嵌入是使用此指令碼從 CMU ARCTIC 資料集中獲得的,但任何 X-Vector 嵌入都應該有效。
from datasets import load_dataset
embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
import torch
speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)
說話人嵌入是一個形狀為 (1, 512) 的張量。這個特定的說話人嵌入描述了一個女性聲音。
此時,我們已經有足夠的輸入來生成對數梅爾譜圖作為輸出,您可以這樣做
spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)
這會輸出一個形狀為 (140, 80) 的張量,其中包含對數梅爾譜圖。第一個維度是序列長度,它在不同執行之間可能會有所不同,因為語音解碼器前置網路總是將 dropout 應用於輸入序列。這會給生成的語音新增一些隨機變異性。
然而,如果我們要生成語音波形,我們需要指定一個聲碼器用於譜圖到波形的轉換。理論上,您可以使用任何適用於 80 頻段梅爾譜圖的聲碼器。方便的是,🤗 Transformers 提供了一個基於 HiFi-GAN 的聲碼器。它的權重由 SpeechT5 的原始作者慷慨提供。
HiFi-GAN 是一種最先進的生成對抗網路 (GAN),專為高保真語音合成而設計。它能夠從譜圖輸入生成高質量和逼真的音訊波形。
從高層次看,HiFi-GAN 由一個生成器和兩個判別器組成。生成器是一個全卷積神經網路,它將梅爾譜圖作為輸入,並學習生成原始音訊波形。判別器的作用是區分真實音訊和生成音訊。這兩個判別器側重於音訊的不同方面。
HiFi-GAN 在大量高質量音訊錄音資料集上進行訓練。它使用一種所謂的 對抗性訓練,其中生成器和判別器網路相互競爭。最初,生成器會生成低質量的音訊,判別器可以很容易地將其與真實音訊區分開來。隨著訓練的進行,生成器會改進其輸出,旨在欺騙判別器。反過來,判別器在區分真實音訊和生成音訊方面變得更加準確。這種對抗性反饋迴圈有助於兩個網路隨著時間的推移而改進。最終,HiFi-GAN 學會了生成與訓練資料特徵非常相似的高保真音訊。
載入聲碼器就像載入任何其他 🤗 Transformers 模型一樣簡單。
from transformers import SpeechT5HifiGan
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
現在您所需要做的就是在生成語音時將其作為引數傳遞,輸出將自動轉換為語音波形。
speech = model.generate_speech(inputs["input_ids"], speaker_embeddings, vocoder=vocoder)
讓我們聽聽結果。SpeechT5 使用的取樣率始終為 16 kHz。
from IPython.display import Audio
Audio(speech, rate=16000)
太棒了!
隨時可以試用 SpeechT5 文字轉語音演示,探索其他聲音,嘗試不同的輸入。請注意,此預訓練檢查點僅支援英語
Bark
Bark 是 Suno AI 在 suno-ai/bark 中提出的基於 Transformer 的文字轉語音模型。
與 SpeechT5 不同,Bark 直接生成原始語音波形,無需在推理過程中使用單獨的聲碼器——它已經整合。這種效率是透過利用 Encodec
實現的,它既充當編解碼器又充當壓縮工具。
使用 Encodec
,您可以將音訊壓縮成輕量級格式以減少記憶體使用,然後對其進行解壓縮以恢復原始音訊。此壓縮過程由 8 個碼本促進,每個碼本都由整數向量組成。可以將這些碼本視為音訊的整數形式表示或嵌入。重要的是要注意,每個後續碼本都會提高從先前碼本重建音訊的質量。由於碼本是整數向量,因此可以透過 Transformer 模型學習它們,這些模型在該任務中非常高效。這就是 Bark 專門訓練的目的。
更具體地說,Bark 由 4 個主要模型組成
BarkSemanticModel
(也稱為“文字”模型):一個因果自迴歸 Transformer 模型,它將分詞後的文字作為輸入,並預測捕獲文字含義的語義文字標記。BarkCoarseModel
(也稱為“粗略聲學”模型):一個因果自迴歸 Transformer,它將BarkSemanticModel
模型的結果作為輸入。它的目標是預測 EnCodec 所需的前兩個音訊碼本。BarkFineModel
(“精細聲學”模型),這次是一個非因果自編碼器 Transformer,它基於先前碼本嵌入的總和迭代地預測最後一個碼本。- 預測了來自
EncodecModel
的所有碼本通道後,Bark 使用它來解碼輸出音訊陣列。
值得注意的是,前三個模組中的每一個都可以支援條件說話人嵌入,以根據特定的預定義語音調節輸出聲音。
Bark 是一個高度可控的文字轉語音模型,這意味著您可以使用各種設定,我們將在後面看到。
首先,載入模型及其處理器。
處理器在這裡的作用是雙重的
- 它用於對輸入文字進行分詞,即將其切成模型可以理解的小塊。
- 它儲存說話人嵌入,即可以影響生成的語音預設。
from transformers import BarkModel, BarkProcessor
model = BarkModel.from_pretrained("suno/bark-small")
processor = BarkProcessor.from_pretrained("suno/bark-small")
Bark 非常通用,可以生成由說話人嵌入庫調節的音訊,該庫可以透過處理器載入。
# add a speaker embedding
inputs = processor("This is a test!", voice_preset="v2/en_speaker_3")
speech_output = model.generate(**inputs).cpu().numpy()
它還可以生成即用型多語言語音,例如法語和中文。您可以在此處找到支援的語言列表。與下面討論的 MMS 不同,無需指定所使用的語言,只需將輸入文字適應相應的語言即可。
# try it in French, let's also add a French speaker embedding
inputs = processor("C'est un test!", voice_preset="v2/fr_speaker_1")
speech_output = model.generate(**inputs).cpu().numpy()
該模型還可以生成**非語言交流**,例如笑聲、嘆息和哭泣。您只需使用相應的提示修改輸入文字,例如 [clears throat]
(清嗓子)、[laughter]
(笑聲)或 ...
。
inputs = processor(
"[clears throat] This is a test ... and I just took a long pause.",
voice_preset="v2/fr_speaker_1",
)
speech_output = model.generate(**inputs).cpu().numpy()
Bark 甚至可以生成音樂。您可以透過在單詞周圍新增 ♪ 音樂音符 ♪ 來提供幫助。
inputs = processor(
"♪ In the mighty jungle, I'm trying to generate barks.",
)
speech_output = model.generate(**inputs).cpu().numpy()
除了所有這些功能之外,Bark 還支援批處理,這意味著您可以同時處理多個文字條目,但會以更密集的計算為代價。在某些硬體(例如 GPU)上,批處理可以加快整體生成速度,這意味著一次性生成樣本可能比逐個生成樣本更快。
讓我們嘗試生成幾個示例
input_list = [
"[clears throat] Hello uh ..., my dog is cute [laughter]",
"Let's try generating speech, with Bark, a text-to-speech model",
"♪ In the jungle, the mighty jungle, the lion barks tonight ♪",
]
# also add a speaker embedding
inputs = processor(input_list, voice_preset="v2/en_speaker_3")
speech_output = model.generate(**inputs).cpu().numpy()
讓我們逐個聽一下輸出。
第一個
from IPython.display import Audio
sampling_rate = model.generation_config.sample_rate
Audio(speech_output[0], rate=sampling_rate)
第二個
Audio(speech_output[1], rate=sampling_rate)
第三個
Audio(speech_output[2], rate=sampling_rate)
Bark,像其他 🤗 Transformers 模型一樣,可以通過幾行程式碼進行最佳化,以提高速度和減少記憶體影響。要了解如何操作,請點選此 Colab 演示筆記本。
大規模多語言語音 (MMS)
如果您正在尋找除英語之外的預訓練模型怎麼辦?大規模多語言語音 (MMS) 是另一個涵蓋一系列語音任務的模型,但它支援大量語言。例如,它可以合成 1,100 多種語言的語音。
MMS 用於文字轉語音是基於 VITS Kim et al., 2021,這是最先進的 TTS 方法之一。
VITS 是一種語音生成網路,可將文字轉換為原始語音波形。它像一個條件變分自編碼器一樣工作,從輸入文字估計音訊特徵。首先,生成以頻譜圖表示的聲學特徵。然後使用從 HiFi-GAN 改造的轉置卷積層解碼波形。在推理過程中,文字編碼被上取樣並使用流模組和 HiFi-GAN 解碼器轉換為波形。像 Bark 一樣,不需要聲碼器,因為波形是直接生成的。
pip install git+https://github.com/huggingface/transformers.git
讓我們試試 MMS,看看我們如何合成除英語之外的語言(例如德語)的語音。首先,我們將載入正確的語言的模型檢查點和分詞器
from transformers import VitsModel, VitsTokenizer
model = VitsModel.from_pretrained("facebook/mms-tts-deu")
tokenizer = VitsTokenizer.from_pretrained("facebook/mms-tts-deu")
您可能會注意到,要載入 MMS 模型,您需要使用 VitsModel
和 VitsTokenizer
。這是因為如前所述,用於文字轉語音的 MMS 是基於 VITS 模型的。
讓我們選擇一個德語示例文字,就像這首兒歌的前兩行一樣
text_example = (
"Ich bin Schnappi das kleine Krokodil, komm aus Ägypten das liegt direkt am Nil."
)
要生成波形輸出,請使用分詞器對文字進行預處理,然後將其傳遞給模型
import torch
inputs = tokenizer(text_example, return_tensors="pt")
input_ids = inputs["input_ids"]
with torch.no_grad():
outputs = model(input_ids)
speech = outputs["waveform"]
我們來聽一下
from IPython.display import Audio
Audio(speech, rate=16000)
太棒了!如果您想嘗試使用其他語言的 MMS,請在 🤗 Hub 上查詢其他合適的 vits
檢查點。
現在讓我們看看如何自己微調 TTS 模型!
< > 在 GitHub 上更新