语音降噪模型部署优化:减小计算量的几类方法
语音降噪模型从论文效果走到真实产品时,常见问题是:听感不错,但放到端侧、实时通话、耳机、车机或低功耗芯片上之后,算不动、延迟高、功耗大。因此做实际部署时,除了 DNSMOS、PESQ、STOI 或主观听感,还要关注 MACs/FLOPs、参数量、内存占用、实时率 RTF、算法延迟、CPU/NPU/DSP 占用、功耗和端侧算子支持情况。
本文以语音降噪模型为例,梳理几类减小部署计算量的方法。除了常见的剪枝和蒸馏,还可以从模型结构、数值表示、信号处理链路和部署后端一起优化。如有不对的地方,欢迎大家指正交流。
本文先做方法梳理,后续我也会选一个具体的语音降噪模型,把其中一些方法做成实际优化实验,欢迎持续关注交流。
1. 先分析:语音降噪模型的计算量来自哪里
以典型的频域神经网络降噪系统为例,处理流程大致如下:
时域音频
-> 分帧 / 加窗
-> STFT 或特征提取
-> 神经网络估计 mask / 频谱 / 滤波器 / 时域波形
-> ISTFT 或合成滤波
-> 后处理 / 增益平滑 / 限幅
-> 输出音频
计算量不一定只在神经网络里。对于小模型,STFT/ISTFT、特征归一化、内存拷贝、张量排布转换和后处理也可能占到明显比例。端侧还会遇到理论 FLOPs 不高、实际运行不快的问题,常见原因是算子不适配、访存开销大、状态缓存设计不好,或者频繁做 layout transform。
所以在优化前,最好先做一次 profile,重点看下面几个问题:
| 问题 | 作用 |
|---|---|
| 每帧神经网络推理耗时多少 | 判断网络是否是瓶颈 |
| STFT/ISTFT 占比多少 | 判断是否需要优化前后处理 |
| RNN/GRU/Conv/Attention 哪类算子最耗时 | 决定结构优化方向 |
| 参数量和激活内存分别是多少 | 判断瓶颈是计算还是内存 |
| batch=1、流式推理时是否充分利用硬件 | 避免只看离线 benchmark |
| 目标平台支持哪些高效算子 | 决定量化、稀疏、卷积结构是否真的有收益 |
部署优化的核心,是在目标硬件上找到 听感、延迟、功耗和稳定性之间的平衡点。
2. 方法一:简化模型结构
2.1 减少通道数、层数和隐藏维度
这是最直接的方法。频域降噪模型里,可以减少卷积通道数、encoder/decoder 层数、RNN hidden size 或全连接层宽度。
以 GRU 为例,输入维度为 D,隐藏维度为 H 时,单层 GRU 的参数量和计算量大致和:
3 * (D * H + H * H)
相关。这里的 H * H 很关键,hidden size 从 256 降到 128,循环部分计算量接近降到四分之一。代价是降噪强度、人声自然度和复杂噪声泛化能力可能下降,需要结合听感实测。
2.2 使用深度可分离卷积
模型里有大量二维卷积或一维卷积时,可以把部分普通卷积换成深度可分离卷积。普通卷积的计算量大致是:
K * C_in * C_out * T * F
深度可分离卷积拆成 depthwise 和 pointwise 两步:
K * C_in * T * F + C_in * C_out * T * F
卷积核较大、通道数较多时,这种拆法能明显降计算。T-F mask 估计、频带特征建模、轻量 encoder/decoder 都可以考虑。depthwise 算子访存占比高,最终收益要看部署后端实测。
2.3 使用分组卷积、瓶颈结构和倒残差结构
分组卷积、瓶颈结构和倒残差结构都可以减少高维通道上的重计算,适合放在频谱特征编码器、时频卷积模块和轻量 U-Net 结构中。常见替换如下:
| 替换前 | 替换后 |
|---|---|
| 大通道普通卷积 | depthwise separable conv |
| 宽 residual block | bottleneck residual block |
| 全频带大卷积 | 分频带小卷积 + 跨带轻量融合 |
| 大型 U-Net | 小通道 U-Net + 轻量时序模块 |
2.4 低秩分解
低秩分解把大矩阵或大卷积核拆成几个小矩阵或小卷积的乘积。比如一个大的全连接层:
W: [M, N]
近似分解成:
W1: [M, R], W2: [R, N], R << M,N
参数量从 M*N 变成 M*R + R*N。全连接层、RNN 输入投影、卷积投影层都可以尝试,分解后一般需要继续 fine-tune。
2.5 频带压缩和子带建模
语音降噪可以按感知频带建模。人耳对不同频段的敏感度不同,语音主要能量也集中在中低频,因此可以:
- 把线性频率 bin 映射到 Bark、Mel、ERB 或自定义 perceptual band。
- 神经网络只预测较少数量的频带增益。
- 再把频带增益插值或映射回原始频率分辨率。
这样可以降低网络输入输出维度和 mask 预测计算量。代价是频率分辨率降低,可能影响窄带噪声、啸叫、音乐噪声和谐波细节。
2.6 轻量时序建模替代重型 RNN 或 Attention
语音降噪需要建模时间上下文。常见方案有 RNN、TCN、因果卷积、Conformer、Transformer 等。它们的计算特性不同:
| 时序模块 | 优点 | 风险 |
|---|---|---|
| GRU/LSTM | 流式友好,状态清晰 | hidden size 大时计算重 |
| TCN/因果卷积 | 并行友好,结构简单 | 感受野和缓存要设计好 |
| Transformer/Attention | 长上下文强 | 实时和端侧成本高 |
| Linear attention/局部 attention | 比全局 attention 轻 | 算子支持和效果需验证 |
| 状态空间模型/轻量序列模型 | 长序列潜力大 | 部署成熟度依平台而定 |
实时降噪更看重稳定延迟和流式状态管理。很多场景下,小型 GRU、TCN 或“卷积 + 小 RNN”比大型 attention 结构更容易落地。
3. 方法二:量化
量化把 FP32/FP16 的权重和激活换成 INT8、INT4 或混合精度表示,用更低的内存、带宽和计算成本完成推理。
3.1 FP32 到 FP16/BF16
目标硬件支持 FP16 或 BF16 加速时,可以先把模型从 FP32 切到 FP16,减少模型体积和内存带宽。语音降噪模型使用 FP16 时,重点检查这些位置:
| 位置 | 风险 |
|---|---|
| STFT 幅度很小的频点 | 数值下溢或动态范围不足 |
| mask 或增益估计 | 过小增益可能产生不稳定 |
| RNN 状态 | 长时间流式累积误差 |
| 归一化层 | 均值方差计算精度 |
实践中可以用混合精度:大部分网络用 FP16,少量敏感运算保留 FP32。
3.2 INT8 量化
INT8 是端侧部署最常见的量化形式,模型小、带宽低,很多 NPU/DSP/CPU 都有成熟优化。INT8 量化有两种常见路线:
| 类型 | 含义 | 特点 |
|---|---|---|
| PTQ | Post-Training Quantization,训练后量化 | 快,但精度损失可能较大 |
| QAT | Quantization-Aware Training,量化感知训练 | 更稳,训练成本更高 |
语音降噪建议优先考虑 QAT。量化误差可能表现为底噪起伏、金属音、齿音损伤或语音断续。量化时需要看:
- 输入特征的动态范围是否稳定。
- 激活是否有极端 outlier。
- RNN/GRU 是否被目标推理框架原生支持 INT8。
- per-tensor 量化是否足够,还是需要 per-channel 量化。
- mask 输出层是否需要更高精度。
3.3 INT4、权重量化和混合精度量化
INT4 可以进一步压缩模型,但听感风险更高。可以先做 weight-only quantization,只量化权重,激活保持较高精度。投影层、卷积层可以尝试 INT4;输出层、增益估计层、RNN 状态更新层可以保留 INT8、FP16 或 FP32。
4. 方法三:剪枝和稀疏化
剪枝会去掉模型里相对不重要的权重、通道、层或模块。它可以减少参数量,也可能减少计算量,但参数量变小不代表推理一定变快。
4.1 非结构化剪枝
非结构化剪枝会把单个权重置零,例如剪掉权重矩阵中绝对值较小的元素。它可以得到很高的稀疏率,但依赖硬件和推理框架对稀疏矩阵的支持。因此它更适合模型存储压缩、有稀疏加速库的平台。
4.2 结构化剪枝
结构化剪枝更适合真实部署。它剪掉通道、卷积核、hidden units、attention heads,甚至整层模块。剪完后模型结构直接变小,可以继续使用普通 dense 算子。常见对象包括:
| 剪枝对象 | 说明 |
|---|---|
| 卷积通道 | 减少 encoder/decoder 计算 |
| GRU hidden units | 降低循环计算量 |
| 全连接中间维度 | 降低投影层计算 |
| 频带分支 | 去掉收益较小的子带分支 |
| attention heads | 减少注意力计算 |
| U-Net skip 分支 | 降低拼接后的通道数 |
结构化剪枝常见流程如下:
训练 baseline 模型
-> 评估通道/单元重要性
-> 按比例剪枝
-> fine-tune 恢复效果
-> 重新评估听感和计算量
-> 多轮迭代
重要性可以用权重范数、BatchNorm gamma、梯度、Taylor expansion、敏感度分析等方法估计。剪枝后重点听低 SNR、非平稳噪声和人声弱能量片段。
4.3 稀疏训练
也可以在训练中加入 L1 正则、group lasso、通道门控、可学习 mask 等稀疏约束。好处是模型更容易适应稀疏结构,风险是正则强度不好调。
5. 方法四:知识蒸馏
蒸馏是用大模型 teacher 指导小模型 student。语音降噪里,小模型通过模仿 teacher,可以在较低计算量下保留更多效果。
5.1 输出蒸馏
最简单的方式是让 student 模仿 teacher 的输出:
| teacher 输出 | student 学习目标 |
|---|---|
| 增强后波形 | waveform L1/L2 loss |
| 复数频谱 | real/imag spectrum loss |
| 幅度谱 | magnitude loss |
| mask | mask loss |
| 频带增益 | band gain loss |
teacher 输出相当于更平滑的软目标,对小模型更友好。
5.2 中间特征蒸馏
也可以让 student 模仿 teacher 的中间特征,比如 encoder feature、bottleneck feature、RNN hidden state、attention map、频带 embedding 等。维度对不上时,加一个训练用 projection layer,部署时去掉。
5.3 感知蒸馏和多目标蒸馏
蒸馏目标可以加入更多感知约束:
- 时域波形误差。
- 多分辨率 STFT loss。
- teacher mask loss。
- 语音保真相关 loss。
- DNSMOS/PESQ/STOI 相关的 proxy loss。
- 噪声残留和语音失真的平衡。
5.4 自蒸馏和渐进式蒸馏
如果没有特别大的 teacher,可以先训练一个较好的模型版本,再用它指导更小版本。压缩比例很大时,可以渐进式蒸馏:
Large teacher
-> Medium student
-> Small student
-> Tiny deploy model
这种方式比一步蒸到极小模型更稳。
6. 方法五:减少输入输出维度和帧率
模型每秒推理次数和帧移直接相关。10 ms 帧移对应每秒 100 次推理,20 ms 帧移对应每秒 50 次推理。增大帧移可以直接减少推理次数。但帧长和帧移会影响延迟、频率分辨率和时间平滑:
| 参数 | 影响 |
|---|---|
| 帧长 | 频率分辨率、算法延迟 |
| 帧移 | 推理频率、时间平滑 |
| lookahead | 降噪效果、实时延迟 |
| FFT size | 频谱维度、STFT 计算 |
| 采样率 | 音质上限、计算量 |
48 kHz 全带宽降噪比 16 kHz 宽带降噪更重。如果目标只是语音通话,16 kHz 或 24 kHz 可能已经足够;高保真录音增强则要谨慎降采样。也可以采用低频高分辨率、高频低分辨率的方式,用较粗的高频频带减少输出维度。
7. 方法六:传统信号处理和神经网络混合
很多成熟 DSP 模块计算量低、可解释、稳定,适合放在神经网络前后,或者替代一部分网络功能。常见组合包括:
| 模块 | 作用 |
|---|---|
| 噪声估计 | 稳定估计背景噪声谱 |
| Wiener filter / spectral subtraction | 提供基础降噪 |
| AEC | 回声消除,不让降噪模型承担回声问题 |
| AGC | 稳定响度,降低模型输入动态范围 |
| VAD | 控制噪声估计和动态推理 |
| 后处理增益平滑 | 减少 musical noise 和增益抖动 |
一种实用思路是:传统算法处理稳定、可建模的部分,神经网络处理复杂、非线性、感知相关的部分。比如传统噪声估计给出先验 SNR,神经网络预测修正增益;或者神经网络只估计残差 mask。混合系统能让小模型做出不错效果,但链路参数需要一起调。
8. 方法七:算子融合和部署后端优化
模型结构和参数压缩之后,还需要做推理工程优化。很多端侧模型的真实瓶颈都在这里。
8.1 算子融合
常见融合包括:
| 融合前 | 融合后 |
|---|---|
| Conv + BN | 把 BN 融入 Conv 权重 |
| Linear + bias + activation | 单个 fused kernel |
| STFT 后多次转置 | 固定 layout,减少拷贝 |
| mask + magnitude + phase | 合并频谱后处理 |
| 多个小 elementwise ops | 合并为一个 kernel |
batch=1 的实时语音里,小算子的调度开销不低。融合多个 elementwise 操作,有时比单纯减少 FLOPs 更有用。
8.2 状态缓存
流式模型有历史上下文,例如卷积缓存、RNN hidden state、overlap-add 缓冲区。每帧重新拼接完整上下文会产生额外拷贝,可以改成:
- 为每路音频维护固定大小 state。
- 用 ring buffer 管理历史帧。
- 避免每帧动态分配内存。
- 输入输出 tensor 复用。
- 把 STFT、网络和 ISTFT 的 buffer 生命周期设计清楚。
实时系统里,减少 malloc/free、tensor 复制和 Python 层调度,能明显提升稳定性。
8.3 选择目标平台友好的算子
模型设计时就要考虑部署后端。比如某些 NPU 对 2D Conv 很友好,但对 GRU 支持不好;某些 DSP 对定点矩阵乘很强,但不支持复杂动态 shape;某些移动 CPU 对小 batch depthwise conv 效率不稳定。模型要能顺利转到目标推理框架,并且在真实设备上跑得快。
9. 可选进阶策略:NAS、动态推理、训练阶段约束
下面几类方法也能降低计算量,但实现成本更高,更依赖具体平台和产品形态,适合作为基础优化后的补充。
9.1 神经网络架构搜索和硬件感知训练
NAS 可以自动搜索模型结构,搜索空间包括通道数、时序模块、频带数量、kernel size、hidden size、skip connection 和量化位宽等。更实用的是硬件感知 NAS,把真实设备延迟、内存和功耗也放进搜索目标:
score = quality_score - alpha * latency - beta * memory - gamma * power
9.2 动态推理
安静环境、稳定背景噪声、静音片段和高 SNR 语音,不需要模型全力工作。动态推理会根据输入难度调整计算量。实时通话中,可以用轻量 VAD 判断是否有人声,用 DTD 判断是否双讲。长时间静音或纯背景噪声时,降低模型调用频率,或者切到更便宜的噪声估计和增益平滑策略。风险是 VAD 误判,弱语音可能被吞掉。另一种做法是准备多个大小不同的降噪模型:常规场景用轻量模型,复杂噪声启用中等模型,极端噪声或高质量模式启用大模型。切换时要避免音色突变或底噪跳变。
9.3 训练阶段加入部署约束
部署要求明确时,可以在训练阶段加入约束。比如在 loss 里加入计算量或参数量惩罚:
loss = quality_loss + lambda * complexity_loss
复杂度项可以是通道门控的 L1 正则、稀疏 mask 正则、可学习架构参数的延迟估计等。语音降噪压缩时,噪声抑制和人声质量都要看。训练目标可以同时加入幅度谱 loss、复数谱 loss、波形 loss、多分辨率 STFT loss、语音保真 loss、感知指标 proxy loss 和 teacher distillation loss。
小模型对数据覆盖更敏感。可以加强噪声类型、SNR、RIR、设备频响、非线性失真、说话人和语种覆盖。训练充分的小模型,可能比数据单一的大模型更适合真实产品。
10. 不同方法的收益和风险对比
下面是各种方法的简单对比:
| 方法 | 主要收益 | 主要风险 | 适合阶段 |
|---|---|---|---|
| 缩小通道/层数 | 直接降低计算 | 效果下降明显 | 模型设计初期 |
| 轻量卷积/瓶颈结构 | FLOPs 下降 | 硬件未必加速 | 结构设计 |
| 频带压缩 | 输入输出维度下降 | 频率细节损失 | 频域模型 |
| 低秩分解 | 压缩大矩阵 | 需要 fine-tune | 训练后压缩 |
| FP16/BF16 | 简单、常有收益 | 数值敏感点要保留 | 部署优化 |
| INT8 QAT | 端侧收益大 | 训练和校准复杂 | 部署前 |
| INT4/混合精度 | 进一步压缩 | 听感风险高 | 极限压缩 |
| 非结构化剪枝 | 参数压缩强 | 不一定加速 | 有稀疏硬件 |
| 结构化剪枝 | 真实加速更稳 | 需要多轮恢复训练 | 模型压缩 |
| 蒸馏 | 小模型效果提升 | teacher 质量决定上限 | 小模型训练 |
| 帧率/频带优化 | 推理次数或输出维度下降 | 延迟和频率细节要平衡 | 语音链路设计 |
| DSP + NN 混合 | 稳定、低成本 | 链路调参复杂 | 工程落地 |
| 算子融合 | 真实延迟下降 | 依赖后端能力 | 部署后端 |
| 状态缓存 | 降低实时开销 | 实现细节复杂 | 流式推理 |
| NAS | 自动找结构 | 搜索成本高 | 平台明确时 |
| 动态推理 | 平均算量下降 | 分支抖动和误判 | 产品化阶段 |
| 训练阶段约束 | 小模型更贴近部署目标 | 训练调参更复杂 | 进阶优化 |
11. 可参考的优化顺序
如果拿到一个效果不错但太重的语音降噪模型,可以按下面顺序优化:
- 先做 profile:确认瓶颈在网络、STFT、ISTFT、内存拷贝还是推理框架。
- 定目标:比如 16 kHz、10 ms 帧移、算法延迟小于 40 ms、单核 CPU 占用小于 30%。
- 改结构:减少 hidden size、通道数,替换轻量卷积,压缩频带维度。
- 调整音频链路:确认采样率、帧长帧移、频带数量是否符合业务目标。
- 训练小模型 baseline:不要只压大模型,也要从头训练一个合理的小模型。
- 蒸馏:用大模型或高质量模型帮助小模型恢复听感。
- 量化:先 FP16,再 INT8 PTQ/QAT,敏感层用混合精度。
- 结构化剪枝:对通道、hidden units 做小步多轮剪枝和 fine-tune。
- 部署优化:算子融合、状态缓存、内存复用、固定 shape、去掉无用转置。
- 完整评测:客观指标、主观听测、端侧长时间稳定性和功耗一起看。
这个顺序的思路是:先让结构适合部署,再用压缩方法推到目标平台上。
12. 多维度评估模型
语音降噪模型压缩后,建议从三类指标一起评价。
第一类是效果指标:
| 指标 | 关注点 |
|---|---|
| DNSMOS SIG | 人声质量是否受损 |
| DNSMOS BAK | 背景噪声是否降低 |
| DNSMOS OVRL | 整体听感趋势 |
| PESQ/POLQA/ViSQOL | 有参考语音时的质量评估 |
| STOI/ESTOI | 可懂度 |
| 主观听测 | 最终听感判断 |
第二类是部署指标:
| 指标 | 关注点 |
|---|---|
| RTF | 是否能实时 |
| p50/p95/p99 单帧耗时 | 是否有卡顿峰值 |
| CPU/NPU/DSP 占用 | 是否影响系统其他任务 |
| 内存峰值 | 是否满足端侧限制 |
| 模型体积 | OTA 和存储成本 |
| 功耗/温升 | 长时间运行体验 |
第三类是稳定性指标:长时间通话是否状态漂移,静音段底噪是否起伏,双讲、笑声、音乐、键盘声是否异常,低电量或低频 CPU 调度下是否仍然实时,多路并发时是否抢占资源。
“平均分变好”也可能掩盖局部问题。压缩方法可能带来金属音、吞字、尾音损伤、底噪闪烁、空间感变窄等副作用,需要分场景测试和人工抽听。
13. 小结
减小语音降噪模型部署计算量,可以从几类方法入手:
- 结构轻量化:小通道、小 hidden size、轻量卷积、低秩分解、频带压缩、轻量时序模块。
- 数值压缩:FP16/BF16、INT8、INT4、混合精度量化。
- 模型压缩:非结构化剪枝、结构化剪枝、稀疏训练。
- 训练辅助:知识蒸馏、自蒸馏、感知蒸馏、多目标 loss。
- 信号链路优化:降低采样率、调整帧长帧移、频带建模、DSP 与神经网络混合。
- 部署工程优化:算子融合、状态缓存、内存复用、固定 shape、目标平台友好算子。
- 可选进阶策略:NAS、动态推理、训练阶段部署约束。
工程落地时,比较推荐的思路是:先 profile,再定目标;先改结构,再做蒸馏和量化;剪枝要尽量结构化;最后一定在真实设备上测 RTF、延迟、功耗和听感。
资料来源
Han Song, Mao Huizi, Dally William J., Deep Compression: Compressing Deep Neural Networks with Pruning, Trained Quantization and Huffman Coding
https://arxiv.org/abs/1510.00149Hinton Geoffrey, Vinyals Oriol, Dean Jeff, Distilling the Knowledge in a Neural Network
https://arxiv.org/abs/1503.02531Jacob Benoit et al., Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Inference
https://arxiv.org/abs/1712.05877Howard Andrew et al., MobileNets: Efficient Convolutional Neural Networks for Mobile Vision Applications
https://arxiv.org/abs/1704.04861Tan Mingxing, Le Quoc, EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks
https://arxiv.org/abs/1905.11946Luo Yi, Mesgarani Nima, Conv-TasNet: Surpassing Ideal Time-Frequency Magnitude Masking for Speech Separation
https://arxiv.org/abs/1809.07454Schröter Hendrik et al., DeepFilterNet: Perceptually Motivated Real-Time Speech Enhancement
https://arxiv.org/abs/2305.08227Microsoft DNS Challenge and DNSMOS resources
https://github.com/microsoft/DNS-Challenge