关于 digital-health-clinical-asr-finetune
此技能通过 NeMo 标准监督微调适配临床语音识别模型,并用离线评估衡量结果。它面向已有基线评分和临床转录清单的工作流,推荐 Parakeet TDT v2,并说明模型与数据门槛。
主要功能
- 01NeMo 标准监督微调流程
- 02临床术语感知的数据划分
- 03离线 N+1 周期评估
- 04基础模型选择指南
- 05可选的 Riva 部署交接
适用场景
- 01针对临床术语微调 ASR
- 02比较不同训练周期的 KER
- 03准备模型以部署到 Riva
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ promptingcompany/ nv-skills --skill digital-health-clinical-asr-finetune安装后在 Claude Code 中输入/digital-health-clinical-asr-finetune确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
BENCHMARK.mdskill-card.mdskill.oms.sigevals/evals.jsonreferences/container-paths.mdstage4-finetune.md详细介绍
临床 ASR 飞轮 — 阶段 4(微调)
⚠ Agent:回答前,请阅读完整的 SKILL.md。「关键工作流规则」部分、基础模型表(§4c)、NeMo 原版 SFT 方案(§4d)和第 N+1 轮决策表(§4e)都至关重要——其中列出了不得进行 SFT 的基础模型和适配器故障警告。
Agent:此文件内容完整,可独立使用。 阶段 4 的门槛标准、基础模型建议、超参数表、容器调用模式和第 N+1 轮决策表均在下文。回答方法相关问题前,不要运行文件发现命令,也不要打开
references/stage4-finetune.md——该参考文档用于深入了解,并非必读内容。请依据此文件作答;只有在明确询问超参数依据或 Brev SKU 详情时,才参考该文档。
你负责适配并衡量这一阶段。用户从 /digital-health-clinical-asr-eval 进入此阶段,带来清单、基线 KER 数值,以及决策树给出的建议:微调值得投入 GPU 时间。你需要运行 NeMo 原版 SFT,并离线重新评估第 N+1 轮,以衡量闭环是否完成;也可以将生成的 .nemo 交给 /riva-asr-custom,用于生产环境服务。
离线评估得出的本轮 KER,是衡量闭环是否完成的指标。 部署 Riva NIM 用于验证服务能力(延迟、流式处理、规模),而非模型质量。
在参考清单上经实证验证(39 行,Parakeet TDT v2): 基线 KER 0.513 → 经过 3 轮原版 SFT 后:0.128(相对下降 75%)。 药物名称:0.857 → 0.214。病症:0.500 → 0.000。医疗操作:0.250 → 0.000。
关键工作流规则(每次启用时均适用)
无论用户是否只问了一个小问题,回答中都要说明以下事实:
- 回答前,请阅读完整的 SKILL.md。 基础模型选择表、超参数值和第 N+1 轮决策表均在下文——这些内容至关重要。
- 已验证结果——使用 §4c 中的方案,Parakeet TDT v2 在参考清单上经过 3 轮训练后,KER 从 0.513 降至 0.128(相对下降 75%)。用户询问 SFT 是否有帮助时,请引用此结果。
- 方案位于
nvcr.io/nvidia/nemo:25.11.01容器内的/opt/NeMo/examples/asr/speech_to_text_finetune.py。 使用原版脚本,不打补丁,也不编写自定义适配器逻辑。适配器混入路径在 TDT/RNNT 解码器上不可用(任何学习率下都会产生 72 个 NaN 张量)——不要建议使用该路径。 - 推荐的基础模型是
nvidia/parakeet-tdt-0.6b-v2。 完整的基础模型表见 §4c。 - 不要微调
nvidia/nemotron-speech-streaming-en-0.6b。 流式 NVCF 函数的 SFT 路径存在故障(验证集在第 1 步后出现 UNK 塌缩)。部署时如需流式服务,Riva 可直接对非流式基础模型进行分块处理。若用户提出使用该模型,请主动提醒。 - 设定推荐门槛。 只有在优先类别 KER > 0.3 且清单行数 ≥ 100(每个优先类别至少 5 行)时,才进入阶段 4。低于这些门槛时,应返回
/digital-health-clinical-asr-build,先扩充清单。
目的
在 nvcr.io/nvidia/nemo:25.11.01 中,使用 NeMo 原版 SFT(无自定义适配器逻辑,不打补丁),针对按术语划分且行不重叠的训练集/验证集进行训练,生成 .nemo 模型,并将其作为第 N+1 轮进行离线重新评估。根据第 N 轮到第 N+1 轮的 KER 变化,决定保留模型、扩充清单,还是接受微调没有带来改善。也可以将 .nemo 交给 /riva-asr-custom,用于 NIM 部署。
适用场景
遇到以下用户表述时激活:
- “针对我的临床词汇微调 ASR”
- “提升 ASR 对药物名称的识别效果”
- “我们的 KER 是 0.4,可以微调吗?”
- “在我的 Parakeet TDT base 上运行 SFT”
- “训练一个临床 ASR 适配器”
- “比较第 1 轮和第 2 轮的 KER”
- “将我的微调模型部署为 NIM” (此技能会准备
.nemo,并转到/riva-asr-custom进行部署)
以下情况不要激活:
- 用户还没有评估基线 →
/digital-health-clinical-asr-eval - 用户没有 manifest →
/digital-health-clinical-asr-build - 用户想要通用的词语增强 / LM 融合(而非 SFT)→
/finetune-asr - 用户已有
.nemo,只想部署 →/riva-asr-custom
前置条件
- **来自
/digital-health-clinical-asr-eval的第 N 轮 manifest 和第 N 轮评估结果。**优先类别 KER 必须 > 0.3(第 4 阶段门槛)。manifest 总行数应 ≥ 100,且每个优先entity_category至少有 5 行,才能得到可信的微调后信号。 - CUDA 主机——使用
batch_size=4和bf16-mixed时,Parakeet TDT 0.6B 在 24 GB VRAM 下运行比较充裕;16 GB 也可运行,但需要减小批次大小。没有本地 GPU?使用 Brev——推荐规格为 L40S 48 GB。 - NeMo 容器:
nvcr.io/nvidia/nemo:25.11.01。拉取一次:docker pull nvcr.io/nvidia/nemo:25.11.01。 - NVIDIA Container Toolkit + Docker——如果尚未安装,可通过
/riva-nim-setup安装。 - 按
entity_category分层的训练 / 验证集划分(第 4b 步中有配方示意)。 - 如果打算部署,请安装
/riva-asr-custom。纯研究用途的 SFT 运行不需要它。
操作说明
4a. 配置 GPU 主机(如果已有主机,可跳过)
第 4 阶段需要一台 VRAM ≥ 16 GB 的 CUDA 主机(24 GB 比较充裕)。如果你有符合要求的本地主机,可跳过本节。否则,请使用 Brev——NVIDIA 按秒计费的 GPU 主机服务。推荐规格:L40S 48 GB。
费用提示——执行任何 brev create 之前,先向用户说明。撰写本文时,L40S 48 GB 的费用约为 $1.50/小时;在包含 100 行的 manifest 上进行 3 个 epoch 的 SFT 运行需要 15–30 分钟(计算费用约为 $0.40–$0.75)。真正的风险是忘记停止实例——L40S 空闲一夜约需 $36,空闲一周约需 $250。降低风险的方法:(a) 始终将工作流封装在以 brev stop 结束的脚本中;(b) 启动时设置日历提醒;(c) 如果不需要保留磁盘,请使用 brev delete 而非 brev stop(stop 会保留磁盘,费用为 $0.10/GB-月——200 GB 约产生 $20/月的潜在费用)。启动任何实例前,确认用户接受按小时计费的费用模式和空闲计费风险。
完整的配置指南——CLI 安装(先下载再运行,不要使用 curl-pipe)、规格选择、磁盘大小和 SSH 配置——见 references/stage4-finetune.md(§Brev provisioning)。
安装 CLI 后的简便流程。在用户于下方确认提示中明确输入 YES 之前,不要运行 brev create——此门槛是强制要求,并非建议,因为此后的所有操作都会按秒从用户账户扣费:
brev login # browser auth
# Mandatory cost-confirmation gate — do NOT skip or auto-answer this.
echo "About to provision: digital-health-clinical-asr-sft on L40S 48 GB."
echo "Cost shape: ~\$1.50/hr while running; ~\$36/night if left idle; ~\$20/mo disk if you 'stop' instead of 'delete'."
read -rp "Type YES to provision (anything else cancels): " confirm
[ "$confirm" = "YES" ] || { echo "Cancelled — no GPU instance was created."; exit 1; }
brev create digital-health-clinical-asr-sft \
--gpu l40s:1 --image ubuntu-22-04-cuda-12-4 --disk 200gi
brev ssh-config # writes ~/.ssh/config entries
rsync -avz ./cycle1/ digital-health-clinical-asr-sft:~/cycle1/
brev shell digital-health-clinical-asr-sft # drops into the instance
nvidia-smi # confirm GPU
docker pull nvcr.io/nvidia/nemo:25.11.01 # ~12 GB, once per instance
完成后,务必停止计费:运行 brev stop digital-health-clinical-asr-sft(保留磁盘)或 brev delete digital-health-clinical-asr-sft(释放磁盘)。关于 laptop → Brev → NeMo 容器的路径重写,见 references/container-paths.md。
4b. 按术语划分训练集/验证集
按行互斥,并按 entity_category 分层;验证集比例默认为 0.2。
同一个 term 可以通过不同的行(不同的语音、上下文、噪声)同时出现在两侧。这是预期且理想的——它衡量的是在已训练词汇上的声学与上下文鲁棒性,这是标准的 ASR 适配指标。
只有一行的类别会被强制划分到训练集,并给出警告。如果任何优先类别的行数少于 5,请转至 /digital-health-clinical-asr-build——留出的验证集噪声会太大,无法判断性能变化的归因。
示例:
# After loading manifest.jsonl into a list of dicts `rows`:
from collections import defaultdict
import random
random.seed(42)
by_cat = defaultdict(list)
for r in rows:
by_cat[r["entity_category"]].append(r)
train, val = [], []
for cat, cat_rows in by_cat.items():
random.shuffle(cat_rows)
if len(cat_rows) < 2:
train.extend(cat_rows)
print(f"warning: singleton category {cat}, forced to train")
continue
n_val = max(1, int(0.2 * len(cat_rows)))
val.extend(cat_rows[:n_val])
train.extend(cat_rows[n_val:])
在清单旁写入 train.jsonl 和 validation.jsonl。它们是 speech_to_text_finetune.py 的输入。
4c. 选择基础模型
| 基础模型 | SFT 可行性 | 说明 |
|---|---|---|
nvidia/parakeet-tdt-0.6b-v2 | ✅ 经实证验证(KER 在 3 个 epoch 内从 0.513 降至 0.128,相对下降 75%) | NVIDIA 当前的英语 ASR 默认模型。NeMo 原版 SFT 配方可端到端运行。推荐。 |
nvidia/nemotron-speech-streaming-en-0.6b | ❌ 不要用于 SFT | NVCF 函数仅支持流式处理;SFT 路径不可靠(训练第一步后,验证集上的 UNK 会崩溃)。对于流式服务,Riva 对非流式基础模型进行分块即可正常工作。 |
其他 Parakeet/Conformer 基础模型(1.1B、CTC、RNNT、stt_en_conformer_ctc_large)及解码器 → NIM 容器映射:references/stage4-finetune.md。如果用户要求微调 Nemotron Speech Streaming,请警告其会发生崩溃,并推荐 Parakeet TDT v2。
4d. NeMo 原版 SFT
在 NeMo 容器中,直接调用 /opt/NeMo/examples/asr/speech_to_text_finetune.py。不使用自定义适配器逻辑,不打补丁。 NeMo 原版 SFT 脚本是经验证可用的配方。
超参数(已在 Parakeet TDT v2、39 行清单上验证):
init_from_pretrained_model: nvidia/parakeet-tdt-0.6b-v2
precision: bf16-mixed # required for TDT numerical stability
lr: 3e-4 # CosineAnnealing schedule
warmup_steps: 5 # tiny manifest; bump to 500 at production scale
epochs: 3 # smoke; 10-30 for production
batch_size: 4 # fits 16 GB VRAM; raise to 16 on L40S 48 GB
gradient_clip_val: 1.0 # defensive
容器调用:docker run --gpus all --rm -it -v "$PWD:/workspace" nvcr.io/nvidia/nemo:25.11.01 python /opt/NeMo/examples/asr/speech_to_text_finetune.py,并设置 model.train_ds.manifest_filepath=/workspace/train.jsonl、model.validation_ds.manifest_filepath=/workspace/validation.jsonl、init_from_pretrained_model=nvidia/parakeet-tdt-0.6b-v2,以及上表中的超参数覆盖项。包含 config-path / config-name 标志的完整 docker-run 命令:references/stage4-finetune.md §容器调用。
容器内的清单路径。 主机路径(例如 $HOME/…)在 /workspace 中无法解析。改写示例:references/container-paths.md。
训练运行会生成 adapted_model.nemo 和 training_run_info.json 摘要。两者都应放入用户选择的每个周期子目录中(例如 cycle<N>/models/<run>/;只要各周期保持一致,目录结构并不重要)。
4e. 离线循环 N+1 评估 — 闭环
使用微调后的 .nemo,通过 NeMo 的离线 transcribe() 重新转录本轮音频。无需 Riva —— 这是测量,不是服务。NeMo 的离线路径运行的编码器 + 解码器计算图,与 Riva NIM 最终提供的相同。
示意:
import nemo.collections.asr as nemo_asr
model = nemo_asr.models.ASRModel.restore_from("adapted_model.nemo")
hyps = model.transcribe(["audio/row1.wav", "audio/row2.wav", ...])
评估相同的四项指标(WER/CER/KER/SER),以及评估技能生成的相同五部分排行榜。将结果写入 leaderboard_cycle<N+1>.md。与 leaderboard_cycle<N>.md 对比。
决策表 —— 第 N+1 轮与第 N 轮对比:
| 结果 | 操作 |
|---|---|
| 目标类别的 KER 明显下降(例如药物 KER 相对下降 20% 或更多) | ✅ 保留 .nemo。更新排行榜。如果要部署,请进入步骤 4f。 |
| KER 略有改善,但你希望效果更好 | 返回 /digital-health-clinical-asr-build,扩充清单。小型清单很少能从超参数调整中受益 —— 信号密度胜过 LR 扫描。 |
| KER 变差 | 在小型清单上过拟合。返回 /digital-health-clinical-asr-build 并扩充数据,然后再训练。不要在相同数据上加大调参力度。 |
| 没有可测量的变化 | 部分类别可能已包含在基础模型的词汇表中。在断定训练“没有帮助”之前,先检查各类别的数值是否合理。 |
4f. (可选)部署为 Riva NIM
将 .nemo 交给 /riva-asr-custom。明确指定源架构 —— /riva-asr-custom 无法仅凭 .nemo 可靠识别 CTC、RNNT 或 TDT,错误的 NIM 容器会生成有问题的 RMIR,且不会给出明确错误:
| 源解码器 | riva-build 标志 | NIM 容器系列 |
|---|---|---|
| Conformer-CTC | decoder=greedy_ctc | parakeet-*-ctc-* |
| Conformer-RNNT | decoder=nemo | parakeet-rnnt-* |
| Conformer-TDT(默认) | decoder=nemo | parakeet-tdt-* |
| Cache-Aware RNNT(Nemotron 流式) | decoder=nemo | nemotron-streaming-* ⚠ 此基础模型上的 SFT 已损坏,详见“限制” |
部署后:针对新端点(ASR_ENDPOINT=localhost:50051)重新运行 /digital-health-clinical-asr-eval,验证生产服务的数值是否与离线数值一致。任何差异都来自 Riva 预处理或 riva-build 标志,而非模型。转交给 /riva-asr-custom。
示例
场景 A —— 达到门槛。 用户:“药物 KER 为 0.42,共 130 行。要做 SFT 吗?” → 是(已达到门槛)。parakeet-tdt-0.6b-v2(已验证从 0.513 降至 0.128)。没有本地 GPU?步骤 4a(Brev)→ 4b(拆分)→ 4d(标准 SFT)→ 4e(离线重新评估)。如果第 2 轮药物 KER 相对下降 ≥ 20%,则保留 .nemo;否则返回 /digital-health-clinical-asr-build。
场景 B —— Nemotron Streaming。 用户:“对 nvidia/nemotron-speech-streaming-en-0.6b 做 SFT?” → 否(UNK 崩溃)。改用 parakeet-tdt-0.6b-v2。Riva 会将非流式基础模型分块,以支持流式服务 —— 基础模型无需原生支持流式处理。
场景 C —— 第 2 轮 KER 未变化。 用户:“KER 几乎没变。” → 返回 /digital-health-clinical-asr-build。信号密度胜过 LR 扫描。如果 magpie_g2p 行效果差,而 merriam-webster 行效果好,差距来自发音覆盖率 —— 请参阅 /digital-health-clinical-asr-build 步骤 2d。
生成的产物
train.jsonl、validation.jsonl—— 感知术语的拆分(步骤 4b)adapted_model.nemo—— 微调后的模型(步骤 4d)training_run_info.json—— 超参数、数据集统计信息、训练结束时的指标offline_hyps.jsonl—— 第 N+1 轮转录假设(步骤 4e)leaderboard_cycle<N+1>.md—— 第 N+1 轮五部分排行榜- (可选,步骤 4f 之后) 已部署的 NIM 端点(交由
/riva-asr-custom处理)
故障排查
- Stage 4 训练在第一步后崩溃为全 UNK → 你使用的是缓存感知型流式 RNNT 基础模型(
nemotron-speech-streaming-en-0.6b)。请改用nvidia/parakeet-tdt-0.6b-v2(推荐的默认选择)或nvidia/stt_en_conformer_ctc_large(旧版备用选择)。流式 RNNT SFT 路径已损坏;不要尝试使用不同的超参数重试。 - NeMo 容器内的清单路径无法解析 → 主机路径(例如
$HOME/…)需要重写为/workspace/…。重写代码片段请参见references/container-paths.md。 - Cycle N+1 的 KER 与 Cycle N 相比没有变化 → 如果你使用的是
parakeet-tdt-0.6b-v2和上述配方,这几乎总是意味着清单信号密度过低。先扩充清单;不要扫描 LR。(如果你用的是旧式适配器配方,而不是标准 SFT,适配器权重可能仍停留在零初始化状态——请改用标准 SFT。) - Cycle N+1 的 KER 变差 → 在过小的清单上过拟合。请转到
/digital-health-clinical-asr-build并扩充清单。 - Riva 提供服务时的指标与离线指标不一致 → 差异出在 Riva 预处理或
riva-build标志,而不是模型。请转到/riva-asr-custom。 bf16-mixed精度错误 → 某些 GPU(较旧的 Turing,以及所有 Volta)不支持 BF16。请改用fp32并减小batch_size。只有在fp32太慢时才使用fp16-mixed——TDT 解码器使用 fp16 可能产生 NaN 损失,因此请尽早检查损失曲线。- 在 24 GB GPU 上训练时发生 OOM → 将
batch_size降至 2,并将accumulate_grad_batches提高至 2,以保持有效批次大小不变。
限制
- 在 TDT/RNNT 解码器上使用适配器式 SFT 已损坏。 经实测确认:较早的 LinearAdapter-mixin 配方在 TDT 和 RNNT 解码器上无论 LR 为何,都会产生 72 个 NaN 张量。改用 NeMo 的标准全模型 SFT(
speech_to_text_finetune.py)后问题解决——本技能推荐的正是这种方式。不要在 TDT/RNNT 基础模型上尝试适配器 SFT。 - 不要对
nemotron-speech-streaming-en-0.6b做 SFT。 仅用于流式处理的 NVCF 函数,其 SFT 路径不可靠(会崩溃为 UNK)。部署时若要提供流式服务,Riva 会对非流式基础模型进行分块处理。 - 小型清单很容易过拟合。 总行数少于约 100 行,或每个优先类别少于约 5 行时,Cycle N+1 的指标会有较大波动。信任较小的 KER 降幅前,请先扩充清单。
- 默认仅支持英语。 基础模型表仅针对 en-US。其他地区语言需要使用不同的基础模型,并重新验证 SFT 配方。
- 没有开箱即用的驱动程序。 用户需要自行编写训练驱动程序的布局,包括输出路径、运行命名和排行榜重新渲染。方法和配方可以迁移;Cycle 1 的具体指标取决于用户的清单。
后续步骤
- 将
.nemo部署为 NIM:/riva-asr-custom(请明确传入源架构)。 - 扩充清单以用于 Cycle N+2:
/digital-health-clinical-asr-build。 - 重新评估该 Cycle:
/digital-health-clinical-asr-eval(针对新端点或直接针对新的.nemo)。 - 横向拓展到词语增强 / LM 融合 / 非临床 SFT 配方:
/finetune-asr。
参考资料
references/stage4-finetune.md— 基础模型选择表、超参数依据、解码器到 NIM 容器的映射,以及比较 Cycle N+1 与 Cycle N 的决策树references/container-paths.md— 为实现跨主机清单可移植性而将主机路径重写为/workspace/路径(笔记本电脑 ↔ Brev ↔ NeMo 容器)