ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

基于 DeepSpeech2 特征空间的 FDSD 语音质量评估:google-research ged_tts 中 Fréchet Deep Speech Distance 重实现的原理与实战

2026/9/21 1:23:14 拓冰建站 浏览量
基于 DeepSpeech2 特征空间的 FDSD 语音质量评估:google-research ged_tts 中 Fréchet Deep Speech Distance 重实现的原理与实战 基于 DeepSpeech2 特征空间的 FDSD 语音质量评估google-research ged_tts 中 Fréchet Deep Speech Distance 重实现的原理与实战【免费下载链接】google-researchGoogle Research项目地址: https://gitcode.com/gh_mirrors/go/google-researchFréchet Deep Speech DistanceFDSD是语音生成领域用于衡量真实语音与合成语音分布差异的经典自动评估指标。本文以ged_tts/fdsd/目录下 Google Research 提供的官方重实现为对象完整讲解 FDSD 的数学原理、DeepSpeech2 特征提取器的架构细节、预训练 checkpoint 的加载方式以及compute_fdsd.py命令行的完整使用方法。读完本文你将掌握如何在本地对任意两组 WAV 音频样本一键计算 FDSD 分数并理解分数从波形到最终数值的完整数据流。FDSD 是什么从原始论文到本仓库的重实现FDSDFréchet Deep Speech Distance最初由 Bińkowski 等人在 2019 年的论文《High fidelity speech synthesis with adversarial networks》arXiv:1909.11646中提出。其核心思想借鉴了图像生成领域广泛使用的 FIDFréchet Inception Distance先用一个预训练模型把样本映射到高维语义特征空间再在该特征空间中用 Fréchet 距离度量两组样本分布之间的差异。区别在于 FDSD 将特征提取器从图像领域的 Inception 网络换成语音识别领域的 DeepSpeech2从而让评估结果更贴近语音内容与发音质量的语义维度。本仓库并未直接使用第三方实现而是提供了独立的官方重实现位于ged_tts/fdsd/目录见 fdsd/README.md。需要特别说明的是该重实现不只是简单的脚本封装由于原版 DeepSpeech2 checkpoint 的 metagraph 依赖 CuDNN 的 GRU 算子无法在其他加速器上运行作者使用 Keras 层重新搭建了与原始权重完全兼容的模型结构依据 ds2_encoder.py 中的模块说明这也是本实现最值得研究的部分。仓库文件结构入口、评估器与依赖ged_tts/fdsd/ ├── README.md # 使用说明本文主体所依据的文档 ├── compute_fdsd.py # 命令行入口数据集构建 指标计算 ├── requirements.txt # 依赖清单 └── eval/ ├── __init__.py # 导出 NoOpScorer 与 DS2Scorer ├── ds2_encoder.py # DeepSpeech2 模型重实现特征前端 编码器 ├── scorer.py # Fréchet 距离核心数学实现与 NoOpScorer └── tts_scorer.py # DS2Scorercheckpoint 恢复 FDSD 分数计算其中 eval/init.py 是统一的库导入入口外部代码通过from ged_tts.fdsd.eval import DS2Scorer即可使用评估器compute_fdsd.py则是面向命令行用户的完整流程脚本。整个 FDSD 计算在项目中的作用是充当 GEDSpectral Energy Distance论文《A Spectral Energy Distance for Parallel Speech Synthesis》的实验评估指标——该论文正文中提到的 cFDSDconditional FDSD正是基于本套实现见 ged_tts/README.md。三步跑通 FDSD 评估第一步安装依赖根据 fdsd/README.md先安装依赖。仓库提供的 requirements.txt 包含五个包tqdm tensorflow numpy scipy absltensorflow模型推理与数据管线代码中使用tensorflow.compat.v2API需 TF 2.x 环境numpy/scipy特征统计量均值、协方差与矩阵平方根scipy.linalg.sqrtm计算absl命令行 flags 解析与日志tqdm特征收集时的进度条显示。原文档给出的安装命令为pip install -m requirements.txt需要提醒的是-m是 pip 的以模块方式运行参数安装依赖清单的标准参数应为-r即实际可用的命令是pip install -r requirements.txt第二步准备 DeepSpeech2 预训练 checkpointFDSD 依赖一个已训练好的语音识别模型来提取特征。原文档要求从 Open Seq2Seq 库下载并解压其 DeepSpeech 2 checkpoint即ds2_large模型。compute_fdsd.py 中给出了该 checkpoint 的默认路径与命名约定flags.DEFINE_string(ds2_ckpt, ds2_large/model.ckpt-54800, Path to the DeepSpeech2 checkpoint.)也就是说默认期望在ds2_large/目录下存在model.ckpt-54800这一 checkpoint 文件。若你的文件位置不同通过--ds2_ckpt参数显式指定即可。该 checkpoint 只包含模型权重不含 metagraph因为重实现使用独立搭建的 Keras 网络通过张量名逐层加载权重这一点在下一节权重恢复中详述。第三步运行 compute_fdsd.py准备两个目录各自存放一组 WAV 音频一组为真实/参考音频sample1一组为待评估的合成音频sample2然后执行python3 compute_fdsd.py \ --sample1 /path/to/real_audio \ --sample2 /path/to/fake_audio \ --ds2_ckpt ds2_large/model.ckpt-54800脚本运行时会依次打印三类信息依据 compute_fdsd.py 的主流程[i] Constructing datasets.、[i] Restoring DS2 checkpoint.、[i] Collecting samples.最后输出[i] FDSD: %.3f格式的分数。FDSD 数值越小说明两组样本在 DeepSpeech2 特征空间中的分布越接近即合成语音与真实语音的可区分度越低、质量越高。compute_fdsd.py支持的完整命令行参数如下依据 compute_fdsd.py参数类型默认值说明--sample1str无必填第一组音频样本所在目录--sample2str无必填第二组音频样本所在目录--ds2_ckptstrds2_large/model.ckpt-54800DeepSpeech2 checkpoint 路径--batch_sizeint64评估时的批大小输入数据约定WAV 目录与样本数量一致性compute_fdsd.py对输入有两个硬性约束理解它们可以避免踩坑。约束一目录下必须全部是.wav文件。数据集构建函数make_wave_dataset通过os.path.join(path, *.wav)拼出文件匹配模式用tf.data.Dataset.list_files枚举目录下所有 WAV 文件再经tf.audio.decode_wav解码为波形张量依据 compute_fdsd.py。约束二两组样本数量必须相等。脚本在构建完两个数据集后立即比较样本数不一致会直接抛出UsageErrorif n_sample1 ! n_sample2: raise app.UsageError(Both sample sets must have the same number of waves (%d and %d). % (n_sample1, n_sample2))依据 compute_fdsd.py。此外DS2Scorer.compute_scores内部还会做一次兜底即使数量不同例如通过库 API 直接调用时也会取min(n_fake, n_real)个样本参与计算并打印警告依据 tts_scorer.py。特征收集阶段使用tqdm显示进度并把每个样本的激活单独剥离出来逐条存入列表供后续统计计算使用依据 compute_fdsd.py。工作原理从波形到 FDSD 分数的完整数据流整个 FDSD 计算可以拆成四段特征提取器搭建 → 波形预处理 → checkpoint 权重恢复 → Fréchet 距离计算。1. DS2Scorer 与 DS2Encoder 模型结构tts_scorer.py 中的DS2Scorer继承了 scorer.py 中的NoOpScorer骨架用DS2Encoder作为实际推理模型并声明只收集pooled_activations这一种输出用于指标计算。DS2Encoder依据 ds2_encoder.py是对 DeepSpeech2Amodei et al., 2016的结构重实现其默认超参数刻意与 Open Seq2Seq 的ds2_large_8gpus_mp配置保持一致结构块默认配置说明卷积层两层((11,41),(2,2),32)、((11,21),(1,2),32)Conv2D BatchNorm ReLUSAMEpadding、无 biasGRU 层5 层每层 800 单元双向 GRUmerge_modeconcattanh 激活 sigmoid 循环激活全连接层1600 单元ReLU 激活的前 logits层代码注释注明本应使用 float16 但 TPU 不支持CTC 层vocab_size29输出 CTCDecoder 所需的 logitsDropout0.5每个 GRU 层之后及全连接层之后施加模型前向__call__返回三个端点endpointsactivationsGRU 输出经全连接映射后的逐帧表示、pooled_activations对时间维度取平均专门为 FDSD 服务、logitsCTC 输出。代码注释明确说明pooled_activations是Frechet DeepSpeech distance 所使用的量依据 ds2_encoder.py。2. 特征前端 represent()从波形到标准化对数幅度谱DS2Encoder.represent方法负责把原始波形转换为模型输入依据 ds2_encoder.py流程如下重缩放波形除以逐样本最大绝对值并乘 32767模拟 16-bit PCM 的幅度范围代码中保留了与 PSF 完全一致的 int16 量化步骤注释但因 TPU 不支持而默认关闭加窗分帧默认采样率 24000 Hz、窗长 0.02 s、窗移 0.01 s即 480 点汉宁窗、240 点步长通过tf.signal.frame分帧STFT因为窗长一般不是 2 的幂代码用scipy.linalg.dft构造 DFT 矩阵做矩阵乘法实现 STFT取幅度谱后计算对数幅度10·log10特征选择与标准化只保留前num_features160个频点再用tf.nn.sufficient_statistics/tf.nn.normalize_moments沿时间与频率轴做全局均值方差标准化。3. checkpoint 权重恢复CuDNN GRU 权重重排这是重实现中最精巧的部分。DS2Scorer.restore先向模型灌入一个形状为[16, 48000, 1]的全 1 批次以触发变量创建然后通过tf.train.load_checkpoint按张量名读取权重依据 tts_scorer.py。卷积、BatchNorm、全连接与 CTC 层的权重按ForwardPass/ds2_encoder/conv1/...、.../fully_connected/...等前缀直接赋值依据 tts_scorer.py。GRU 部分则需要特殊处理原 checkpoint 中的cudnn_gru权重存储格式与 KerasGRUCell不同load_gru_cell函数会把 gates kernel/bias、candidate 的 input/hidden projection 权重重新拼接为 Keras 期望的[kernel, recurrent_kernel, bias]三元组依据 tts_scorer.py。这解释了为什么必须依赖固定 checkpoint 结构——权重是逐张量名对齐的。4. Fréchet 距离计算FID 数学在语音特征空间的迁移DS2Scorer.compute_scores先对两组的pooled_activations分别计算均值向量mu与协方差矩阵sigma依据 tts_scorer.py再调用 scorer.py 中的compute_frechet_inception_distancediff mu1 - mu2 covmean sqrtm(sigma1 · sigma2) # scipy.linalg.sqrtm FDSD diff·diff trace(sigma1) trace(sigma2) - 2·trace(covmean)这套公式与图像领域 FID 完全同源——函数名也保留了compute_frechet_inception_distance的历史命名。从源码注释Pooled activations are used by Frechet DeepSpeech distance可以确认本实现计算的是无条件 FDSD即直接用两组样本池化特征的整体分布差异来衡量生成质量不依赖任何条件标签论文正文中使用的 cFDSD 则是在此基础上的条件化变体。数值稳定性与工程细节奇异协方差处理sigma1.dot(sigma2)可能近乎奇异sqrtm结果含非有限值时会在两个协方差对角线同时加上epsilon1e-6后重算并打印警告日志复数误差防御矩阵平方根可能引入微小虚部代码允许对角线虚部在1e-3容差内并自动取实部虚部不可忽略时直接抛出ValueError而不是静默给出错误分数依据 scorer.py显式类型断言mu必须为 1D 向量、sigma必须为 2D 矩阵且两组形状一致否则直接断言失败避免误用TPU 兼容性取舍模型多处注释提到应使用 float16 但 TPU 不支持说明该实现有意兼顾多种硬件环境依据 ds2_encoder.py。在 GED 论文中的角色与扩展用法FDSD 重实现是《A Spectral Energy Distance for Parallel Speech Synthesis》项目ged_tts/的三大交付物之一与多尺度频谱能量距离distance_function/spectral_ops.py和 GED 玩具示例toy_example并列依据 ged_tts/README.md 的 Source code 一节。论文使用本实现报告了 cFDSD 指标下的生成质量对比因此当你复现该论文或评估同类并行语音合成模型时ged_tts/fdsd即是论文所用指标的官方参考实现。除了命令行用法你还可以把DS2Scorer作为库函数嵌入自己的评估管线from ged_tts.fdsd.eval import DS2Scorer scorer DS2Scorer(ds2_large/model.ckpt-54800) scorer.restore() # 对任意波形批次调用 scorer.infer收集 pooled_activations 后 # 调用 scorer.compute_scores(real_samples..., fake_samples...) 得到 {FDSD: ...}已知限制与注意事项checkpoint 必须自备本仓库不随代码分发 DeepSpeech2 预训练权重首次使用前需从 Open Seq2Seq 库下载ds2_large模型并按默认命名放置或通过--ds2_ckpt指定路径权重按张量名对齐换用其他版本的 DeepSpeech2 checkpoint 时需要核对ForwardPass/ds2_encoder/...、cudnn_gru/...等张量名前缀是否一致否则恢复会失败环境要求 TF 2.x所有模型与数据代码基于tensorflow.compat.v2编写不建议在 TF 1.x 环境中运行样本数量严格一致两个 WAV 目录的文件数必须相同否则命令行会直接报错退出采样率约定特征前端按 24 kHz、窗长 20 ms、窗移 10 ms 的默认参数做 STFT若你的音频采样率不同需要同步调整DS2Encoder构造参数sample_freq、window_size、window_step以保证特征计算与 checkpoint 训练时一致。总体而言ged_tts/fdsd是一个小而完整的评估工具链从 WAV 目录读取、DeepSpeech2 特征提取、checkpoint 权重移植到 Fréchet 距离计算全部开源可查既是复现 GED 论文实验结果的关键部件也可直接移植到其他语音合成项目中充当自动评估指标。【免费下载链接】google-researchGoogle Research项目地址: https://gitcode.com/gh_mirrors/go/google-research创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考