城东有家小酒馆,台下常坐着一位叫老周的老乐手。你最近总哼一段旋律,却怎么也想不出下一句。老周把吉他抱起来说:“哼给我听听。”你哼完,他没急着接,而是先在餐巾纸上记下音符,又问你:“想要什么感觉?欢快点还是安静点?”然后他闭眼想了想,手指落下,顺着你的调子滑出一个你没想到、却恰到好处的转折——整首歌活了。“这就是哼唱续写。”老周说,“先听清你哼的什么,再问你要什么,接着凭乐感往下走,最后你觉得顺耳才算数。” AI 音乐生成干的是同一件事:先把你的哼唱变成它能读懂的乐谱(旋律表示),再把“欢快、民谣”这类要求翻译进去(条件编码),然后用模型像老周一样逐音推敲续写(条件生成),最后用一套尺子和耳朵评估好坏(质量评估)。这篇文章就沿着这四步展开,让你从“模糊哼唱”到“完整乐曲”的 AI 创作全流程,建立一套可以迁移到任何条件生成任务的心智模型。
读懂哼唱续写,你就掌握了 Suno、Udio、MusicGen 等主流音乐 AI 的共同骨架:条件表示、条件编码与条件控制。这套“以用户输入为条件、由模型补全”的范式,也是文生图、文生视频等生成式产品的基本架构——掌握它,你就能在音视频与多模态项目里设计、评估并迭代真正的生成式交互。
可视化演示
动态演示旋律条件生成与哼唱续写的核心机制,通过总览/传输/转换/输出四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
旋律条件生成与哼唱续写:旋律条件 旋律条件生成与哼唱续写概述 旋律表示与哼唱音频转MIDI 核心机制可视化 旋律条件生成与哼唱续写整体架构与关键组件
旋律表示方法
酒馆里,你给老周哼了一段,老周听完没有直接接吉他,而是先在餐巾纸上画了个简易谱子。他一边画一边说:“我得先把你哼的这些音'记下来',不然脑子一乱就忘了。”老周有三种记法:给熟悉钢琴的朋友画五线谱、给不出门的朋友录一段语音、给自己写一行行数字。每种记法保存的信息不同,后来的“续写质量”也不一样。
在老周这里,“记下来”是续写的前置步骤;在 AI 这里,这个步骤叫旋律表示(melody representation)。模型不直接“听歌”,它只认数字。所以工程师要决定:把音乐变成什么形式喂给模型。主流做法有三种:符号表示把旋律抽象成“音符列表”,类似 MIDI,每个音符用(音高,时值)二元组表示;音频表示把波形切成帧、计算频谱图,保留了音色与气息;离散Token把音符或音频块映射为离散编号,像把音乐“翻译”成一段文字,方便 Transformer 这类模型处理。
用符号表示,一首旋律就是一组有序的“(音高,时值)”对:
老周的餐巾纸谱子就是符号表示,录音就是音频表示,那行数字就是离散Token——他后来弹得顺不顺、像不像你,很大程度上取决于哪种“记法”记得准。模型也一样,表示方式决定了它“看到”的是旋律的骨架,还是声音的血肉。
- 有序集合 M旋律被展开为自左向右的 T 个音符,排列顺序就是时间先后。
- 音高 p_t第 t 个音符的高低,MIDI 编号 60 即中央 C,编号越大音越高。
- 时值 d_t第 t 个音符的持续长度,以四分音符的时长为 1 做相对度量。
哼唱信号处理
你以为自己哼得很准,老周却笑:“你刚才那个'咪',起码跑了四分之一音。”但他依然能准确弹出你真正想表达的旋律——因为他做了三件事:先竖起耳朵锁住每个音的主频(音高提取),再用脚打拍子把你的自由节奏对齐到节拍网格(节奏量化),最后把漂移的音高悄悄拨回标准键位(音高修正)。
手机录下来的哼唱是一段连续声波,而模型需要的是干净的离散音符。从“模糊声波”到“干净音符”的中间环节,就是哼唱信号处理,也叫前端提取。如果用传统乐器弹奏,这一步可以省略;但哼唱天然带有音准漂移、气息起伏和自由节奏,不处理就直接进模型,等于把歪歪扭扭的声音连谱交给老周,谁都听不清你想表达什么。
音高提取通常是先估算每一小段信号的基频 f,再换算成 MIDI 编号:
老周帮你“校准”过的旋律,才是他真正能发挥的故事开头。AI 也一样,前端处理的好坏直接决定后续编码与生成的质量——你是把一张干净的谱子递给老周,还是让他对着你含糊的哼唱猜谜。
- 基频 f_i先从这一小段声音里估计出主频率,单位是赫兹。
- 对数换算人对音高的感知是对数的,取 log2 才能让“每高八度频率翻倍”对应等距的音高变化。
- 偏移与取整乘以 12 得到与 A4 的半音距离,加 69 平移到 MIDI 编号,向下取整得到离散音高。
条件编码方式
老周记完谱子,抬头问你:“想要什么感觉?”你说:“欢快点,最好带点民谣的味道。”老周怎么把这句话“装”进脑子里?他告诉我们三种做法:把纸条贴在谱子旁边随时看(条件拼接)、每弹一个音符都瞥一眼纸条确认方向(交叉注意力)、把纸条上的关键词画成谱面符号(特殊标记)。
在 AI 里,你说的“欢快、民谣”这些要求叫作条件(condition)。“使条件发挥作用”的过程就是条件编码。它决定了模型在执行续写时,能多好地“听见”用户的要求。条件拼接是最直观的做法:把条件向量 c 与每个音符的嵌入向量拼在一起,让模型每一步都能看到完整的 c——相当于老周把“欢快民谣”四个字贴在谱架上。
记第 t 个音符的嵌入为 emb(m_t),条件的嵌入为 emb(c),条件拼接的公式为:
如果说旋律是故事,条件就是“这一章必须有的氛围”。老周把纸条贴在谱旁的朴素做法,对应最简单的条件拼接;而成熟乐手会“察言观色”、该看要求时才看,这就是交叉注意力要解决的问题。
emb 是把离散符号变成稠密向量的嵌入层,∥ 表示拼接。- 音符嵌入 emb(m_t)把第 t 个音符(音高、时值)映射为固定维度的稠密向量,机器才能“理解”它。
- 条件嵌入 emb(c)把“欢快、民谣”这类条件映射成向量,整段旋律共享同一个条件向量。
- 拼接运算两个向量首尾相连成 D+C 维向量,每个位置既能看到音符、也能看到条件。
生成模型架构
最令你好奇的是:老周凭什么知道下一个音该怎么走?他笑着说:“我不背谱,我只是太懂旋律了。每弹一个音,我都会回想前面所有音,然后感觉'这个音后面就该接那个音'。”换句话说,老周是一个“下一个音符预测器”。
AI 续写的核心正是自回归生成模型:给定已经产生的音符序列和条件,模型预测下一个音符的概率分布,再采样一个音接上去,如此循环,直到达到目标长度或遇到终止符。目前主流实现是 Transformer 解码器——每个音符 token 经过嵌入后进入多层自注意力,与前面所有位置交互,最后用 softmax 输出整个音符词表上的概率分布。上下文窗口则限定了模型能“回想到多远的过去”,窗口越长,越能捕捉长程的旋律结构。
整个续写过程的数学形式是一个条件概率的连乘:
老周那句“感觉”,其实是几十年听过的旋律在他脑中沉淀出的统计规律;Transformer 的“感觉”,则是海量乐谱中学到的转移规律。一个是老乐手的语感,一个是机器的乐感,结构上异曲同工。
- 概率连乘整段续写的难度分解为 T_ext 个小任务,每小步只负责预测一个音符。
- 历史依赖第 t 步以 t 之前的所有音符和全局条件 c 为条件,体现“边弹边回顾”。
- 采样接龙从分布中抽一个音符接上,把它并入历史,继续预测下一步,如此循环往复。
条件控制策略
续写时老周还面临一个“度”的问题:完全按你的要求来,曲子会像命题作文一样呆板;完全由着性子发挥,又不像你要的感觉。老周的答案是“七分听你的,三分留给自己”——在大方向上服从条件,在细节处自由挥洒。
模型同样需要这样的平衡杠杆,这就是条件控制策略。控制方式分为全局与局部:全局条件在整个序列上恒定施加,比如流派、速度、情绪基调;局部条件只在某些片段生效,比如某小节情绪渐强、某处要转调。两者结合,才能让续写既“整体对味”又“细节有戏”。
最通用的调节手段是无分类器引导(CFG):同时训练有条件模型和无条件模型,采样时用二者的对数概率差放大条件信号,引导强度 γ 控制放大倍数。γ=0 时退化为完全自由生成,γ 越大越忠于条件,但过大会让旋律变得僵硬、失去灵气。
γ 就是老周心中的那杆秤:调太低,他弹着弹着忘了你要的民谣味;调太高,他每个音都小心翼翼讨好你,反而失了灵气。好的续写产品,往往把“听话程度”做成一个用户可以拨动的旋钮。
- 条件预测项模型在“听到要求”时的正常预测,是续写的基础。
- 方向差项条件预测与无条件预测的差异,恰好是“条件让模型往哪个方向偏”。
- 引导系数 γγ=0 时第二项消失,恢复自由发挥;γ>0 时方向被放大,生成更贴条件。
质量评估方法
老周弹完,你俩听了一遍,他问:“怎么样?”你咂咂嘴说:“挺好的,就是最后那个转调有点怪。”你们其实从两个层面评价:一是“和你常听的版本比,音准节奏对不对”(尺子量),二是“顺不顺耳、有没有感觉”(耳朵听)。AI 评估同样是双轨。
哼唱续写的输出是主观艺术,但工程上必须可度量。客观指标自动计算、可复现,适合批量对比;主观评估依赖真人盲听打分,贴近真实体验。还有一致性检验,专门确认生成内容有没有偏离用户指定的风格与情绪。
客观指标最常用的是音高准确率(PA):逐音符比较生成旋律与参考旋律,音高差在容差范围内就算预测正确。参考旋律通常来自人工标注或高置信度样本:
客观指标是老周随身携带的调音器,能告诉他“有没有按错键”;主观评估是酒馆里那桌听众的反应。真正成熟的续写系统像老周一样,既对音准敏感,更对“感觉”敬畏——两者缺一不可。
- 逐音符对齐把生成旋律与参考旋律逐一对齐,共形成 N 对音符。
- 容差判断差值不超过 ε 记为 1(正确),否则记为 0;ε=1 表示允许半个音误差。
- 取平均正确对数除以总对数,得到 0 到 1 之间的准确率,越高越贴近参考。
应用与挑战
后来老周发现,自己那套“听音记谱、问风格、往下顺”的本事,被人搬进了一个叫“AI 作曲”的手机 App:你对着手机哼一段,几秒钟后一首完整的曲子就回来了,编曲、配器、混音样样齐全。老周成了产品经理口中的“哼唱续写”功能。
哼唱续写是旋律条件生成最典型的落地场景,Suno、Udio、MusicGen 等产品的核心玩法都包含这条链路:哼唱 → 前端处理 → 条件编码 → 自回归生成 → 评估迭代。但落地中还有三座山:数据稀缺——带“哼唱-完整曲”配对的数据远少于纯音乐数据,冷门风格的续写效果骤降;风格控制——用户想要的“感觉”很难用几个标签穷尽,需要更细粒度的条件表达;生成与自由的平衡——既不能完全复刻哼唱导致呆板,也不能放飞自我导致跑题。未来的方向包括多模态条件(哼唱加歌词、加画面情绪)、可解释作曲以及实时交互续写。
从数学上看,哼唱续写就是一次带条件的搜索:
老周听完产品经理的汇报,笑着说:“你们把它做成了产品,但别忘了——一段歌最好听的瞬间,永远是哼唱的人自己的那一句。”技术可以补全旋律,但创作的心意仍来自人的哼唱。这正是条件生成最有魅力的地方:AI 按人的条件续写,人始终握着方向盘。
- 已知信息M_hum 是用户的哼唱片段,c 是风格等附加条件。
- 最大化搜索在所有可能的续写片段里,选出概率最高的那一个作为最终输出。
- 从最优到多样实际产品常做带温度的采样而非严格 argmax,为创作保留惊喜感。
AI 应用场景
全民创作——灵感碎片秒变完整编曲
阶段:条件编码与自回归生成
解决的问题:传统编曲软件门槛高,普通人哼出灵感却不会配器;AI 把哼唱当作条件输入,自动补全旋律、伴奏与编曲,几秒产出可听的 demo。
具体案例:独立音乐人小陈在通勤路上哼出一段副歌,用手机录下后导入 App,选择“民谣、120 BPM”,AI 生成 30 秒完整编曲,他微调后直接用于新歌小样,demo 周期从一周缩短到半天。
影视配乐的快速草案
阶段:哼唱信号处理与条件控制
解决的问题:配乐师要先出多个情绪方向的旋律草案供导演挑选,传统方式一首首手写耗时;用哼唱快速勾勒动机,再用不同条件一键生成多个风格版本。
具体案例:游戏音效设计师为一段竹林追逐战场景哼出 4 小节动机,生成“紧张电子”与“武侠民乐”两个版本,导演 10 分钟选定方向,比以往快了一个上午。
音乐教学中的“续写练习”评估
阶段:质量评估
解决的问题:学生在旋律写作课上的续写作业难以及时获得反馈;AI 用客观指标加主观规则双重评估,指出音准偏差、风格偏离与终止式问题。
具体案例:某在线音乐学院接入哼唱续写练习:学生哼出开头并上传续写,系统返回“整体衔接自然,但结尾未落在主音上”等结构化反馈,教师端可汇总全班薄弱点。
Python 演示
"""Humming continuation demo: learn note-transition rules from a small corpus,then continue a user-hummed melody with a Markov chain model."""from collections import defaultdictimport random def build_model(corpus): """Statistics of adjacent note transitions -> conditional table.""" trans = defaultdict(list) for melody in corpus: for i in range(len(melody) - 1): # 记录"听到这个音之后,下一个音是什么" trans[melody[i]].append(melody[i + 1]) return trans def continue_melody(hummed, model, length=8, seed=42): """Given the hummed segment, sample length new notes step by step.""" random.seed(seed) result = list(hummed) # 起点是哼唱片段的最后一个音符 current = hummed[-1] for _ in range(length): candidates = model.get(current) if not candidates: break # 按经验频率采样: 高频的后续音更容易被选中 nxt = random.choice(candidates) result.append(nxt) current = nxt return result def is_finished(melody): """A long final note roughly implies a sense of ending.""" return melody[-1][1] >= 1.5 def main(): # 风格语料: 每首旋律是(音高, 时值)序列, 时值以四分音符为1 corpus = [ [(60, 1), (62, 1), (64, 1), (65, 2), (64, 1), (62, 1), (60, 2)], [(67, 1), (67, 1), (65, 1), (64, 1), (62, 2), (60, 2)], [(64, 1), (65, 1), (67, 1), (69, 2), (67, 1), (65, 1), (64, 2)], [(55, 1), (60, 1), (64, 1), (67, 2), (64, 1), (60, 1), (55, 2)], ] model = build_model(corpus) hummed = [(60, 1), (62, 1), (64, 1)] # 用户哼唱: do-re-mi full = continue_melody(hummed, model, length=10) print("hummed seg :", hummed) print("generated :", full[len(hummed):]) print("full melody:", full) print("ends on a long note:", is_finished(full)) if __name__ == "__main__": main()
trans[melody[i]].append(melody[i + 1])统计语料中相邻音符的转移频次,构成“老周的乐感经验表”。current = hummed[-1]从哼唱片段的最后一个音符出发,作为续写的起点。candidates = model.get(current)查经验表,得到“在这个音之后可能接哪些音”。random.choice(candidates)按出现频率采样,出现越频繁的后续音越容易被选中。melody[-1][1] >= 1.5用最后音符的时值是否足够长,粗略判断旋律是否停在终止感上。
常见误区
误区哼唱续写不就是把哼唱片段拿去数据库里找最像的歌,然后截取后半段拼出来吗?
正解实际是生成式模型从条件分布采样,模型学的是“在这种音符序列和条件下,下一个音符应该是什么”的统计规律,而不是拷贝现有歌曲。拼接会带来版权风险与衔接断裂,生成则天然连贯。就像老周不是“背歌谱”,他是凭乐感即兴接着弹。
为何常见:因为“AI 听过很多歌”听起来就像在检索,大家容易混淆检索式与生成式两条技术路线。
误区我哼得差不多就行了吧?模型自己会处理错音,不用专门清洗。
正解哼唱常伴音准漂移、节奏抖动,必须经过音高提取、节奏量化、音高修正才能变成离散 token。否则相当于把歪歪扭扭的声音连谱递给老周,他再厉害也判断不出你想表达什么。前端处理是整个链条的地基。
为何常见:用户看到 AI 产品输出很顺滑,误以为“烂输入也能被魔法修复”,忽略了产品背后看不见的信号处理管道。
误区给模型越多条件(风格、情绪、乐器、速度、流派),生成就越符合我的预期。
正解条件过细会大幅压缩可行输出空间,模型在“满足所有条件”和“保持音乐性”之间两头为难,生成反而平庸甚至牛头不对马嘴。好的条件设计讲究“克制的关键约束”——信息太少会跑偏,信息太多会束手束脚。
为何常见:直觉上“更多信息等于更好结果”,但生成模型需要海量数据支撑条件组合,条件太细时数据稀疏,条件反而变成噪声。
误区音高准确率、节奏重合度这些客观指标高,就说明续写质量好。
正解客观指标只衡量“与参考的吻合程度”,不衡量音乐性与情绪一致性。一段完全复制参考旋律的续写指标满分,却毫无创作价值。所以行业采用客观加主观(MOS)双轨评估:尺子负责“对不对”,耳朵负责“好不好听”。
为何常见:客观指标可复现、可比较,人们天然偏爱“看得见的分数”,而忽略了听感才是音乐生成的最终裁判。
误区只要上下文窗口够大,模型就能无限续写,越长越厉害。
正解自回归生成的误差会随长度累积,越长越容易跑题,甚至陷入重复循环。工业产品通常采用分句续写、分段生成,并在段间重新注入条件,像老周弹完一段会停下来喝口酒、再问你“往哪个方向走”。
为何常见:看到 demo 能生成几十秒就以为无限延长没问题,忽略了自回归模型“一步错、步步错”的累积效应。
面试题
Q1. 哼唱续写流程中,把哼唱录音变成“音符序列”的环节是?
- A.旋律信号提取转换← 正确答案
- B.条件引导采样环节
- C.主观评分评估环节
- D.自回归生成阶段
答案:A。哼唱录音是连续声波,必须先经过音高提取、节奏量化等前端处理变成离散音符序列,这属于旋律表示与信号处理环节。B 属于条件控制,C 属于评估,D 属于生成阶段,都不是“变成音符”这一步。
Q2. 公式 p = ⌊12·log2(f/440) + 69⌋ 的主要作用是?
- A.把频率变成 MIDI 音高值← 正确答案
- B.把音高值还原成频率值
- C.计算旋律的总体长度
- D.表示音符的相对时值
答案:A。公式把基频 f 经对数刻度换算并加 69 偏移,映射为 MIDI 编号,是音高提取的核心步骤。B 方向反了;C 与旋律长度无关;D 涉及的是时值量化,公式里并没有时长信息。
Q3. 下列哪些属于哼唱输入处理的关键步骤?
- A.音高提取与修正← 正确答案
- B.节奏量化对齐← 正确答案
- C.对抗攻击防御
- D.生成结果加密
答案:AB。哼唱处理要做的正是“听清音高、对齐节奏、修正偏差”,A、B 正确。对抗防御与结果加密属于安全工程话题,与“把声波变成干净音符”无关。
Q4. 将条件向量拼在每个音符向量后面的编码方式叫?
- A.条件拼接式融合← 正确答案
- B.交叉注意力机制
- C.特殊标记符注入
- D.对抗判别式训练
答案:A。题目描述正是条件拼接:h_t = [emb(m_t); emb(c)]。交叉注意力是拿条件当“可查询的记忆”;特殊标记是把条件作为 token 插入序列开头;对抗训练是另一种训练范式,都不是“拼在音符向量后面”。
Q5. 自回归旋律生成模型的核心思想是什么?
- A.逐音符预测下一个音符← 正确答案
- B.一次性输出整段旋律
- C.检索最相似的历史曲
- D.随机拼接已有片段
答案:A。自回归把联合概率拆成条件概率的连乘,每次只预测下一个音符,生成时逐音符接龙。B 是非自回归路线的特征;C 是检索式;D 是拼接式,均不属于自回归生成。
Q6. 关于无分类器引导 CFG,下列说法正确的有?
- A.需同时训练条件与无条件模型← 正确答案
- B.用两种预测的差放大条件方向← 正确答案
- C.引导系数越大越忠实于条件← 正确答案
- D.引导系数越大生成越自由
答案:ABC。CFG 同时使用条件与无条件两条预测线,用二者对数概率之差表征“条件带来的方向”,γ 越大方向被放大得越强,生成越贴条件。D 正好说反了:γ 越大意味着越不自由、越忠于条件。
Q7. 哼唱续写的质量评估中,客观指标主要衡量什么?
- A.生成与参考旋律吻合度← 正确答案
- B.听众主观情感满意度
- C.模型推理速度的快慢
- D.训练数据量的大小
答案:A。客观指标(如音高准确率、节奏重合度)自动计算生成结果与参考旋律的吻合程度,可复现、可批量对比。B 属于主观评估的范畴;C 是工程性能;D 与输出质量没有直接关系。
Q8. 为什么哼唱续写中“条件越多”不一定越好?
- A.条件组合稀疏使数据不足← 正确答案
- B.条件会覆盖掉哼唱旋律
- C.模型无法编码多个条件
- D.条件越丰富训练才越慢
答案:A。细粒度条件组合在训练数据里往往稀疏,模型学不牢“同时满足全部条件”的映射,生成趋于平庸甚至混乱。B 的因果关系不对;C 现代模型完全可以编码多个条件;D 训练速度与条件数量没有必然联系。
Q9. 关于符号表示与音频表示,下列说法正确的有?
- A.符号表示利于离散序列建模← 正确答案
- B.音频表示可保留音色细节← 正确答案
- C.符号表示包含丰富音色
- D.音频可直接输入符号模型
答案:AB。符号表示把音乐抽象为“音高-时值”序列,天然适合自回归离散建模;音频表示保留频谱与音色细节,信息更丰富。C 说反了——符号表示恰恰丢弃音色;D 音频需要先转成 token 才能进入符号模型。
Q10. 主观评估 MOS 相比客观指标最独特的价值是什么?
- A.衡量听感与情绪一致性← 正确答案
- B.能完全替代客观指标
- C.支持自动化大规模测试
- D.结果不受听众主观影响
答案:A。MOS 让真人盲听打分,能捕捉客观指标抓不到的“顺耳与否、情绪是否一致”。B 错,两者互补而非替代;C 是客观指标的优势;D 说反了,MOS 恰恰依赖人的主观感受来反映真实体验。