外观
音频 DSP 特征工程与四大 ONNX 模型深度解析
本文档深入剖析 onnx-platform/funasr-asr-server 中用纯 Rust 实现的 Kaldi 兼容前端特征提取流程,以及平台内置的四大深度学习声学/语音模型的运作机理。
1. 纯 Rust 音频前端特征提取流程 (frontend.rs)
深度神经网络无法直接消费原始时域振幅采样点(PCM 波形)。必须先将时域信号转换为模仿人类听觉特征的时频图(Mel-Spectrogram)。 整个提取流程严格对齐工业界标准的 Kaldi 与 FunASR:
text
原始 PCM16 LE 字节流
|
v
[1. 字节解包与定点转浮点] -> [-32768.0, 32768.0]
|
v
[2. 预加重滤波 (Pre-emphasis)] -> y[n] = x[n] - 0.97 * x[n-1] (补偿高频衰减)
|
v
[3. Hamming 加窗分帧] -> 窗长 25ms (400采样), 帧移 10ms (160采样)
|
v
[4. 512 点实数快速傅里叶变换 (FFT)] -> Cooley-Tukey 蝶形运算, 产出 257 维功率谱
|
v
[5. 80 维 Mel 三角滤波器组] -> 模拟人耳非线性感知, 输出 80 维 Log-Mel 特征
|
v
[6. LFR 动态拼帧 (Low Frame Rate)] -> 每 7 帧拼接为 560 维, 每 6 帧跳跃下采样
|
v
[7. CMVN 均值方差归一化] -> 加载 am.mvn, 消除麦克风增益与设备差异
|
v
送入声学神经网络推理1.1 核心算法定性概述
- 预加重 (Pre-emphasis):高频声音在空气中衰减很快,语音的高频信噪比通常偏低。通过一阶高通滤波器提升高频分量,使整个频谱能量更加平坦;
- Hamming 窗:直接把音频切段会导致边缘产生频谱泄漏(假高频)。Hamming 窗两端渐变平滑,消除边缘突变;
- 512 点实数 FFT:纯 Rust 内置 Cooley-Tukey 快速傅里叶变换算法,在启动时预计算旋转因子(Twiddle Factors)与位反转表(Bit Reversal),避免运行时重复三角函数计算;
- Mel 滤波器组:人耳对 1000Hz 以下的低频极其敏感(差 100Hz 就能明显听出音调差异),而对 5000Hz 以上的高频分辨率很低。Mel 刻度模仿此特性,在低频布置密集滤波器,高频布置稀疏滤波器,最终压缩为 80 维特征;
- LFR 拼帧与下采样:10ms 的一帧音频信息量过小,容易导致模型时域计算冗余。LFR 将上下文 7 帧拼接($7 \times 80 = 560$ 维),每 6 帧输出一步(帧率从 100Hz 降为约 16.7Hz),大幅降低模型推理开销。
2. FSMN-VAD 语音活动检测 (vad.rs)
2.1 什么是 FSMN?
FSMN(Feedforward Sequential Memory Networks)是一种轻量高效的前馈时序记忆网络。它不像传统 RNN/LSTM 需要沿时间步串行递归传递隐藏状态,而是通过在网络层中引入“有限冲激响应(FIR)时域记忆块”,既能捕捉长程上下文,又能像全连接网络一样进行并行推理。
2.2 4 层 Memory Cache 机制
在流式推流中,音频是一包一包到达的。为了让流式推流的结果与离线整段识别完全一致,FSMN-VAD 模型导出了 4 层 Cache 张量:
- 每一包音频推理时,输入必须携带上一包计算出的
in_cache0 ~ in_cache3; - 推理结束后,模型吐出下一包所需的
out_cache0 ~ out_cache3,循环保存; TwoPassSession在会话生命周期内严格维护该缓存,直到一句话结束时才做复位。
2.3 状态机判决
模型每帧输出语音与静音的概率分布,VadStateMachine 通过双门限滑动窗口平滑:
- 当人声概率持续若干帧超过阈值:触发
speech_started; - 当静音概率在说话后持续超过指定时长(如 800ms):判定为说话人停顿切句,触发
speech_completed。
3. Paraformer-Online 与 CIF 连续积分点火器 (online.rs)
Paraformer 是阿里达摩院提出的非自回归(Non-Autoregressive)端到端语音识别模型。相比传统的自回归模型(如 Whisper 一次预测一个字、后面的字依赖前面的字),Paraformer 能够一次性并行预测一整句话的所有汉字,推理速度提升数倍。
而在流式场景下,系统必须边听边出字。这通过 CIF(Continuous Integrate-and-Fire,连续积分点火器) 实现:
text
流式音频特征帧序列 (经过 Encoder 提取)
帧 1 (alpha=0.3)
帧 2 (alpha=0.4)
帧 3 (alpha=0.5) ---> 累积 0.3 + 0.4 + 0.5 = 1.2 >= 1.0 (达到阈值!)
|
v
【触发点火 (FIRE!)】
|
+---> 加权聚合成当前汉字的声学向量
+---> 送入 Decoder 解码出 1 个汉字 (例如 "你")
+---> 余数 0.2 保留到下一轮累加- 工作机制:
- Encoder 每帧预测一个权重 $\alpha_t \in [0, 1]$,代表当前帧含有多少比例的字边界信息;
CifSearcher持续累加权重并按权重线性融合声学特征向量;- 一旦累积值达到 1.0,即代表一个发音单元(字/词)结束,触发点火(Fire),发射声学表征至 Decoder 实时预测汉字,并立即将文字下发给前端作为 Partial 结果;
- 当收到客户端终结帧(
is_final == true)且剩余累加值达到尾部门限(默认 0.8)时,强制发射最后一个字,防止吞尾音。
4. Paraformer-Large 离线大模型 (paraformer.rs)
虽然 Paraformer-Online + CIF 能做到极低延迟的 Partial 文字实时上屏,但由于流式模型在听当前字时看不到未来的音频,其在长同音词、专业术语或复杂语境下的容错率略低于全局模型。
因此,在 2-Pass 流水线的句尾切句时,系统激活 Paraformer-Large:
- 全局双向自注意力机制:该模型拥有全局时域视野,当前发音可以同时结合前后的语义上下文进行消歧;
- 贪心解码 (Greedy Search):对输出的预测矩阵执行最大概率索引提取,并结合
tokens.json快速映射回汉字; - 作用:产出的 Final 文本质量极高,覆盖并替换此前实时显示的 Partial 字幕。
5. CT-Transformer 标点恢复 (punc.rs)
语音识别输出的原生文本通常是不带标点的“流水账”(例如:“你好我想咨询一下业务明天可以吗”)。
CT-Transformer(Controlled Time-delay Transformer)负责智能断句并插入标点:
- 中文切词:使用纯 Rust 实现的
jieba-rs对文本分词; - 嵌入与预测:模型根据前后词语义关系,预测词与词之间应当出现的标点标记(无标点、逗号、句号、问号等);
- 文本重组:将预测出的标点回填插入到字词之间,生成人类阅读友好的标准文本格式(例如:“你好,我想咨询一下业务,明天可以吗?”)。