Nvidia Mellotron 解説

目次

Nvidia Mellotron とは

Nvidia の開発した音声のピッチ, リズム, スタイル変換や歌声の生成ができる Deep Learning モデルです。

ざっと論文の概要を掴むため最初に落合陽一フォーマットでまとめてみます。

1. どんなもの?
音声とテキストのペアのデータのみから感情のある音声の生成、歌声の生成、スタイル変換を可能にした。

2. 先行研究と比べてどこがすごい?
感情ラベルや歌声生成のための楽譜データ (alignment, pitch) を全く使用しない点。

3. 技術や手法のキモはどこ?
style token, speaker embedding, pitch contour(=f0) を入力にいれることで感情, 話者特性, Pitch調節を可能にし、
推論時に tacotron2 の attention の alignment を外から与えることで rhythm の調節を可能にしている。

4. どうやって有効だと検証した?
E2EProsody と比較して F0 Frame Error が低い。

5. 議論はある?
著者の future work で挙げられているのは rhythm, pitch が音声のクオリティに与える影響の調査と
Pitch に関してはボーカルレンジを広げる or multispeaker での学習が与える影響の理解。

6. 次に読むべき論文は?
E2EProsody (https://arxiv.org/pdf/1803.09047.pdf)

ここまで。

ここからはもう少し詳細を追っていきます。

Mellotron で出来ること

音声とテキストデータ (+ MultiSpeaker にするなら SpeakerId) のみで主に以下ができます。

  1. 音声の Style, Pitch, Rhythm 変換
  2. 歌声生成

デモはこのページで公開されています。

私は特に歌声生成が歌声の学習データ無しで出来るという点に興味を持って使ってみました。(前回記事参照)
一般的な歌声生成モデルの作成には歌の音声データと共に musicXMLMIDI 形式の楽譜データも必要とされますが、Mellotron は楽譜データを一切使用せず音声データとテキストのペアのみ用意すればモデルを作れます。
学習に楽譜データが必要だとすると、例えば特定のアニメキャラを歌わせようと思った時「そのキャラクターの歌が大量に必要で、なおかつ各歌に対応する musicXML 形式の楽譜データも用意する必要がある」という条件になり、これはかなりキツイです。。。

Mellotron の手法詳細

大体は Tacotron2 と同じなので違う部分をピックアップして紹介していきます。Tactron2 の解説はしません (こちらの方の記事などを参考いただければと)。

モデルの構造

Tacotron2 + GST をベースに入力に speaker embedding と pitch contour (=F0) をモデルに追加することで Style, Pitch, Rythom 変換を可能にしています。

モデルの構造の図はこんな感じ。赤色で囲った部分が Tacotron2 から追加された箇所です。

f:id:tosaka-m:20200429122214p:plain
図 1. Mellotron の NN 構造
Tacotron2 はテキストから音声波形データの特徴量である melspectrogram を推論するモデルですが、Mellotron はテキスト + pitch contour, SpeakerId, GlobalStyleToken(=GST, スタイル情報, 感情ラベルのようなもの) を使用して melspectrogram を推論します。

モデルの学習方法などはだいたい Tacotron2 と同じなのですが、 Tacotron2 では   p(melspec|Text, \theta)   (\theta はモデルのパラメータ) を最大化する学習を考えるのに対し、 Mellotron では melspectrogram を構成する要素をより細かく
    M = [ Text, SpeakerId, PitchContour, Rhythm, GlobalStyleTokens ]
に分けて   p(melspec|M, \theta)   を最大化する学習を考えます。(単にモデルに追加する情報を増やすだけ。)

このように Mellotron は Text, SpeakerId, PitchContour, Rhythm, GlobalStyleTokens を受け取り melspectrogram を予測出来るモデルなので、
話者やスタイルの変換は SpeakerId, GlobalStyleToken を別のものに置き換え、
声の高さやリズムの変換は Rythm, PitchContour を別のものに変えることで実現できます。

また、モデルの構造上 SpeakerId は学習データセットにないといけないですが、Text, PitchContour, Rhythm は学習データセット外のデータでも OK で、
さらに、GlobalStyleTokens は学習データから自動で作られます (なので感情ラベルを必要とせず感情を変化させた音声が生成できる)。

モデルの学習方法

学習時に使用するデータは テキスト音声波形データ (+ SpeakerId) のペアのみで、基本的には Tacotron2 と同じ方法でモデルの学習を行います。

違う点としては、モデルに PitchContour, SpeakerId, GlobalStyleToken の 3 つの情報をさらに加えて学習することです。(単一話者モデルの場合は SpeakerId はいりません。)

この 3 つは以下のように処理します。

PitchContour

入力に加える Pitch の情報は学習する音声波形データから Yin アルゴリズムで推定し、melspectrogram と時間方向の長さを揃えたものを使用します。
モデルは推定された 1次元の melspectrogram と同じサイズの Pitch データを 1 層の Conv + ReLU で Decoder 内の Prenet 後 (= LSTM の入力) のベクトルに channel 次元で concat する形で組み込みます。
Conv の構造は何パターンか試しているようですが、github上では inputdim=1, ouputdim=1, kernelsize=1 でした。

SpeakerId

SpeakerId ごとに embedding vector を作りテキストの encode vector に concat する形でモデルに組み込みます。
Multi-speaker モデルの場合は必須であり SpeakerId 自体をあらかじめ用意しておく必要があります。

Global Style Token

Global Style Token はこの論文の手法です。本筋ではないので GTS はざっくりと説明します。
GTS の構造は下の図2. の通りです(GSTの論文から引用)。

f:id:tosaka-m:20200429122304p:plain
図2. GST 概要

GST はいくつかの style token (図2. の A~D, スタイルの情報を表す vector) を持っており、 モデル(の学習時)は各音声データがどの style token に対応するかを求めて、 Mellotron にその対応する style token を与えて decode することでスタイルを考慮した予測が出来ます。
学習時の対応するスタイルの求め方は以下の流れです。

  1. 入力の melspectrogram から図2.中の Reference encoder により固定長の vector を作成 (以下 reference embedding)
  2. reference embedding と各 token の類似度を算出 (図2.の 0.2, ..., 0.1 の値の部分, 和が 1 になるように正規化)
  3. その類似度による token の重み付け和が入力の melspectrogram のスタイルを表す embedding vector (図2.の style embedding) になる

token 自体も最初はランダムな値から学習させるので、ラベル無しでデータセットの特徴からスタイルの種類を自動で作ってくれます

モデルによる推論方法

Mellotron の推論時には以下の図3. のように 5 つの入力をとります。

f:id:tosaka-m:20200429122332p:plain
図3. Mellotron 推論の流れ

ここで図中の Alignment とは Tacotron2 の Attention map のことで、大まかにはどの時刻にどの単語を話しているかの情報を持っています。
例えば Alignment は以下の図4. のような 2 次元の matrix になり、この matrix の時刻 t における各単語の値の大きさを見るにことよりその時刻で話している単語をおおまかに判断できます。

f:id:tosaka-m:20200429122409p:plain
図4. Alignment の例
(ある時刻 t の 「こ」 ~ 「わ」 の値を足すと 1 になるように正規化されている)

通常 Tacotron2, Mellotron は melspectrogram の推論をしながらこの Alignment も同時に推論するのですが、Mellotron でリズムをいじりたい場合はにこの Alignment をあらかじめ作っておき、モデルの推論途中 Attention の値を参照する時にあらかじめ作っておいた Alignment の値を使用することで特定の時刻に特定の単語を話させることが出来ます。

入力データを用意する方法

続いては推論時の各入力データをどうやって用意すれば良いか論文に乗っている方法を紹介します。
データを用意する方法は 「音声データを用意する」と「楽譜データを用意する」の 2 パターンに分かれます。
GlobalStyleToken と SpeakerId は学習データや使用するデータをそのまま使うだけなので省略します。
ちなみに、前回の記事の歌声を生成した時は「楽譜データを用意する」方法でやりました。音声データを用意するパターンもいずれ試したいとは思ってます。

音声データを用意する場合

音声データを用意する場合は主にスタイル変換を想定しています。既存の歌を他の声で歌わせる場合も該当します。
では、音声データからモデルの推論時に必要な Text, PitchContour, Alignment をあらかじめ用意した音声データから作る方法をそれぞれ述べます。

1. Text
論文では音声データから Text を得る方法としては Jasper などの ASR (Automatic Speech Recognition) モデルを紹介してます。

2. PitchContour
Yin や Melodia と呼ばれる手法で推定します。(参考: Yin は Mellotron のリポジトリ中にあります。 Melodia はこちらとか。使ったことはないですが。)

3. Alignment
gentle などのツール、または、 Mellotron の Teacher Frocing の推論で算出される alignment を使用します。
Teacher Forcing とは、時刻 t+1 の melspectrogram の推定の際入力に時刻 1~t の教師データの melspectrogram を使用する方法です。
学習時は基本 Teacher Forcing を使用しており、推論時は普通は教師データの melspectrogram なんかないので Teachear Forcing は使用せず時刻 1~t の melspectrogram に自身の予測を用いる自己回帰で行います。

ここでは音声データを用意している想定なのでそれを教師データとみなして学習時のように Teacher Forcing で推論すると、 元の音声データと時系列のあった Alignment が得られます。
Teacher Forcing で Alignment が綺麗に推論されない場合は低lrで少しのiter学習を回すと良いそうです。

楽譜データを用意する場合

楽譜から Text, PitchContour, Alignment を用意する方法を述べます。
楽譜データは musicxmlMIDI などのメジャーな形式なら Pitch などの情報を取り出すのに music21 という python で使えるツールがあり、nvidia/mellotron の github リポジトリでも使用されています。なので、楽譜データは music21 で読める形式のものを用意するのが良いでしょう。

1. Text
楽譜からそのまま取ればいいですが前処理が必要になります。英語の場合はアルファベットを発音記号に変換します。
例. hello → HH AH0 L OW1

私が日本語でやった時は発話記号がよくわからなかったので、(今もよくわかってないですが)ローマ字に変換しました。
例. こ → k o

2. PitchContour
こちらも楽譜からそのまま取ります。各音符に対応する周波数の値を時間を揃えてそのまま並べるだけです。

3. Alginment
こちらも楽譜からそのまま取ればいいと言いたいですが、例えば日本語で1つの音符に「こ」が対応している場合「こ -> k, o」と分けるので k が何秒, o が何秒と割り当てる必要があります。英語も発音記号に分けるので同じ問題があります。

Mellotron のコードでどう処理されているかというと、 楽譜上で(単語はおそらくだいたい母音ごとに区切られているので) "HH AH0" と "L OW1" の塊がそれぞれ 0.25, 0.25 secと定義されているとすると、
  HH=0.05 sec,   AH0=0.25-0.05,   L=0.05,   OW1=0.25-0.05
と各発音記号に時間の長さを割り当てます。
子音の発話記号ごとに固定長が定義されているようで、HH, L はそれぞれ 0.05 secでした。母音の長さは子音の長さを引いた残りの値で定義されます。

私が日本語でやった時はローマ字にしたので 「こ」 → 「k, o」が 0.25sec なら
  k=0.075,   o=0.25-0.075
といった感じに単語の時間の長さの割り当てて実行しました。
0.075 の部分は子音に関して全部同じ値の固定長の割り当てをしており、母音には残りを割り当てるようにしています。

このあたり詳しくないので詳しい方がいらっしゃったら参考文献をお教えいただけると幸いです。
楽譜読める人とか音楽やっている人の方がこのあたり詳しいかもしれませんね。

以上がデータを用意する方法です。
最後に Mellotron の推論で各種変換と 歌声生成の流れを軽く述べます。

話者,スタイル,ピッチ変換方法

音声データを用意
 ↓
Text, PitchContour, Alginment, SpeakerId, GlobalStyleToken を作成・用意
 ↓
声の高さ変換 → PitchContour を変更
リズム変換 → Alignment を変更
話者変換 → SpeakerId 変更
スタイル変換 → GlobalStyleToken を変更
 ↓
Mellotron で推論

歌声生成方法

音声 or 楽譜データ を用意
 ↓
Text, PitchContour, Alginment, SpeakerId, GlobalStyleToken を作成・用意
楽譜の場合は Style Token, Speaker Id は学習データから適当に選択
 ↓
Mellotron で推論

おわりに

ニュアンスが論文と異なっている箇所があるかもしれませんので、より深く興味があるかたはぜひ元論文も読んでみてください。 あと、間違っている箇所などありましたらコメントいただけますと幸いです。