深夜的厨房里,外婆拿出一本泛黄的菜谱,照着上面的字句——“盐三克、糖一勺、小火闷十分钟”——一道道菜便端上餐桌。你会发现一个奇妙的事实:菜谱不是菜,它只是符号;但有了菜谱,任何人(甚至机器人)都能做出那道菜。音乐世界同样如此。MIDI 和 ABC 记谱,就是音乐的“菜谱”;而 wav、mp3 音频文件,则是端上桌的“菜”。以前我们收集的是“菜”(音频),现在 AI 要学的是“写菜谱”——这就是符号音乐生成。与之相对的 Suno、Udio、MusicGen 等模型,就像是不断试菜的大厨,有的直接凭感觉炒出成品(端到端音频生成),有的则先工工整整写好谱子再让乐手演奏(符号生成 + 渲染)。这篇文章,就是带你走进这间“音乐厨房”,看看 MIDI 与 ABC 这两套谱面语言如何被 AI 读懂、学习、进而写出新曲子。

岗位关联

对 AI 从业者而言,掌握符号音乐生成等于掌握了音乐领域的“结构化数据”玩法:可控、可编辑、可评估,是做配乐、扒谱、教学等落地项目的关键拼图。

目录
  1. 可视化演示
  2. 符号音乐基础
  3. 数据表示与词元化
  4. 生成模型原理
  5. 对比音频生成模型
  6. 工程实现与工具
  7. 项目应用实战
  8. 常见陷阱与对策
  9. AI 应用场景
  10. Python 演示
  11. 常见误区
  12. 面试题

可视化演示

动态演示符号音乐生成MIDI与ABC的核心机制,通过采集/分析/决策/反馈四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

符号音乐生成MIDI与ABC:符号音乐 符号音乐表示方法概述 MIDI序列建模与Transf 核心机制可视化 符号音乐生成MIDI与ABC整体架构与关键组件

符号音乐基础

想象外婆的厨房:菜谱写“糖二勺”,你永远不会把糖罐子本身端上桌,糖是“原料”,文字是“描述”。音乐世界同理——音频是切切实实的声波振动,是入口的菜;符号(乐谱、MIDI、ABC)是对音乐的描述,是纸上的菜谱。普通人听歌听到的是菜的味道,而 AI 要创作音乐,首先得学会读菜谱。

MIDI 就是最经典的“数字化菜谱卡”。它不记录任何声音波形,只记录事件:第几拍按下哪个键、按多大力、松手。像菜谱写“第 3 分钟加盐 3 克”。每条 MIDI 消息都有明确的编号——中央 C 是 60,往上升一个半音就加 1。ABC 记谱则更像外婆随手写的便签:一行纯文本 C4 D4 E4 就能表示"Do-Re-Mi",人类可读、可 diff、可放进 Git 管理,是轻量交换和 AI 数据标注的利器。

MIDI 和 ABC 的优势在于精确可控——菜谱可以随时改“盐三克”为“盐两克”,音频却没法直接改某个音符的音高。这正是符号音乐生成在配乐、教学等场景不可替代的原因:模型生成的不是一团无法修改的声音,而是一份可以反复雕琢的乐谱。

回到厨房:这条公式就像“一茶匙=5 克”的单位换算表。AI 读完 MIDI 菜谱上的编号,靠它就能算出真实的声波频率,把纸上的符号变成锅里翻滚的食材——符号音乐的第一步,就是让 AI 学会这份换算表。

f=440×2n−6912\displaystyle f = 440 \times 2^{\frac{n - 69}{12}}
这条公式把 MIDI 编号(菜谱里的“编号盐勺”)翻译成声波频率(菜的实际咸度),是符号世界通向声音世界的桥梁。
  1. nMIDI 编号:如中央 C 记为 60,它表示乐谱里的第 n 号指令。
    nn
  2. 69 号基准MIDI 编号 69 对应国际标准音 A4,频率恰为 440 Hz,是菜谱的“基准口味”。
    n−69n - 69
  3. 除以 12 得半音程每 12 个半音是一个八度,用差值除以 12 得到相对八度数。
    n−6912\frac{n - 69}{12}
  4. 以 2 为底的指数每升高一个八度,频率翻倍;指数部分决定翻几倍。
    2n−69122^{\frac{n - 69}{12}}
  5. 乘 440 得频率从基准音出发,按倍数缩放得到实际振动频率 f。
    f=440×2n−6912f = 440 \times 2^{\frac{n - 69}{12}}

数据表示与词元化

外婆写菜谱时,会把“适量”改成“3 克”,因为机器没法理解模糊量。AI 读乐谱同样需要标准化食材——把连续的音乐切成一粒粒明确的“词元”(token)。第一步是时间离散化:音乐是流动的时间,但计算机只能记录离散的时刻,于是我们把一秒切成若干均匀的小格子,每个音符落在某个格子里,像把一锅粥分成一碗碗定量米饭。

音符词元的设计是核心。一个完整的音符词元必须回答三个问题:音高(哪个键)、时值(按住多久)、力度(按多用力)。在 MIDI 世界,这三个量分别对应 note number、duration、velocity。ABC 记谱里则写成 G4/2 表示 G4 音长半拍。为了让模型学会“节奏感”,还必须把休止符也编码进去——菜谱里“静置 10 分钟”同样是一道工序。

词元序列的构建方式,直接影响模型效果。常见做法是采用“事件流”格式:[NOTE_ON, 60, VELOCITY, 80, TIME_SHIFT, 120] 这样的三元组串成一条长序列,就像把菜谱改写成一行行带时间戳的流水账。这样,音乐生成问题就被完美转化成了文本生成问题——既然音符序列像句子,那语言模型的那套本事就能直接搬过来用了。

这一节就像把外婆的“盐少许”改写成“盐 3 克、第 5 分钟加入”。时间离散化把流动的音乐冻结成一格格清晰的步骤,AI 这个学徒才能照着流水账一步步执行,不慌不忙。

ttoken=⌊tsec×TPQ60/BPM⌋\displaystyle t_{\text{token}} = \left\lfloor \frac{t_{\text{sec}} \times \text{TPQ}}{60 / \text{BPM}} \right\rfloor
把以秒为单位的音乐时间,换算成以"tick“为单位的离散词元位置,相当于把”3 分钟“换算成”180 秒 × 节拍器刻度"。
  1. BPM每分钟拍数:决定菜谱的火候基准,BPM=120 意味着一秒两拍。
    BPM\text{BPM}
  2. 一拍时长60 除以 BPM,得到每一拍占多少秒。
    60BPM\frac{60}{\text{BPM}}
  3. TPQ每拍的 tick 数:为了更细的粒度,每拍再切成 TPQ 个小格(常见 480)。
    TPQ\text{TPQ}
  4. 秒转 tick音乐秒数乘以 TPQ,得到以 tick 为单位的精细时间。
    tsec×TPQt_{\text{sec}} \times \text{TPQ}
  5. 除以拍长并取整除以每拍秒数,向下取整,得到离散的词元位置。
    ⌊tsec×TPQ60/BPM⌋\left\lfloor \frac{t_{\text{sec}} \times \text{TPQ}}{60 / \text{BPM}} \right\rfloor

生成模型原理

有了词元序列,AI 就像拿到了一本本菜谱开始学习写作。它学的不是背诵某道菜,而是逐字接龙的能力:看到“盐、糖、酱油”,预测下一个很可能是“醋”;看到“C、E、G“,预测下一个可能是”C”。这种逐个预测下一个词元的模型,叫自回归生成模型,是目前符号音乐生成的主流骨架。

具体来说,模型把整首曲子的词元序列按顺序拆开,每一步只看已经生成的部分,输出下一个词元的概率分布。训练时用海量 MIDI/ABC 语料教它“人类通常怎么接下去”;推理时,我们从起始符开始,一个词元一个词元地往外蹦,直到遇见终止符。为了让生成不呆板,还要引入采样策略——在概率分布里“掷骰子”,而不是永远选概率最大的那个。

条件控制也是关键需求。想生成“爵士风格、90 BPM、钢琴独奏”,就把这些信息作为前缀拼在序列前面,或者用专门的风格向量引导生成。这样模型从“随便写”变成“照着命题作文”——外婆点菜,AI 照单做菜。

此刻的模型,像极了学写菜谱的徒弟:它不背菜,而是掌握了“咸了配糖、辣了配醋”的接龙直觉。你给它一个开头“宫保鸡丁”,它能凭条件概率一路写到“出锅装盘”——这就是符号音乐生成的魔法引擎。

P(x1,…,xT)=∏t=1TP(xt∣x1,…,xt−1)\displaystyle P(x_1, \dots, x_T) = \prod_{t=1}^{T} P(x_t \mid x_1, \dots, x_{t-1})
整首曲子的概率,等于每个音符在“看到前面所有音符”之后的条件概率相乘——一句句接龙,串成整篇乐章。
  1. 序列 x₁…x_T一首曲子的完整词元序列,相当于一整份菜谱的配料步骤表。
    x1,…,xTx_1, \dots, x_T
  2. 乘积符号 ∏把所有步骤的概率乘起来,每一步都算数。
    ∏t=1T\prod_{t=1}^{T}
  3. 条件概率第 t 个音符出现的概率,取决于它前面所有音符。
    P(xt∣x1,…,xt−1)P(x_t \mid x_1, \dots, x_{t-1})
  4. 链式法则整体概率分解为一步步条件概率的连乘,这就是“接龙”的数学形式。
    ∏t=1TP(xt∣x<t)\prod_{t=1}^{T} P(x_t \mid x_{<t})

对比音频生成模型

同样是“做菜”,不同 AI 主厨的路数截然不同。Suno 和 Udio 是两位“感觉派大厨”:你报一句菜名(提示词),它们直接端出一盘热气腾腾的菜——整段音频凭空生成,中间没有乐谱这个过程,优势是成品自然、氛围感强,缺点是菜谱不可见,想改其中一味调料(一个音符)几乎不可能。

MusicGen 则走了一条折中路:先用音频压缩模型(如 EnCodec)把声音变成“音频词元”,在压缩空间里做自回归或流匹配生成,再解码回波形。相当于大厨用一套只有自己懂的速记符号写菜谱,外人看不懂,但生成效率高。而符号音乐生成(MIDI/ABC 路线)是彻底的“写谱派”:先产出人类可读的乐谱,再交给音源库渲染成音频。每一步都可编辑、可复盘。

实际工程里,聪明团队常用混合方案:符号模型先快速产出旋律草稿(便宜、可控),再由音频模型或高质量音源库进行“渲染”(补足音色质感)。这就像先用菜谱写好框架,再请米其林大厨掌勺——既保住了菜谱的可改性,又拿到了成品的色香味。

所以别再把符号生成和音频生成看作敌人了。Suno 是即兴创作的感觉派,MusicGen 是自创暗号的效率派,MIDI/ABC 是明明白白的写谱派——聪明的后厨三者兼用,用写谱派打底,用感觉派提味。

P(y∣c)=∏tP(yt∣y<t,c)\displaystyle P(y \mid c) = \prod_{t} P(y_t \mid y_{<t}, c)
条件生成公式:在给定条件 c(风格/乐器/情绪)下逐词元生成,条件像菜谱上的“口味备注”。
  1. 条件 c用户输入的风格、BPM、乐器等要求,相当于“少辣多醋、要脆”的口味备注。
    cc
  2. y_t 与 y_&lt;t当前生成的词元和它之前的所有词元。
    yt,  y<ty_t, \; y_{<t}
  3. 条件概率每一步生成都参考条件 c 和历史 y_&lt;t。
    P(yt∣y<t,c)P(y_t \mid y_{<t}, c)
  4. 连乘整段条件生成的联合概率,是每一步条件概率的乘积。
    ∏tP(yt∣y<t,c)\prod_{t} P(y_t \mid y_{<t}, c)

工程实现与工具

纸上谈兵结束,真刀真枪上厨房。工程实现的第一步是选框架:Hugging Face Transformers 生态里已有针对音乐词元序列的模型与数据加载器,能直接读取 MIDI 并转成 token 序列,就像厨房里现成的切菜机。搭建生成流水线时,核心是一个循环:喂入前缀词元 → 模型输出概率分布 → 采样得到下一个词元 → 拼接回序列 → 重复直到结束符。这个循环用 PyTorch 几十行就能写出来,但魔鬼在细节里。

采样策略是调味的灵魂。直接用概率最大值(贪心)会让音乐单调得像复读机;纯随机又像野马脱缰。行业标准做法是温度采样 + Top-p 截断:温度 T 控制分布的“陡峭度”,T 越低越保守、T 越高越冒险;Top-p 则只从累计概率到达 p 的最小候选集里采样,排除那些离谱的尾部选项。二者结合,既保留创造性又不至于跑调。

评估指标同样不能马虎。符号生成的评估分两类:客观指标看词元准确率、音高直方图分布、节奏一致性;主观指标则靠人听——“像不像人写的曲子”。实践中常用负对数似然做训练监控,用人听评测做最终验收。性能调优时,优先检查数据预处理(BPM 归一化、音高范围裁剪)和采样超参(温度、Top-p),往往比换模型收益更大。

这条公式就是厨房里的“火候旋钮”:T 调小,AI 只敢用最稳妥的配料,曲子规矩但无聊;T 调大,AI 大胆尝试奇怪搭配,可能惊艳也可能翻车。工程调优的本质,就是找到让“顾客满意度”最高的那个旋钮位置。

pi=ezi/T∑jezj/T\displaystyle p_i = \frac{e^{z_i / T}}{\sum_j e^{z_j / T}}
Softmax 温度采样:把模型的原始得分变成概率分布,温度 T 调节这个分布是“保守”还是“奔放”。
  1. z_i第 i 个候选词元的得分:模型对每个可能音符给出的原始打分,像厨师对每种调料的推荐度。
    ziz_i
  2. 温度 T 缩放得分先除以 T,T 越大,得分差距被压缩,分布越平缓。
    ziT\frac{z_i}{T}
  3. 指数化取 e 的幂,把任意实数得分转成正数,方便归一化。
    ezi/Te^{z_i / T}
  4. 分母归一对所有候选求和,使各概率加起来等于 1。
    ∑jezj/T\sum_j e^{z_j / T}
  5. 得到概率第 i 个词元被采样到的概率 p_i。
    pi=ezi/T∑jezj/Tp_i = \frac{e^{z_i / T}}{\sum_j e^{z_j / T}}

项目应用实战

学了这么多配方,该开店营业了。最常见的落地场景是自动配乐:游戏或短视频需要几十段不同情绪的循环 BGM,人工写太慢。用符号生成模型,输入“紧张、快板、钢琴”,几分钟内产出大量 MIDI 草稿,再由音源库渲染成成品——好比餐厅批量预制招牌菜,出餐快且质量稳定。

第二个热门方向是扒谱转 MIDI:用户哼一段旋律或用乐器弹一句,系统先用音高估计(如 CREPE)提取音高序列,再转换成 MIDI/ABC 谱,最后可用符号生成模型自动补全和弦与编曲。这和“美食家尝一口菜,反推出菜谱”异曲同工——把音频逆向工程成可编辑的乐谱,在音乐教学、翻唱改编场景极有价值。

第三个方向是风格迁移与教学辅助。把一首钢琴曲的 MIDI 输入模型,用风格条件控制改成爵士版或电子版;或者把枯燥的练习曲变成好听的伴奏,提升琴童练琴兴趣。这些应用共同指向同一个洞察:符号是可控的中间表示。只要守住“乐谱”这一层,产品的可编辑性、可搜索性、可教学性就全部盘活了。

从配乐到扒谱再到教学,每一个项目都是“菜谱生意”的具体形态。AI 写出的不是不可修改的音频文件,而是一张张等待二次创作的菜谱——这正是符号音乐生成在真实世界安身立命的根本。

L=−1N∑t=1Nlog⁡P(xt∣x<t)\displaystyle L = -\frac{1}{N} \sum_{t=1}^{N} \log P(x_t \mid x_{<t})
交叉熵损失:衡量模型预测“下一步”的能力有多差,是训练时不断修正菜谱笔误的老师。
  1. 概率 P(x_t | x_&lt;t)模型对第 t 个真实音符给出的预测概率,越接近 1 说明越有把握。
    P(xt∣x<t)P(x_t \mid x_{<t})
  2. 取负对数概率越大,负对数越小;概率为 1 时损失为 0。
    −log⁡P(xt∣x<t)-\log P(x_t \mid x_{<t})
  3. 求和平均把整首序列每个位置的损失加起来,再除以长度 N。
    1N∑t=1N\frac{1}{N} \sum_{t=1}^{N}
  4. 整体损失 LL 越小,模型“接龙”水平越高,生成的曲子越像人写的。
    L=−1N∑t=1Nlog⁡P(xt∣x<t)L = -\frac{1}{N} \sum_{t=1}^{N} \log P(x_t \mid x_{<t})

常见陷阱与对策

后厨翻车,往往不是刀工不行,而是细节疏忽。第一个大坑是过拟合记忆:训练集里某首名曲出现太多,模型生成时直接“背”出原曲片段,像徒弟背菜谱背串了页。对策是数据去重、加入重复惩罚项、用 Top-p 截断降低复现概率。

第二个坑是长序列退化:曲子越长,前面生成的内容对后面的引导越弱,后半段容易重复或混乱。类比写作文,写到第三页忘了开头写了啥。对策包括使用相对位置编码、分段落生成再拼接、或设置“主题 token”在关键位置反复注入。

第三个坑是多轨对齐:生成钢琴+小提琴+鼓的多轨 MIDI 时,各轨独立生成会“打架”——节拍对不上、和声不和谐。传统方法是先定和弦骨架,再让各轨围绕骨架生成,就像先定好宴会菜单再让各个厨师分头备菜。最后还有数据偏差:训练语料若以西方古典和流行乐为主,模型永远写不出东方五声音阶的味道——数据即食材,食材单一,菜系必然单一。

回头看,这些陷阱全是“厨房管理”问题:怕背菜谱就多换花样,怕写乱就列提纲,怕打架就分好工,怕菜系窄就多进新食材。符号音乐生成的工程之道,本质上就是一份细致入微的后厨守则。

PPL=exp⁡(−1N∑t=1Nlog⁡P(xt∣x<t))\displaystyle \text{PPL} = \exp\left(-\frac{1}{N} \sum_{t=1}^{N} \log P(x_t \mid x_{<t})\right)
困惑度:把交叉熵损失取指数,直观反映模型“每次接龙有多纠结”——数值越大越迷茫。
  1. 交叉熵平均先算序列上每一步负对数概率的平均值。
    −1N∑t=1Nlog⁡P(xt∣x<t)-\frac{1}{N} \sum_{t=1}^{N} \log P(x_t \mid x_{<t})
  2. 取指数用 exp 把损失映射回“平均候选数”的量纲,便于直觉理解。
    exp⁡(⋅)\exp(\cdot)
  3. PPL 含义困惑度 10 表示模型每次相当于在 10 个候选里瞎猜;值越小,生成越自信连贯。
    PPL=exp⁡(−1N∑t=1Nlog⁡P(xt∣x<t))\text{PPL} = \exp\left(-\frac{1}{N} \sum_{t=1}^{N} \log P(x_t \mid x_{<t})\right)

AI 应用场景

AI 游戏配乐管线

阶段:符号生成 → 渲染 → 集成

解决的问题:传统游戏配乐需要作曲家逐首创作,一部游戏动辄几十首 BGM,周期以月计且改稿困难。AI 先以符号生成模型批量产出 MIDI 草稿,再通过音源库渲染成音频,配合情绪标签(紧张/轻松/悲伤)自动匹配游戏场景,将配乐周期从数月压缩到数天。

具体案例:某独立游戏团队在开发平台跳跃游戏时,输入“像素风、快节奏、80 BPM”的文本条件,让符号模型生成 200 段 8 小节 MIDI 循环,人工挑选 30 段用钢琴音源渲染,最终包进游戏并依据关卡速度动态切换——整个流程没有录制任何真实乐器。

哼唱扒谱与教学工具

阶段:音频转录 → 符号表示 → 教学可视化

解决的问题:琴童想弹喜欢的歌却找不到谱,音乐老师需要把学生的哼唱快速转成可编辑的练习谱。传统手动扒谱依赖绝对音感,门槛极高。AI 把哼唱音频转为 MIDI/ABC 谱,再辅助配和弦、标指法,让“听歌→看谱→学弹”全链路数字化。

具体案例:一款音乐教学 App 内置“哼唱转谱”功能:用户对着手机哼旋律,后台用音高估计模型提取音高序列,量化成 MIDI 音符后自动生成 ABC 谱和钢琴卷帘可视化,并给出节奏准确度评分,成为幼儿钢琴课的标配练习工具。

多轨编曲辅助工作站

阶段:条件生成 → 多轨对齐 → 人工精修

解决的问题:独立音乐人编曲时最怕“灵感枯竭”——有了主旋律却不知道配什么贝斯和鼓。符号生成模型以主旋律为条件,分别生成贝斯轨、鼓轨、和弦轨,并对齐节拍骨架,输出多轨 MIDI 工程文件供宿主软件(如 Ableton)直接打开精修。

具体案例:一位 up 主分享了自己用开源符号模型生成“爵士鼓 + 电子贝斯 + 弦乐pad”的编曲过程:输入钢琴主旋律后,模型生成三条辅助音轨,人耳微调后直接混音导出,播放量破百万,评论区惊呼“AI 编曲已到这种程度”。

Python 演示

python52 行
import mathimport structimport wave SAMPLE_RATE = 44100NOTE_NAMES = {'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11}DEFAULT_DURATION = 0.5  def note_to_midi(note_str):    name = note_str[0]    octave = int(note_str[1:])    return 12 * (octave + 1) + NOTE_NAMES[name]  def midi_to_freq(midi_note):    return 440.0 * (2 ** ((midi_note - 69) / 12.0))  def render_tone(freq, duration, volume=0.5):    frames = int(SAMPLE_RATE * duration)    data = []    for i in range(frames):        t = i / SAMPLE_RATE        env = 1.0 - i / frames        sample = volume * env * math.sin(2 * math.pi * freq * t)        data.append(sample)    return data  def abc_to_wav(abc_text, output_name):    notes = abc_text.split()    audio = []    for note_str in notes:        midi = note_to_midi(note_str)        freq = midi_to_freq(midi)        audio.extend(render_tone(freq, DEFAULT_DURATION))    with wave.open(output_name, 'w') as wav:        wav.setnchannels(1)        wav.setsampwidth(2)        wav.setframerate(SAMPLE_RATE)        frames = []        for sample in audio:            encoded = int(max(-1.0, min(1.0, sample)) * 32767)            frames.append(struct.pack('<h', encoded))        wav.writeframes(b''.join(frames))  if __name__ == '__main__':    melody = "C4 C4 G4 G4 A4 A4 G4"    abc_to_wav(melody, 'twinkle.wav')    print("生成完成: twinkle.wav, 音符数 =", len(melody.split()))
目的:把简化版 ABC 记谱文本(如 C4 C4 G4...)解析成 MIDI 音符,再用正弦波合成渲染成 wav 音频文件——“菜谱”到“菜”的完整闭环。
  1. NOTE_NAMES = {'C': 0, 'D': 2, ...}音名到半音偏移的查表,相当于菜谱里“代号→实际克数”的换算字典
  2. def note_to_midi(note_str):把 ABC 风格文本(如 C4)解析成 MIDI 编号 0-127
  3. return 12 * (octave + 1) + NOTE_NAMES[name]用八度 × 12 + 音级偏移得到 MIDI 编号
  4. def midi_to_freq(midi_note):正文第 1 节公式的代码实现:MIDI 编号 → 频率
  5. return 440.0 * (2 ** ((midi_note - 69) / 12.0))以 A4=440Hz 为基准的指数换算
  6. env = 1.0 - i / frames线性衰减包络,避免音符首尾产生爆音
  7. audio.extend(render_tone(freq, DEFAULT_DURATION))把每个音符的波形片段首尾拼接成整曲
  8. with wave.open(output_name, 'w') as wav:以标准 wav 格式落盘,让“菜谱”真正端上桌
  9. wav.writeframes(b''.join(frames))把所有采样点的二进制数据一次性写入文件

常见误区

误区我一直以为 .mid 文件和 .mp3 一样,里面存的是音频波形,只是体积小一些,所以听起来音质“差”是因为压缩太狠。

正解MIDI 文件里一个声音样本都没有,只有指令序列:什么时候按下哪个键、力度多大、松开。它像菜谱而不是菜,播放器需要自带“音源库”(合成器)把指令实时变成声音。不同音源播放同一 MIDI 文件,味道完全不同,正如不同厨师做同一道菜。

为何常见:操作系统双击 .mid 就能播放,且音源默认加载,让人误以为文件本身包含声音。

误区ABC 记谱是上世纪的老古董,现在都有专业打谱软件和 AI 了,学它纯属浪费时间。

正解ABC 记谱的简洁性恰恰是它的王牌:纯文本、人类可读、可放进 Git 做版本管理,还能作为 AI 训练数据的轻量标注格式。许多开源数据集和实时协作工具仍以 ABC 为交换格式。它像是厨房里的“口头传菜”——没有大厨不用,只是你平时注意不到。

为何常见:初看以为“文本谱”很初级,忽略了它在数据工程和互操作场景中的独特价值。

误区符号生成太“机械”,MusicGen 这种端到端音频生成才是未来,符号生成迟早被淘汰。

正解二者解决的是不同问题:音频生成像即兴发挥的创意菜,氛围感强但不可控;符号生成像标准菜谱,每个音符都可改。工业界大量采用混合方案:符号生成草稿 → 音频模型或音源库渲染。符号层负责结构和可编辑性,音频层负责音色和质感,各司其职。

为何常见:教程常把两类方法分开讲,容易让人误以为“先进”的一定取代“落后”的。

误区把 `C4` 编成 60、`D4` 编成 62,然后一股脑塞给模型,这不就是词元化吗?

正解词元化必须同时编码时间、力度、休止、轨道等维度。单有音高编号,模型分不清“C4 弹一拍”和“C4 弹四拍”的区别——菜谱只写“放盐”不写“几克几时放”,厨师必然翻车。事件流格式(NOTE_ON + TIME_SHIFT + VELOCITY)才是完整词元化。

为何常见:受文本 NLP 影响,初学容易把“词元”简单理解为“字”,忽略了音乐是随时间展开的多维信号。

误区温度调高能让 AI 更有创造力,所以我写曲子时把 T 设成 1.5,结果听起来更“高级”。

正解高温度意味着更大随机性,偶尔有惊艳灵感,但更大概率跑调、节奏散乱。温度是“冒险程度”而不是“质量旋钮”。专业做法是 T 设在 0.8-1.0 并配合 Top-p 截断,或先生成多个候选再由人来挑——让 AI 多试菜,但端上桌的必须试吃过关。

为何常见:生成式 AI 的“多样性”概念被想当然地迁移,忽视了音乐对连贯性极高的要求。

面试题

Q1. MIDI 文件的本质是什么?

单选题 · easy

  • A.记录音符指令的序列← 正确答案
  • B.压缩过的音频波形
  • C.歌手演唱的原始录音
  • D.包含歌词的文本字幕

答案:A。MIDI 是典型的符号音乐格式,只存“何时按哪个键、力度多大”等指令,不存任何声音波形。就像菜谱只写“加盐三克”,而不是把盐本身装进袋子里。B、C、D 都是对音频或文本的描述,混淆了符号层与信号层。

Q2. ABC 记谱最突出的特点是什么?

单选题 · easy

  • A.用纯文本字母表示音符← 正确答案
  • B.必须依赖专业软件打开
  • C.只能记录钢琴一种乐器
  • D.文件体积比音频更庞大

答案:A。ABC 记谱就是一行行可读的文本,例如 C4 D4 E4,任何文本编辑器都能打开,便于做版本管理。B 说反了,ABC 的优势正是无需专业软件;C、D 均不符合事实。

Q3. MIDI 编号 69 对应多少 Hz 的标准音?

单选题 · mid

  • A.每秒振动 220 次的标准音
  • B.每秒振动 440 次的标准音← 正确答案
  • C.每秒振动 880 次的标准音
  • D.每秒振动 110 次的标准音

答案:B。MIDI 编号 69 对应国际标准音 A4,频率 440Hz。公式是 f = 440 × 2^((n-69)/12)。220Hz 是 A3(MIDI 57),880Hz 是 A5(MIDI 81)。记住 69→440Hz 这个“基准口味”,其他音高都从它推算。

Q4. 采样温度参数 T 调大会带来什么效果?

单选题 · mid

  • A.采样结果越发随机冒险← 正确答案
  • B.采样结果越确定保守
  • C.模型推理速度明显加快
  • D.模型训练时间显著缩短

答案:A。温度 T 缩放了 softmax 的输入得分,T 越大概率分布越平缓,模型更容易选中低概率的“冷门”词元,所以更随机、更有冒险性。T 越小则越倾向高概率词元,输出更保守。温度只影响采样分布,不改变推理速度或训练时间。

Q5. 与端到端音频生成相比,符号生成的最大优势是什么?

单选题 · mid

  • A.每个音符都精确可控可编辑← 正确答案
  • B.音色质感更加自然真实
  • C.彻底摆脱训练数据依赖
  • D.生成速度永远快上十倍

答案:A。符号生成产出的是 MIDI/ABC 乐谱,每个音符、时值、力度都是显式数据,可任意编辑后重新渲染。音频生成直接出波形,想改一个音符几乎不可能。B 是音频生成的优势,C、D 说法过于绝对,都不成立。

Q6. 时间离散化在符号音乐生成中的核心作用是什么?

单选题 · hard

  • A.把连续时刻切成均匀格子← 正确答案
  • B.把音量大小划分成等级
  • C.把音色质感压缩成编码
  • D.把歌词内容切割成词语

答案:A。音乐时间本质连续,但词元是离散的。时间离散化把每拍或每秒切成固定 tick 格,让每个音符落在明确的格子里,模型才能像读文本一样处理。B 属于力度/动态编码,C 属于音色编码,D 属于歌词处理,均与时间无关。

Q7. 自回归生成模型的工作方式是什么?

单选题 · hard

  • A.逐词元预测下一个音符← 正确答案
  • B.一次性输出整段全部音符
  • C.直接复制训练集里的原曲
  • D.对已有的乐谱做无损压缩

答案:A。自回归模型的本质是链式接龙:每一步只预测下一个词元,且依赖此前所有词元,公式为 ∏P(x_t|x_<t)。B 是非自回归方案,C 是过拟合故障,D 是压缩问题,都不属于自回归生成的定义。

Q8. 符号生成与音频生成混合方案的益处有哪些?

多选题 · mid

  • A.兼顾精确控制与音色质感← 正确答案
  • B.可从小模型快速产出草稿← 正确答案
  • C.彻底摆脱对训练数据的依赖
  • D.自动获得完美的歌词内容

答案:AB。混合方案先用符号模型生成可编辑的 MIDI 草稿(小模型即可,速度快、可控),再用音源库或音频模型渲染补足音色质感,因此 A、B 正确。C 说“彻底摆脱数据”不现实,任何生成模型都依赖训练数据;D 中歌词属于文本生成范畴,与符号音乐混合方案没有必然关系。

Q9. 长序列符号生成容易退化的原因有哪些?

多选题 · hard

  • A.注意力机制难以对齐遥远音符← 正确答案
  • B.误差随着词元逐级累积放大← 正确答案
  • C.采样随机性导致后半段漂移← 正确答案
  • D.训练数据被全部损坏无法使用

答案:ABC。长序列退化有三个典型原因:注意力对远距离依赖建模困难(A);自回归的误差会像滚雪球一样逐词元累积(B);采样随机性让生成轨迹逐渐偏离主题(C)。D 是极端异常情况,不是长序列退化的结构性原因。

Q10. 下列哪些属于符号音乐生成的典型应用?

多选题 · mid

  • A.为游戏自动生成 MIDI 背景音乐← 正确答案
  • B.将哼唱录音转成可编辑乐谱← 正确答案
  • C.压缩音频文件以节省存储空间
  • D.音乐教学中生成可视化练习谱← 正确答案

答案:ABD。自动配乐(A)、哼唱扒谱转 MIDI(B)、教学辅助可视化(D)都以“乐谱”为核心产出,是符号音乐生成的典型场景。C 是音频压缩编码任务,处理的是波形信号而非符号,不属于符号音乐生成。