服务端降噪三家:FRCRN, FullSubNet+, MP-SENet

服务端质量档 ------ 参数量 2-10 M,权重 55-100 MB,依赖 PyTorch + 生态库,追求质量而不追求延迟。本文一次讲三家,逐家介绍原理 + 调用 + 5 case 实测。

三家规格一览(参数量为论文口径 · checkpoint 文件体积指 repo 上下载得到的完整文件大小 · fp32 参数本体理论体积会更小 · MP-SENet checkpoint 包含判别器/优化器等训练附加字段):

算法 年份 出处 技术路线 参数量 checkpoint 文件体积 采样率
FRCRN 2022 阿里达摩院 复数 CRN + CFSMN 频率轴 recurrence · cIRM 6.9 M ~55 MB (ModelScope) 16 kHz
FullSubNet+ 2022 清华深圳(THUHCSI) Sub-band + Full-band 交互 + 通道 attention ~6 M ~100 MB (Google Drive .tar) 16 kHz
MP-SENet 2023 中国科大 mask + phase 联合估计 · TS-Conformer 2.1 M ~100 MB (best_ckpt/g_best_dns · 含判别器/优化器) 16 kHz

三家都是频域语音增强(speech enhancement,SE)主流方案,分别代表复数 CRN 家族、sub-band + full-band 交互家族、mask+phase 联合建模的 SOTA。

一、FRCRN

1.1 原理

  • 论文 https://arxiv.org/abs/2206.07293(Zhao et al., 2022 ICASSP · "FRCRN: Boosting Feature Representation using Frequency Recurrence for Monaural Speech Enhancement")
  • 代码 & 权重 ModelScope damo/speech_frcrn_ans_cirm_16k · https://modelscope.cn/models/iic/speech_frcrn_ans_cirm_16k · Apache-2.0 · checkpoint ~55 MB(ModelScope 侧口径)
  • 采样率 16 kHz 单声道 wideband
  • 训练目标 复数理想比掩码 cIRM · Ŷ = M̂ ⊙ X
  • 训练数据(论文 recipe)DNS Challenge + WSJ0
  • 算法延迟(论文因果版)约 30 ms(论文口径)
  • 参数量 约 6.9 M(论文口径)
  • 成绩 ICASSP 2022 DNS Challenge 实时全带非个性化赛道第 2 名

FRCRN(Frequency-Recurrent Convolutional Recurrent Network)是阿里达摩院 2022 ICASSP DNS Challenge 的降噪方案,走复数频域网络 + cIRM 训练目标,复数域 SE 一条脉络的现代代表。

核心机制 · 5 大块一图看清

  • CR Block,复数版卷积块:Complex Conv2d + BN + LeakyReLU + CFSMN 串起来,频域 stride=2 逐层压缩,时域 stride=1 保留分辨率,6 层 encoder + 6 层 decoder 对称 U-Net
  • CFSMN 建模 ,FRCRN 相对 DCCRN 的核心贡献:不用 LSTM 的 hidden state 传信息,而是用显式的 memory block(可学的时间 FIR 加权),causal 配置回看约 200 ms(细节以图为准);FRCRN 把这套 CFSMN 嵌到 CR Block 内部替代 LSTM 做时序 recurrence
  • cIRM 输出 ,两个 tanh 分别输出实部虚部 mask,组合成复数 ,跟 noisy STFT 复数点乘,ISTFT 回时域。复数 mask 同时管幅度和相位
  • CCBAM attention,encoder → decoder skip connection 上加复数版 CBAM,时频维度重加权

演进:DCUNet → DCCRN (Interspeech 2020) → FRCRN (2022)。再往后 MossFormer / MossFormer 2 (2023) 走 Transformer 路线。

1.2 调用方式

复制代码
pip install "modelscope[audio]" torch==2.1.2 torchaudio==2.1.2 soundfile librosa

from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks

ans = pipeline(Tasks.acoustic_noise_suppression,
               model='damo/speech_frcrn_ans_cirm_16k')
ans("in.wav", output_path="out.wav")     # 输出 16 kHz mono

首次调用会自动从 ModelScope 下载 pytorch_model.bin(约 55 MB)到 ~/.cache/modelscope/hub/

二、FullSubNet+

2.1 原理

  • 代码 & 权重 https://github.com/hit-thusz-RookieCJ/FullSubNet-plus · 论文 https://arxiv.org/abs/2203.12188
  • 出处 清华大学深圳国际研究生院 · THUHCSI(Human-Computer Speech Interaction Lab)· ICASSP 2022
  • 采样率 16 kHz 单声道
  • 训练目标 cIRM · DNS Challenge 2020
  • 前身 FullSubNet(Hao et al., ICASSP 2021)------ 论文报"性能超过 DNS Challenge 2020 top-ranked 方案",并非当届冠军本身 (DNS Challenge 2020 · Interspeech 2020 的冠军方案是 DCCRN ,西工大 ASLP · Lei Xie 团队)。FullSubNet+ 是 2022 改进版,本文用其官方 Google Drive checkpoint + 官方 inference.toml recipe

FullSubNet+ 是 FullSubNet 家族的升级版,核心思路是 sub-band + full-band 交互建模 : - Full-band model ,学一个"整段频谱"的全局特征 - Sub-band model ,每个频点独立学"这个频点的局部子带模型" - 加通道 attention,三个通道(幅度谱 / 实部 / 虚部)分别做 attention 加权

为什么这么设计 :单纯 full-band 网络看全局但对局部频段响应弱;单纯 sub-band 网络看局部但缺乏跨频段结构信息。FullSubNet+ 把两条支流结合,加通道 attention 强化频段信息

核心组件: - STFT 输入 → 三通道(幅度谱、实部谱、虚部谱)分别送 MulCA(Multi-Channel Attention)加权 - 加权特征分别进 Full-band Extractor 提取全频上下文,再 unfold / 拼接局部子带特征后送 Sub-band Model - 输出 cIRM,跟 noisy 复数谱点乘

在这一批 case 上表现明显不如 FRCRN / MP-SENet,见 §四。作为 FullSubNet 家族在 DNS Challenge 2020 数据上的后续升级,引用价值高于生产使用价值。

2.2 调用方式

复制代码
git clone https://github.com/hit-thusz-RookieCJ/FullSubNet-plus
cd FullSubNet-plus
pip install torch librosa toml colorful joblib torch_complex
# 下 checkpoint (100 MB · Google Drive)
gdown 1UJSt1G0P_aXry-u79LLU_l9tCnNa2u7C -O ./fsnplus_ck.tar

# 修改 config/inference.toml 里的 dataset_dir_list · 或用 -I flag
python -m speech_enhance.tools.inference \
  -C config/inference.toml \
  -M ./fsnplus_ck.tar \
  -I /path/to/noisy_wavs \
  -O /path/to/enhanced_output

三、MP-SENet

3.1 原理

MP-SENet(Mask-Phase-aware Speech Enhancement Network)是 Interspeech 2023 的 mask + phase 显式联合建模方案 ,论文在 VoiceBank-DEMAND 及其 DNS 设置上报告 SOTA 级结果,核心创新是用独立 decoder 显式预测干净相位

核心机制 : - 双路输出 ,用同一个 encoder + 两组独立 decoder,一路输出 mask(预测干净幅度 = mask ⊙ noisy 幅度),另一路输出 phase(直接预测干净相位) - TS-Conformer ,时频双 Conformer 交替处理,时间轴 Conformer 学时序,频率轴 Conformer 学频段间关系,相比纯 CNN 或纯 Transformer 表达力更高 - 相位建模是关键 ,传统方法里 IRM / 幅度 mask 通常直接复用 noisy phase 只重建幅度;CRM / cIRM 通过复数掩码可隐式 改变相位,但受 mask 结构约束。MP-SENet 的差异是用独立 decoder 显式预测干净相位,理论上在低 SNR 相位污染重的场景更稳

注意坑 :MP-SENet 官方 inference.py一次性把整段音频送 attention ,20 s 音频 = 3200 帧,attention 矩阵内存开销随帧数二次方增长,本文实测环境(NVIDIA RTX 4090D 24 GB · torch 2.1)默认脚本直接 OOM。生产用要手动分段 (训练时 segment_size = 32000 = 2 s,推理时也切成 2 s 段处理)。

3.2 调用方式

复制代码
git clone https://github.com/yxlu-0102/MP-SENet
cd MP-SENet
pip install torch librosa soundfile rich pesq
# checkpoint 官方 repo 里带(best_ckpt/g_best_dns 是 DNS 训练的)

推荐用分段推理避免 OOM (官方 inference.py 直接跑 20s 音频会爆显存)。下面是最小防 OOM 示例,硬切 2 s 边界;生产环境要改为 50% overlap + Hann / crossfade 淡入淡出以避免块边界的相位/能量不连续

复制代码
import sys, torch, librosa, numpy as np, soundfile as sf, json
sys.path.insert(0, "/path/to/MP-SENet")
from env import AttrDict
from dataset import mag_pha_stft, mag_pha_istft
from models.model import MPNet

h = AttrDict(json.load(open("best_ckpt/config.json")))
device = torch.device("cuda")
model = MPNet(h).to(device)
model.load_state_dict(torch.load("best_ckpt/g_best_dns", map_location=device)["generator"])
model.eval()

SEG = int(2.0 * h.sampling_rate)   # 2 s / 32000 samples

y, _ = librosa.load("in.wav", sr=h.sampling_rate, mono=True)
out = np.zeros_like(y)
with torch.no_grad():
    for i in range(0, len(y), SEG):
        seg = y[i:i+SEG]; L = len(seg)
        if L < SEG: seg = np.pad(seg, (0, SEG - L))
        x = torch.from_numpy(seg).float().to(device)
        norm = torch.sqrt(len(x) / torch.sum(x**2 + 1e-9)).to(device)
        x = (x * norm).unsqueeze(0)
        amp, pha, _ = mag_pha_stft(x, h.n_fft, h.hop_size, h.win_size, h.compress_factor)
        amp_g, pha_g, _ = model(amp, pha)
        o = mag_pha_istft(amp_g, pha_g, h.n_fft, h.hop_size, h.win_size, h.compress_factor)
        o = (o / norm).squeeze().cpu().numpy()
        out[i:i+L] = o[:L]
sf.write("out.wav", out, h.sampling_rate)

四、5 case 跑的结果

同一套 5 case benchmark,三家分别处理后的时域波形 + STFT 频谱对照(音频控件里是原始 noisy 输入,方便读者听底噪;三家 enhanced 输出以图片和 DNSMOS 分数呈现):

case 01 · 音乐 BGM

case 02 · 白噪

case 03 · 键盘打字

case 04 · 会议室环境

case 05 · 餐厅 babble

DNSMOS OVR 前 → 后 (P.835 primary · DNSMOS sig_bak_ovr.onnx · 输入统一重采样到 16 kHz mono · 9.01 s 分块聚合 · Δ 从未舍入原始值算得,可能与展示两位小数差 0.01):

# case(场景) FRCRN FullSubNet+ MP-SENet
01 音乐 BGM 1.02 → 2.94 (+1.92) 1.02 → 2.29 (+1.27) 1.02 → 2.99 (+1.97)
02 白噪 2.17 → 4.08 (+1.92) 2.17 → 2.85 (+0.69) 2.17 → 3.90 (+1.73)
03 键盘打字 2.23 → 3.76 (+1.53) 2.23 → 3.19 (+0.96) 2.23 → 3.89 (+1.66)
04 会议室环境 2.67 → 3.97 (+1.30) 2.67 → 3.27 (+0.60) 2.67 → 3.91 (+1.24)
05 餐厅 babble 2.19 → 3.77 (+1.58) 2.19 → 2.89 (+0.70) 2.19 → 3.82 (+1.62)
--- 均值 2.06 → 3.71 (+1.65) 2.06 → 2.90 (+0.84) 2.06 → 3.70 (+1.64)

DNSMOS BAK 前 → 后(Δ 同样从未舍入原始值算得):

# case FRCRN FullSubNet+ MP-SENet
01 音乐 BGM 1.05 → 3.86 (+2.81) 1.05 → 2.40 (+1.35) 1.05 → 3.85 (+2.80)
02 白噪 1.75 → 4.60 (+2.85) 1.75 → 3.08 (+1.33) 1.75 → 4.42 (+2.67)
03 键盘打字 1.70 → 4.46 (+2.76) 1.70 → 3.34 (+1.64) 1.70 → 4.47 (+2.77)
04 会议室环境 2.27 → 4.54 (+2.27) 2.27 → 3.77 (+1.50) 2.27 → 4.50 (+2.23)
05 餐厅 babble 1.87 → 4.45 (+2.58) 1.87 → 2.92 (+1.05) 1.87 → 4.40 (+2.53)
--- 均值 1.73 → 4.38 (+2.65) 1.73 → 3.10 (+1.37) 1.73 → 4.33 (+2.60)

五、简单分析

  • FRCRN 和 MP-SENet 打平 (OVR 3.71 vs 3.70 · BAK 4.38 vs 4.33),一个是 ICASSP 2022 DNS Challenge 实时全带非个性化赛道第 2 名方案,一个是 Interspeech 2023 mask+phase 显式建模方案(论文报 SOTA 级结果),两代频域 SE 的代表都在同一档位。频谱图上也能看出:两家在 5 case 上都能干净剥掉背景,保留语音谐波结构
  • MP-SENet 在 case01 音乐 BGM 略高(OVR 2.99 vs FRCRN 2.94),差距只有 0.05;是否来自显式相位建模需更多样本 / 消融支持,不作定性归因
  • FRCRN 在 case02 白噪略高(OVR 4.08 vs MP-SENet 3.90),单个 case 分数最高;机制上 cIRM + CFSMN 频率轴 recurrence 对稳态背景可能有利,但只 1 case 不足以下"最强"
  • FullSubNet+ 明显落后 (OVR 均值 2.90 · BAK 3.10,比另外两家低 0.8-1.3 分),频谱图上能明显看到白噪 case 保留了大量中低频残余,在本文 checkpoint 与 DNSMOS 口径下明显落后 (checkpoint / 训练集 / 推理 recipe / DNSMOS 偏好都可能影响结果,不作年代因果归因)。它至今被引用是因为 FullSubNet 家族在 DNS Challenge 2020 数据集上是学界广泛沿用的强 baseline,后续论文都以 FullSubNet 家族对照;FullSubNet+ 是 2022 改进版

三家取舍

  • FRCRN:ModelScope 上一行 pipeline 直接跑通,本文三家里接入成本最低;如果业务链路已经在 ModelScope / 中文栈内,是较低摩擦的选择
  • FullSubNet+ · 学界主流对照 baseline ------ 现代跑分不占优,但引用它是学术必要(跟你的方案对比,读者要看到 FullSubNet 家族数字)
  • MP-SENet · 相位建模路线代表 ------ 用独立 decoder 显式预测相位是它的核心亮点;在本文 case01 上 OVR 略高,是否对应"音乐 / 高 SNR 场景更强"需更多样本验证。推理坑:默认脚本对长音频 OOM,生产要包分段 wrapper

服务端档的定位 :权重 55-100 MB 起步,依赖 PyTorch 全家桶,单条 20 s 音频 GPU 上推理 200 ms - 1 s。本文这套 Python 离线调用不等于可以直接 in-loop 实时通话(FRCRN 论文有因果版 + 30 ms 延迟口径,但是否能上实时通话取决于流式实现、chunking、端到端延迟预算和硬件)。业务场景:离线批处理、播客后期、直播录制清理、ASR 前置 ------ 有 GPU、有质量诉求、不 in-loop 实时。


benchmark 复现口径 :本文 5 case 各 20 s,采样率原 48 kHz mono;三家统一 resample 到 16 kHz 推理,输出直接送 DNSMOS sig_bak_ovr.onnx(P.835 primary)打分。case 图 STFT 展示均为 16 kHz 频段(0-8 kHz),与 DNSMOS 评估口径一致。DNSMOS 对剪切 / 音乐残留 / 瞬态伪影这类听感缺陷的敏感度有限,正文结论仅覆盖打分层面。

环境 / 版本 :Ubuntu 22.04 · Python 3.11 · torch 2.1.2 + CUDA 12.1 · GPU RTX 4090D 24 GB · modelscope[audio] 1.16.x(FRCRN pipeline · ModelScope 侧 checkpoint 自动拉)· hit-thusz-RookieCJ/FullSubNet-plus 主分支(本文分数对应 2026-06 拉取的主分支快照 · 未固定 commit · 精确复现建议记录 git rev-parse HEAD )· Google Drive checkpoint 1UJSt1G0P_aXry-u79LLU_l9tCnNa2u7C · yxlu-0102/MP-SENet 主分支(同上,2026-06 快照 · 未固定 commit)· checkpoint = best_ckpt/g_best_dns · DNSMOS ONNX 走 官方仓库 DNSMOS/DNSMOS/sig_bak_ovr.onnx · librosa 0.10 做 resample。

相关推荐
Niuguangshuo1 小时前
RNNoise:极小体积的实时降噪 baseline
降噪
dong_junshuai1 小时前
每天一个开源项目#74 OpenViking:3万星Agent上下文数据库
开源·github·agent
小弥儿2 小时前
GitHub今日热榜 | 2026-08-20:Agent 上下文数据库接棒
数据库·学习·开源·github
分布式存储与RustFS2 小时前
给 Kubernetes 找一个对象存储后端:RustFS Helm 部署 + 应用接入实录
云原生·kubernetes·开源·对象存储·分布式存储·s3·rustfs
YANYIyes2 小时前
闲得慌自研「手机局域网遥控电脑」开源项目,零密钥安全架构设计
开源
FIT2CLOUD飞致云4 小时前
智能运维如何落地?WorkBuddy+ JumpServer Skills给你答案
运维·开源·1panel·运维面板
m4Rk_4 小时前
【论文阅读】Agent 记忆机制(45):ReMemR1——让长期上下文 Agent 可以回溯历史记忆进行非线性推理
论文阅读·人工智能·学习·开源·github
大模型丫丫16 小时前
RAGFlow:开源、可深度定制的企业级 RAG 应用开发引擎
开源·rag