残差向量量化
语言模型只能处理离散符号,但音频是连续信号——如何将声音"分词"成可被自回归模型建模的离散序列,是音频大模型时代的基础问题,残差向量量化(RVQ)正是解决这一矛盾的核心技术。
Linde、Buzo和Gray在IEEE Transactions on Communications发表基于Lloyd迭代的向量量化算法,将连续向量空间划分为有限码本条目,成为语音编码(如CELP)的基石。其核心思想是用K个代表向量近似整个分布,但单层码本面临指数级增长困境:要达到高保真度需要天文数字的码本大小。
Juang和Gray提出多级向量量化(MSVQ),核心洞见是:与其用一个巨大码本一步到位,不如用多个小码本逐层逼近——第一层量化原始信号,第二层量化第一层的残差,以此类推。这将码本复杂度从$K^N$降至$N \times K$,在同等比特率下大幅降低存储和搜索开销。这一思想在ITU-T G.729等标准中得到工程验证。
van den Oord等人在NeurIPS发表VQ-VAE,首次将向量量化嵌入神经网络端到端训练框架。关键创新是直通估计器(straight-through estimator)绕过量化不可导的问题,以及指数移动平均(EMA)更新码本。这使得离散潜变量可以通过梯度下降学习,为后续所有神经音频编解码器奠定了训练范式。
Google在IEEE/ACM TASLP发表SoundStream,将经典RVQ与深度编解码器架构结合:卷积编码器压缩波形为帧级向量,RVQ将其量化为多层离散码,卷积解码器重建波形。通过对抗训练和多尺度频谱损失,在3kbps即可达到透明音质。这是第一个在极低比特率下超越Opus等传统编解码器的端到端神经方案。
Meta发表EnCodec(ICLR 2023),改进训练稳定性并开源,成为AudioLM、MusicGen、VALL-E等系统的标准分词器。微软VALL-E证明:将语音RVQ码视为"语言",用自回归模型建模第一层、用非自回归模型建模剩余层,即可实现零样本语音克隆。RVQ从编解码工具升级为音频大模型的"词表"。
MELD、LoSATok等工作提出不再冻结分词器,而是让编码器与下游模型联合训练,使离散表示更适配生成或理解任务,标志着音频分词从固定工具走向可学习模块。
设编码器输出帧向量$\mathbf{z} \in \mathbb{R}^d$,RVQ使用$N$级量化器,每级拥有码本$\mathcal{C}^{(n)} = \{\mathbf{e}_1^{(n)}, ..., \mathbf{e}_K^{(n)}\}$,$K$为码本大小。量化过程递归定义:初始残差$\mathbf{r}_0 = \mathbf{z}$;第$n$级选择最近码字$k_n = \arg\min_k \|\mathbf{r}_{n-1} - \mathbf{e}_k^{(n)}\|_2^2$;更新残差$\mathbf{r}_n = \mathbf{r}_{n-1} - \mathbf{e}_{k_n}^{(n)}$。最终重建为所有层码字之和:$\hat{\mathbf{z}} = \sum_{n=1}^{N} \mathbf{e}_{k_n}^{(n)}$。量化误差为$\|\mathbf{z} - \hat{\mathbf{z}}\|_2^2 = \|\mathbf{r}_N\|_2^2$,随层数增加单调递减。训练损失包含三项:$\mathcal{L} = \underbrace{\|\mathbf{x} - \hat{\mathbf{x}}\|_1}_{\text{重建}} + \underbrace{\|\text{sg}[\mathbf{z}] - \hat{\mathbf{z}}\|_2^2}_{\text{码本更新}} + \beta\underbrace{\|\mathbf{z} - \text{sg}[\hat{\mathbf{z}}]\|_2^2}_{\text{承诺损失}}$,其中$\text{sg}[\cdot]$为停止梯度算子,$\beta$控制编码器对码本的"承诺"程度(通常0.25)。比特率计算:每秒$F$帧,每帧$N$个索引,每索引$\log_2 K$比特,总比特率$= N \cdot \log_2 K \cdot F$ bps。例如SoundStream:$F=50$,$N=12$,$K=1024$,得$50 \times 12 \times 10 = 6000$ bps = 6kbps。这解释了为何RVQ可以灵活控制比特率——增减层数即可。
RVQ音频分词的整体逻辑是:编码器压缩时域波形为紧凑帧表示,多级量化器将连续表示离散化为码本索引序列,解码器从离散码重建波形,整个流程端到端联合优化。
编码器接收原始波形(如24kHz采样),通过多层一维卷积逐步降采样(如320倍),将每320个采样点压缩为一个$d$维向量($d$通常128-512)。为什么用卷积而非Transformer?因为音频帧率极高(24000Hz),卷积的局部感受野和固定计算量更适合长序列压缩。关键设计:使用因果卷积确保流式推理兼容性;残差块保持梯度流通;降采样倍率决定帧率(320倍→75Hz帧率)。
编码器输出的连续向量经过$N$级RVQ。第一级捕捉信号的粗粒度结构(基频、能量包络),后续各级逐步细化细节(谐波结构、噪声纹理)。为什么不用单级大码本?因为$K^N$的搜索空间在$N>2$时已不可行(如$1024^8$),而RVQ将其降为$N \times K$次距离计算。实现细节:码本初始化用K-means在首批数据上预聚类;训练中使用EMA更新避免码本坍塌(codebook collapse);若某码字使用率低于阈值则重新初始化为当前batch中的随机向量。
python def rvq_forward(z, codebooks, n_levels): residual = z indices = [] quantized_sum = 0 for n in range(n_levels): distances = torch.cdist(residual, codebooks[n]) idx = distances.argmin(dim=-1) quantized = codebooks[n][idx] residual = residual - quantized.detach() quantized_sum += quantized indices.append(idx) # Straight-through estimator quantized_out = z + (quantized_sum - z).detach() return quantized_out, indices【Step 3 ·