unilm GSLM 语音离散单元质量评估:基于 ABX 度量的特征转储与评分完整流程
【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm
本文围绕 GSLM(Generative Spoken Language Modeling)示例代码中的 ABX 评估方案展开,讲解如何对 Speech-to-Unit 量化后的离散语音单元进行音位区分度、词区分度与类词性(ABX)三项指标的度量。读完本文,你将掌握从测试集声学特征提取、K-means 量化特征转储(dump),到调用 Libri-light 的eval_ABX.py脚本计算最终 ABX 分数的完整可复现流程,并理解各命令行参数与底层源码调用链的对应关系。
1. ABX 度量在 GSLM 评估体系中的位置
GSLM 系统由三个组件构成:speech2unit(语音到离散单元的量化)、ulm(单元语言模型)、unit2speech(单元到语音的合成),定义见 GSLM 总览文档。为了评估"离散单元到底好不好",GSLM Metrics 文档 给出了三类互补的度量:
- ASR 指标:用 ASR 模型把合成语音转写成文本,再用基于文本的指标(如 BLEU、WER)评估,适合端到端地看系统最终效果;
- ABX 指标:直接在量化表示上评估"音位类别分离得有多好",即本节的主题;
- sWUGGY / sBLIMP:零样本语义类判别度量。
ABX 由三项子指标组成:
- A(phoneme discriminability):同一语音类别内样本应该彼此更接近;
- B(word discriminability):不同词之间应该彼此更远离;
- X(word-likeness):词内平均距离应小于词间平均距离。
这三项合起来刻画了离散单元在"类内紧致、类间分离、类间一致性"三个维度上的质量。ABX 评估的完整生命周期(life cycle)包含四个步骤:
- 训练声学模型(或复用现成声学模型);
- 通过 K-means 聚类模型学习语音的量化;
- 使用训练好的聚类计算 ABX 所需的离散特征;
- 利用 Libri-light 的 ABX 评估脚本在离散特征上计算 ABX 分数。
本节聚焦后两步,即假设前两步已经完成(已有声学模型 checkpoint 和 K-means 量化模型),只做特征提取与 ABX 评分计算。
2. 前置准备:Libri-light 环境与数据
ABX 评分依赖 Libri-light 仓库提供的eval_ABX.py脚本及其配套的 ABX 评估数据(.item文件)。需要:
- 按 Libri-light 官方说明安装运行环境;
- 按其 ABX 评估章节的指引下载所需的
ABX_data数据项(每个测试子集一个.item文件,如eval/ABX_data/dev-clean.item)。
这些文件位于 Libri-light 仓库中,本文不重复其安装细节,只关注 unilm 仓库侧的对接方式。
此外,特征转储步骤需要一个 manifest 文件。从源码 clustering/utils.py 的get_audio_files实现可以确认,manifest 的格式为:
<path_of_root_directory_containing_audio_files> <relative_path_of_audio_file_1>\t<number_of_frames_1> <relative_path_of_audio_file_2>\t<number_of_frames_2> ...即第一行为存放音频的根目录,其后每行为"相对音频路径 \t 帧数"两列制表符分隔的内容。该格式与 speech2unit 文档 中训练 K-means 时使用的 manifest 完全一致。源码中的assert len(items) == 2也表明每行必须严格为两列,否则解析会直接报错。
3. 转储量化特征(Dumping quantized features)
ABX 计算的第一步,是转储测试集每段音频对应的量化后表示(而非原始连续声学特征)。仓库提供的脚本是 dump_abx_feats.py,调用方式如下:
TYPE="hubert" LAYER=6 CKPT_PATH="<PATH_TO_HUBERT_MODEL_CHECKPOINT_FILE>" KM_MODEL_PATH="<PATH_TO_PRETRAINED_KM_MODEL_FILE>" SUBSET="dev-clean" MANIFEST="<PATH_TO_MANIFEST_FOR_LS_DEV-CLEAN>" DATA_DIR="<PATH_TO_DIR_TO_STORE_FEATURES>/$SUBSET" PYTHONPATH=. python examples/textless_nlp/gslm/metrics/abx_metrics/dump_abx_feats.py \ --feature_type $TYPE \ --kmeans_model_path $KM_MODEL_PATH \ --checkpoint_path $CKPT_PATH \ --layer $LAYER \ --manifest_path $MANIFEST \ --out_dir_path $DATA_DIR \ --extension ".flac"3.1 参数逐项说明
结合 dump_abx_feats.py 的get_parser函数,各参数的约束如下:
| 参数 | 必填 | 取值 / 默认 | 说明 |
|---|---|---|---|
--feature_type | 是 | logmel/hubert/w2v2/cpc四选一 | 声学特征类型,决定使用哪个特征读取器 |
--kmeans_model_path | 是 | K-means 模型文件路径 | 用joblib加载的量化模型(km.bin) |
--manifest_path | 否 | manifest 文件路径 | 根目录 + 音频相对路径与帧数,格式见上文 |
--checkpoint_path | 否 | 声学模型 checkpoint | 预训练声学模型权重,如 HuBERT-Base 的.pt文件 |
--layer | 否 | 整数,默认-1 | 从声学模型的第几层抽取特征(-1为最后一层) |
--out_dir_path | 是 | 输出目录 | 每段音频生成一个.npy文件存放于此 |
--extension | 否 | 默认.flac | manifest 中音频文件扩展名,用于拼接输出文件名 |
其中--feature_type的四种选择与 speech2unit/README.md 中支持的声学模型一一对应,该文档还给出了 Modified CPC、HuBERT-Base、Wav2Vec 2.0 三种预训练声学模型以及 KM50~KM500 各档 K-means 量化模型的下载清单,KM_MODEL_PATH可直接从中选取。
3.2 源码层面的处理流程
dump_abx_feats.py的main函数流程非常清晰,可分为四段:
声学特征提取。调用 pretrained/utils.py 的
get_features(feature_type, checkpoint_path, layer, manifest_path, sample_pct=1.0, flatten=False)。get_features内部通过get_feature_reader按feature_type分发到HubertFeatureReader、Wav2VecFeatureReader、LogMelFeatureReader或CpcFeatureReader,逐文件解析 manifest(第一行为 root,其余行取第一列拼接为完整路径)、依次读取音频并抽取特征,最终以未展平的列表形式返回(flatten=False),保证"一段音频对应一个特征矩阵"。以 hubert_feature_reader.py 为例,HubertFeatureReader通过fairseq.checkpoint_utils.load_model_ensemble_and_task加载模型,对超长音频按max_chunk=1600000分块调用model.extract_features(..., output_layer=self.layer)后再拼接,从而得到指定--layer层的隐藏表示序列。加载 K-means 模型。用
joblib.load读取--kmeans_model_path指向的聚类模型并关闭verbose。该模型由 cluster_kmeans.py 训练得到——脚本使用sklearn.cluster.MiniBatchKMeans(--num_clusters默认 50,--init默认k-means++),与 speech2unit 文档中"训练 K-means"和"用 K-means 量化"两步产出的是同一类文件。逐段预测 + one-hot 编码。对每段音频特征矩阵执行
kmeans_model.predict(feats)得到帧级聚类下标序列pred,再经one_hot(pred, kmeans_model.n_clusters)展开为形状(T, n_clusters)的 0/1 矩阵。也就是说,转储到磁盘的特征是离散单元的 one-hot 编码,这正是 ABX 评估要求输入"类别表示"的原因——ABX 的相似度计算(词内/词间距离)必须在离散类别空间上进行,而不在连续声学空间上。写盘。输出文件名为"音频文件名去掉扩展名 +
.npy"(base_fname = os.path.basename(fnames[i]).rstrip(args.extension)),随后np.save保存 one-hot 矩阵。这些.npy文件名与 Libri-light.item文件中登记的条目名相互对应,是下一步评分时的匹配键。
4. 使用 Libri-light 计算 ABX 分数
在 Libri-light 环境就绪的前提下,用其eval_ABX.py脚本对上一步的.npy特征目录打分:
LIBRILIGHT_ROOT="<PATH_TO_LIBRILIGHT>" SUBSET="dev-clean" DATA_DIR="<PATH_TO_DIR_TO_STORE_FEATURES>/$SUBSET" ITEM_FILE_PATH="$LIBRILIGHT_ROOT/eval/ABX_data/$SUBSET.item" OUT_DIR="<PATH_TO_DIR_TO_STORE_ABX_SCORES>/$SUBSET" FILE_EXTENSION=".npy" FEATURE_SIZE=0.02 # depends on the model used PYTHONPATH=$LIBRILIGHT_ROOT \ python $LIBRILIGHT_ROOT/eval/eval_ABX.py \ $DATA_DIR \ $ITEM_FILE_PATH \ --file_extension $FILE_EXTENSION \ --feature_size $FEATURE_SIZE \ --out $OUT_DIR \ --mode "all"关键参数说明:
位置参数:第一个是上一步输出的特征目录
DATA_DIR,第二个是该子集的.item文件(dev-clean子集对应dev-clean.item),它登记了参与评分的词条与对应音频条目;--file_extension:特征文件扩展名,因dump_abx_feats.py固定输出.npy,此处为.npy;--feature_size:单帧特征的时长(秒),必须与特征帧率匹配:- HuBERT 与 Wav2Vec 2.0:
FEATURE_SIZE=0.02(对应 50 Hz 帧率); - CPC 与 Log Mel:
FEATURE_SIZE=0.01(对应 100 Hz 帧率)。
帧率不一致会导致词内/词间距离的时间对齐出现偏差,进而影响 A/B/X 各项数值的可信度;
- HuBERT 与 Wav2Vec 2.0:
--out:ABX 分数输出目录,按子集组织(如<ABX_SCORES>/dev-clean);--mode "all":一次性计算 A、B、X 全部三项指标;GPU 加速:若可用 GPU,加上
--cuda标志可显著加快计算。
5. 流程小结与相关文件索引
整体数据流可以概括为:
音频 manifest ──(声学模型 @ --layer)──> 连续特征 (T, D) ──(K-means predict + one_hot)──> 离散 one-hot (T, n_clusters) ──> 逐段 .npy ──(Libri-light eval_ABX.py + .item)──> A / B / X 分数需要牢记的两个易错点:其一,dump_abx_feats.py输出的文件名必须能被.item文件中的条目匹配到,因此 manifest 中的文件名与 Libri-light ABX 数据的命名需保持一致(如dev-clean子集);其二,FEATURE_SIZE必须随--feature_type切换(0.02 vs 0.01),这是原文档中特别强调的依赖项。
相关代码与文档索引,便于继续深入:
- 评估流程说明(本文主体来源):abx_metrics/README.md
- 特征转储脚本:dump_abx_feats.py
- 三类度量的总说明(ASR / ABX / sWUGGY):metrics/README.md
- 声学模型与 K-means 模型下载清单:speech2unit/README.md
- K-means 训练脚本:clustering/cluster_kmeans.py
- 特征提取公共工具(manifest 解析、按模型类型分发):pretrained/utils.py、clustering/utils.py
【免费下载链接】unilmLarge-scale Self-supervised Pre-training Across Tasks, Languages, and Modalities项目地址: https://gitcode.com/GitHub_Trending/un/unilm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考