歌声数据集实战:wav、midi与歌词对齐的预处理全攻略

歌声数据集实战:wav、midi与歌词对齐的预处理全攻略
简介本资源是面向歌声合成研究者与深度学习工程师的专业数据集聚焦语音合成中的音高建模、时长预测与声学特征学习等核心任务特别适配基于HMM声学建模及端到端神经网络如Tacotron、WaveNet的训练需求。压缩包共502个文件包含100首高质量WAV人声录音无损音频基础、100个对应MIDI文件提供精确音高与节奏结构、100个CSV时长标注文件逐音节起止时间支撑对齐建模、200个TXT歌词文本含韩语发音单元切分另有JSON元信息与.ds_store占位文件整体容量971.99MB。已有836人学习下载数据已按曲目编号规范组织如kr008a/b、kr012a/b等双声道/多标注变体便于构建训练-验证-测试子集及开展跨音节时长建模、音高-文本联合对齐等关键实验。 最近在处理音频数据时从网盘里翻出一份名为“100首歌声数据集含midi 歌词 标注时长 wav.zip”的压缩包。名字很直白但解压之后我发现这东西对做歌声合成、音乐信息检索、歌词对齐这类项目的朋友来说确实是一份相当实用的起步材料。wav音频、midi标注、歌词文本、时长对齐信息全给配齐了不管是用来做算法基准测试还是当作数据预处理的练手样本都比自己一首首去爬、去标要省事太多。这篇就聊聊我拆包之后看到的细节以及怎么把这套数据真正用起来。1. 数据集整体审视这100首歌声到底包含什么拿到zip第一件事当然是先看目录结构。这个环节往往决定了后面处理流程怎么写所以我习惯先把完整文件树列出来再逐个打开样本确认格式统一性。1.1 文件结构与命名规则解压后最常见的是按歌曲编号组织的方式比如song_001、song_002这样递增有的版本也直接沿用原始曲名。每首歌内部大致有四个文件audio.wav歌声主音频单声道或立体声都有采样率常见22050Hz或44100Hz。melody.mid主旋律midi记录音符序列、音高、时长、速度。lyrics歌词文件可能是.txt纯文本也可能是.lrc带时间轴。alignment标注格式不固定常见的是label.json或annotation.txt记录每个句子、每个音节或每个音符的时间边界。文件命名这个细节我建议拿到后先统一规范一下。因为后续写脚本时如果有的叫audio.wav有的叫vocals.wav有的midi叫mid.mid有的叫melody.mid整个批处理流程会变得非常痛苦。我会先跑一遍文件树识别把不统一的重命名成{id}.wav、{id}.mid、{id}.txt、{id}.json这种结构。1.2 四种核心内容分别解决了什么问题这套数据的价值在于它把“音频 符号标注 文本 时间信息”全凑齐了。单独看每一部分很多项目都能用到但放在一起时它能支撑起更完整的任务链路。wav是目标音频。歌声合成任务里模型要从midi和歌词去预测wav歌声转换任务里wav又充当声音内容的参照。midi是音高和节奏的符号化表达。做音高估计、音符分割、歌声合成时midi可以直接作为ground truth省去用pYIN、CREPE这类工具去手动提音高的麻烦。歌词是内容层信息。唱歌内容不仅仅靠音高文本也是控制条件歌词文件还可以配合wav做语音识别、歌词识别任务。时长标注用来对齐。很多人忽略这个但训练声学模型时每个歌词/音符对应的起止时间是最关键的对齐依据没有它就得另外用强制对齐工具生成精度还不一定保证。这套组合可以理解成音频是“结果”midi是“音高计划”歌词是“内容台词”时长标注是“拍摄脚本里每个镜头的起始时间”。四样拼接在一起数据才真正可训练、可评测。2. 数据预处理从zip到可训练状态的完整流程解压只是开始。真实项目里拿到数据之后首先面对的是格式不统一、采样率混乱、标注字段残缺等问题。不要想着直接丢进模型先把数据整理成干净状态否则后面跑出来的结果没法溯源。2.1 wav音频的规范化检查我习惯先用ffprobe批量读取文件头把采样率、位深、声道数、时长全部导出一张表再根据项目需求统一格式。ffprobe -v error -show_entries streamsample_rate,channels,bit_rate,duration \ -of json audio.wav检查后无非是几类情况44.1kHz / 16bit / 立体声居多这是最常见标准部分来源是22050Hz单声道这是很多开源数据集的默认配置少数wav可能是压缩格式伪装比如扩展名是.wav但内部是mp3编码ffprobe里会显示codec_namemp3。对于训练歌声合成模型我一般统一转成44.1kHz / 16bit / 单声道如果是给Neural Vocoder类模型用22050Hz其实也够关键是全数据集保持一致。转码跑一次ffmpeg就行后面会写具体命令。2.2 midi与wav的对齐逻辑检查midi文件的时间单位是“拍”而音频的时间单位是秒中间必须通过速度和节拍信息换算。常见midi格式1的速度大概在960 ticks per beat如果有速度变化还要按比例单独计算。我在检查midi时重点关注两点midi里是否包含歌词事件。标准midi可以用lyrics元事件存歌词但很多从简谱转出来的midi根本没有歌词这时歌词只能靠单独的txt/lrc文件关联。midi音符范围是否合理。人声主旋律通常在中音区如果音符全部异常偏高或偏低可能是转调问题也可能是midi本身是乐器版本。检查midi合理性的快速脚本用Python的mido库读取就够了import mido mid mido.MidiFile(melody.mid) for track in mid.tracks: for msg in track: if msg.type note_on and msg.velocity 0: note_numbers.append(msg.note)把音符转折成频率范围来看或者直接跑一个分布直方图异常情况一眼可见。2.3 歌词与时长标注的清洗歌词文件最常踩的坑是编码问题。国内数据集很多歌词是GBK编码直接用UTF-8打开就是乱码。我处理时习惯先用chardet检测编码再统一转换import chardet with open(lyrics.txt, rb) as f: raw f.read() enc chardet.detect(raw)[encoding] text raw.decode(enc, errorsignore)时长标注的字段格式五花八门有的标了句子时长有的标了音节时长有的还额外给了音素边界。如果是JSON格式通常长这样{ sentences: [ { text: 夜空中最亮的星, start: 1.23, end: 6.45, notes: [ {pitch: 67, start: 1.23, end: 2.10} ] } ] }如果某个字段缺失不必硬补。把缺失样本单独挑出来后面做训练集时按需过滤即可。强行自己写一段对齐逻辑去猜标注反而容易引入噪音。3. 实操环节用ffmpeg批量处理数据集的经典方案这节是很多人最关心的部分。数据到手之后真正花时间的是批量处理而不是什么模型调参。ffmpeg在这里是绝对的主力从转码、裁剪、静音检测到音量归一化一条命令全搞定。3.1 批量重采样与声道转换如果数据集混着多种采样率第一步统一格式。这段命令遍历所有wav转成44.1kHz单声道16bit PCMfor f in song_*/audio.wav; do ffmpeg -y -i $f -ac 1 -ar 44100 -sample_fmt s16 ${f%.wav}_fixed.wav mv ${f%.wav}_fixed.wav $f done这段命令里-ac 1表示强制单声道-ar 44100重采样到44.1kHz-sample_fmt s16改成16位PCM。注意-y参数要加上不然批量运行时每个文件都会卡在覆盖确认。如果只想转码但不想改变采样率去掉-ar即可。也可以加上-af loudnorm做响度归一化但我建议第一次先不要动音频本身等确认好训练需求再做音量统一。3.2 从mp3、ape等压缩格式转换成wav热搜里经常看到“猴子ape转wav”、“mp3转wav”这类需求其实都是同一个思路。ffmpeg对格式的处理方式基本统一关键在于确认输入格式和编码。ape格式是Monkeys Audio早年很多无损资源用这个格式但很多工具不认建议统一转成wav或flac。ffmpeg -i input.ape -c:a pcm_s16le output.wav ffmpeg -i input.mp3 -c:a pcm_s16le output.wav如果是批量处理数据集里混进来的非wav文件可以先检测再转码。比如检查当前目录下所有音频文件凡是扩展名不在白名单里的全部转成wavfind . -type f \( -name *.mp3 -o -name *.ape -o -name *.m4a \) | while read f; do ffmpeg -y -i $f ${f%.*}.wav done转完后别忘了用ffprobe复查编码格式避免出现扩展名wav、内部实际是mp3的奇葩文件。3.3 midi转wav做快速预听做歌声合成的过程中经常需要快速听一下midi对应的旋律长什么样。midi本身没有声音需要音源库播放。常用方案是一些开源SoundFont配合fluidsynth或者用timidity。fluidsynth -ni soundfont.sf2 melody.mid -F melody_preview.wav -r 44100这样生成的是一个纯乐器版本方便对比音频是不是同一首歌同一段旋律。另一个相关需求是“mml转换midi”MMLMusic Macro Language是早期音乐播放器/游戏音源里常用的一种文本记谱格式把它转成midi主要靠第三方脚本或在线工具。正规完成MML解析并不复杂核心是把每一个音符字母、长度、八度参数换算成midi事件。如果你拿到的数据里只有MML文本没有midi可以用现成的转换器先变成midi再接后面的流程。3.4 批量提取音频时长与标注时长对比数据集的时长标注是否准确直接决定后续对齐质量。我用ffprobe把所有音频真实时长扫出来再和标注文件里的总时长做对比ffprobe -v error -show_entries formatduration -of csvp0 audio.wav写个Python脚本把每首歌的真实时长和标注时长计算并排出误差如果误差超过0.5秒就得人工核查。这一步在训练前做能省下很多调试时间。4. 常见问题与排查技巧实录数据集中盘阶段我整理了几个高频问题基本每隔一段时间就会踩一次顺手做个速查表。4.1 标注时长和音频实际时长对不上这是最常遇到的问题。假设音频总长47.3秒但标注里所有句子加起来只有39.2秒中间差了8秒。原因一般有两个一是标注只覆盖了有效歌唱段开头结尾有纯音乐前奏和尾奏没算进去二是标注按midi音符起止计算如果音符事件本身没有完全覆盖音符时值比如拍了80%长度整体就会偏短。处理方法结合midi的事件时间范围来裁剪音频让音声片段与标注范围对齐。具体做法是取出midi里第一个note_on和最后一个note_off的时间换算成秒后用ffmpeg裁剪音频ffmpeg -i audio.wav -ss 2.34 -to 44.52 -c copy trimmed.wav4.2 midi音符和实际演唱音符差一个八度这种情况在男声数据里较常见。midi记谱可能是57即简谱低音但实际男声唱出来可能是60甚至更高。原因不少比如原曲是女声key男声翻唱降调但midi没跟着改。这种问题没有自动修复方案最好按歌曲重新做一次音高统计看主旋律分布集中在哪个区间。如果只是整体偏移可以用脚本统一加减固定半音数。4.3 中文歌词乱码或出现繁体/简体混排上一节提到的chardet检测可以解决编码问题。但有些数据集的歌词本身就是繁体或者同一首歌里简繁混用做模型训练时会增加文本字典的负担。我建议只用简体中文训练时可以把繁体统一转成简体。最稳妥的方法是维护一张人工对照表尤其是“著”“裏”“發”这类一对多映射要小心。4.4 wav文件损坏或无法解码运行ffprobe时偶尔会报Invalid data found when processing input我遇到过几次通常是文件大小不足或下载时丢包导致。排查时先看文件大小是否正常再用ffmpeg -v error -i audio.wav -f null -做完整解码测试。损坏文件如果没有备份源只能从数据集中剔掉。完整跑一遍解码测试把坏文件列出来find . -name *.wav -print0 | xargs -0 -I{} sh -c ffmpeg -v error -i {} -f null - 21 | head -1 | grep -q . echo {}4.5 时长标注、midi、歌词三者粒度不一致有的歌曲标注到了句子级有的到了音节级而midi只到音符级。混在一起训练时模型可能会学混乱。解决方式是按任务需要对齐粒度。做歌声合成最好统一到“音符级”因为midi给的粒度就是音符做语音识别统一到“音节级”更合适做歌词对齐需要“字级”边界。粒度转换可以从粗粒度切分但细粒度到粗粒度合并比较简单所以清洗时尽量保留最细粒度其他任务按需聚合。常见问题原因解决方案时长对不上标注不含前奏间奏按midi边界裁剪八度偏差记谱key与人声key不一致音高分布统计后再移调中文乱码GBK/UTF-8混用用chardet检测并统一wav损坏下载不完整ffmpeg解码测试并剔除粒度不统一来源多个统一成音符级或音节级5. 扩展玩法用这份数据集玩出更多花样数据集不只是用来训一个端到端模型它能做的事比想象中多。我自己就用这套数据给好几个项目做了快速验证。5.1 做一套简单的歌声合成demo流程想快速做歌声合成demo可以分成“特征提取-声学模型-声码器”三段式。数据里的wav和midi直接构成特征提取的输入输出对。特征提取阶段用librosa加载wav提取mel谱和F0F0可以直接用midi转成Hz不需要单独估计f0_midi extract_midi_notes(mid_file) f0_hz 440.0 * (2 ** ((f0_midi - 69) / 12))声学模型用现成的端到端框架或传统HMM声码器用HiFi-GAN或WaveGlow。这一套下来只要数据清洗过关跑出来的效果基本能说明问题。5.2 标注数据在歌声转换里的用法歌声转换任务不需要歌词只需要音频和音高曲线。这时midi直接提供音高目标歌词文件可以完全不用反而是时长标注帮助做音素级别的对齐特征让转换模型知道每个音应该在什么时间切。5.3 当评测基准用如果只想验证某个音乐信息检索算法比如音高估计、起点检测、歌手识别这份数据集的固定标注就是天然ground truth。我用它测试过两三个开源音高估计器因为midi来自原始标注比用第三方工具二次提取的结果干净很多评测误差明显更可控。6. 这套数据的局限和补齐策略没有数据集是完美的这套也一样。给心里提前打个底免得做到一半发现不够用。6.1 数量有限覆盖风格单一100首对深度学习模型来说只够做基准测试和过拟合验证远不够训生产级模型。补数据的方法可以是自己爬更多歌但这个涉及版权问题只建议在个人研究中使用结合开源歌声数据集比如OpenSinger、M4Singer、NUS-48E等做数据增强变调、加混响、时间拉伸。6.2 标注精度需要置信度筛选时长标注不一定每一条都准确。我在训练时会给每条样本计算一个“自洽度”即把wav输入一个现成的音高估计器输出的音高序列和midi对齐如果偏差率高就降低该样本权重或者直接筛掉。6.3 版权问题这个很多人容易忽略。100首歌声数据集的原始来源、授权协议不明确时做演示和学术研究没问题但如果想商用还是要认真核实版权链条。这个务必要确认清楚再上生产环境。7. 个人实操心得最后分享几个实际用下来的体会仅供参考。第一处理这类数据集最花时间的不是模型代码而是清洗和格式统一。准备好ffprobe批量检查脚本能省掉一大半去重、排查的时间。第二midi和wav的对齐是整个数据链路里最容易出错的一环。做对齐时不要只依赖标注文件最好写一个可视化工具把频谱、F0曲线、midi音符画在同一个坐标轴上肉眼扫一遍比任何自动计算都靠谱。第三先把最简单的模型跑通再往上加复杂度。我第一次拿这套数据时直接想搞端到端扩散模型结果数据预处理问题一大堆跑出来的东西驴唇不对马嘴。后来退回用传统拼接合成的方式把流程走通才有信心继续做更复杂的模型。第四一定保留“原始数据”备份。不管怎么清洗、转换、裁剪都不要覆盖原始解压文件。很多处理是不可逆的比如重采样后再想恢复44.1kHz版本虽然技术上能转回去但已经丢了很多高频信息。老话讲“数据不清理亲人两行泪”对这个领域同样适用。本文还有配套的精品资源点击获取

最新新闻

日新闻

周新闻

月新闻