评估指标说明:STOI、PESQ、LSD等分数含义解析

你有没有遇到过这种情况——模型生成的音频听起来“怪怪的”,但又说不清是哪里出了问题?🤔 是语音模糊?音色失真?还是干脆就“不像人声”?这时候,靠耳朵听已经不够用了。我们需要一把“尺子”,来量化声音的质量。

在AI音频生成的世界里,这把“尺子”就是客观评估指标。尤其是当你在开发像 ACE-Step镜像模型 这类融合文本到音乐、旋律到歌声的复杂系统时,仅靠主观打分(比如MOS)简直是杯水车薪。试想一下,每天跑几百个实验,难道要请一屋子人挨个听?🙈 不现实!

于是,STOI、PESQ、LSD 就成了我们最常调用的“质检三剑客”。它们不说话,却能告诉你:“这段音频,到底差在哪。”


STOI:听得清吗?可懂度的黄金标尺 🎯

先问一个关键问题:用户能不能听清楚内容?

别小看这个问题。在语音增强、去噪、TTS甚至歌声合成中,“听不清”是最致命的失败。而STOI(Short-Time Objective Intelligibility),正是专门为此设计的指标。

它模拟的是人耳对语音结构的时间-频率敏感性。简单来说,它会把原始语音和生成语音切成一小段一小段(25ms帧长),然后在不同频率子带里比对它们的相关性。这些子带的设计,其实是在模仿人类耳蜗的滤波特性👂。

最终输出一个 [0,1] 之间的值——越接近1,说明语音越清晰、越容易被理解。研究表明,STOI 和人类实际听写正确率的相关性高达 0.9以上!这意味着,如果你的模型输出STOI从0.6提升到0.8,那真实用户很可能真的“更容易听懂了”。

不过,STOI也有它的“盲区”👇
- ❌ 它不管“好不好听”,只管“能不能听清”;
- ❌ 对相位完全无感,两个频谱一样但相位乱掉的音频,它照样给高分;
- ❌ 基本不适合纯音乐评估——毕竟没有语言结构,何谈“可懂度”?

所以,在处理含人声的歌曲或旁白时,STOI非常有用;但如果是纯钢琴曲?那就别浪费计算资源了。

顺便提一句,使用前一定要对齐音频!哪怕错开几十毫秒,STOI也会“暴走”💥。推荐配合DTW(动态时间规整)做预对齐,效果更稳。

import numpy as np
from pystoi import stoi

fs = 16000
clean = np.random.randn(fs * 4)
noisy = clean + 0.1 * np.random.randn(len(clean))

min_len = min(len(clean), len(noisy))
score = stoi(clean[:min_len], noisy[:min_len], fs, extended=False)
print(f"STOI Score: {score:.3f}")  # 比如 0.782 → 听得比较清楚

💡 小贴士:在训练过程中监控STOI趋势,如果突然下降,可能是噪声估计模块出问题了,或者注意力机制“漏掉了”某些关键音素。


PESQ:听起来舒服吗?感知质量的“拟人裁判” 🧠

如果说STOI是“听力考试判卷老师”,那PESQ就是那个真正坐下来听你录音的“普通听众”。

PESQ(Perceptual Evaluation of Speech Quality)是由ITU-T标准化的权威方法(P.862),目标只有一个:预测人类主观打分(MOS)。它的输出范围通常是1.0(极差)到4.5(极好),和我们常说的MOS五分制高度对应。

它是怎么做到的?靠的是复杂的心理声学建模🧠:
- 模拟掩蔽效应(强音盖住弱音)
- 考虑频率非线性响应
- 处理时间延迟与抖动
- 识别咔嗒声、断续、回声等典型失真

举个例子,你的模型可能生成了一段看似平滑的语音,但因为解码器步长不对齐,出现了微小断裂。这种细节人耳很敏感,传统SNR根本发现不了,但PESQ能精准捕捉到,并给出低分警告⚠️。

而且它还挺“聪明”——自带时间对齐功能,允许±100ms偏移补偿,省去了手动对齐的麻烦。支持窄带(NB)和宽带(WB)模式,对于现代AI生成的高清语音,建议一律用 'wb' 模式测试。

当然,优点背后也有代价:
- ⏱️ 计算慢:比STOI和LSD都耗时,不适合每轮迭代都跑;
- 📦 兼容性坑:存在v1.0和v2.0版本差异,务必统一工具链;
- 🚫 只认语音:音乐、环境音、打击乐……统统无效。

但它依然是语音类任务的“黄金标准”。尤其是在TTS、语音修复、变声系统中,PESQ几乎成了发布前必过的关卡。

from pesq import pesq
import numpy as np

fs = 16000
ref = np.sin(2 * np.pi * 500 * np.arange(fs * 2) / fs)
deg = ref + 0.1 * np.random.randn(len(ref))

score = pesq(fs, ref, deg, 'wb')
print(f"PESQ Score (WB): {score:.3f}")  # 比如 3.4 → 中上水平

🔍 实战经验:当PESQ提升但用户反馈“听着假”时,可能是模型过度平滑导致缺乏自然波动。这时候可以引入韵律损失或对抗训练来改善。


LSD:频谱像不像?工程师最爱的“显微镜” 🔬

如果说PESQ像一位挑剔的听众,那LSD(Log-Spectral Distance)更像是个严谨的工程师,拿着放大镜检查每一个频点。

它的逻辑极其直接:
👉 把两段音频都转成对数功率谱;
👉 算每一帧的欧氏距离;
👉 最后取均方根,单位是dB。

公式也不复杂:
$$
\text{LSD} = \sqrt{ \frac{1}{T} \sum_{t=1}^{T} \frac{1}{F} \sum_{f=1}^{F} \left( \log|S(f,t)|^2 - \log|\hat{S}(f,t)|^2 \right)^2 }
$$

数值越小越好,一般低于2dB就算不错,超过6dB就可能明显听出失真。

LSD最大的优势是什么?快!✅
因为它不需要复杂的感知模型,完全可以放在GPU上批量跑,甚至还能嵌入训练流程作为可微损失(只要你用可微STFT)。在歌声合成、音色迁移这类任务中,它是监控频谱保真度的第一道防线。

而且它不挑食🍽️——不仅能用于语音,也能评估乐器音色、哼唱重建、泛音结构保留等情况。只要你想知道“频谱有没有跑偏”,LSD都能给你答案。

但它也有明显的短板:
- 😵 相位失真看不见:两个频谱完全一致但相位混乱的音频,LSD会误判为“完美”;
- 🔊 高频噪声拉胯:一点点高频嘶嘶声就能让LSD飙升;
- 🧩 缺乏心理权重:没考虑人耳对不同频段的敏感度差异。

所以在实际项目中,我通常把它当作“初步筛选器”——LSD太高?赶紧查声码器或潜空间重建模块。但如果LSD很低但听着不舒服?那就得上PESQ进一步诊断了。

import torch
import torchaudio

def compute_lsd(ref_audio, gen_audio, n_fft=1024, hop_length=256, win_length=1024):
    spec_fn = torchaudio.transforms.Spectrogram(
        n_fft=n_fft, hop_length=hop_length, win_length=win_length,
        power=2.0, normalized=True
    )
    ref_spec = spec_fn(ref_audio)
    gen_spec = spec_fn(gen_audio)

    eps = 1e-10
    ref_lps = torch.log10(ref_spec.pow(2) + eps)
    gen_lps = torch.log10(gen_spec.pow(2) + eps)

    lsd_per_frame = torch.sqrt(torch.mean((ref_lps - gen_lps) ** 2, dim=-2))
    lsd = torch.sqrt(torch.mean(lsd_per_frame ** 2, dim=-1))
    return lsd.item()

# 示例
waveform_ref = torch.randn(16000)
waveform_gen = waveform_ref + 0.05 * torch.randn_like(waveform_ref)
lsd_score = compute_lsd(waveform_ref.unsqueeze(0), waveform_gen.unsqueeze(0))
print(f"LSD Score: {lsd_score:.3f} dB")  # 比如 1.23 → 很接近

💡 工程建议:在训练日志中同时记录LSD和PESQ,形成“工程-感知”双维度监控。若LSD降而PESQ升 → 成功!若LSD降但PESQ也降 → 可能引入新 artifacts。


实际落地:如何构建你的“音频质量仪表盘” 🛠️

ACE-Step镜像模型 的研发过程中,我们早就不再依赖单一指标了。相反,我们搭建了一个多维评估闭环:

[输入] → [扩散模型生成] → [波形输出] → [STOI/PESQ/LSD并行计算]
                                          ↓
                                 [可视化面板 & 告警机制]
                                          ↓
                               [自动触发模型回滚或调参]

具体工作流是这样的:

  1. 准备高质量参考集:精选100+真实音乐片段,涵盖男女声、独唱、合唱、器乐等类型;
  2. 统一预处理:重采样至16kHz,峰值归一化至[-1,1],避免增益干扰;
  3. 智能启用指标
    - 含人声轨道 → 同时跑 STOI + PESQ + LSD
    - 纯器乐 → 主要看 LSD,辅以人工抽查
  4. 分段评估:按乐句切分,避免长尾噪声拖累整体得分;
  5. 趋势分析:绘制三项指标的历史曲线,识别异常波动;
  6. 决策支持:设置阈值告警,例如:
    - STOI < 0.7 → 触发可懂度优化流程
    - PESQ 下降 > 0.3 → 暂停上线评审
    - LSD > 4.0 → 回查声码器配置

我们还总结了一些典型的“指标组合诊断法”:

现象 可能原因 应对策略
PESQ↑ + LSD↓ 质量提升,频谱更准 ✅ 保存模型
PESQ↓ + STOI↓ 明显失真,听不清 🔧 检查去噪/重建模块
PESQ↑ + LSD↑ 过度平滑,牺牲细节 ⚖️ 调整损失权重
STOI↓ + LSD↑ 可懂度受损且频谱偏离 🔄 重新设计潜空间约束

有趣的是,有一次我们发现模型在某些方言上PESQ很高,但用户反馈“听着别扭”。深入分析才发现,虽然频谱干净,但语调节奏被“标准化”了,失去了地方特色。这说明:再好的客观指标,也不能完全替代真实场景验证。🎯


写在最后:指标是工具,不是终点 🌟

STOI、PESQ、LSD,每一个都有自己的视角和局限。
它们不是魔法数字,而是帮助我们理解模型行为的“翻译器”。

ACE-Step 这样的AI音乐生成系统中,我们的终极目标从来不是“刷高某个分数”,而是让每个人都能轻松创作出既清晰、又好听、又有表现力的作品。🎵

这些指标的价值,正在于它们能把抽象的“好听”拆解成可测量、可优化的具体维度。它们让我们在黑暗中调试模型时,至少手里有盏灯💡。

未来,我们也期待更多面向音乐的专用指标出现——比如“旋律可辨识度得分”、“情感传达指数”、“节奏稳定性评分”等等。也许有一天,我们会有一个真正的“音乐版PESQ”。

但在那天到来之前,不妨先用好这三把“尺子”,一步步逼近那个理想的声音世界吧。🎧✨

Logo

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。

更多推荐