YuE2は公式にLoRA作成をサポートしていませんが、コミュニティでLoRA生成を可能にするトークナイザが公開されています。
Mothersuperior/yue2-mothersuperior-realaudio-tokenizer-v4 · Hugging Face
ai-toolkitなどがこれに対応し、簡単にLoRAを作ることができます。
Hugging Faceで公開されているファイルはtokenizer_head_jointとnar_lora_jointの2種類あります。以下AIによる解説
tokenizer_head_joint
壁その1: 実音をトークンに変換するものが存在しない
学習、つまり「この実音はこのトークン列である」という教師データを作るには、音声→トークン方向の変換器が必要です。ところが公式リリースにあるのはトークン→音声のデコーダだけ。逆向きの道具は非公開でした。
tokenizer_head_joint はこの穴を埋めるコミュニティ製の変換器です。仕組みはこんな感じです:
- 音声を24kHzにして MERT-v2-FullSong(音楽理解用の事前学習モデル)に通し、20層目の特徴量を取り出す
- 曲ごとにインスタンス正規化
- 8層のTransformer分類器で512フレーム(約20秒)の窓ごとに「この瞬間、YuE2の32,768語彙ではどのトークンか」を予測する
本体はMERTなので比較的軽量で、学習時のデータセットキャッシュ(実音→教師トークン列)作成に使われます。推論時、ARは自分でトークンを書くので、純粋な生成にはこのheadは不要です。
nar_lora_joint
壁その2: デコーダが「自家製の音」しか知らない
もう一つの問題はもっと根深いものでした。公式のNARはYuE2が自分で生成した4,765曲で学習されていたため、実音から来たトークン・潜在変数を忠実にレンダリングできないのです。せっかく良いトークナイザーを作っても、「実音の再現」が目的のデコーダに渡らないと意味がありません。
nar_lora_joint はこのギャップを埋めるNAR専用のアダプタで、2つの部品で構成されます。
- rank 32のLoRA: NARの全28層のattention(q/k/v/o)とMLP(gate/up/down)に、実音由来の潜在変数を正しく扱えるよう補正をかける
- vae2llm / llm2vae の全置換: LLMの隠れ状態空間(2048次元)とVAE潜在空間(64次元)を橋渡しする2つの射影は、LoRAではなく重みを丸ごと入れ替える
ここで重要なのが「joint」という名前です。headとNARアダプタは共同学習されており、headが「こうトークン化する」と決めた世界に合わせてNAR側が「そのトークンをこうレンダリングする」と学習されている。片方だけ差し替えると、共通言語の意味がずれてしまう。だからファイルのメタデータには pair_with: tokenizer_head_joint_v9 とペアが明記されていて、バージョンは必ず揃えます。
AIによる解説ここまで
LoRAを作る
このトークナイザのおかげで、ai-toolkitや他のツールでLoRA作成は簡単にできるようになりました。ではどのツールで作るのが簡単か、また高品質なものになるのかという話になります。1種類しか試してないので何も言えませんが、信頼と実績のai-toolkitで作成した過程を書いていきます。
トークナイザは公開当初v4でしたが活発にアップデートされており2026-09-19時点でv9が出ています。ai-toolkitはここから最新のものを取ってくる仕様になっています。
トークナイザのバージョンに関わらずデフォルト設定のままではnar_lora_jointを使用しません。これを使わなくても作れますが、あるものは使いたいし品質が上がる気がするので使います。GUIでは設定できないのでconfig.yamlを編集してmerge_nar_lora: trueという値を追加します。model→model_kwargsに書きます。
model:
name_or_path: "path/to/yue2_3b_bf16.safetensors"
quantize: false
quantize_te: false
arch: "yue2"
low_vram: true
model_kwargs:
merge_nar_lora: true
cot: "full"
データセット
データセットはどのくらい必要でキャプションなどはどう付けたらよいのか。ベストプラクティスは分かりませんが、私がやったのは
- 40秒くらいに機械的に(あるいはパートごとに手動で)スライスした曲データ50個程度(10曲分ほど)
- 歌詞やキャプション、タグは何もなし
設定で変更したところは
- モデルは
yue2_3b_bf16.safetensors(convrotだとmerge_nar_loraできないとAIが言ってた) - QuantizeをNoneに変更(効果があるかは分からない。VRAMの容量次第)
- 上記
merge_nar_lora: true
2,000~3,000ステップくらいが安定している気がします。RTX5070Tiで2,000ステップ1時間弱といったところです。歌詞やキャプションをまったく指定しなくてもきちんとしたものが出来ました。abcとlyricsを指定したカバーでは歌詞が崩れたりしますが、これは現状のLoRA本来の制限でもあり、キャプションや歌詞で改善するかどうかは分かりません(書くのが大変なので検証が面倒)。
LoRAを使う
nar_lora_jointを使ってトレーニングしたLoRAは推論時にもnar_lora_jointが必要です。作成したLoRAだけで推論しても一応動きますが、nar_lora_jointを挟んだほうが効きが良いです。
私は純正CLIを改造したもので推論しています。
使い方は
python examples/generate.py
--output "path/to/outputs"
--request "path/to/.json"
--abc-file "path/to/.abc"
--lyrics "path/to/lyrics.txt"
--nar-lora "path/to/nar_lora_joint_v9.safetensors"
--lora "path/to/lora.safetensors"
--lora-strength 0.6
GUIと比べて面倒かもしれませんが、jsonやlyricsにパラメータを保存できるのでこれもありかなと思います。
今回の例は個人的なforkなのであまりお勧めはできませんが、どのツールを使うにせよnar_lora_jointを使用しているかどうかが重要なのではないかと思います。