最近几年我一直在盯语音去噪这个方向,从传统谱减法一路看到深度学习的各种模型,尤其是Transformer架构出来之后,整个领域的思路被改写了。以前大家觉得语音去噪是纯信号处理问题,维纳滤波、谱减法、MMSE这些经典方法统治了很多年;后来CNN和RNN进来,效果上了一个台阶;再到Transformer成了主流,模型的建模能力又拉升了一个量级。这篇文章,就围绕“我翻过的一堆基于Transformer的语音去噪论文”做一个系统的总结,梳理它们的核心思路、模型结构、训练细节和复现时踩过的坑。不管你是刚入门想做语音增强的研究生,还是已经在工程里折腾过几版去噪模型的开发者,这份总结应该都能帮你省下不少筛论文的时间。
我会把论文里那些比较绕的架构拆开讲,用大白话解释它们各自解决了什么问题,为什么选这种结构而不是另一种,以及在训练和部署的时候有哪些真正值得注意的细节。全文不聊虚的,全是论文里能落实到代码和实验里的东西。
1. 为什么Transformer能统治语音去噪
1.1 语音去噪到底在解决什么问题
语音去噪,学术点叫语音增强,本质上是给定一段带噪语音,要从里面把干净语音恢复出来。数学上可以写成 y = s + n,y是麦克风采集到的信号,s是说话人的干净语音,n是各种各样的噪声,比如街道嘈杂声、键盘声、风扇声、别人的说话声。模型要做的就是估计出s,或者说估计一个增益函数,把噪声压下去。
这个问题难在哪?难在它同时要处理时域和频域两个维度的信息。语音本身是高度结构化的信号,它在一段话的时间范围内有语言内容的连续性,在频域上又有共振峰、基频这些稳定的模式。噪声的类型千变万化,有些和语音在频谱上重叠得很厉害,单纯在频域上做掩蔽很容易把语音细节切掉,导致“去噪去过头”了,听感像泡在水里一样,闷闷的,甚至丢词。所以一个好的去噪模型,需要同时捕捉时间上的长程依赖和频率上的局部结构,还要能对不同噪声类型泛化。
传统方法比如维纳滤波,本质上是在频域上估计一个最优滤波器系数,它假设噪声和语音都是平稳的,这在真实场景中基本不成立。RNN系的模型能建模时序依赖,但受限于记忆长度和串行计算的瓶颈,训练效率也低。这就是Transformer能切入的核心原因,它的自注意力机制可以一次性看到整段序列的全部位置,长程依赖建模能力天然比RNN强,而且可以并行计算,训练效率高。把这套机制用到语音序列上,就是目前大部分论文的出发点。
1.2 从RNN/CNN到Transformer的演进逻辑
在Transformer之前,语音去噪里最有代表性的模型是SEGAN、WaveNet-based的去噪变种,以及后来在DNS Challenge上大放异彩的DCCRN。DCCRN用的是复数域卷积循环网络,它把频谱当成图像,用CNN抽取频域特征,再用RNN捕获时间维度上的依赖。它的效果在当时很惊艳,但有个明显问题——RNN的过程是串行的,每个时间步都要依赖前一个时间步的隐状态,训练慢,而且面对长音频时记忆会衰减。
Transformer的出现几乎是顺理成章的。它的自注意力机制让每个时间帧都能直接跟所有其他帧互动,不再有“遗忘”问题。网上很多人把Transformer比作“全班同学都互相认识,每个人发言前先听清所有人的意见再决定自己说什么”,这个类比用在语音上也算贴切。每个时频位置经过自注意力后,都知道整段音频里其他位置的贡献,从而更好地决定当前该保留多少、抑制多少。
不过Transformer也有它的代价:计算复杂度是序列长度的平方,而语音帧数通常上万,直接套用原始Transformer在计算上是完全不可行的。所以这个方向的大部分论文,其实都在回答一个问题——怎么让Transformer适应语音这种长序列信号。比如有缩放在频域维度的,有缩放在子带块的,有分双路径处理的,还有用卷积降采样再加注意力的。模型架构上的创新,基本都围绕降低复杂度、保留有效信息来展开。这也是我下面拆解模型时的一个主线。
2. 主流的Transformer语音去噪模型盘点
2.1 时域端到端:SepFormer与Dual-Path系列
有一类模型不走频谱这条路,直接在原始波形上做端到端的处理。时域模型的优势是没有频谱重构过程的误差,相位信息天然保留,因为波形本身就是包含相位的;缺点是哪都需要模型自己学,对数据量的要求更高。这类模型里面最有代表性、论文引用量特别高的就是SepFormer。
SepFormer是2020年的工作,最初是面向语音分离(speech separation)的,但它的架构被大量借用到语音去噪上。它核心的思想来自Dual-Path RNN,就是把一段变长的语音波形经编码器变成特征序列后,转换成一个二维矩阵,一个轴是“块内”(chunk),一个轴是“块间”(num_chunks),然后分别在这两个轴向上做Transformer。把序列拆成固定块长的小段,每个块内部做一次注意力,这叫块内处理,负责建模局部细节;再把各块对应位置聚在一起做一次注意力,这叫块间处理,负责建模全局依赖。这样做的结果是,原本可能需要处理上万帧的序列注意力,被分解成了几十个块内部的小注意力和跨块的轻量注意力,计算量大幅下降。
我在实际测试SepFormer类结构时的一个感受是,它对语音的自然度保持得很好,尤其是处理长句时,不会出现后面半句被压没了的情况,这应该归功于块间注意力让模型能把一段话开头的说话人特征延续到结尾。不过它的缺点也很明显,模型参数通常偏大,对大点阵显存不友好,另外实时性比较差,因为在块内做注意力需要积累够一块的数据才能出结果,延迟和块长强相关。这类模型比较适合离线批处理场景,比如给一集电视剧做整体的音频清理,而不是放在耳机里做实时降噪。
2.2 频域掩蔽派:FullSubNet及其增强版本
另一种主流路线是在频域做掩蔽,模型输入是STFT后得到的复数谱,输出是每个时频点上的增益系数,乘以带噪谱就得到增强谱,再通过ISTFT还原成波形。这条路线的优势是计算效率高,可以直接拿语音信号处理的成熟工具来做预分析和后处理;劣势是相位估计是难点,很多模型干脆忽略相位,只用幅度谱预测掩蔽,这导致语音和噪声在初始相位不一致时出现失真。
FullSubNet是这里绕不开的一个节点。它的核心观察非常接地气:“全带模型”用整个频谱的信息来预测掩蔽,能利用全局频率相关结构;“子带模型”只关注自己那个频带的局部模式,计算量小,对细节恢复更友好。于是好多人干脆结合两者,先用全带模型提取全局特征,再把每个子带的特征输入子带模型进行预测。FullSubNet最初用的是LSTM作为子带模型,到了FullSubNet+,作者直接换成了Transformer,用多头注意力处理子带序列里的帧间依赖,效果又往上走了一截。
复现FullSubNet系列时有个关键的坑大家要注意,它每个子带是按中心频率划分的,子带的数目和帧长、频率分辨率相关,如果你的STFT参数变了,子带划分也要跟着变。而且它训练时的输入特征是拼接了全带特征和子带特征,维度处理比较繁琐,对新手不友好。我自己是把它的数据管线单独抽出来跑了几遍才搞清楚,建议复现前先把STFT的参数理清楚,尤其是window size、hop size和子带数目的对应关系,否则后面改参数很容易出形状不匹配的错误。
2.3 混合架构:CMGAN与DeepFilterNet这类“实用派”
如果去翻近两年的语音增强论文,会发现单纯唱独角戏的网络已经很少了,基本都是“卷积+Transformer+GAN”的混合体。CMGAN(Conformer-based Metric GAN)就是很典型的一个。它的前端用了Conformer块,这是Google提出的一种把Transformer和深度可分离卷积结合的结构,不光是注意力,还用卷积以局部窗口的形式建模相邻帧的模式。语音信号本身既有长程的时间依赖,又有很强的局部结构,Conformer这种“一个块里既有CNN又有注意力”的设计,恰好能同时照顾两者。
CMGAN另一个值得关注的设计是它的双分支结构。它把输入频谱分两路处理,一路专门修复幅值,一路专门修复相位,最后再通过一个融合模块把两路信息合在一起。这个思路解决了上面说的相位估计难题,至少让相位信息不再被无视。此外它是用GAN的方式训练的,“判别器”去判断增强后的语音和干净语音的差异,而生成器不只要最小化信号重构误差,还要骗过判别器,这样模型会学习到更贴近自然语音分布的细节。多任务加上对抗训练,让模型的主观听感通常比纯重构训练的好一截。
DeepFilterNet则是“工程效率派”的代表。它目标很明确:在慢速CPU上也要跑实时。论文里大量使用子带建模和分组卷积,把计算控制在极低的量级。它基于一个很扎实的信号处理原理:人耳对频域的感知是非均匀的,低频分辨率高、高频分辨率低,所以不需要在每个FFT频点上分配同样的计算。DeepFilterNet把频谱按ERB尺度分组,每组用很少的参数去预测一个动态滤波器的系数,从数学上保证了计算复杂度远低于逐频点Transformer模型。如果你做的是实时降噪的产品,我建议多研究一下它的分组滤波思想,虽然论文里有些实现细节比较绕,但整个方向的取舍非常值得学。
3. 训练一个语音去噪模型的关键细节
3.1 数据准备与数据增强
论文看得再多,最后效果好不好还是数据说了算。语音去噪训练数据的构造,核心就两步:拿干净语音和噪声,按不同信噪比混在一起,让模型看到得越多越好。常用的干净语音数据集有LibriSpeech、Common Voice,噪声库有MUSAN、TAU Urban Acoustic Scenes,这些是公开的、大家都在用的。混音的时候,信噪比最好在一个区间里随机采样,比如从-5dB到15dB都出现,这样模型对不同噪声强度的场景都有覆盖。这里要提醒一个新手很容易犯的错误,训练和测试的信噪比分布要尽量一致,不然你会看到训练指标非常好看,一到真实场景就崩。
数据增强也是论文里高频出现的一个点。常见的有随机裁剪、音高调整、加混响、SpecAugment那一套。SpecAugment就是在输入谱上随机屏蔽一小部分时间块或频率块,逼迫模型学会从周围信息去推断被遮住的部分,增强鲁棒性。混响这块尤其重要,因为真实环境几乎都有房间反射,不经过混响增强训出来的模型,到了办公室、车里这些地方往往会变得很“干”,像是把人声从录音棚里强行抠出来一样。
另外要注意的一个点是做数据归一化。语音波形或频谱的尺度在不同样本间差异很大,很多人直接把原始音频丢进模型里训练,loss波动很大。常见的做法是计算每个batch的均值和方差做实例归一化,或者在输入模型前把音频能量归一化到统一水平。论文里可能一句话带过,但实际操作中这几步极其关键。
3.2 损失函数怎么选
模型能不能学到东西,损失函数的设计是灵魂。语音去噪里最常用的几类损失,我给一个横向对比。
第一类是信号级损失,代表是SI-SNR(尺度不变信噪比)。它直接计算增强后波形和干净波形之间的比例误差,对尺度不敏感,只关心相对形状对不对。这个损失训练出来的模型,常见问题是主观听感有时候一般,因为信噪比高不代表语音的语音细节就自然。第二类是频域损失,比如把增强谱和干净谱之间的MSE或者L1作为损失。频域损失的好处是能更直接控制谱结构,配合STFT恢复出来的波形也相对稳定。现在很多论文喜欢用多分辨率STFT损失,就是同时用多个不同的窗口长度去算STFT,再在多个尺度上比较,这样比单一窗口更平滑,能兼顾时间和频率的细节。
第三类是对抗损失,就是我前面提的GAN那套,让生成样本的分布接近干净语音的分布。很多指标模型用GAN训练后PESQ不一定涨多少,但MOS主观分提升肉眼可见,因为人耳对细节那些“说不出来哪里怪”的失真特别敏感。我在实际实验中最常用的组合是“SI-SNR + 多分辨率STFT损失 + 轻量判别器对抗损失”,三者在不同层面约束模型的输出,信号级保证总体相似,频域级保证细节平滑,判别器把听感往上拉。当然三个损失之间权重需要调,我一般让SI-SNR占比最大,大概0.8,其他两个是辅助。
3.3 评估指标怎么看
评估去噪效果,最通用的客观指标是PESQ(语音质量感知评估)和STOI(短时客观可懂度)。PESQ打分范围是-0.5到4.5,它模拟人耳的主观感受来对增强后语音打分,是目前论文里报得最多的一个指标;STOI则是衡量语音可懂度的,分数0到1,通常关心在噪声环境下别人能不能听懂你在说什么,对助听器等场景特别重要。如果你在做实时系统,还要关注RTF(实时因子),也就是处理一段时长x的音频需要的时间除以x,小于1才能满足实时处理。
还有一个值得提的是DNSMOS,这是微软出的一个无参考评估指标,专门用来在没有干净参考的复杂场景下评估去噪效果,很适合评估真实录音。我一般看论文会先看PESQ和STOI的组合,再结合模型参数量、实时性,这样基本能判断一个模型适不适合自己的场景。纯堆指标的论文要小心,有些模型为了指标好看,大量使用未来信息,做离线增强还行,套到实时系统里直接完蛋。
4. 复现论文时常踩的坑
4.1 设备与显存的取舍
Transformer模型在语音这个场景上最麻烦的就是显存。直接对整条3秒音频的时频谱做全局注意力,8GB显存根本不够看。我刚开始复现SepFormer的时候,把编码器输出序列推到Transformer层里,直接爆显存,后来才意识到需要把序列长度控制在合理范围内。论文里通常不会告诉你这些工程细节,所以复现时要自己做一些裁剪。
最实用的策略有以下几种。一是对时域信号做不均匀的分块,块内注意力用短序列,块间注意力挑有代表性的帧做采样。二是用卷积降采样来缩短序列长度,比如在进入Transformer之前,先用步长为2的卷积把时间维度减半、通道数翻倍。三是使用窗口注意力或局部注意力,类似Swin Transformer的做法,只在局部窗口内做自注意力,这个在语音里也有不少论文在尝试。四是使用FlashAttention等高效注意力实现,既能省显存又能提速,现在的深度学习框架基本都直接支持了。实验的时候建议先用小维度把完整流程跑通,再逐步放大到论文里的配置。
4.2 训练不稳定怎么办
Transformer训练不稳定是出了名的,我自己总结下来,最大原因无非这几个:学习率设置不合理、数据尺度不平衡、损失函数权重波动大。
针对第一个问题,Transformer的标配是warmup加余弦退火。刚开始用一个很小的学习率跑几千步,让模型预热一下,再把学习率升上去,后面逐渐衰减。这个过程像热身运动,不热身直接全力冲刺,模型特别容易震荡。第二个问题,前面提到数据归一化,这在Transformer中尤其重要,因为注意力里要算softmax,输入尺度一大,softmax就会过度饱和,梯度消失。第三个问题,多损失函数时动不动就盯着某个损失猛降,实际上是其他损失根本没学进去,这种情况需要可视化训练过程中各个损失的曲线,及时调整权重。
还有一个常见坑是mask的数值范围。在频域掩蔽类模型里,很多论文输出是经过sigmoid或tanh的限制在[0,1]或[-1,1],但有的复现会漏掉这个限制,模型输出的增益出现负值或大于1的情况,导致增强后的音频出现明显失真。建议在模型最后一层显式加激活函数,并用mask的约束重新思考模型的物理意义。
4.3 指标好看但听感差的原因
我见过不少模型PESQ提了0.4、STOI提了0.05,听起来却很难受的情况。原因通常是模型在频域上把噪声压得太狠,导致语音的高频细节也一起被抹掉了,人耳的感知是灵敏的,一旦均匀抹掉细节,就会听出“不自然”的感觉。这种失真在指标上体现不明显,因为PESQ对短时谱形状的相似度打分,缺少了对自然感的惩罚。
避免这个问题的经验是,训练时不要只用SI-SNR这种粗粒度损失,要加一个频域细节约束,比如STFT损失里可以按频率加权,中低频段给更多权重,高频段允许一定误差。另外GAN那类对抗训练的模型往往听感好,因为它强迫输出落到干净语音的流形上面。还有个小技巧,预测mask的时候,用幂压缩处理一下,比如对频谱加一个幂指数压缩,类似log谱而不是线性谱去算损失,这样模型会更多关注能量低但人耳敏感的部分。
5. 未来趋势与我的看法
5.1 扩散模型与生成式增强
Transformer在语音去噪里站稳脚跟后,扩散模型又开始往这个方向渗透了。扩散模型的思路是先逐渐给干净语音加噪声,直到变成纯高斯噪声,然后训练一个网络去学习相反的过程。到了推理阶段,从一个随机噪声出发,逐步去噪还原出干净的语音。这个方法在图像生成上非常火,用在语音增强上也有不少论文在探索,核心卖点是可以生成非常自然的语音细节,不容易出现“去噪过度”的塑料感。
不过扩散模型的实时性目前是硬伤,它通常需要多次迭代去噪才能得到结果,一次推理就是几十次模型前向,计算量比Transformer模型大出几个量级。所以学术界现在更多在研究怎么加速它,比如缩小迭代步数、用蒸馏压缩模型、或者用它只增强特定频段。短期来看,扩散模型还替代不了Transformer成为主流产品方案,但它在离线高质量增强场景,比如影视音频修复,很有潜力。
5.2 轻量化与端侧部署
另一个很明显的趋势是端侧部署,也就是把模型塞进手机、耳机、助听器这些小设备里面。Transformer模型的参数量和计算量在端侧是个大问题,所以我看到许多论文开始关注模型压缩、剪枝、蒸馏和高效注意力。比如TPTN这类专门做轻量级Transformer的工作,把注意力在时间和频率两个维度上拆开,计算量大幅下降,在低算力设备上跑得很舒服。
如果你要做端侧部署,我给一个实用建议:先确定目标设备的计算预算和内存上限,再反过来选模型。不要一上来就复现一篇SOTA论文,很可能是论文里指标的漂亮的模型在你的设备上跑不动。轻量化的Transformer在去噪上其实已经能达到很可用的水平,关键是把你手头的音频特点和噪声分布用好,数据针对性强比模型大个两倍更管用。
5.3 真实场景鲁棒性是终极考验
音频领域比视觉更尴尬的地方在于,每个场景的声学条件、设备麦克风、噪声类型都不同。模型对训练时的噪声类型有一点过拟合的倾向,这点非常明显。我在实际把模型部署到不同设备时发现,同一个模型在A手机上表现很好,换到B手机上就变差,原因是两个手机的麦克风频响曲线、底噪水平、采样率都不一致。所以现在论文也越来越看重跨域泛化。
解决思路有两个方向。一个是在训练数据上做更彻底的域随机化,比如混入不同麦克风采集的真实噪声、随机改变采样率、做设备模拟(把录音模拟成经过某个麦克风之后的样子)。另一个是做自监督适配,就是模型到了新设备上,只利用现场录到的一段噪声就能自己微调一小会儿。这些都是未来更值得投入的方向。我自己在做工程时很看重“真实场景测试胜过一切指标”,在实验室指标差不多的情况下,我更愿意选那个在多种设备上听感都稳定的模型,而不是某个指标排名第一的模型。
最后分享一个我自己复现论文时的操作建议:拿到任何一篇语音去噪论文,先别急着复现网络核心,先把它的数据处理和STFT相关参数表整理出来,这一步搞清楚了,模型部分反而没那么多坑。很多论文的效果好,其实有一半是数据策略的功劳,模型只是把数据利用得好。找个周末,把你收藏夹里那十几篇Transformer去噪论文列一张表,按照输入域、核心模块、损失函数、实时性四个维度填个简单表格,你会很快发现它们之间的演化脉络,比一篇篇零散地看效率高得多。