
前段时间一个做独立音乐的朋友丢给我一段三百来字的歌词问我能不能在本地把它变成一首带人声的完整歌不要云端、不要按次计费、不要上传素材。这个问题放在两年前基本等于许愿但在 YuE 这类开源音乐基础模型出来之后它变成了一个配置问题加耐心问题。YuE 是一套面向全长歌曲生成的开源模型输入是歌词加一组风格描述输出是带人声和伴奏的完整音频不是那种给个关键词吐八秒 loop 的玩具而是奔着整首三分钟左右的歌去的。我按自己实际跑通的顺序把过程整理一遍先讲清楚它的生成链路和背后的技术取舍再落环境、落权重、落参数然后聊歌词格式、采样调优和后处理最后说说把它接进真实工作流时的几条边界。手里有一张二十四 G 显卡、想把音乐生成接到自己流程里的人可以直接照着做只想搞明白开源全曲生成到底走到哪一步的人也可以扫一遍。1. YuE 到底在做什么把整首歌当成一个语言建模问题1.1 它不解决编曲它解决的是从文本到有声先把预期摆正。YuE 不做混音不做母带不帮你改和弦走向也不理解这段副歌情绪再往上推一点这种指令。它做的事情非常单一吃进去一份带结构标记的歌词和一个风格描述吐出来一条包含人声与伴奏的音频波形。你可以把它理解成一个作曲加演唱加编曲一次性完成的黑盒但盒子的输入输出都是死板的文本和音频中间没有可拖拽的轨道、没有可编辑的音符。这个定位决定了它的使用方式。你不可能拿它当 DAW 用正确的姿势是把它当成小样生成器先用它把一首歌从零变成有声再决定哪一首值得投入真人和真乐器去重做。我自己的流程就是这样以前写十首歌可能只挑一首做完整编曲现在可以让模型先把十首全部唱出来听一遍筛掉明显不行的剩下的再进编曲环节。省下来的时间不是一点半点特别是那种旋律在脑子里但唱不出来的状态它能帮你快速验证这首歌到底成不成立。从技术角度看它走的是大语言模型加音频离散编码这条路。音频先被一个音频编解码器压成离散的 token 序列模型再像预测下一个词那样预测下一个音频 token。所以它天然继承了大模型的一系列特性能吃很长的上下文、能做上下文学习、能通过提示词控制风格也天然继承了采样参数调优这一整套麻烦事。1.2 两条 token 轨道人声和伴奏分开建模的意义YuE 在架构上最关键的一个设计是把一首歌拆成人声轨和伴奏轨两条离散 token 流分别建模又保持同步。这件事听起来是工程细节实际直接决定听感。如果把人声和伴奏混成一条流去做预测模型会面临一个非常别扭的任务它必须同时决定这一秒唱什么字和这一秒用什么乐器两者的节奏规律完全不同。人声的时间尺度是音节和乐句伴奏的时间尺度是小节和和声进行混在一起学很容易出现伴奏对了人声糊或者人声清楚但和弦乱飘的情况。分开建模以后每条轨道的预测难度下降而且天然带出来一个好处理论上你可以只换一边。比如保留伴奏轨、重跑人声轨换一版唱法或者反过来只改编曲。我实测里最常用的是前者同一份伴奏跑三遍人声挑咬字最清楚的那一版。代价是上下文长度被吃掉一半。两条轨意味着单位时间内的 token 数量翻倍而模型的上下文窗口是固定的所以单次能生成的音频时长是有上限的。这也是为什么它不能一次性生成十分钟的歌得靠分段生成再拼接或者干脆把歌写短一点。理解这一点以后你再看后面所有关于生成时长和分段的参数就不会迷糊了。另外轨道分离也让后处理变得友好。模型直接输出的是一条混好的音频但因为它内部是分轨的用现成的音源分离工具再拆一遍人声和伴奏效果比从纯混音里拆要好尤其是人声的齿音和气息部分残留会少一些。1.3 跑之前先算清楚的三笔账在动手之前把算力账、时间账、磁盘账先算一遍可以省掉很多白折腾。算力账的核心是显存。七 B 级别的权重用 bf16 加载光权重就占十五六 G加上激活值、KV cache 和音频解码器二十四 G 显存是比较舒服的档位三十二 G 以上基本可以不用管优化。十六 G 显存能跑但要开低显存模式速度会掉得比较明显。十二 G 以下就不建议折腾本地了除非你愿意接受一首歌跑一小时这种节奏。时间账要看你的目标时长。我的机器上一次完整的两阶段推理生成三分钟左右的音频包括模型加载、token 生成和解码大概在十分钟上下其中 token 生成阶段占大头。如果你一次要跑十几首候选这就是两三个小时的机器占用所以批量任务最好放在晚上挂着跑白天来做筛选和后处理。磁盘账容易被忽略。一份权重七 B 的模型两个 stage 加起来就是三十多 G加上音频编解码器的权重、缓存目录、输出音频一台机器上留一百 G 空间是比较稳妥的。我第一跑就是因为临时目录所在的盘只剩四十 G跑到解码阶段直接写失败白等了十几分钟。环节主要占用判断标准Stage1 token 生成显存、算力时长的主要瓶颈占七成以上时间Stage2 音频解码显存、内存显存不够会退到内存交换明显变慢音频编解码器加载显存常被忽略的一小块固定开销权重与缓存磁盘建议预留一百 G 以上提示把模型缓存目录和输出目录指到同一块大容量盘上避免临时文件跨盘搬迁带来的额外等待。2. 环境和权重准备第一次跑通要绕开的几个硬坑2.1 flash-attn 装不上时该走哪条路YuE 的官方实现推荐使用 flash-attn 加速注意力计算但这个包装起来是出了名的看运气Python 版本、CUDA 版本、编译器版本、PyTorch 版本四者必须对上。我遇到过两次编译失败一次是编译器版本过高导致的模板报错一次是已经装了旧版本导致符号冲突。处理思路按代价从低到高排优先尝试预编译好的 wheel装的时候加--no-build-isolation让安装过程复用当前环境里已有的构建依赖很多莫名编译失败都是构建隔离导致的。如果预编译包装不上检查 PyTorch 的主版本号flash-attn 对 PyTorch 的小版本比较敏感版本错配时宁可降 PyTorch 也不要硬刚编译。实在装不上就放弃它在加载模型时把注意力实现换成 SDPA 或 eager。SDPA 在多数显卡上速度损失可以接受eager 会慢一些但兼容性最好。# 优先方案复用当前环境构建依赖安装预编译包 pip install flash-attn --no-build-isolation # 兜底方案不装 flash-attn加载时切到 SDPA # 在推理脚本的模型加载处改这个参数 # attn_implementationsdpa需要强调的是换成 SDPA 之后输出音频的质量不会变差只是慢。这类加速库影响的是速度不是结果所以卡在安装上完全没必要死磕。另外一个高频坑是 numpy 的版本。一些音频处理依赖对 numpy 二点零之后的接口变化还不适应症状是导入阶段就报奇怪的属性错误。遇到这种情况把 numpy 降到一点二六附近通常能解决但要注意别把其他依赖一起带崩改完立刻回头验证一遍主流程能不能跑。2.2 CoT 版和 ICL 版权重到底选哪个同一个模型会放出好几种权重变体名字里带 CoT 和 ICL 的区别值得说清楚因为这直接决定你该拿它干什么。带 CoT 的版本针对风格标签推理做了调优你给一串比较粗糙的风格描述它会在内部先展开成更细的描述再开始生成。适合那种我只知道要一首抒情的、慢的、带钢琴的歌但说不清具体风格的人。带 ICL 的版本走的是上下文学习路线你喂它一小段参考音频它会顺着那段音频的风格往下写。适合我想要这种感觉你照着来的场景前提是你手里有干净的参考素材。语言维度上还会细分英文和地方语言的版本是分开的。中文歌词一定要用对应语言的权重用英文版跑中文词结果通常是咬字含混、声调乱飞。我一开始偷懒用英文版试了段中文词听感像是外国人在念拼音音节数量还对不上白跑一轮。Stage2 那边也有对应变体通用版和特定语言版。我的做法是 Stage1 用语言匹配版Stage2 用通用版输出稳定性没有明显差异但具体到你的素材最好各跑一遍对比。2.3 最小可跑命令与参数逐项拆解第一次跑通只需要关心五六个参数其他都保持默认。命令大致长这样python infer.py \ --stage1_model /path/to/stage1-model \ --stage2_model /path/to/stage2-model \ --genre_txt ./prompt/genre.txt \ --lyrics_txt ./prompt/lyrics.txt \ --output_dir ./output \ --run_n_segments 2 \ --stage2_batch_size 2 \ --max_new_tokens 3000 \ --repetition_penalty 1.1逐项说。--run_n_segments控制把歌词切成几段来跑段数越多单段越短、显存压力越小但段与段之间的衔接痕迹越明显。--stage2_batch_size是解码阶段的批大小显存紧就降到一。--max_new_tokens决定单段最多生成多少音频 token这个值直接决定时长上限调小了会在一句话中途截断听起来像突然断电。--repetition_penalty是防止模型陷入循环的关键参数后面单独展开。我建议第一次跑不要追求完整歌曲把歌词砍到四行max_new_tokens设小一点十分钟内看到有音频文件落在输出目录就算环境通了。先跑通再跑好这个顺序别反。2.4 显存不够时的四档降级方案显存紧张时按下面顺序逐级降越往后代价越大第一档开低显存模式。配置文件里一般有个开关打开后模型会把部分模块临时换出显存速度损失大概两三成是最划算的一档。第二档减少分段长度。把一段歌词拆成更小的块单次前向的激活值显著下降代价是拼接处需要人工听一遍。第三档降低解码批大小到一并缩短单段 token 上限。这一步会让总时长成倍增加但能保证跑得完。第四档把 Stage1 和 Stage2 严格串行跑完一个卸载一个再加载另一个。这是官方推荐的常规做法很多人图省事同时加载两个模型直接把显存顶爆。注意不要指望用系统内存做全量卸载来跑七 B 模型。数字上能跑但每生成一个 token 都要在内存和显存之间搬几百兆权重实际速度会慢到没有使用价值。3. 歌词文件才是效果的下限格式、时长配比与风格标签3.1 结构标签的写法与真正的生效条件歌词文件不是随便写一段文字丢进去就行模型对结构标签的识别有比较严格的前提。标签要单独占一行放在它所描述的段落开头用方括号包起来常见的有主歌、副歌、桥段、前奏、尾奏、纯器乐段这几类。渲染成音频时它影响的是段落的能量走向和配器密度比如标了副歌的地方人声会更靠前、伴奏会更满标了纯器乐段的地方会自然地把人声让出来。我第一次写歌词的时候把标签和歌词挤在同一行结果模型完全无视从头到尾一副平铺直叙的调子副歌没有任何推力。另一个前提是标签要符合音乐上的常识顺序。你写一段前奏接一段副歌再接一段前奏再接一段主歌模型虽然不会报错但生成出来的段落边界会很模糊因为它内部的音乐结构先验被破坏了。老老实实按主歌、副歌、主歌、副歌、桥段、副歌的顺序写出来的东西最稳。还有一个细节是段落之间的空行。保留空行有助于模型对齐段落边界尤其是当你想让某一段更短的时候空行加上短句的组合比单纯写短句更容易被识别。3.2 歌词字数和生成时长之间的换算关系这是最容易翻车的地方我甚至觉得它比参数调优更重要。模型需要在有限的 token 预算里把歌词唱完。歌词给得太多、时长上限给得太小结果是后半段被硬生生砍掉或者为了塞进去而加快语速听起来像在赶时间。反过来歌词太少而时长上限给得太大后半段会变成纯器乐甚至开始循环前几句听起来像卡带。我的经验换算大致是这样一段主歌四到六行、每行八到十二个字大致对应三十到四十秒的音频。整首歌如果按主歌两段、副歌三段算总歌词量控制在百字上下对应时长三分钟左右比较舒服。这个比例不是精确公式因为不同语言的音节密度差别很大英文一个单词占的时间可能比中文一个字长所以换语言的时候要重新试一遍。实践里的做法是先按经验值写好歌词跑一遍听哪里被截断然后只调max_new_tokens这一个变量每次加一两百直到不截断且末尾不空转。不要同时改歌词和参数否则你永远搞不清是哪个在起作用。3.3 风格描述词的粒度选择风格描述的写法决定了这首歌像什么但它的最佳粒度跟直觉相反不是越详细越好。太短的描述比如只写一个流行模型会给出一个非常中庸的结果编曲往往偏保守人声也偏模板化听上去像广告配乐。太长的描述比如堆上十几个形容词加五种乐器加三种情绪模型反而会顾此失彼最后呈现出一个四不像。比较有效的结构是三到五个维度每个维度一个词整体类型、人声特征、主要乐器、情绪基调。比如一首抒情歌可以写成整体偏流行、女声、钢琴主导、情绪克制这种组合。想再精确一点可以加上节奏快慢或者年代感这类描述。关键是每个维度只给一个主选项不要在同一维度上写互相冲突的词比如同时写温柔和爆发模型会随机挑一个你两次跑出来的结果差异会很大。另外风格描述和歌词的语言最好统一。中文歌词配英文风格描述能跑但模型在跨语言对齐上会弱一些稳定做法是用歌词所在语言的描述词。描述维度推荐给几个词常见写法容易出问题的写法整体类型一至两个流行、民谣、轻摇滚同时写流行和重金属人声特征一个女声、男声、童声同时写男声和女声主要乐器一至两个钢琴、木吉他列五个以上乐器情绪基调一个明亮、克制、忧伤同时写忧伤和欢快节奏可选一个中速、慢速与整体类型冲突4. 采样参数调优糊、卡、跑调、重复都是怎么来的4.1 重复惩罚和温度之间的相互拉扯生成式模型都有一组采样参数YuE 这套参数的作用方式和大语言模型很像但表现出的症状完全不同。重复惩罚负责压制原地打转。这个值设低了模型会在某一句上反复循环尤其是副歌的第一句因为它在训练数据里高频出现模型很容易陷进去。设高了呢问题会更隐蔽模型为了避免重复会强行选择概率很低的 token表现出来就是突然冒出一个奇怪的音、音高突然跳一下、或者人声破一瞬。我踩过的最典型的一个坑就是把重复惩罚从一点一拉到一点三想解决副歌循环结果整首歌冒了七八处怪音比循环本身更难听。后来稳定在一到一点一五这个区间循环问题改用调整歌词段落的方式来治。温度控制的是随机性。温度高创意多但容易跑偏温度低输出稳但平。做完整歌曲我倾向设得接近默认值甚至略低一点因为一首歌是一个整体任何一段出格都会破坏整体感。如果你在找灵感阶段可以临时调高温度多跑几版听个大概方向定下来之后再用低温度精跑。这两个参数最好不要同时动。固定一个、只调另一个每次只跑一版对比着听这样才分得清因果。4.2 咬字不清的三种成因和对症改法人声糊是所有人都会遇到的第一类问题但它其实有三种完全不同的原因用错药方会越调越差。第一种是歌词信息密度超过模型的演唱能力。中文尤其明显同样时长里塞进太多字模型为了赶节奏会把音节连读听上去像含着一口水。改法只有一条删字。把每行控制在十个字以内把长句拆开。第二种是风格描述和人声特征冲突。比如你写了低沉的男声歌词却是密集高亢的句式模型会在两个目标之间摇摆输出的人声就会发虚。改法是让风格描述里明确人声特征并且只写一个。第三种是最容易被误判的其实不是人声糊而是伴奏把人声盖住了。因为模型输出的是混好的音频编曲偏满的时候人声会被压下去听感上像咬字不清。这种情况调参数没用正确做法是用音源分离工具把人声轨拆出来单独听确认人声本身是清楚的然后在后处理阶段重新平衡两轨的音量。我有一版歌折腾了半天参数最后发现人声轨拎出来非常干净纯粹是伴奏太满。4.3 结构塌陷和段落重复的处理思路另一个高频问题是歌跑着跑着结构塌了副歌和主歌的差别越来越小最后变成一大段没有起伏的音频。成因通常是歌词量超出了模型能维持结构的长度。模型的注意力是有限的段落一多、每段又长它就开始走捷径把所有段落唱成同一个调子。解决办法是缩短单段长度、用分段生成的方式跑然后在拼接处做一点过渡处理。分段生成的代价是段落衔接处可能有一点点不自然但比起结构塌陷这个代价完全值得。还有一种情况是副歌被完整重复了两遍甚至三遍。如果歌词里本来就有重复的副歌这属于正常如果歌词里只有一段副歌而输出里出现多遍说明重复惩罚需要稍微上调一点点或者把副歌的歌词换几个字打破完全一致的 token 序列。这个技巧很土但有效把第二遍副歌的结尾改一两个字模型就不会把它当成可以无限延续的模式。5. Stage2 之后的收尾工作分轨、响度与交付5.1 拆人声和伴奏为什么比想象中重要模型直接给的是混音成品但真正拿去用的时候你几乎一定需要分轨。做视频配乐时人声和伴奏的音量比需要按画面调做小样时你可能要保留伴奏替换人声或者保留人声重做编曲做纯音乐版本时直接把伴奏轨拎出来就能用比重新生成一首纯器乐效率高得多。这些需求都要求你手里有分离的两轨。分离工具用现成的音源分离方案就行选人声两轨模式。因为原始音频本身就是人声加伴奏的结构没有太多现场环境音和复杂混响分离质量通常不错。需要注意的一点是分离之后的伴奏轨在低频部分会有一点损失如果要用它做正式出版建议还是在 DAW 里补一层低音。实际操作里我会把分离出来的两轨都存成无损格式然后再做后续处理不要在有损格式上反复转码。5.2 响度对齐和导出格式的选择AI 生成的音频有一个通病就是不同版本之间的响度差异很大同一批生成五首可能有两首明显比别的轻。如果直接放到同一个播放列表里听感会非常割裂。处理办法是做响度归一化找一个目标响度值把所有音频统一到同一个水平。命令行工具一行就能完成不需要进 DAW。归一化的时候要注意别把动态压死选那种只调增益不做压缩的模式保住原来的起伏。导出格式上中间产物一律用无损格式最终交付再看用途。上传到平台用常见的有损格式就够了但码率别压得太低人声的齿音部分对码率比较敏感。另外记得检查一下音频开头和结尾模型生成的音频有时开头会带几十毫秒的空白结尾会拖一小段静音剪掉之后听感会紧凑很多。# 响度归一化示例只调增益不做动态压缩 ffmpeg -i input.wav -af loudnormI-14:TP-1.5:LRA11 -ar 44100 output.wav5.3 批量生成时的任务编排单首跑通之后真正的工作量在批量上。我的经验是不要在一台机器上并行跑多个实例模型本身就吃满显存多开只会互相抢资源最后全都变慢。正确的做法是串行排队把歌词和风格描述整理成一批任务清单写个循环脚本依次跑中间加上失败重试。清单最好带一个编号和备注列记清楚哪条歌词配了哪组风格描述。一次跑十几首之后你根本记不住第三首用了什么参数没有记录就只能重跑。我自己用的是一张表每行一首歌记录歌词文件路径、风格文件路径、生成的音频文件名、初步评价跑完一轮之后按评价排序挑选。跑批的时候建议分两阶段跑先用很短的上限快速跑一遍所有歌词的前三十秒听主歌第一句的咬字和整体感觉筛掉明显不行的再对留下来的完整跑。这样能省掉大量时间因为一首歌的行不行通常在第一个乐句里就能听出来。6. 把 YuE 接进真实工作流几种玩法和该守住的边界6.1 当小样机用把创作环节拆开最实用的场景就是当小样机。写歌这件事的瓶颈往往不在旋律而在我脑子里的旋律到底是什么样。有了全曲生成你可以先不纠结编曲和演唱把歌词写成能唱的格式让模型给你一版有声的然后坐在那儿听判断这首歌的旋律骨架立不立得住。这一步筛完之后真正的编曲、录音、混音环节才有意义。我现在的习惯是每首歌至少让模型出三个版本用不同的风格描述因为同一份歌词在不同风格下的可塑性差很多有时候一首本来打算做民谣的词用偏摇滚的处理反而更带感。这种试错在传统流程里成本极高需要找人编曲、找人唱现在就是几分钟的事。反过来说也要清楚它的边界。它生成的东西细节上是经不起推敲的尤其是编曲的层次和人声的呼吸感跟真人录出来的差距还是很明显。所以它适合做筛选和方向验证不适合直接当成品交付。6.2 风格注入和微调的现实预期如果你手里有大量自己风格的素材会自然想到微调。这件事能不能做取决于你的目的。如果只是想固定某个音色或者某种编曲习惯上下文学习这条路更划算准备几段干净、结构完整的参考音频在提示里带上模型会明显往那个方向靠。这种方式不需要训练改参考素材就能换风格迭代速度快。如果要微调权重投入产出比需要认真评估。数据方面你需要的是成对的高质量素材歌词和对应音频严格对齐格式干净没有杂音。计算方面七 B 模型的微调对显存的要求比推理高一个档次普通消费级显卡基本只能做小规模参数高效微调训练时长以天计。我的判断是除非你要做一个持续产出的产品否则先把提示词工程做到位收益更快。6.3 授权和商用这件事必须提前确认最后说一件容易被跳过但很重要的事能不能商用以权重文件随附的许可说明为准不同版本、不同发布批次的条款可能不一样用之前一定去仓库里把许可文件读一遍不要看二手转述。即便许可允许模型生成内容的原创性、和你自己已有作品的相似度这些都需要你自己判断和承担。实践中我会做两步一是生成之后用音频指纹类工具过一遍确认没有和已知作品高度重合二是保留下生成过程的记录包括歌词文件、风格描述、参数配置万一有争议至少有据可查。我个人最后的体会是把它当成一个需要磨合的合作者而不是一个按钮。第一版永远不好听把歌词结构调两轮、把风格描述收敛到三四个维度、把重复惩罚压在一到一点一五之间第三版开始才会有能听的东西。还有个小技巧我一直在用同一份歌词别只跑一遍就下结论改掉其中一句的结尾两个字再跑一次两版对比着听往往能听出哪一版的人声走向更贴合你原来的想法这比死磕参数快得多。