記事一覧に戻る

Matthijs Hollemans's avatar

この記事は中国語でもご覧いただけます 簡体中文

最先端の機械学習モデルの使いやすい実装を提供するオープンソースライブラリ、🤗 TransformersでSpeechT5が利用可能になったことを発表します。

SpeechT5は元々、Microsoft Research Asiaの論文 SpeechT5: Unified-Modal Encoder-Decoder Pre-Training for Spoken Language Processing で紹介されました。論文の著者によって公開された 公式チェックポイント はHugging Face Hubで利用できます。

早速試してみたい方は、Spacesのデモをご覧ください:

はじめに

SpeechT5は1つや2つではなく、1つのアーキテクチャで3種類の音声モデルを実現します。

以下のタスクが可能です:

  • 音声→テキスト:自動音声認識や話者識別
  • テキスト→音声:音声合成
  • 音声→音声:異なる声への変換や音声強調

SpeechT5の主なアイデアは、テキスト→音声、音声→テキスト、テキスト→テキスト、音声→音声のデータ混合で単一のモデルを事前学習することです。これにより、モデルはテキストと音声を同時に学習します。この事前学習アプローチの結果、テキストと音声の両方で共有される統一された隠れ表現空間を持つモデルが実現します。

SpeechT5の中心には、通常のTransformerエンコーダー-デコーダーモデルがあります。他のTransformerと同様に、エンコーダー-デコーダーネットワークは隠れ表現を用いてシーケンスからシーケンスへの変換をモデル化します。このTransformerバックボーンは、すべてのSpeechT5タスクで共通です。

同じTransformerがテキストと音声データの両方を扱えるようにするため、プレネットポストネットが追加されました。プレネットの役割は、入力テキストまたは音声をTransformerが使用する隠れ表現に変換することです。ポストネットはTransformerからの出力を再度テキストまたは音声に変換します。

SpeechT5のアーキテクチャを示す図を以下に示します(原論文より引用)。

SpeechT5 architecture diagram

事前学習中は、すべてのプレネットとポストネットが同時に使用されます。事前学習後、エンコーダー-デコーダーバックボーン全体が単一のタスクでファインチューニングされます。このファインチューニング済みモデルは、指定されたタスクに特有のプレネットとポストネットのみを使用します。たとえば、SpeechT5をテキスト→音声に使用する場合、テキスト入力用にテキストエンコーダープレネットを入れ替え、音声出力用に音声デコーダープレネットとポストネットを入れ替えます。

注:ファインチューニング済みモデルは共有事前学習モデルの同じ重みセットから始まりますが、最終版はすべてかなり異なります。たとえば、ファインチューニング済みのASRモデルからプレネットとポストネットを入れ替えて動作するTTSモデルを得ることはできません。SpeechT5は柔軟ですが、そこまで柔軟ではありません。

テキスト→音声

SpeechT5は、🤗 Transformersに追加された最初のテキスト→音声モデルであり、今後さらに多くのTTSモデルを追加する予定です。

TTSタスクでは、モデルは以下のプレネットとポストネットを使用します:

  • テキストエンコーダープレネット。 テキストトークンをエンコーダーが期待する隠れ表現にマッピングするテキスト埋め込み層。BERTなどのNLPモデルで起こることと似ています。

  • 音声デコーダープレネット。 ログメルスペクトログラムを入力として受け取り、一連の線形層を使用してスペクトログラムを隠れ表現に圧縮します。この設計はTacotron 2 TTSモデルから採用されています。

  • 音声デコーダーポストネット。 出力スペクトログラムに加算する残差を予測し、結果を洗練するために使用されます。これもTacotron 2から採用されています。

ファインチューニング済みモデルのアーキテクチャは以下のようになります。

SpeechT5 architecture for text-to-speech

以下は、SpeechT5テキスト→音声モデルを使用して音声を合成する方法の完全な例です。 このインタラクティブなColabノートブック で一緒に試すこともできます。

SpeechT5はまだ最新版のTransformersリリースでは利用できないため、GitHubからインストールする必要があります。また、追加の依存関係であるsentencepieceもインストールし、ランタイムを再起動してください。

pip install git+https://github.com/huggingface/transformers.git
pip install sentencepiece

まず、Hubから ファインチューニング済みモデル を、トークナイゼーションと特徴抽出に使用するプロセッサオブジェクトとともに読み込みます。使用するクラスは SpeechT5ForTextToSpeech です。

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モデルは単一の話者に対する音声生成に限定されません。代わりに、特定の話者の声の特徴を捉える話者埋め込みを使用します。このような話者埋め込みをHub上のデータセットから読み込みます。

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)のテンソルです。この特定の話者埋め込みは女性の声を表しています。埋め込みは CMU ARCTIC データセットから このスクリプト を使用して取得されましたが、任意のX-Vector埋め込みが機能します。

これで、入力トークンと話者埋め込みを指定して、モデルに音声生成を指示できます。

spectrogram = model.generate_speech(inputs["input_ids"], speaker_embeddings)

これにより、形状(140, 80)のテンソルとしてログメルスペクトログラムが出力されます。最初の次元はシーケンス長で、音声デコーダープレネットが常に入力シーケンスにドロップアウトを適用するため、実行ごとに変動する可能性があります。これにより、生成された音声に少しのランダムな変動が加わります。

予測されたログメルスペクトログラムを実際の音声波形に変換するには、ボコーダーが必要です。理論上は80ビンのメルスペクトログラムで動作する任意のボコーダーを使用できますが、利便性のためにTransformersにHiFi-GANに基づくボコーダーを用意しました。このボコーダーの 重み とファインチューニング済みTTSモデルの重みは、SpeechT5の原著者から親切に提供されました。

ボコーダーの読み込みは、他の🤗 Transformersモデルと同様に簡単です。

from transformers import SpeechT5HifiGan
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")

スペクトログラムから音声を作成するには、以下のようにします:

with torch.no_grad():
    speech = vocoder(spectrogram)

スペクトログラム作成の中間ステップを省略するためのショートカットも用意されています。generate_speech にボコーダーオブジェクトを渡すと、直接音声波形が出力されます。

speech = model.generate_speech(inputs["input_ids"], speaker_embeddings, vocoder=vocoder)

最後に、音声波形をファイルに保存します。SpeechT5で使用されるサンプリングレートは常に16 kHzです。

import soundfile as sf
sf.write("tts_example.wav", speech.numpy(), samplerate=16000)

出力は次のように聞こえます(音声をダウンロード):

Your browser does not support the audio element.

これでTTSモデルの説明は終わりです!良い音にするための鍵は、適切な話者埋め込みを使用することです。

Spacesで インタラクティブなデモ をお試しいただけます。

💡 独自のデータセットや言語でSpeechT5 TTSをファインチューニングする方法に興味がありますか?プロセスの詳細な手順が記載された このColabノートブック をご確認ください。

声質変換のための音声→音声

概念的には、SpeechT5を使用した音声→音声モデリングはテキスト→音声と同じです。テキストエンコーダープレネットを音声エンコーダープレネットに入れ替えるだけです。モデルの残りの部分は同じままです。

SpeechT5 architecture for speech-to-speech

音声エンコーダープレネットwav2vec 2.0 の特徴量エンコーディングモジュールと同じです。入力波形をオーディオフレーム表現のシーケンスにダウンサンプリングする畳み込み層で構成されています。

音声→音声タスクの例として、SpeechT5の著者は声質変換用の ファインチューニング済みチェックポイント を提供しています。これを使用するには、まずHubからモデルを読み込みます。モデルクラスは SpeechT5ForSpeechToSpeech になります。

from transformers import SpeechT5Processor, SpeechT5ForSpeechToSpeech

processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_vc")
model = SpeechT5ForSpeechToSpeech.from_pretrained("microsoft/speecht5_vc")

入力として使用する音声オーディオが必要です。この例では、Hub上の小さな音声データセットから音声を読み込みます。モノラルでサンプリングレート16 kHzの独自の音声波形を読み込むこともできます。ここで使用しているデータセットのサンプルはすでにこの形式です。

from datasets import load_dataset
dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation")
dataset = dataset.sort("id")
example = dataset[40]

次に、モデルが期待する形式に音声を前処理します。

sampling_rate = dataset.features["audio"].sampling_rate
inputs = processor(audio=example["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt")

TTSモデルと同様に、話者埋め込みが必要です。これらはターゲットの声がどのように聞こえるかを表します。

import torch
embeddings_dataset = load_dataset("Matthijs/cmu-arctic-xvectors", split="validation")
speaker_embeddings = torch.tensor(embeddings_dataset[7306]["xvector"]).unsqueeze(0)

生成されたスペクトログラムを音声波形に変換するためにボコーダーも読み込む必要があります。TTSモデルと同じボコーダーを使用しましょう。

from transformers import SpeechT5HifiGan
vocoder = SpeechT5HifiGan.from_pretrained("microsoft/speecht5_hifigan")

これで、モデルの generate_speech メソッドを呼び出して音声変換を実行できます。

speech = model.generate_speech(inputs["input_values"], speaker_embeddings, vocoder=vocoder)

import soundfile as sf
sf.write("speech_converted.wav", speech.numpy(), samplerate=16000)

異なる声に変更するのは、新しい話者埋め込みを読み込むだけで簡単です。自分の声から埋め込みを作成することもできます!

元の入力(ダウンロード):

Your browser does not support the audio element.

変換後の声(ダウンロード):

Your browser does not support the audio element.

この例の変換後の音声は文の終わりで途切れていることに注意してください。これは2つの文の間の休止が原因で、SpeechT5が(誤って)シーケンスの終端に到達したと予測した可能性があります。他の例で試してみてください。変換が正しい場合が多いですが、時々途中で停止することがあります。

こちらで インタラクティブなデモ をお試しいただけます。🔥

自動音声認識のための音声→テキスト

ASRモデルは以下のプレネットとポストネットを使用します:

  • 音声エンコーダープレネット。 これは音声→音声モデルで使用されるものと同じプレネットで、wav2vec 2.0のCNN特徴量エンコーダー層で構成されています。

  • テキストデコーダープレネット。 TTSモデルで使用されるエンコーダープレネットと同様に、埋め込み層を使用してテキストトークンを隠れ表現にマッピングします。(事前学習中、これらの埋め込みはテキストエンコーダーとデコーダーのプレネット間で共有されます。)

  • テキストデコーダーポストネット。 これらは最もシンプルで、隠れ表現を語彙に対する確率に射影する単一の線形層で構成されています。

ファインチューニング済みモデルのアーキテクチャは以下のようになります。

SpeechT5 architecture for speech-to-text

以前に他の🤗 Transformers音声認識モデルを試したことがある場合、SpeechT5も同様に簡単に使用できます。最も簡単な方法はパイプラインを使用することです。

from transformers import pipeline
generator = pipeline(task="automatic-speech-recognition", model="microsoft/speecht5_asr")

音声オーディオとして、前のセクションと同じ入力を用いますが、パイプラインが自動的に音声を正しい形式に変換するため、任意の音声ファイルが使用できます。

from datasets import load_dataset
dataset = load_dataset("hf-internal-testing/librispeech_asr_demo", "clean", split="validation")
dataset = dataset.sort("id")
example = dataset[40]

これで、パイプラインに音声を処理させてテキスト書き起こしを生成させることができます。

transcription = generator(example["audio"]["array"])

書き起こしを表示すると次のようになります:

a man said to the universe sir i exist

これはまさに正しいです!SpeechT5で使用されるトークナイザーは非常に基本的なもので、文字レベルで動作します。したがって、ASRモデルは句読点や大文字を出力しません。

もちろん、モデルクラスを直接使用することも可能です。まず、 ファインチューニング済みモデル とプロセッサオブジェクトを読み込みます。クラスは SpeechT5ForSpeechToText になります。

from transformers import SpeechT5Processor, SpeechT5ForSpeechToText

processor = SpeechT5Processor.from_pretrained("microsoft/speecht5_asr")
model = SpeechT5ForSpeechToText.from_pretrained("microsoft/speecht5_asr")

音声入力を前処理します:

sampling_rate = dataset.features["audio"].sampling_rate
inputs = processor(audio=example["audio"]["array"], sampling_rate=sampling_rate, return_tensors="pt")

最後に、モデルに音声入力からテキストトークンを生成させ、プロセッサのデコード関数を使用してこれらのトークンを実際のテキストに変換します。

predicted_ids = model.generate(**inputs, max_length=100)
transcription = processor.batch_decode(predicted_ids, skip_special_tokens=True)

音声→テキストタスク のインタラクティブなデモをお試しください。

結論

SpeechT5は、他のほとんどのモデルとは異なり、同じアーキテクチャで複数のタスクを実行できるという点で興味深いモデルです。変更されるのはプレネットとポストネットのみです。これらの複合タスクでモデルを事前学習することで、ファインチューニング時に各個別タスクの性能が向上します。

音声認識(ASR)、音声合成(TTS)、声質変換タスクのチェックポイントのみを含めましたが、論文では音声翻訳、音声強調、話者識別にもモデルが正常に使用されたことが述べられています。非常に汎用性が高いです!