返回文章列表

威爾斯語語音合成技術與語者特徵處理

本文探討如何使用預訓練的 SpeechT5 模型進行威爾斯語語音合成,並深入研究語者特徵的擷取與處理技術。文章涵蓋了資料集載入、預處理、語者辨識模型的初始化與使用、語者特徵擷取函式的實作,以及音訊資料處理與 TTS

語音合成 機器學習

SpeechT5 模型在語音合成領域展現出良好的效能,但應用於威爾斯語這類別資源相對較少的語言時,需要額外處理語者特徵和資料集。首先,利用 Hugging Face 的 datasets 函式庫載入威爾斯語語音資料集,並統一音訊取樣率。接著,使用 SpeechBrain 的語者辨識模型擷取語者特徵,生成語者嵌入向量。為了提升合成語音的品質,對 SpeechT5 模型進行微調,並使用 HifiGan vocoder 生成更自然流暢的語音。過程中,需考量威爾斯語的特殊字元,並進行相應的預處理。此外,針對資料集的詞彙進行分析,並篩選出貢獻度適中的語者,以確保訓練資料的平衡性和模型的泛化能力。

語音合成中的語者特徵擷取與處理

在進行語音合成(Text-to-Speech, TTS)任務時,語者特徵的擷取與處理是至關重要的一環。本章節將詳細介紹如何利用預訓練的 SpeechT5 模型進行威爾斯語(Welsh)的語音合成,並著重於語者特徵的擷取與處理。

載入與預處理威爾斯語音資料集

首先,我們需要載入威爾斯語的語音資料集。以下程式碼展示瞭如何使用 Hugging Face 的 datasets 函式庫來載入 mozilla-foundation/common_voice_13_0 資料集中的威爾斯語部分,並將音訊資料的取樣率轉換為 16000 Hz。

welsh_voice_train_dataset = load_dataset("mozilla-foundation/common_voice_13_0", "cy", split="train")
welsh_voice_train_dataset = welsh_voice_train_dataset.cast_column("audio", Audio(sampling_rate=16000))

內容解密:

  1. load_dataset 函式用於從 Hugging Face 的資料函式庫中載入指定的資料集。這裡我們載入的是 common_voice_13_0 資料集中的威爾斯語(cy)部分。
  2. cast_column 方法用於轉換資料集中特定欄位的資料型別或屬性。在這裡,我們將 audio 欄位的取樣率統一轉換為 16000 Hz,以確保音訊資料的一致性。

資料過濾與語者特徵擷取

為了提高模型的表現並減少變異性,我們需要對資料進行過濾,只保留特定語者的音訊樣本。同時,我們也需要擷取這些樣本的語者特徵。

client_id_to_filter = 'ccdf75e8e5f1a3c84918a8616f520e605825c284dc124dfadeb3f1d36e26f4a86a893075dc03589ff4996b449f273627a9fb0c39f2b76a20227567faee343016'
welsh_voice_train_filtered_dataset = welsh_voice_train_dataset.filter(lambda example: example['client_id'] == client_id_to_filter)

內容解密:

  1. 我們根據特定的 client_id 對資料集進行過濾,以保留特定語者的音訊樣本。
  2. 這樣的過濾有助於在後續的模型微調過程中保持語者的一致性,從而能夠更公平地比較預訓練模型和微調後的模型。

語者辨識模型的初始化與使用

為了擷取語者的特徵,我們需要初始化一個語者辨識模型。以下程式碼展示瞭如何使用 SpeechBrain 的 spkrec-xvect-voxceleb 模型來進行語者特徵的擷取。

speaker_recognition_model_name = "speechbrain/spkrec-xvect-voxceleb"
computation_device = "cuda" if torch.cuda.is_available() else "cpu"
speaker_recognition_model = EncoderClassifier.from_hparams(
    source=speaker_recognition_model_name,
    run_opts={"device": computation_device, "timeout": 30},
    savedir=os.path.join("/tmp", speaker_recognition_model_name),
)

內容解密:

  1. 我們根據是否有可用的 CUDA 環境來選擇計算裝置,以提高運算效率。
  2. 使用 EncoderClassifier.from_hparams 方法來初始化語者辨識模型,並指定相關的執行選項和模型儲存路徑。

語者特徵擷取函式的實作

def generate_speaker_embedding(audio_waveform):
    with torch.no_grad():
        embeddings = speaker_recognition_model.encode_batch(torch.tensor(audio_waveform))
        normalized_embeddings = torch.nn.functional.normalize(embeddings, dim=2)
        flattened_embeddings = normalized_embeddings.squeeze().cpu().numpy()
        return flattened_embeddings

內容解密:

  1. generate_speaker_embedding 函式接收音訊波形資料,並利用語者辨識模型生成對應的語者特徵。
  2. 在函式內部,我們首先將音訊波形轉換為 tensor,並透過模型的 encode_batch 方法生成特徵向量。
  3. 對生成的特徵向量進行標準化處理,並將其壓縮至適當的維度後傳回。

音訊資料處理與 TTS 處理器的初始化

tts_processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_tts")
welsh_voice_train_filtered_dataset = welsh_voice_train_filtered_dataset.map(process_audio_data, remove_columns=welsh_voice_train_filtered_dataset.column_names)

內容解密:

  1. 初始化一個預訓練的 SpeechT5 TTS 處理器,用於將文字轉換為語音。
  2. 將過濾後的威爾斯語音資料集透過 process_audio_data 函式進行處理,生成包含語者特徵和標籤的豐富資料。

微調語音合成模型以提升威爾斯語音質

在前面的程式碼中,我們首先從資料集中選擇一個樣本。接著,我們提取該樣本的說話者嵌入(speaker embeddings),並將其轉換為PyTorch張量。透過torch.tensor(),我們將嵌入轉換為模型可處理的格式。然後使用unsqueeze(0)函式為張量新增一個額外的維度,實際上是將其從一維陣列轉換為具有一行的二維陣列。

第三步:模型推斷

讓我們載入預訓練模型並評估其產生的音訊品質。

tts_input_parameters = tts_processor(text="Doedd hi ddim wedi arfer gyda'r math yma o beth chwaith.", return_tensors="pt")
speech_synthesis_model = SpeechT5ForTextToSpeech.from_pretrained("microsoft/speecht5_tts")

內容解密:

  1. 文字轉語音處理器(TTS Processor):首先,我們使用tts_processor處理威爾斯陳述式子,將文字轉換為模型可理解的格式,並指定輸出應為PyTorch張量(“pt”)。
  2. 載入預訓練模型:接著,我們從Microsoft載入預訓練的SpeechT5模型,該模型專門用於將文字轉換為語音,並將其指定給speech_synthesis_model。此模型現已準備好從處理後的文字輸入生成語音。
audio_generator = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")
generated_audio = speech_synthesis_model.generate_speech(tts_input_parameters["input_ids"], sample_speaker_embeddings, vocoder=audio_generator)

內容解密:

  1. 初始化高品質音訊生成器:首先,我們初始化一個高品質音訊生成器SpeechT5HifiGan,並使用Microsoft的預訓練模型進行載入。此模型專門用於將原始合成語音訊號轉換為更自然、更高品質的音訊。
  2. 生成語音:接著,我們使用先前載入的語音合成模型將處理後的文字和說話者嵌入轉換為語音。我們將文字的輸入ID和說話者嵌入傳遞給模型,並指定audio_generator作為聲碼器(vocoder)。聲碼器是增強輸出音訊真實性的關鍵元件,確保合成語音聽起來更像人類聲音。此操作的結果是generated_audio,其中包含我們的輸入文字的音訊表示。
from IPython.display import Audio
Audio(generated_audio, rate=16000)

內容解密:

  1. 播放生成的音訊:現在,我們利用Python的IPython函式庫播放從文字生成的音訊。透過匯入Audio函式並使用我們的generated_audio和16000 Hz的取樣率呼叫它,我們能夠在筆記本環境中直接播放合成語音。
  2. 音訊輸出:上述音訊輸出可在我們的GitHub儲存函式庫中存取。音訊品質並非最佳,有些語音斷裂的情況,且整體清晰度不佳。現在,讓我們繼續微調SpeechT5模型,看看是否能夠提高音訊品質。

微調文字轉語音模型

微調SpeechT5模型代表了一種針對特定語言(如威爾斯語)提升文字轉語音(TTS)翻譯品質的量身定製方法。透過調整已經擅長一般語音合成任務的SpeechT5模型,使其專注於威爾斯語,我們旨在提高其對此語言環境的理解和輸出品質。微調提供了多個好處,包括提高語音和語調的準確性、對語言特定細微差別的更好適應性,以及可能更自然的語音輸出。此過程利用相同的資料集來訓練SpeechT5模型處理威爾斯語,提供了一個直接比較效能改進的機會。

第一步:安裝函式庫和資料載入

在載入資料集之前,讓我們先安裝必要的函式庫。

!pip install transformers datasets soundfile speechbrain accelerate

接下來,我們匯入微調過程中將使用的函式庫。

from datasets import load_dataset, Audio
from transformers import SpeechT5Processor, SpeechT5ForTextToSpeech, Seq2SeqTrainingArguments, SpeechT5HifiGan, Seq2SeqTrainer
import os
import torch
from speechbrain.pretrained import EncoderClassifier
from dataclasses import dataclass
from typing import Any, Dict, List, Union
from functools import partial
from collections import defaultdict

現在,讓我們使用以下程式碼片段從Google Colab登入到Hugging Face Hub:

from huggingface_hub import notebook_login
notebook_login()

現在我們已準備好載入資料集。

welsh_voice_train_dataset = load_dataset("mozilla-foundation/common_voice_13_0", "cy", split="train")

內容解密:

  1. 載入威爾斯語訓練資料集:透過上述程式碼,我們從Mozilla的Common Voice版本13.0中載入了威爾斯語語言資料集的訓練部分到我們的環境中。

第二步:資料預處理

讓我們準備我們的資料集,以確保它已準備好進行模型訓練。

welsh_voice_train_dataset = welsh_voice_train_dataset.cast_column("audio", Audio(sampling_rate=16000))

內容解密:

  1. 統一音訊取樣率:首先,我們將威爾斯語聲音訓練資料集的音訊列轉換為具有統一的16000 Hz取樣率,使其在模型訓練中保持一致。
model_checkpoint = "microsoft/speecht5_tts"
tts_processor = SpeechT5Processor.from_pretrained(model_checkpoint)
tts_tokenizer = tts_processor.tokenizer

內容解密:

  1. 設定文字轉語音系統:首先,我們透過將Microsoft的SpeechT5模型的識別符指定給model_checkpoint來指定我們將使用的模型。然後,我們初始化SpeechT5Processor,並使用預訓練的模型檢查點進行載入。這為我們的TTS系統奠定了基礎。

語音合成中的語料函式庫處理與語者嵌入技術

在開發語音合成系統時,語料函式庫的處理以及語者特徵的擷取是至關重要的步驟。本章將探討如何使用SpeechT5模型進行威爾斯語(Welsh)的語音合成,並著重於語料函式庫的詞彙分析、特殊字元的處理,以及語者嵌入(Speaker Embedding)的生成。

語料函式庫詞彙分析與處理

在進行語音合成之前,首先需要對語料函式庫進行詳細的分析,以瞭解其詞彙的多樣性。以下程式碼展示瞭如何從資料集中提取並編譯出唯一的詞彙:

def compile_dataset_vocabulary(batch):
    concatenated_sentences = " ".join(batch["sentence"])
    unique_vocab = list(set(concatenated_sentences))
    return {"unique_vocab": [unique_vocab], "concatenated_sentences": [concatenated_sentences]}

extracted_vocab = dataset.map(
    compile_dataset_vocabulary,
    batched=True,
    batch_size=-1,
    keep_in_memory=True,
    remove_columns=dataset.column_names,
)

內容解密:

  1. compile_dataset_vocabulary 函式:將批次中的所有句子連線成一個字串,並找出其中所有唯一的字元,儲存在 unique_vocab 中。
  2. dataset.map 方法:將 compile_dataset_vocabulary 函式應用於整個資料集,批次處理所有資料並保留處理結果。
  3. 移除原始列:由於我們的重點是提取的詞彙和連線的文字資料,因此移除了資料集的原始列。

處理威爾斯語特殊字元

由於 SpeechT5 模型主要針對英文訓練,因此需要處理威爾斯語中特殊的字元,以確保它們能夠被正確地識別和處理。以下程式碼展示瞭如何找出並替換這些特殊字元:

complete_dataset_vocab = set(extracted_vocab["unique_vocab"][0])
tts_processor_vocab = {k for k, _ in tts_processor.tokenizer.get_vocab().items()}
missing_vocab_in_processor = complete_dataset_vocab - tts_processor_vocab

welsh_to_english_replacements = {
    '¬': '',
    'Â': 'A',
    'Ô': 'O',
    # 其他替換規則...
}

missing_vocab_replacements = [(src, dst) for src, dst in welsh_to_english_replacements.items()]

def normalize_sentence_characters(sentence_mapping):
    for original_char, replacement_char in missing_vocab_replacements:
        sentence_mapping["sentence"] = sentence_mapping["sentence"].replace(original_char, replacement_char)
    return sentence_mapping

welsh_voice_train_dataset = welsh_voice_train_dataset.map(normalize_sentence_characters)

內容解密:

  1. 找出缺失的詞彙:比較資料集詞彙與 TTS 處理器詞彙,找出威爾斯語中特殊字元。
  2. 建立替換字典:定義 welsh_to_english_replacements 字典,將威爾斯語特殊字元對映到相應的英文字元或替代字元。
  3. normalize_sentence_characters 函式:遍歷替換列表,更新資料集中的句子,替換特殊字元。

篩選適當的語者

為了建立一個更平衡的資料集,需要篩選出貢獻次數適中的語者。以下程式碼展示瞭如何統計每個語者的貢獻次數並篩選出符合條件的語者:

speaker_frequency = defaultdict(int)
for client_identifier in welsh_voice_train_dataset["client_id"]:
    speaker_frequency[client_identifier] += 1

def is_speaker_within_range(client_id):
    return 100 <= speaker_frequency[client_id] <= 400

dataset_with_selected_speakers = welsh_voice_train_dataset.filter(is_speaker_within_range, input_columns=["client_id"])

內容解密:

  1. 統計語者貢獻次數:使用 speaker_frequency 統計每個語者的錄音次數。
  2. is_speaker_within_range 函式:判斷某個語者的貢獻次數是否在指定範圍內(100至400次)。
  3. 篩選資料集:根據篩選條件,保留符合條件的語者的錄音。

生成語者嵌入

語者嵌入是表示語者特徵的一種向量,可以用於語音合成中的語者識別。以下程式碼展示瞭如何使用預訓練的語者識別模型生成語者嵌入:

speaker_recognition_model_name = "speechbrain/spkrec-xvect-voxceleb"
computation_device = "cuda" if torch.cuda.is_available() else "cpu"
speaker_recognition_model = EncoderClassifier.from_hparams(
    source=speaker_recognition_model_name,
    run_opts={"device": computation_device, "timeout": 30},
    savedir=os.path.join("/tmp", speaker_recognition_model_name),
)

def generate_speaker_embedding(audio_waveform):
    with torch.no_grad():
        embeddings = speaker_recognition_model.encode_batch(torch.tensor(audio_waveform))
        normalized_embeddings = torch.nn.functional.normalize(embeddings, dim=2)
        flattened_embeddings = normalized_embeddings.squeeze().cpu().numpy()
    return flattened_embeddings

內容解密:

  1. 載入預訓練模型:使用 EncoderClassifier 載入預訓練的語者識別模型。
  2. generate_speaker_embedding 函式:將音訊波形輸入模型,生成並歸一化語者嵌入向量。

透過上述步驟,我們可以有效地處理威爾斯語語料函式庫,篩選出合適的語者,並生成高品質的語者嵌入,為後續的語音合成任務做好準備。