返回

文章详情

展示 HN:我训练了一个 1.25 亿参数的模型来实现移动设备上的钢琴自动补全

Hacker News2026年8月20日 12:04

简而言之:我训练了一个 1.25 亿参数的变换器,以实时(约 108 音符/秒,在 iPhone 15 上)自动补全钢琴演奏。最大的改进来自于找到合适的 MIDI 表示,大幅清理训练数据,以及添加 DPO 后训练。几乎一年前,我开始尝试一个想法:将我的 MIDI 钢琴连接到手机,演奏一些曲目,让 AI 为我完成歌曲。想象一下 GitHub Copilot,但适用于钢琴。结果比我预期的要复杂得多。经过十四次实验后,它终于达到了我满意的程度,可以写出来。您的浏览器不支持视频标签。视频质量较差,因为好的手机正忙于运行 MIDI 模型。如果您有 MIDI 键盘和 iPhone/iPad,可以在此免费下载应用 RollTab。1 一些声音样本 每个音频都以一个简短的提示开始,随后是模型的延续。宝可梦,调色板镇(8 音符提示)您的浏览器不支持音频标签。最终幻想 VI,特拉的主题(16 音符提示)您的浏览器不支持音频标签。致爱丽丝(16 音符提示)您的浏览器不支持音频标签。MIDI 文件中有什么?MIDI 文件与 MP3 或其他音频格式有很大不同。它不是存储录制的声音,而是将音乐存储为一系列事件:某个音符以特定音高和力度按下,某个音符释放,延音踏板状态改变,等等。其他事件包括切换乐器或改变音量。这些事件通常被组织成多个轨道。流行或游戏 MIDI 可能有旋律、和弦、低音、鼓、弦乐和几个合成器部分。这个项目专注于钢琴延续,因此我大多数时间保留了类似钢琴的材料,并删除或减少了其他部分。如何对音乐进行标记?为了训练一个变换器,我首先需要将 MIDI 事件转换为模型可以读取和预测的离散序列。最明显的映射是为每个 MIDI 事件创建一个标记:NOTE_ON_60_80 # {音高}_{力度} NOTE_OFF_60 # {音高} TIME_SHIFT_12 # {时间步长} 如果您直接在 NOTE_ON 标记中包含音高和力度,词汇表可能会迅速增长。有 128 个 MIDI 音高和 128 个力度值,因此简单的音符开关词汇表最多有:128 * 128 + 128 = 16,512 个标记,仅用于开音符和闭音符。实际上,您可能会对力度进行分组,但基本问题仍然存在:许多组合都是稀有的,模型必须从稀疏标记中学习大量结构。一个常见的改进是用语法对表示进行因式分解:[NOTE_ON, PITCH, VELOCITY] | [NOTE_OFF, PITCH] | [TIME_SHIFT, DURATION] 现在输出空间更小:NOTE_ON / NOTE_OFF / TIME_SHIFT 音高:128 个值 劲度:约 16 持续时间:约 100 您可以通过屏蔽无效的下一个标记来在生成过程中强制执行语法。NOTE_ON 后,只有音高标记是有效的。音高后,只有力度标记是有效的。这可以保证语法上的有效输出。我尝试了开音符/闭音符样式的表示,但我的模型往往会漂移。它们会忘记发出闭音符,留下挂起的音符,或失去活跃状态的跟踪。这对我的目标尤其糟糕:一个在笔记本电脑或手机上接近实时运行的小型模型。我尝试的另一种表示更接近:[NOTE, PITCH, VELOCITY, DURATION] | [TIME_SHIFT, DURATION] 。这避免了闭音符漂移,因为音符持续时间是明确的。当没有音符被演奏时,时间移位标记可以推动播放头。这在音乐上效果更好,但速度较慢。一个音乐音符大约需要四个自回归变换步骤。它还快速消耗上下文窗口。最终的表示我最终确定的表示为:NOTE(pitch, delta_onset, duration, velocity) 最终版本中没有单独的 TIME_SHIFT 事件。静音通过下一个音符的 delta_onset 来表示:上一个音符起始时间以来的时间。例如:NOTE(C4, delta=0, duration=12, velocity=80) NOTE(D4, delta=24, duration=12, velocity=80) 的意思是:演奏 C4,等 24 个时间步后再演奏下一个音符,然后再演奏 D4。和弦表示为多个音符,delta_onset = 0,按音高排序:NOTE(C4, delta=24, duration=24, velocity=80) NOTE(E4, delta=0, duration=24, velocity=78) NOTE(G4, delta=0, duration=24, velocity=82) 这也不是像这样的平坦标记流:NOTE, PITCH, DELTA, DURATION, VELOCITY。变换器不需要花费四个传递来生成一个音符的属性,而是一次移动音乐一个完整的音符。在实践中,这让大型模型在 iPhone 上达到约 108 音符/秒,远远超过人类在现场演奏所需的任何速度。内部每个音符都有五个分类字段,每个字段都有自己的词汇表3,时间量化为固定步骤4:[event_type, pitch_id, delta_id, duration_id, velocity_id] 每个字段都有自己的嵌入。音符标记是所有嵌入的总和:note = event_type_embedd

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡