
pdoom-video 词级对齐原理CTC 强对齐 Whisper 如何让歌词精确到每一个词【免费下载链接】pdoom-videoCode-rendered music video for Im Upping My P(doom)项目地址: https://gitcode.com/gh_mirrors/pd/pdoom-videopdoom-video 是一个代码渲染的音乐视频项目画面每一帧都是歌曲时间的确定性函数其中的卡拉 OK 排版要求歌词精确到每一个词。为此项目用 Demucs 分离人声、两个 CTC 声学模型做逐帧发射概率、一次覆盖全曲的 Viterbi 强制对齐再以 Whisper 词级时间戳做独立交叉验证最终产出带置信度的词级甚至音节级时间轴 data/lyrics.json。本文用 5 个步骤讲清这套词级对齐管线的原理。为什么需要词级而不是句级对齐普通歌词字幕只需要行级时间但这个项目要做逐词点亮的卡拉 OK 排版哪个词在响哪个词就该被点亮。行级时间做不到这件事——一行 8 个词你只知道整行的起止不知道 AGI 的每个字母分别落在哪 20 毫秒上。原始歌词只有粗略的行级时间见 lyrics/lyrics.src.js所以必须通过音频信号反推出每个词的精确起止。第 1 步先把人声从混音里剥出来 ️整首歌是完整混音人声埋在人声、鼓、贝斯、合成器里。项目先用 Demucshtdemucs_ft模型把歌曲拆成人声 / 鼓 / 其他声部得到人声干声vocal stem另外用一个 mel-band-roformer 卡拉 OK 模型再分离出主唱 lead专门救回被和声垫底淹没的词。这一步很关键后面所有对齐都只跑在人声轨上模型才不会被鼓点干扰。第 2 步CTC 发射概率——给每一帧 20 毫秒打字母分CTCConnectionist Temporal Classification是语音识别里经典的输出结构模型每 20 ms 吐出一帧字母概率分布其中包含一个空blank选项天然能处理发音时间 ≠ 文本长度的错位问题。项目同时跑两个独立的 CTC 声学模型见 analysis/ctc_emissions.py模型特点MMS_FA多语言、专训对齐、带 star 垃圾 tokenwav2vec2-large-lv60k英文 960 小时语料字母级两个模型各自在单声道和声 / 左声道 / 右声道上各跑一遍副歌是左右双轨和声单声道里反而糊得到 6 路发射概率按概率混合融合成一路——这就是代码里叫fused6的主发射。单模型会有的系统性偏差在融合后被互相抵消。第 3 步一次 Viterbi 强制对齐覆盖整首歌 有了发射概率问题变成已知歌词文本在 7833 帧的发射序列上找出一条概率最大的路径。这就是强对齐forced alignment——文本是已知的只需把每个字母钉到帧上。项目没有逐句对齐而是一次 Viterbi 遍历整首歌 46 行核心实现在 analysis/ctcalign.py用 numba 加速垃圾 star token在每两行歌词之间插一个虚拟 token逐帧分数 该行最佳字母概率 − 边际值。它专门吸收歌词文本里没有的内容——和声、即兴 ad-lib、outro 的 oh-oh-oh 吟唱——让真正匹配的歌词词依旧胜出。音素级拼写缩写和怪词先转成发音拼写再对齐比如P(doom) → pee doom、AGI → ay gee i、RLHF → are el aitch eff映射表在 analysis/pron.py。于是 AGI 能对出每个字母的时间窗。手动锚点少数难段CTC 在长连音、被和声淹没处会迷路用人工核验的时间窗约束路径。第 4 步Whisper 做第二证人 CTC 对齐再准也是单一来源。项目让mlx-whisper large-v3-turbo独立转写人声轨并输出词级时间戳analysis/whisper_run.py把结果模糊匹配回歌词词序。它的角色是交叉验证而非主力Whisper 与 CTC 主路径开始时间差 ≤150 ms 的词置信度加分差太多则标记为可疑。两条完全独立的算法路线给出一致的时间比任何单模型都可靠。第 5 步信号级精修 置信度评分 ✂️CTC 路径的边界是字母出现的时间但人耳感知的词开始更微妙。analysis/align.py 在 5 ms 精度的人声特征RMS、音高、频谱通量 onset见 analysis/vocal_feats.py上做规则精修rest-onset词前有 ≥50 ms 的静默且人声提前 40 ms 就回来了 → 起点前移到人声重新出现处修 CTC 在长元音上发得晚的毛病onset-snap吸附到 CTC 起点附近最强的频谱通量峰值连音起的 /ʔ/、元音起点fricatives/sh/ch/f/th 开头的词起点回退到 4–10 kHz 摩擦噪声真正开始的位置CTC 习惯把辅音标在摩擦结束时终点连音则取下一词起点否则取人声比该词电平低 15 dB 并保持 60 ms 的时刻——长音能保住完整长度。最后综合四个因素给每个词打分基础分 0.35 独立对齐间一致性≤60 ms 记为一致 CTC 后验 Whisper 一致性得到 0–1 的conf人工修正的词带上各自的置信度。全部 46 行还逐行在放大频谱图 / 音高图上人工核验过analysis/qa_plot.py约 20 处手动校正。最终数据长什么样产物 data/lyrics.json 就是渲染器吃到的全部时间轴。第 0 行的节选{ text: I see sparks of AGI in your eyes, words: [ { w: sparks, start: 2.739, end: 3.46, conf: 1.0 }, { w: AGI, start: 3.677, end: 4.704, conf: 0.84, syl: [[3.677,4.06],[4.06,4.355],[4.355,4.704]] }, { w: eyes, start: 5.263, end: 5.88, conf: 0.91 } ] }普通词有start/end/conf缩写词额外有syl子字/音节时间窗AGI 三个字母各占一段——这就是视频中字母逐一点亮的依据。如何复现这条词级对齐管线 ️仓库里已提交了最终的data/*.json浏览器预览和离线导出都只依赖它。若想用别的歌重新生成时间轴cd analysis uv run python align.py # 生成 data/lyrics.json uv run python analyze.py # 生成 data/audio.json节拍/段落等注意需要先在本地用 Demucs 与卡拉 OK 模型跑出人声 stem模型权重约 4 GB会下载进analysis/.cache/完整说明见 README.md 的 Regenerate the timing data 一节。小结为什么这套方案稳层次手段解决的问题声学输入Demucs 人声干声去掉鼓与伴奏干扰双模型 CTC 融合6 路概率混合抵消单模型偏差、左右和声全局 Viterbi 强对齐一次遍历 star token全局最优、自动吸收即兴段落Whisper 交叉验证独立词级时间戳发现并标记不可靠的词信号级精修onset / 摩擦 / 静默规则起点提前到人耳听到的位置置信度 人工核验conf 分 QA 图可审计、可追溯最终精度大部分词起点误差在 30–50 ms 内被和声淹没的词置信度 0.35–0.45则显式标注为不确定——这套组合拳让 pdoom-video 的每个发光字母都踩在了真正的发音瞬间上。渲染器与场景 API 的更多细节可参考 docs/ENGINE.md 与 docs/TREATMENT.md。【免费下载链接】pdoom-videoCode-rendered music video for Im Upping My P(doom)项目地址: https://gitcode.com/gh_mirrors/pd/pdoom-video创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考