エンジニアリング

DanceGAIがPlanner + Noterでbeatmapを生成する理由

ManiaGAIは音声を直接ノーツに変換せず、まず拡散モデルで各セクションのゲームプレイを計画し、MaskGIT型Transformerでノーツを配置します。その理由、トレードオフ、そして可能になること。

AI beatmapジェネレーターを説明するとき、いちばん自然なのは「音声を入れて、ニューラルネットワークを通し、ノーツが出てくる」という言い方でしょう。ManiaGAIはそういう仕組みではありません。仕事を二つに分けています:Plannerが曲の各部分をどんなプレイ感にするかを決め、Noterがノーツを正確にどこに置くかを決めます。この記事では、その理由、それぞれのモデルの役割、そしてこの分割の代償を説明します。

beatmapは書き起こしではなく、アレンジである

音声に忠実に沿った譜面が、必ずしも良い譜面とは限りません。良いosu! maniaの譜面は、むしろアレンジに近いものです:どの音にノーツを置くか、セクションをどれくらいの密度に感じさせるか、どこにjackやロングノーツが合うか、パターンを両手の間でどう流すか — そして、同じ曲のEasyとExpertでそれらをどう変えるか、をmapperが決めています。

音声からノーツへ直接変換する単一のモデルは、そうした判断のすべてを、あらゆる瞬間に一度に下さなければなりません:構成、難易度、スタイル、そして正確なレーン配置。この種のモデルは、局所的な細部は正しくても、曲全体の形を失いがちです — サビがAメロより盛り上がらない、ブレイクに抜けがない、といった具合に。

二つの問いに、二つのモデル

  1. 音楽
  2. 理解
  3. Planner
  4. Noter
  5. 検証
  6. beatmap

どちらのモデルも、曲について同じ音楽的な情報を読み取ります:タイミンググリッドと、それに拍ごとに整列した音声表現(オープンソースのMERTモデルによるもの)です。そこから:

  • Plannerは何が起こるべきかに答えます。ノーツが一つもない段階で、曲全体のゲームプレイ構成をセクションごとに組み立てます:各部分をどれくらい難しくするか、そしてロングノーツ、jack、その他のパターンタイプをどう配合するか。
  • Noterはノーツをどう置くかに答えます。プランと音声の両方に従って、プランを実際の配置に落とし込みます — どのレーンか、どのノーツを単ノーツにしてどれをロングノーツにするか、パターンをどうつなぐか。

それぞれのモデルの役割が絞られ、さらにプランは、ノーツを一つずつ生成するモデルにはないものをノーツ生成に与えます:すでに決まっている曲全体の見通しです。

Planner:曲全体を対象とするガウス拡散

Plannerは約6Mパラメータのガウス拡散モデルです。音楽、キー数、指定された難易度とスタイルを条件として、曲のすべてのセクションのプランをまとめて生成します。

拡散モデルがこの仕事に向いている理由は二つあります。プランは曲を滑らかで連続的に記述したもの — 時間とともに上下する局所的な難易度とパターン配合 — であり、拡散モデルが得意とする種類の信号です。そして、セクションを順番にではなく全体として生成することで、Plannerは曲全体のバランスを一度に取れます:サビとブリッジの両方が見えているからこそ、サビを山場にしてブリッジで休ませることができるのです。

Noter:MaskGIT型の反復改良

Noterは約51MパラメータのMaskGIT型の非自己回帰Transformerです。譜面は離散的なパターントークンとして表現されます。Noterは曲の頭から終わりまで一つずつ書いていくのではなく、譜面全体を埋めてから何回かのパスで改良していきます — 確信のあるノーツを確定させ、残りを見直すのです。そのパスを曲全体にどう割り振るかは私たち独自の手法で、非公開にしているものの一つです。

なぜ言語モデルが文章を書くように、譜面を左から右へ生成しないのでしょうか?

  • 厳密に左から右へ書くと、早い段階の判断がその後の音楽を考慮できず、長い曲ではミスが積み重なっていきます。
  • 反復改良型のモデルでは、どのパスもすべてのセクションの前後両側の文脈を見られるので、曲全体でパターンの一貫性が保たれます。
  • トークンを一つずつではなく、決まった回数のパスで譜面全体が生成されます — これは速度の面でも重要です。
  • あるセクションを、その後ろをすべて生成し直すことなく修正できます(詳しくは後述)。

難易度とスタイルは後付けではなく入力

この分割は、生成を制御可能にするものでもあります。ManiaGAIは明示的な制御パラメータを受け取り、モデルはそれに従うように学習されています:

  • キー数 — 4Kから9Kまで。
  • 難易度 — ★1から★10までの★レートを自由に組み合わせて選択。1回の実行でmapset一式が生成されます。
  • スタイル — 五つの軸:ロングノーツ比率、inverseロングノーツ、jack、短いロングノーツ、delay。難易度ごとに別のスタイルを指定でき、そのキー数と★レートの実際の譜面をもとにキャリブレーションされています。

これらの制御は、効果が出るところ、つまりプランに作用します:「もっと難しく」「ロングノーツを多く」「jackを多く」は、ノーツ一つではなくセクションの形についての判断だからです。密度は独立したつまみではなく、目標難易度とプランから決まります。そして、どの難易度も曲に対する同じ理解から生成されるため、mapsetは無関係な譜面の寄せ集めではなく、一つのファミリーとして読めるものになります。

部分再生成は設計から自然に生まれる

生成された譜面が全体的にダメということはめったにありません。多いのは、ある一節だけがおかしいケースです — 合わないパターン、密度が高すぎる区間。それを直すために譜面全体を生成し直すと、すでに良かった部分まで捨てることになります。

  1. 選択
  2. マスク
  3. 再生成
  4. 改良

Noterは譜面を左から右へ書くのではなく全体を改良していくので、選んだ範囲だけを、周囲をすべて固定したまま、周りのノーツを文脈として使って再生成できます — だから新しいセクションは譜面とぶつからず、自然につながります。これがセクション単位の編集の土台です:気に入らない部分を選んでそのセクションだけを再生成したり、ノーツを自分で編集して結果をテストプレイしたりできる譜面エディターを、現在社内でテストしています。サイトではまだ利用できません。

別々に学習させる

二つのモデルは、それぞれが扱う表現で別々に学習させています:Plannerは各セクションのゲームプレイの記述を対象とする拡散モデルとして、Noterはパターントークンに対するマスクトークン予測で。サンプルはキー数と難易度ごとにバランスさせ、★10の8Kのような珍しい組み合わせがよくある組み合わせに埋もれないようにしています。両方の基になっているデータについてはAI osu! mania mapperを支えるデータセットの中身で紹介しています。

分割の代償

階層構造はタダではありません。私たちが受け入れているトレードオフ:

  • 学習させ、同期を保つべきモデルが二つある。プランは両者の間のインターフェースで、その定義が変わると、両側が追従しなければなりません。
  • Noterの出来は、与えられたプランの出来を超えられない。セクションの判断を誤ったプランは、Noterに間違った指示を与えることになります。
  • プランが記述するのは、私たちが記述すると決めたものだけ。セクション単位の難易度とパターン配合は、譜面のプレイ感を決めるものの多くをとらえますが、mapperが意図するすべてではありません。

主張しないこと

この設計を、同じデータで学習させた単一のエンドツーエンドモデルと比較するベンチマークはまだ行っていないので、それより優れているとは主張しません。言えるのは、この設計によって、長い範囲の構成と局所的なノーツ配置を別々にモデル化するすっきりした方法、難易度とスタイルの制御を置く自然な場所、そして譜面の一つのセクションを残りに触れずに修正できるモデルが得られる、ということです。譜面スタイルはまだ少数の軸で制御しています。スライダーではなく例を示してスタイルを伝えられるようにすることが、私たちの目指している方向です。

テクノロジーページでは両モデルがパイプライン全体のどこにあるかを示しており、生成を高速化した方法では、それらを動かすのに何が必要かを紹介しています。