之前一直没太理解MusicGen模型的结构,也读不懂Meta的文章,代码也比较复杂。现在重新学习理解了一下,下面是我对MusicGen的一些浅薄认知,如果有不正确的地方或需要讨论的地方,欢迎大家一起来交流:
项目链接:
https://github.com/facebookresearch/audiocraft#
https://github.com/facebookresearch/audiocraft/blob/main/docs/MUSICGEN.md
参考链接:
https://github.com/facebookresearch/audiocraft/issues/410
https://github.com/facebookresearch/encodec
以text input only为例
推理阶段
主要由文本编码器,transformer和Encodec音频解码器组成:
- 文本 → 文本 encoder(T5 encoder) → 文本 embedding;
- 文本 embedding输入到Transformer中进行自回归预测音频 token(多码本);
- EnCodec decoder 把 token 还原成真实音频;
训练阶段
musicgen的训练阶段主要训练的是transformer,目的是让它学会如何预测音频token:
- 真实音乐(来自训练集) → 预训练 EnCodec encoder(冻结) → 音频 token;
- 文本 → 文本 encoder (冻结)→ 文本 embedding;
- 文本 embedding + 已有 token → Transformer(训练它预测下一个 token)→ 音频token;
- 音频token → EnCodec decoder (冻结)→ 真实音频;
Encodec
要理解musicgen,那么看懂Encodec是必不可少的。在推理阶段和训练阶段用到的EnCodec encoder,EnCodec decoder还有提到的codebook都来自于Encodec,它的结构如图:
这个过程可以大致理解为:
- Encoder:把音频变成连续 embedding;
- Quantizer + Codebooks:把连续 embedding 离散化成 token;
- Decoder:根据 token 查码字再重建波形;
其中,Encodec的核心就是如何将连续的音频embedding变成token。
codebook可以理解为一个向量字典,这里面有很多向量,每个向量有自己的编号(token),quantizer需要从字典里挑一个和embedding最像的向量,用token表示。但是原始的音频embedding非常大,维度高,值连续,如果用一本字典(一个codebook)来表示的话,就需要一个巨大的字典才能覆盖全部的声音细节,这样会导致存储麻烦,训练困难,离散化误差大,耗显存和transformer预测难度高等问题。
因此,Encodec就采用了多级量化Residual Vector Quantization (RVQ)的方式,它不靠一本巨型字典,而是用多本小字典合作拼成一个向量。具体来说,用了4个codebook,也就是分了四次修补误差来表示音频的embedding。
假设encoder输出的是一个128维的连续embedding E,直接用1个codebook去逼近它,难度很大,Encodec采用的方法是用4个codebook(codebook1-4)逐级逼近它:
- 从codebook1中找到一个向量C1,尽量让它逼近E,留下残差R1=E-C1;
- 从codebook2中找到一个向量C2,尽量让它逼近残差R1,留下残差R2=R1-C2;
- 以此内推,得到C3和C4;
- 最后E≈C1+C2+C3+C4,也就是一个embedding被分解成了多个小向量的和;
在训练Encodec的时候,quantizer就会学习如何选择合适的向量,让decoder重建得更接近真实音频。codebook在训练过程中会不断更新,最终得到一套适合理解音频结构的向量体系。而在推理阶段,codebook是固定的,不会更新。在musicgen的推理过程中,transformer会预测音频token,decoder在codebooks中查找音频token对应的向量并相加,最后解码成波形,得到生成的音乐。
Text + Melody作为input的情况
musicgen除了纯文本输入的模型,还有可以提供参考音频+文本描述的模型musicgen-melody,它与纯文本输入生成音乐的原理一致,只是在进入transformer前有些许不一样:
- 文本 → 文本 encoder(T5 encoder) → 文本 embedding;
- Melody → ChromaStemConditioner → chroma embedding
- 文本 embedding和chroma embedding会进行拼接,作为前缀序列进入到Transformer中进行自回归预测音频 token(多码本);
- EnCodec decoder 把 token 还原成真实音频;