DanceGAI 是 AI osu! mania beatmap 生成器 ManiaGAI 背后的团队。DanceGAI 正在打造把音乐变成可玩体验的 AI 基础设施,ManiaGAI 是它的第一款产品:你上传一首歌,它就会生成一个完整、可玩的 osu! mania mapset——timing、音符和一组难度梯度——打包成标准的 .osz。歌曲可以是上传的音频文件,也可以是你链接的 osu! beatmapset 中的歌曲;无论哪种方式,都只使用音频,绝不使用现有的谱面。本站运行的是这套系统的第 2 版。osu! mania 是第一种输出格式:这套系统面向的是广义的下落式音游(VSRG)。
本页解释它如何运作,以及为什么这样设计。我们公开架构和工程决策;但不公开别人重建它所需的细节。凡是尚未公开的数字,本页会直接说明,而不是去猜测。
技术概要
| 任务 | 音频 → 可玩的 osu! mania mapset(.osz),每次运行生成一整组难度 |
|---|---|
| 范围 | 下落式音游(VSRG)——首先是 osu! mania;其他 VSRG 格式在计划中 |
| Timing | Beat This 激活值 → 自研网格拟合(支持变速)。在我们的基准测试中,2,501 首恒定速度的 Ranked 歌曲中有 97.1% 的 timing 与 mapper 的 timing 误差在 40 ms 以内 |
| 音乐表示 | MERT-v1-95M,逐拍对齐到 timing 网格 |
| 规划器 | 基于每段玩法状态的高斯扩散模型,约 6M 参数 |
| 音符模型 | 基于配置 token 的 MaskGIT 式非自回归 Transformer,约 51M 参数 |
| 控制项 | 4K–9K · ★1–10 目标星级 · 5 个风格维度(LN 比例、LN 反键、jack、短 LN、delay) |
| 训练数据 | 150,622 张人工制作的谱面 · 86,255 首歌曲 · 约 14,500 位 mapper · 4,227 小时音频 |
| 验证 | timing 网格检查、无效音符清理、静音保护、osu! 星级测量、mapset 一致性 |
| 训练 | 一张 RTX 4070 Ti SUPER · 生产模型整个演进过程中记录在案的 GPU 时长约 580 小时 |
| 生成 | 所选的各个难度在一次批量 GPU 计算中一起生成 · 完整 mapset 约需 20 秒 GPU 计算 |
| 部署 | 从内存快照恢复的 Serverless GPU 实例;音频在浏览器中完成标准化 |
beatmap 不是扒谱
描述自动 beatmap 生成最直观的方式是“输入音频,经过神经网络,输出音符”。但实际上,这种思路做出来的谱面虽然在技术上跟着音乐走,打起来却很难受。一张好的 osu! mania 谱面更像是编曲,而不是扒谱:mapper 要决定哪些声音值得放音符、一段应该有多密、jack 或 LN 该放在哪里、配置如何在双手之间流动,以及这一切在 Easy 和 Expert 难度之间如何变化。
所以 ManiaGAI 把 beatmap 生成拆成一系列不同的问题——理解音乐、规划玩法、放置音符、检查结果:
- 音乐
- 理解
- 规划
- 生成
- 精修
- Beatmap
1. 音乐理解
后续的一切都依赖于对歌曲的精确把握。第一阶段把原始音频变成两样东西:一个 timing 网格,以及歌曲每个时刻的高分辨率音乐表示。
Timing。节拍和强拍的激活值来自开源节拍追踪模型 Beat This。把这些激活值转换成 osu! 的 timing 网格——BPM 和 offset,包括变速歌曲——用的是我们自研的网格拟合方法,它产出的网格与生成模型训练时所用的网格属于同一类。timing 是玩家最先注意到的部分:一张谱面只要偏离节拍几毫秒,无论配置多好都没法玩,所以我们把它当作头等问题来对待,而不是一个预处理步骤。
音乐特征。音频由自监督音乐表示模型 MERT-v1-95M 编码,并对齐到 timing 网格——这样模型就能逐拍“看到”音乐:起音、质感、强度,以及它们在整首歌中的变化。静音段落会被单独检测出来,确保不会在上面放音符。
2. beatmap 规划
ManiaGAI 的核心设计选择是把“应该发生什么”与“音符怎么放”分开。
一个专门的规划模型会读取音乐表示,在任何音符出现之前就决定整首歌的玩法结构:每一段应该有多密、哪种配置该放在哪里、难度应该如何起伏,以及这一切如何契合所选的难度和风格。它输出的是一份逐段描述谱面的规划——局部难度,以及 LN、jack 和其他配置类型的比例——而不是音符。
规划器是一个高斯扩散模型(约 6M 参数)。它以音乐、键数、目标难度和风格为条件,联合生成整首歌每一段的规划。扩散模型很适合这项工作:规划是对一首歌平滑、连续的描述,整体生成能让规划器同时平衡整首歌。
在这个层面上做规划,让系统拥有了逐音符模型所缺少的东西:对整首歌的全局视野。副歌可以被规划得比前面的主歌更有冲击力;breakdown 段落可以被规划得留出喘息空间。
3. 音符生成
第二个模型把规划变成实际的音符放置——放在哪些轨道、哪些是单点哪些是 LN、配置如何衔接。规划决定结构;音符生成把这个结构变成既遵循规划、又跟随音频的可玩音符。
音符模型是一个 MaskGIT 式非自回归 Transformer(约 51M 参数)。谱面被表示为离散的配置 token,模型不是从头到尾一个个写出来,而是先填满整张谱面,再经过多轮精修——确定它有把握的音符,重新审视其余部分。每一轮都能看到每一段前后两侧的上下文,这正是配置能在整首歌中保持一致的原因。这些精修轮次在整首歌上如何调度,是我们自研的精修方法。
ManiaGAI 为什么采用 Planner + Noter(英文)→
4. 可控生成
ManiaGAI 不是一个“生成完听天由命”的系统。同一首歌可以在明确的控制项下生成,而遵循这些控制项本身就是模型训练目标的一部分:
- 键数——4K 到 9K。
- 难度——从 ★1 到 ★10 任意选择星级。一首歌一次运行就能产出一整个 mapset,从 Easy 到 Expert。
- 风格——玩法特征,例如 LN 所占比例,以及谱面中 jack、反键 LN、短 LN 和 delay 配置的多少,每一项都可以在生成器上调整。
- 密度——由目标难度和规划决定,而不是由固定规则决定。
每个难度都基于对歌曲的同一份理解生成,所以一个 mapset 读起来是同一个家族的谱面,而不是互不相干的几张。接下来,我们正在研究可学习的风格表示——通过示例来描述一种做谱风格,而不是靠几个滑条。
5. 验证与质量控制
在谱面交到你手上之前,系统会对它进行检查:
- Timing——写入的 timing 点会与检测到的网格进行比对。
- 无效和不可玩的音符——重叠的音符、损坏的 LN 以及游戏无法表示的放置都会被处理掉,明显静音的音频上不会放任何音符。
- 实测难度——每张谱面的星级都用 osu! 所用的同一套星级算法测量,难度以实测值命名,而不是以请求的值命名。
- mapset 内的一致性——如果一张谱面比本应低它一级的谱面还简单,或者与相邻难度几乎一样,就会被丢弃,而不会交付。在生成器上,你可以看到哪些星级被丢弃了以及原因。
- 输出有效性——结果会被打包成标准的 .osz,包含音频、背景和打击音效,可以直接导入 osu!。
数据一览
- 训练集中的歌曲
- 86,255
- 训练谱面
- 150,622
- Mapper
- 约 14,500
- 去重后的音频
- 4,227 小时
- 磁盘上的训练特征
- 约 0.7 TB
- 训练算力(记录在案,生产模型演进过程)
- 约 580 GPU 小时
- 音符模型最终一轮训练
- 约 4 天
- 模型参数量
- 约 57M(音符模型 51M + 规划器 6M)
- 完整 mapset 生成
- 约 20 秒
- 键数模式
- 4K–9K
- 难度范围
- ★1–★10
- 每次运行的难度数
- 最多 10 个(长歌曲会更少)
训练数据
生产模型的学习来源是约 14,500 位 mapper 制作的 150,622 张人工 osu! mania 谱面,涵盖 86,255 首歌曲——共 4,227 小时的去重音频。这类系统的大部分工作不在模型,而在数据:判断什么样的谱面值得学习、确保每个训练样本的 timing 都是对的,以及用一种能捕捉谱面可玩性的形式来表示谱面。
评估:timing 准确度
我们在每一个能够评估的、单一恒定速度的 Ranked osu! mania mapset 上——共 2,501 首歌曲——将我们的 timing 与人工 timing 进行了对比,同时对比了开源的 Mapperatorinator 的 timing 模式,以及我们之前的检测器 ManiaGAI v1。当 BPM 与 mapper 的一致(允许半速/倍速)且节拍相位在给定容差内时,该歌曲计为正确。
| 方法 | ≤10 ms | ≤20 ms | ≤40 ms | BPM 正确 | 单条 timing 线 |
|---|---|---|---|---|---|
| ManiaGAI v2 | 71.4% | 92.3% | 97.1% | 98.0% | 100% |
| Mapperatorinator | 78.0% | 90.9% | 91.7% | 92.6% | 11.0% |
| ManiaGAI v1 | 74.8% | 88.0% | 90.7% | 94.0% | 92.8% |
仅限恒定速度的 Ranked 歌曲;“单条 timing 线”= 该歌曲像 mapper 那样只用一条线打 timing(在恒定速度的歌曲上多出一条线,就是一次错误的变速)。测量所用的配置与实际上线的配置接近,但不完全相同。
训练
规划器和音符模型分别训练,各自基于自己所处理的表示——规划器是在每段玩法的高斯化描述上训练的高斯扩散模型,音符模型则通过对配置 token 做掩码预测来训练。训练样本在各键数和各难度等级之间做了平衡,避免 8K 和 ★10 的谱面被 4K 和 ★4 淹没;音符模型采用混合精度训练。
每一次改动都以生成的谱面本身来评判——timing 准确度、实测难度与目标的差距、可玩性——而不只看训练损失。
推理与性能
一个有用的 AI 系统不只关乎模型质量;它还必须快到能用。一次 ManiaGAI 请求的运行过程如下:
- 在你的浏览器中:你一选好文件,歌曲就会被解码、响度标准化并重新编码,而此时你还在选择设置——所以 GPU 永远不用等待音频处理。
- 在 GPU 上进行音乐理解:Beat This 和 MERT,网格拟合在 CPU 上与 MERT 并行运行。
- 在一次批量计算中,为每个所选难度完成规划和音符生成。
- 验证——星级测量、一致性检查。
- .osz 打包,然后下载。
GPU 实例从预加载的快照启动,所以即使是冷启动的实例,也能在几秒内就绪,而不必花时间加载模型。对于一首典型的歌曲,一个完整 mapset 大约需要 20 秒的 GPU 计算时间——不包括上传、排队和下载;一首实测时长 2:50、包含五个难度的歌曲在 NVIDIA T4 上用了 12.7 秒——timing 和音乐特征 3.8 秒(并行运行),规划 1.0 秒,五个难度的音符生成 6.1 秒。
我们不公开什么
我们公开架构原则、背后的工程决策,以及这套系统能做什么、不能做什么——包括我们所基于的开源模型(Beat This、MERT),以及我们自己的模型所属的模型家族(高斯扩散、MaskGIT)。我们不公开自己开发的方法,也不公开能让别人复现这套系统的细节:timing 网格如何拟合、其速度分段如何合并,音符模型的精修轮次如何在整首歌上调度,模型如何进行条件控制,确切的架构、损失函数和超参数,以及训练数据如何获取、筛选和构建。这就是“对我们所打造的东西保持透明”和“把配方交出去”之间的界线。当我们对质量做出声明时,我们打算用公开的基准测试来支撑——而不是用形容词。
接下来
超越 osu! mania。ManiaGAI 的设计围绕着一种并非 osu! mania 专属的玩法表示:分布在各条轨道上的音符和 LN,放在 timing 网格上,并以目标难度为条件。osu! mania 是第一种输出格式,而不是这套系统的边界。
深入阅读
ManiaGAI 背后的研究与工程细节: