news 2026/9/25 5:21:00

ESPnet2 MultiMed-ST 英德语音翻译 Recipe:基于 OWSM v4 small 微调的完整实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ESPnet2 MultiMed-ST 英德语音翻译 Recipe:基于 OWSM v4 small 微调的完整实战指南
  • 人工智能
  • 语音
  • 音频
  • 深度学习
  • NLP

【免费下载链接】espnet

End-to-End Speech Processing Toolkit

项目地址:https://gitcode.com/gh_mirrors/es/espnet
点击查看免费下载

本篇技术指南以 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 共同实现。流程为:

  1. 从 Hugging Face 以流式(streaming)方式读取 MultiMed-ST 数据;
  2. 将每条音频解码为 mono wav 文件;
  3. 生成 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_datasetleduckhai/MultiMed-STHugging Face 数据集 ID
--src_langeng源语言,可选eng/vie/fra/deu/zho
--tgt_langdeu目标语言,可选值同上
--taskst任务类型,可选asr、st、multitask_asr_st
--out_root必填输出根目录
--max_train_samples0训练集最大样本数,0表示全部
--max_valid_samples0验证集最大样本数
--max_test_samples0测试集最大样本数

脚本内置的语言信息映射(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 transcript
  • text:带 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

这些文件由脚本自动生成,不应被提交到版本库。其核心实现逻辑:

  1. 通过snapshot_download从 Hugging Face Hub 下载模型仓库快照;
  2. 用find_one在快照中定位*.pth(优先选择名称含valid的 checkpoint)、config.yaml、bpe.model、feats_stats.npz;
  3. 在downloads/owsm_v4_small_370M/与data/de_token_list/bpe_unigram50000/下创建指向真实文件的符号链接(symlink),避免把大文件复制进 Recipe 工作区;
  4. 从config.yaml中读取token_list,写出tokens.txt;
  5. 读取模型自带的训练配置,经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 6LM 收集统计量
Stage 7LM 训练
Stage 8计算困惑度
Stage 9N-gram 语言模型训练
Stage 10S2T 收集统计量(collect stats)
Stage 11S2T 模型训练
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 1

Stage 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 0

run.sh中可用的 OWSM 相关参数及默认值如下:

run.sh 参数默认值作用
--owsm_max_epoch1微调 epoch 数
--owsm_num_iters_per_epoch1000每个 epoch 迭代数,设为0表示不限制(由数据量决定)
--owsm_batch_size1训练 batch size
--owsm_valid_batch_size1验证 batch size
--owsm_accum_grad8梯度累积步数

这些参数会透传给 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 的评测包含两层:

  1. ESPnet 默认的 WER/CER/TER 输出(来自 s2t.sh 的 scoring 逻辑);
  2. 额外调用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_size5束搜索宽度
ctc_weight0.0CTC 权重,纯自回归解码,不混合 CTC
maxlenratio1.0最大生成长度与输入长度的比例
minlenratio0.0最小生成长度比例
lang_sym"<eng>"源语音语言符号,作为 prompt 注入
task_sym"<st_deu>"任务符号,指定翻译成德语
predict_timefalse不预测时间戳

对于英语到德语语音翻译,lang_sym表示源语音的语言(英语),task_sym指定翻译目标(德语)。在 OWSM 的解码流程中,这两个符号连同<notimestamps>一起构成模型输入的 prompt 前缀,指引模型执行"将英语语音翻译为德语且不输出时间戳"的任务。

7. ST 指标评测:sacrebleu 与 prompt 剥离

7.1 评测流程

Stage 13 完成后,local/score.sh 会在每个解码目录下查找text_nospecial假设文件(可通过--test_sets限定,默认全量查找),并执行:

  1. 定位参考文件dump/raw/${dset}/text;
  2. 调用 local/align_ref_hyp.py 对齐参考与假设;
  3. 调用sacrebleu计算 BLEU、chrF、TER;
  4. 将结果写入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 标记后的参考上计算:

ModelTest set# uttsBLEUchrF2TER
OWSM v4 small zero-shottest475129.456.360.6
OWSM v4 small fine-tunedtest475131.458.058.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 的默认输出,仅供对照参考:

ModelTest set# uttsWERCERTER
OWSM v4 small zero-shottest475163.149.062.9
OWSM v4 small fine-tunedtest475160.647.861.1

需要说明的是,WER/CER/TER 是基于词/字符编辑距离的指标,与 ST 语义质量指标(BLEU/chrF)衡量维度不同,因此在解读时应以第 8.1 节的 ST 指标为主。

9. 关键文件速查表

文件作用
egs2/multimed_st/s2t1/README.mdRecipe 官方说明文档
egs2/multimed_st/s2t1/run.sh顶层入口脚本,承载全部--owsm_*与通用 stage 参数
egs2/multimed_st/s2t1/s2t.shESPnet2 S2T 通用流水线(Stage 1–15)
egs2/multimed_st/s2t1/local/data.sh数据准备驱动脚本
egs2/multimed_st/s2t1/local/prepare_multimed_st.pyMultiMed-ST 下载、降混、Kaldi 数据目录生成
egs2/multimed_st/s2t1/local/prepare_owsm_v4_assets.pyOWSM 资产下载、符号链接与微调配置生成
egs2/multimed_st/s2t1/local/score.shST 的 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

项目地址:https://gitcode.com/gh_mirrors/es/espnet
点击查看免费下载

相关推荐

上一篇:Sol剪贴板管理器使用技巧:轻松管理复制历史提升工作效率
下一篇:【亲测有效】SQLline 新手必看:解决90%常见问题的终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/25 5:19:31

恶意代码检测分类平台毕设源码包:从特征工程到Web部署全流程

简介&#xff1a;这份本科毕业设计资源聚焦恶意代码检测与分类方向&#xff0c;面向计算机、信息安全等专业需要完成毕设或课程设计的学生&#xff0c;以及希望了解机器学习在安全领域落地实践的开发者。资源以完整项目工程形式组织&#xff0c;涵盖数据预处理、特征提取、模型…

作者头像 李华
网站建设 2026/9/25 5:18:55

【Dify】记忆测试应用

认知力和记忆能力评估是编程自学者常见的需求。高效、自动化的记忆测试系统能够为不同学习和训练场景提供更科学的解决方案。 本文介绍Dify记忆测试工作流的结构与应用方法,涵盖核心模型设计、流程节点设置、典型应用案例,帮助理解其在认知评估和能力训练中的价值。 文章目录…

作者头像 李华
网站建设 2026/9/25 5:18:13

DataFusion Crate 构建配置指南:Git 依赖、编译优化与错误回溯调试

大数据数据分析后端 【免费下载链接】datafusion Apache DataFusion SQL Query Engine 项目地址&#xff1a; https://gitcode.com/gh_mirrors/datafu/datafusion 点击查看 免费下载 本篇技术指南围绕 Apache DataFusion 官方文档 crate-configuration.md 展开&#xff0c;系统…

作者头像 李华
网站建设 2026/9/25 5:16:14

STM32开发踩坑实录:从时钟树到调试救砖的实战指南

开篇先唠叨两句。搞STM32这些年&#xff0c;从标准库一路折腾到HAL库&#xff0c;从Keil MDK换到VSCode&#xff0c;从F1玩到H7&#xff0c;踩过的坑比吃过的盐还多。尤其是刚入门那阵子&#xff0c;一个延时函数卡死能折腾一晚上&#xff0c;一个芯片包装不对能让你怀疑人生。…

作者头像 李华