後ろの方へ随時更新を追加していきます。
RVCモデルのeach key mergeの実験
目的
RVCモデルのkeyマージで実験することにより、どのkeyにどのような話者の特徴が入っているかを調べたい
手法
モデルAとモデルB(性別は揃え、学習元の声の高さもある程度は揃える)を用意して、RVC-WebUI のMergeのweight sumのeach key mergeを利用して、次を調べる。
- 全てのkeyの値を0に揃える(つまりそのままだとモデルAが出るようにする)
- 各keyについて、それを(とりあえず全ての層で)1、他を0とした場合、どのkeyを1にしたときに話者がAでなくBに聞こえるかを調べる
- 影響が大きいkeyについて、その中でさらに影響が大きい層がないか、ある層だけ0にして他の層は1などとして一つ一つ調べる
もちろん複数のモデルの組で実験。
結果
- 話者がAからBに変化したと感じる具合に対して一番影響が大きいのは、
dec.resblocks(RVCのアーキテクチャや仕組みを詳しくしらないけどこれは当たり前なんでしょうか?)。
これは、dec.resblocks以外の全てを1にして他を0にしたときでもまだ話者Aに聞こえることからほとんど確実そう。
(これはAモデルを別のモデルに変えて試してもそうだった、もちろん全体的な響きはAモデルの選び方によって大きく変化するが、Bに聞こえるという点では同じ。ただし男性モデルと女性モデルのペアは例外)。
他のkeyは正直Bに変化したとは感じなかったので、dec.resblocksを全て1に降った状態で、他のkeyをそれぞれ1にして実験した。
enc_p.encoder.ffn_layersは、モデルAとモデルBの声の高さが違うほど、1に降ったときとそうでないときの差が大きいっぽい(これは例えばAの声が低くBの声が高いと、エンコーダが学習する声はAは低めBが高めだから、その関係でエンコーダーが再現度に効いてくる?)(AとBの高低差が大きいと、1に降るとあきらかに変換の質が上がる)dec.upsが、モデルBが演技がかった特徴的な母音の発音をするようなモデルの場合に、1にするとB度が上がる気がする、でも気のせいかもしれない
各層について
dec.resblocksの中で1層だけ変えることを試した結果、8層dec.resblocks.8を変えたときに耳に聞こえる感触が変化することが多かった(他は聞き取れる変化は分からず)。
dec.resblocks.8は、感覚としては低音の響き・スタジオの録音特性や体感音質のようなものに影響を与えている気がする。
enc_p.encoder.ffn_layersの層については分からず
推測・まとめ
- 話者の特徴的な量はほとんどは
dec.resblocksに入っており、その8層が特に低音や全体の響きに影響する。 - また特徴的な母音の発音の仕方をするモデルでは
dec.upsにその感じが入っていそう。 - 一方でおそらく学習時の高低の関係から、エンコーダの特に
enc_p.encoder.ffn_layersの中に学習データのピッチと近いピッチの解像度があがっており、
マージする場合はモデルの高低差によりエンコーダの値を気をつける必要がある
応用?今後やりたいこと?
- 音質がよくノイズも少ないモデルをAとし、一方でちょっと質が微妙なモデルをBとして、
dec.resblocksの8層以外とdec.ups(と必要ならエンコーダ)を1、他0でマージすることで、Aモデルと同様の響きを持つけれど声がBであるようなモデルが作れるのではないか? - 各層の持っている情報をもっと精密に考察できないか?(モデルのアーキテクチャやそもそも機械学習分からないので分からない……)
flowやら、層になってない他のパラメータやらの意味?(そもそも意味付けができるのか?flowってなんだ?)- Add differenceについては全く手つかずなのでもう少しいろいろ実験すべきことはある。
8/22追記
Pretrainedモデルとeach key mergeする実験
趣旨
上と同じ目的だけど、よく考えたら片方を学習を始める段階のpretrainedモデルにしてしまえば、検証再現度とかいろいろな点でよさそうなことに気づいた。
pretainedモデルと学習が終わったモデルとを、pretrained全振りから徐々に変えながらマージしてどこで違いが出るかをみればいろいろ探れるのではないかという実験。
準備
RVC v2のpretrainedモデルf0G40k.pthファイルを、RVC本家の「ckptファイルの処理」タブの一番下から変換することで、推論に使えるRVCモデルが出てくる。
(このモデルを直で使うと、話者性がめっちゃ失われた見事な汎用声に変換される。)
これをpretrained.pthモデルとし、これをRVC-WebUIのeach key mergeのモデルAとして、
f0G40kを事前学習元として作ったRVCモデル(つまりRVC v2のピッチ付き40kモデル)をモデルBとし、値を変えながらweight sumマージしていく。
(多分)以前の実験で分かっていること
以前、モデルAとモデルBがともにきちんと学習された女性声モデルの場合は、dec.resblocksが話者性に一番大きく影響を与えており、
またAとBの学習元の音の高さが違う場合はenc_p.encoder.ffn_layersも重要なファクターになっていた。
しかし他のパラメータについてはあまりいじっても差は感じなかった。
結果
- 以前の実験をもとに、まず
dec.resblocksのみを1に変更してモデルBの話者に聞こえるかを試してみたところ、
完全にふにゃふにゃでこもって音質最悪の音声になってしまい、モデルBに聞こえるかどうかいうレベルの質ではなかった。
これは、冷静に考えると以前の実験ではエンコーダーは両者ともきちんと学習されていたからうまくいっていたと考え、次を試した。 enc_p.encoder.ffn_layersのみを1、他を(デコーダ含め)0にしてみた。ちょっとマシになるがふにゃふにゃ感がある。- エンコーダの他の箇所も影響していると考え、エンコーダを全て1、他を全て0に。かなり滑舌が普通になり、きちんとした汎用音声感があるが、
RVC特有の摩擦音・破擦音(「そ」とか「つ」とか)でのノイズがやたらと目立つ。原因を探ろうとする。
デコーダは話者性を持っていると思われるのでそこはいじらず、すると残ったflowが子音の自然さやノイズの情報を持っているのかと推測し、次を試す。 - エンコーダ全て1、flowを全て1にしてみる。と子音も母音も自然な汎用音声に!
モデルBを複数試したり変換元音声も変えたりしてみても同じ結果に。
ただしモデルBを変えると、話者性が消えた汎用音声という聞こえは変わらないが、細かい響きやノイズの感じは違う(質が高いモデルはなんとなく質が高い汎用感がある?) flowのどの層が子音や摩擦破裂音に対する影響が大きいかは分からず。
以下この設定をデフォルトにした上で実験。
- エンコーダ全て1、flowを全て1、
dec.resblocksのみを1とすると、ほとんどモデルBの声に聞こえる。 - 以前の結果から
dec.resblocksの8層が情報を多く持っていそうだったので、さらに加えてdec.resblocks.8を0にすると、やはり響きがかなり違う(0にしてしまうと汎用感が大きく増える)。 - ただし逆に
dec.resblocks.8のみを1、他のデコーダーを0とすると、汎用音声になってしまう。しかしデコーダ全て0にした場合とは明確に違う音声だと聞き取れる。
(やはり何となくの音質感・響きの度合い・スタジオの雰囲気、みたいなのが乗っていそう)
次にエンコーダの学習具合のピッチ依存度合いを調べるために、わざとモデルBと変換元音声の性別を別にしてみる
- エンコーダ全て1、flowを全て1、変換元音声を男性(ピッチ調整無し)、モデルBを女性としてみると、これでも自然な汎用音声に聞こえる。
しかし、モデルBとして男性をいくつか入れた場合の比較すると、感触が異なる感じがある
(モデルBが女性の場合がちょっと何となく高い響き?低音が薄い?滑らかさが少ない?汎用女性のピッチを下げただけのような声?) - 同じ設定で、今度は変換元音声を女性、モデルBを男性でいくつか試してみる。こちらも同じで汎用女性に聞こえるが、モデルBが女性の場合と比べて質が劣る(汎用男性のピッチを上げただけみたいな声?)
- エンコーダーの中で
enc_p.encoder.ffn_layersがピッチ依存が多いと予想されていたので、
enc_p.encoder.ffn_layersを0、他のエンコーダを1、flowを全て1で試してみると、こちらは性差ピッチ差に関わらず(ちょっと質が落ちた)汎用声に聞こえる。
考察・まとめ
各keyはなんとなく次のような役割を担っていそうである。
- エンコーダー:入力音声をちゃんとした解像度で理解するために必要(エンコーダーがpretrainedのままだとボケボケ)。
学習する際の学習元データの声の高さ付近の解像度が特にあがり、そういうピッチ依存の情報(モデルの性差やピッチ差)が大きく出るのはenc_p.encoder.ffn_layers。 - デコーダー:その人らしさが、とくに
dec.resblocksに多く入っている。その中でも8層dec.resblocks.8が多くの聴覚的情報を持っている。 - flow(ちょっと怪しい): 子音についての特性を持っている?とくにflowがpretrainedのままだと子音のノイズがかなり大きく音質が悪い典型的な出来が悪いモデルのように聞こえる。
応用?
以上を踏まえると、次のようなことが出来そう。
質が高いモデル(解像度高く音質もよく子音付近のノイズも少ない)から汎用音声を、上の エンコーダ全て1、flowを全て1の設定で作ると、
それを新たな事前学習モデルとしてすると、そこから学習すると質が高いモデルができるのではないか?←学習には大きいGとDモデルがいるので、それが作れない限りは無理そう、意味なかったすみません- 同様に、質が高いモデルをA、ノイズが多いが使いたい声のモデルをBとして、
dec.resblocksの全てを1にして他を0にすると、Bの声のままで質があがるのではないか?
(8層のみ0にしておいてもいいが、少し試したらBよりもAに聞こえてしまうこともあったので、そこらへんは0.5とか微調整とかする必要がありそう?)
またあまりボイチェンに乗せて試していないので今後も要実験。(差分マージは使い道が正直分からん……)
8/23 追記
実験結果置き場
質が微妙なモデルに高品質モデルを階層マージすることで話者性を変えずに質を底上げできるのではという実験。
- https://cdn.discordapp.com/attachments/1072055032826052611/1143758099161829499/original.mp3
- https://cdn.discordapp.com/attachments/1072055032826052611/1143758099858079806/merged.mp3
- https://cdn.discordapp.com/attachments/1072055032826052611/1143758099518328832/merged-layer8.mp3
入力音声は同じ、一番上はあるモデル(以下モデルB)で変換したもの、他2つは、Bに(個人的に質が高いと思っている)あるモデル(以下モデルA)を次のeach key mergeでweight sumマージしたものから変換した結果。
- 2番目:
enc_p.encoder.ffn_layers(母音の響き?)とdec全部を1(モデルBに全振り)、他を全て0(モデルA寄り)にしたもの。 - 3番目: 上と同じ設定のまま、1箇所
dec.resblocks.8のみを1から0(A側を使うよう)に変えたもの。
個人的には何となくの質が上がっているような感じがする。がdec.resblocks.8を変えると響きが大きく変化して、音質がより上がっている気もするが、同一話者かと言われると微妙に混ざっている感じもある。
ただノイズ耐性が上がっているというよりは録音スタジオを高音質に取っ替えただけ、みたいな感じがしなくもない……
まだもっといいマージパラメータがありそうなので要研究。
8/26追記
dec.upsについて
データセットの音質がよろしくないであろうモデルと手持ちの高音質モデルを混ぜたとき、今まであまり聴覚的影響が感じられなかったdec.upsの値によって、聞こえる音質というか違和感が大きく変化することがわかった。
詳細:
Model Aを高音質モデル、Model Bを低音質データセットモデルとし、Model Aの質をModel Bの話者に移植しようと、
enc_p.encoder.ffn_layers、dec.resblocks(の8層以外)を1(モデルBより)、他を全て0(モデルA寄り)
にすると、やたら質がキャピキャピ?した音質で違和感があった。
デコーダーのどこかが悪さをしていると思い試すとdec.upsを1、つまりモデルBに揃えると違和感がなくなった(低音質に聞こえる感じ)。
これを0.5にしてみるとちょっと音質が上がったような気がする。
推測
dec.upsとは「デコーダーでのアップスケール」の略で、生成された音をアップスケールにして高音質化する的な部分を担っているのでは?
データセットの音質に寄ってここの学習され具合が違って、低音質データセットのうちdec.upsだけを高音質なものにとっかえると、
(ねらった高音質化よりも)ドンシャリみたいな音質の悪さがよけい目立つ(荒い音質を無理やりアップスケールしている感?)
ただ0.5くらいで混ぜるといい感じになるかも?
↑少し調べるとupscaleというよりupsamplingなのでは説
まだ実験不足だしアーキテクチャを知らないので、いろいろ間違っていたらご指摘ください。