- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
本篇技术指南以 ESPnet 仓库中的 egs2/multimed_st/s2t1/README.md 为主线,系统讲解如何在 ESPnet2 S2T 框架下,基于 MultiMed-ST 医学语音翻译数据集完成英语到德语的语音翻译(Speech Translation, ST)任务,并利用 OWSM v4 small(370M 参数)预训练模型进行下游微调与解码评测。读完本文,你将掌握该 Recipe 的数据准备流程、OWSM 资产准备机制、stage 调度策略、微调参数覆盖方法、德语 ST 解码配置,以及 BLEU/chrF/TER 与 WER/CER/TER 两套评测体系的完整落地方式。
1. 任务总览:在医学语音数据上做英德双向语音翻译
egs2/multimed_st/s2t1是一个面向多语言医学语音翻译数据集 MultiMed-ST 的 ESPnet2 S2T Recipe,核心设定如下:
| 维度 | 配置 |
|---|---|
| 数据集 | MultiMed-ST(医学领域多语言语音翻译语料) |
| 源语言 | 英语(English) |
| 目标语言 | 德语(German) |
| 任务类型 | Speech Translation(st) |
| 预训练模型 | espnet/owsm_v4_small_370M |
该数据集的背景论文为MultiMed-ST: Large-scale Many-to-many Multilingual Medical Speech Translation(arXiv 2504.03546)。Recipe 的核心思路是:不从头训练 S2T 模型,而是复用 OWSM v4 small 预训练模型的 tokenizer、token list、checkpoint 与特征统计量,在医学领域数据上进行轻量微调,并在测试集上与零样本(zero-shot)解码结果做对照。
在 run.sh 中,语言与任务被固定为:
src_lang=eng tgt_lang=deu task=st同时train_set=train、valid_set=valid、test_sets="test"三个数据划分贯穿整个 Recipe,后续所有命令与评测均围绕这三个集合展开。
2. 数据准备:从 Hugging Face 流式下载到 Kaldi 风格数据目录
2.1 整体流程
数据准备由 local/data.sh 与 local/prepare_multimed_st.py 共同实现。流程为:
- 从 Hugging Face 以流式(streaming)方式读取 MultiMed-ST 数据;
- 将每条音频解码为 mono wav 文件;
- 生成 Kaldi 风格的
data/train、data/valid、data/test目录。
数据目录的根路径由 db.sh 中的MULTIMED_ST=downloads控制,即默认下载到本地downloads目录(该变量可在运行前按需修改为自定义路径)。
local/data.sh 的主体逻辑为:
mkdir -p "${MULTIMED_ST}" python local/prepare_multimed_st.py \ --src_lang "${src_lang}" \ --tgt_lang "${tgt_lang}" \ --task "${task}" \ --out_root "${MULTIMED_ST}/${src_lang}_${tgt_lang}_${task}" \ --max_train_samples "${max_train_samples}" \ --max_valid_samples "${max_valid_samples}" \ --max_test_samples "${max_test_samples}" mkdir -p data cp -r "${MULTIMED_ST}/${src_lang}_${tgt_lang}_${task}/data/train" data/train cp -r "${MULTIMED_ST}/${src_lang}_${tgt_lang}_${task}/data/valid" data/valid cp -r "${MULTIMED_ST}/${src_lang}_${tgt_lang}_${task}/data/test" data/test for dset in train valid test; do utils/fix_data_dir.sh --utt_extra_files "text.prev text.ctc" data/${dset} utils/validate_data_dir.sh --no-feats data/${dset} done可以看到,生成的数据目录随后会被拷贝到 Recipe 根目录下的data/,并通过fix_data_dir.sh(携带--utt_extra_files "text.prev text.ctc")与validate_data_dir.sh做标准化与校验。
2.2 脚本参数与数据划分映射
local/prepare_multimed_st.py 支持以下命令行参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--hf_dataset | leduckhai/MultiMed-ST | Hugging Face 数据集 ID |
--src_lang | eng | 源语言,可选eng/vie/fra/deu/zho |
--tgt_lang | deu | 目标语言,可选值同上 |
--task | st | 任务类型,可选asr、st、multitask_asr_st |
--out_root | 必填 | 输出根目录 |
--max_train_samples | 0 | 训练集最大样本数,0表示全部 |
--max_valid_samples | 0 | 验证集最大样本数 |
--max_test_samples | 0 | 测试集最大样本数 |
脚本内置的语言信息映射(LANG_INFO)同时给出语言名称与对应的 OWSM 特殊符号:
LANG_INFO = { "eng": ("English", "<eng>"), "vie": ("Vietnamese", "<vie>"), "fra": ("French", "<fra>"), "deu": ("German", "<deu>"), "zho": ("Chinese", "<zho>"), }Hugging Face 原始划分到 ESPnet 划分的映射(SPLIT_MAP)为:
SPLIT_MAP = { "train": "train", "eval": "valid", "corrected.test": "test", }即 HF 的eval对应 ESPnet 的valid,corrected.test对应test。脚本还对 ST 任务做了参数校验:当任务为st或multitask_asr_st时,src_lang与tgt_lang必须不同,否则直接抛出ValueError。
2.3 音频处理与文本格式
MultiMed-ST 的音频可能是立体声(stereo),而 ESPnet S2T 推理期望单声道(mono)输入。因此脚本在写 wav 前会做降混处理,见 prepare_multimed_st.py 中的decode_and_write_wav:
speech, sr = sf.read(BytesIO(audio_bytes), dtype="float32") # ESPnet S2T inference expects mono audio. # MultiMed-ST audio can be stereo, so downmix before writing wav. if getattr(speech, "ndim", 1) == 2: speech = speech.mean(axis=1) sf.write(wav_path, speech, sr)对于 OWSM 微调,每个划分目录需要三个关键文本文件,其格式约定如下:
text utt_id <eng><st_deu><notimestamps> German translation text.prev utt_id <na> text.ctc utt_id English source transcripttext:带 OWSM prompt 前缀的目标语言翻译文本,<eng>为源语言符号,<st_deu>为"翻译成德语"的任务符号,<notimestamps>表示不预测时间戳;text.prev:前文上下文,微调时统一置为<na>;text.ctc:英语源语言转写(用于 CTC 辅助监督)。
脚本生成的 utterance ID 遵循eng_deu_st_<split>_<8位序号>_<音频名>的命名模式。由于 MultiMed-ST 元数据未提供可靠的说话人轮次信息,脚本将每个 utterance 视为独立说话人,即utt2spk写作utt_id utt_id,同时在spk2utt中生成一一对应关系。此外,脚本还会按任务类型额外生成text.asr(ASR 文本)与text.st(ST 文本)文件,方便多任务扩展。
值得注意的细节是:脚本逐条检查音频字节是否完整、源文本是否为空(ST 任务还要求目标文本非空),解码失败的样本会被跳过并打印skip idx=...日志,保证数据目录的可用性;同时每个划分的头 5 个样本会打印采样率、时长、源/目标文本片段,便于人工抽查。
3. OWSM v4 small 资产准备:符号链接 + 微调配置生成
OWSM 微调需要复用espnet/owsm_v4_small_370M的预训练 tokenizer、token list、checkpoint 与特征统计量。这一步骤由 local/prepare_owsm_v4_assets.py 完成,它在 Recipe 目录下生成如下文件结构:
downloads/owsm_v4_small_370M/model.pth downloads/owsm_v4_small_370M/config.yaml downloads/owsm_v4_small_370M/bpe.model downloads/owsm_v4_small_370M/feats_stats.npz data/de_token_list/bpe_unigram50000/bpe.model data/de_token_list/bpe_unigram50000/tokens.txt conf/finetune_owsm_v4_small.yaml这些文件由脚本自动生成,不应被提交到版本库。其核心实现逻辑:
- 通过
snapshot_download从 Hugging Face Hub 下载模型仓库快照; - 用
find_one在快照中定位*.pth(优先选择名称含valid的 checkpoint)、config.yaml、bpe.model、feats_stats.npz; - 在
downloads/owsm_v4_small_370M/与data/de_token_list/bpe_unigram50000/下创建指向真实文件的符号链接(symlink),避免把大文件复制进 Recipe 工作区; - 从
config.yaml中读取token_list,写出tokens.txt; - 读取模型自带的训练配置,经
sanitize_train_config清洗后写出conf/finetune_owsm_v4_small.yaml。
3.1 配置清洗与本地微调默认值
sanitize_train_config会剔除模型卡片/HF 元数据与 Recipe 运行时字段(如config、required、version、distributed、output_dir、token_list、init_param、pretrain_path等),并注入面向本地微调的默认值:
max_epoch: 1 num_iters_per_epoch: 1000 batch_size: 1 accum_grad: 8 use_amp: true同时还会做一系列面向单机/CPU 友好的调整,这些细节在 prepare_owsm_v4_assets.py 中均有体现:
- 训练节奏:
drop_last_iter=false、num_workers=1、log_interval=1、num_att_plot=0、keep_nbest_models=[1]、patience=None; - 分布式配置全部关闭:
dist_launcher=None、multiprocessing_distributed=false、dist_world_size=1、sharded_ddp=false; - 优化器:学习率固定为
1.0e-5,关闭fused;调度器使用warmuplr,warmup_steps=1; - 避免可选的 Flash Attention 依赖:
encoder_conf/decoder_conf中use_flash_attn=false、gradient_checkpoint_layers=[]; - 特征归一化:
normalize=global_mvn,normalize_conf.stats_file指向符号链接feats_stats.npz。
上述参数均可通过run.sh暴露的--owsm_*参数在命令行覆盖(详见第 5 节)。
4. Stage 调度:为什么跳过 Stage 5–9
egs2/multimed_st/s2t1复用了 ESPnet2 通用 S2T 流水线 s2t.sh 的 stage 体系。通过检索 s2t.sh 中的 stage 分支可以确认各阶段职责:
| Stage | 职责 |
|---|---|
| Stage 1 | 数据准备(data/train、data/valid等) |
| Stage 2 | 变速扰动(Speed perturbation) |
| Stage 3 | 格式化wav.scp/ 特征提取 |
| Stage 4 | 去除过长/过短数据 |
| Stage 5 | 生成token_list(BPE/字符级/Whisper/HF tokenizer) |
| Stage 6 | LM 收集统计量 |
| Stage 7 | LM 训练 |
| Stage 8 | 计算困惑度 |
| Stage 9 | N-gram 语言模型训练 |
| Stage 10 | S2T 收集统计量(collect stats) |
| Stage 11 | S2T 模型训练 |
| Stage 12 | 解码(Decoding) |
| Stage 13 | 评测(Scoring) |
| Stage 14 | 打包模型 |
| Stage 15 | 上传模型到 Hugging Face |
本 Recipe 有意跳过 Stage 5:Stage 5 通常从训练文本训练新的 BPE tokenizer,但这不适合 OWSM 微调——模型必须沿用预训练的 OWSM BPE 模型与 token list(即data/de_token_list/bpe_unigram50000/下的bpe.model与tokens.txt)。
Stage 6–9 同样被跳过,因为本 Recipe 不训练、也不使用外部神经 LM 或 n-gram LM(use_lm=false)。OWSM 解码直接由微调后的 S2T 模型完成,无需语言模型打分。
因此官方推荐的操作方式是:
--stage 1 --stop_stage 4先完成数据准备,然后从 Stage 10(collect stats)继续。
在 run.sh 中,当启用微调模式(--finetune_owsm_v4_small true)时,会自动完成以下配置注入:
token_type=bpe nbpe=50000 use_lm=false s2t_config=conf/finetune_owsm_v4_small.yaml inference_config=conf/decode_owsm_st_de.yaml s2t_args="--init_param downloads/owsm_v4_small_370M/model.pth --ignore_init_mismatch true"其中--init_param指定从 OWSM checkpoint 初始化参数,--ignore_init_mismatch true允许部分参数(如输出层维度)与预训练权重不一致时忽略不匹配项。同时run.sh会调用python local/prepare_owsm_v4_assets.py,把第 3 节中的资产准备流程串入流水线。
5. 运行指南:数据准备 → 微调 → 解码评测
5.1 数据准备(Stage 1–4)
./run.sh \ --finetune_owsm_v4_small true \ --stage 1 \ --stop_stage 4 \ --ngpu 0此阶段不需要 GPU。执行后会在data/下生成train、valid、test三个 Kaldi 风格目录。
5.2 OWSM v4 small 微调(Stage 10–11)
./run.sh \ --finetune_owsm_v4_small true \ --stage 10 \ --stop_stage 11 \ --ngpu 1Stage 10 为 collect stats(基于feats_stats.npz等资产),Stage 11 为正式训练。默认生成的微调配置采用固定步数的初步设定:
max_epoch: 1 num_iters_per_epoch: 1000 batch_size: 1 accum_grad: 8 use_amp: true即默认只跑 1 个 epoch、每个 epoch 最多 1000 次迭代、batch size 为 1 并配合 8 步梯度累积、开启混合精度。这套默认值适合快速验证流水线。
5.3 覆盖生成的配置参数以延长训练
如果希望进行更长的本地训练,可以借助 run.sh 暴露的--owsm_*参数覆盖生成配置中的对应旋钮。例如以下命令去除固定迭代上限,将 epoch 数提高到 5:
./run.sh \ --finetune_owsm_v4_small true \ --stage 10 \ --stop_stage 11 \ --ngpu 1 \ --owsm_max_epoch 5 \ --owsm_num_iters_per_epoch 0run.sh中可用的 OWSM 相关参数及默认值如下:
| run.sh 参数 | 默认值 | 作用 |
|---|---|---|
--owsm_max_epoch | 1 | 微调 epoch 数 |
--owsm_num_iters_per_epoch | 1000 | 每个 epoch 迭代数,设为0表示不限制(由数据量决定) |
--owsm_batch_size | 1 | 训练 batch size |
--owsm_valid_batch_size | 1 | 验证 batch size |
--owsm_accum_grad | 8 | 梯度累积步数 |
这些参数会透传给 prepare_owsm_v4_assets.py(--max_epoch、--num_iters_per_epoch、--batch_size、--valid_batch_size、--accum_grad),进而写入新生成的conf/finetune_owsm_v4_small.yaml。注意:当num_iters_per_epoch为 0 时,脚本会从配置中移除该键(见sanitize_train_config中的cfg.pop("num_iters_per_epoch", None)),从而由实际数据量决定迭代轮数。
5.4 解码与评测(Stage 12–13)
./run.sh \ --finetune_owsm_v4_small true \ --stage 12 \ --stop_stage 13 \ --ngpu 1 \ --gpu_inference true \ --inference_nj 1 \ --inference_s2t_model 5epoch.pth--gpu_inference true:在 GPU 上执行解码;--inference_nj 1:解码并行 job 数(受限于资源可调大);--inference_s2t_model 5epoch.pth:指定推理所用的 checkpoint 文件名。如果按第 5.3 节以--owsm_max_epoch 5训练,生成的模型文件名为5epoch.pth(ESPnet2 按 epoch 命名保存的 checkpoint)。
Stage 13 的评测包含两层:
- ESPnet 默认的 WER/CER/TER 输出(来自 s2t.sh 的 scoring 逻辑);
- 额外调用
local/score.sh,使用sacrebleu报告 ST 的 BLEU、chrF 与 TER。
6. 德语 ST 解码配置详解
德国 ST 解码使用 conf/decode_owsm_st_de.yaml,完整内容如下:
beam_size: 5 ctc_weight: 0.0 maxlenratio: 1.0 minlenratio: 0.0 lang_sym: "<eng>" task_sym: "<st_deu>" predict_time: false各字段含义:
| 字段 | 值 | 说明 |
|---|---|---|
beam_size | 5 | 束搜索宽度 |
ctc_weight | 0.0 | CTC 权重,纯自回归解码,不混合 CTC |
maxlenratio | 1.0 | 最大生成长度与输入长度的比例 |
minlenratio | 0.0 | 最小生成长度比例 |
lang_sym | "<eng>" | 源语音语言符号,作为 prompt 注入 |
task_sym | "<st_deu>" | 任务符号,指定翻译成德语 |
predict_time | false | 不预测时间戳 |
对于英语到德语语音翻译,lang_sym表示源语音的语言(英语),task_sym指定翻译目标(德语)。在 OWSM 的解码流程中,这两个符号连同<notimestamps>一起构成模型输入的 prompt 前缀,指引模型执行"将英语语音翻译为德语且不输出时间戳"的任务。
7. ST 指标评测:sacrebleu 与 prompt 剥离
7.1 评测流程
Stage 13 完成后,local/score.sh 会在每个解码目录下查找text_nospecial假设文件(可通过--test_sets限定,默认全量查找),并执行:
- 定位参考文件
dump/raw/${dset}/text; - 调用 local/align_ref_hyp.py 对齐参考与假设;
- 调用
sacrebleu计算 BLEU、chrF、TER; - 将结果写入
score_st_bleu/result.txt并打印。
7.2 Prompt 剥离与对齐逻辑
由于参考文本(text)带有<eng><st_deu><notimestamps>这类 OWSM prompt 标记,直接计算 BLEU 会失真。align_ref_hyp.py 通过正则表达式将行首的连续特殊符号剥离:
text = re.sub(r"^(?:<[^>]+>)+\s*", "", text).strip()随后只保留参考与假设共同包含的 utterance ID(并统计 hyp-only 与 ref-only 的数量),按 ID 排序后分别写出纯文本参考文件与假设文件,供sacrebleu使用:
sacrebleu "${scoredir}/ref.txt" \ -i "${scoredir}/hyp.txt" \ -m bleu chrf ter \ >> "${scoredir}/result.txt"8. 结果与对照解读
官方在 README 中给出的结果用于验证 Recipe 可行性,并对比 OWSM v4 small 零样本解码与在 MultiMed-ST 上微调的效果,而非报告完全优化的基准(fine-tuned 模型从espnet/owsm_v4_small_370M初始化)。
8.1 ST 指标(由local/score.sh计算)
这些分数在剥离 OWSM prompt 标记后的参考上计算:
| Model | Test set | # utts | BLEU | chrF2 | TER |
|---|---|---|---|---|---|
| OWSM v4 small zero-shot | test | 4751 | 29.4 | 56.3 | 60.6 |
| OWSM v4 small fine-tuned | test | 4751 | 31.4 | 58.0 | 58.0 |
可以看到,微调后 BLEU 提升 2.0 个点(29.4 → 31.4),chrF2 提升 1.7 个点(56.3 → 58.0),TER 下降 2.6 个点(60.6 → 58.0),说明医学领域微调对翻译质量有明确增益。
8.2 ESPnet 默认评测(Stage 13 的 WER/CER/TER)
以下为 s2t.sh Stage 13 的默认输出,仅供对照参考:
| Model | Test set | # utts | WER | CER | TER |
|---|---|---|---|---|---|
| OWSM v4 small zero-shot | test | 4751 | 63.1 | 49.0 | 62.9 |
| OWSM v4 small fine-tuned | test | 4751 | 60.6 | 47.8 | 61.1 |
需要说明的是,WER/CER/TER 是基于词/字符编辑距离的指标,与 ST 语义质量指标(BLEU/chrF)衡量维度不同,因此在解读时应以第 8.1 节的 ST 指标为主。
9. 关键文件速查表
| 文件 | 作用 |
|---|---|
| egs2/multimed_st/s2t1/README.md | Recipe 官方说明文档 |
| egs2/multimed_st/s2t1/run.sh | 顶层入口脚本,承载全部--owsm_*与通用 stage 参数 |
| egs2/multimed_st/s2t1/s2t.sh | ESPnet2 S2T 通用流水线(Stage 1–15) |
| egs2/multimed_st/s2t1/local/data.sh | 数据准备驱动脚本 |
| egs2/multimed_st/s2t1/local/prepare_multimed_st.py | MultiMed-ST 下载、降混、Kaldi 数据目录生成 |
| egs2/multimed_st/s2t1/local/prepare_owsm_v4_assets.py | OWSM 资产下载、符号链接与微调配置生成 |
| egs2/multimed_st/s2t1/local/score.sh | ST 的 sacrebleu 评测入口 |
| egs2/multimed_st/s2t1/local/align_ref_hyp.py | 参考/假设对齐与 prompt 剥离 |
| egs2/multimed_st/s2t1/conf/decode_owsm_st_de.yaml | 英德 ST 解码配置 |
| egs2/multimed_st/s2t1/db.sh | 数据集路径变量(MULTIMED_ST=downloads) |
10. 小结
本 Recipe 演示了一条完整的"医学领域多语言语音翻译"落地路径:从 Hugging Face 流式拉取 MultiMed-ST、自动降混与 Kaldi 目录构建,到 OWSM v4 small 预训练资产的符号链接复用与本地微调配置生成,再到跳过 LM 相关 stage、直接以微调模型完成英德 ST 解码,最后通过 prompt 剥离 + sacrebleu 输出 BLEU/chrF/TER 指标。其设计对"在自有领域数据上微调 OWSM 类多语言多任务 S2T 模型"具有直接的可迁移参考价值:凡是需要沿用预训练 tokenizer、避免重新训 BPE、且不需要外部语言模型的场景,都可以借鉴这种 stage 裁剪与资产符号链接策略。
参考论文:MultiMed-ST: Large-scale Many-to-many Multilingual Medical Speech Translation(arXiv 2504.03546),数据来自 MultiMed-ST 数据集。
- 人工智能
- 语音
- 音频
- 深度学习
- NLP
【免费下载链接】espnet
End-to-End Speech Processing Toolkit
相关推荐
基于 fairseq 的 MuST-C 英德语音翻译联合语音-文本训练实战指南(Joint Speech Text Training)
基于 fairseq 的 MuST C 英德语音翻译联合语音 文本训练实战指南(Joint Speech Text Training) 导读 本文基于 kosm
人工智能大模型预训练深度学习NLP计算机视觉多模态语音音频微调Ice:把 macOS 菜单栏图标管理这件事做简单了
Ice:把 macOS 菜单栏图标管理这件事做简单了 菜单栏图标多到互相遮挡,刘海屏上还有图标被刘海吞掉一半,这种事很烦。Ice 菜单栏图标管理工具就是冲着这个
桌面应用如何构建英语-德语翻译模型:基于seq2seq框架的终极实战指南
如何构建英语 德语翻译模型:基于seq2seq框架的终极实战指南 想要快速构建高质量的机器翻译模型吗?seq2seq(序列到序列)框架为你提供了完美的解决方案!
深度学习NLP
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考