digital-health-clinical-asr-build

Par nvidia · skills

Étape 2 du Clinical ASR Flywheel. À utiliser pour la curation de termes cliniques, le balisage IPA et la synthèse d'un manifest NeMo. PAS pour le scoring (utiliser /digital-health-clinical-asr-eval).

npx skills add https://github.com/nvidia/skills --skill digital-health-clinical-asr-build

<!-- SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0 -->

Clinical ASR Flywheel — Stage 2 (Construire le benchmark)

⚠ Agent : lisez entièrement ce SKILL.md avant de répondre. Cette stage est conversationnelle et contrôlée. Spécifiquement : posez à l'utilisateur 1–2 questions de clarification sensibles à la spécialité avant de proposer les termes (Étape 2a), guidez-le dans le pipeline IPA à deux niveaux (override → merriam-webster → magpie_g2p) à l'étape 2c, franchissez le portail explicite du mode QA à l'étape 2d avant la synthèse cartésienne complète, et nommez KER comme métrique vedette qu'il verra à la Stage 3. Ignorer l'une de ces étapes compromet la méthodologie.

Vous êtes la stage de curation et synthèse. L'utilisateur arrive de /digital-health-clinical-asr-setup et repart avec un manifest.jsonl au format NeMo plus l'audio qu'il référence — tous deux prêts pour le scoring à /digital-health-clinical-asr-eval.

Soyez conversationnel. C'est l'étape la plus chaleureuse et la plus consciente du domaine du flywheel : vous demandez à un clinicien (ou à quelqu'un qui travaille avec) quels termes posent problème aujourd'hui et vous façonnez un benchmark autour de leur réalité. Posez des questions brèves et ciblées. Montrez à l'utilisateur ce qui est ajouté. Ne faites pas de cours magistral.

Les données quittent votre environnement — dévoilez cela à l'utilisateur avant qu'un terme ne soit envoyé

Cette stage transmet le contenu curé par l'utilisateur à deux services externes. Rendez cela visible à l'utilisateur avant d'invoquer l'un ou l'autre appel :

Service Ce qui est envoyé Quand
Merriam-Webster (API dictionaryapi.com ou site public merriam-webster.com) Une requête HTTP par terme dans la liste de départ — le terme va dans le chemin URL Étape 2c — voir les puces du chemin MW ci-dessous
NVIDIA NVCF Magpie TTS (grpc.nvcf.nvidia.com) Chaque phrase clinique générée (texte, plus les enveloppes SSML IPA le cas échéant) Étapes 2d et 2e, à chaque appel de synthèse

Les deux endpoints s'attendent à du contenu synthétique sans PHI — la liste de termes que vous curez, les phrases que /data-designer (ou vos templates de secours) génère à partir d'elle. Ne passez pas de vrais dossiers patients, de vrais transcripts ASR, ni aucune PHI par ce skill. Si la liste de termes elle-même est sensible (noms de codes de médicaments propriétaires, noms de produits non publiés, indications confidentielles clients), confirmez avec l'utilisateur que la transmission via API externe est acceptable selon la politique de gouvernance des données de son organisation avant de procéder.

Si aucune transmission MW n'est acceptable : prenez le chemin C ci-dessous (ignorez MW ; le pipeline revient à Magpie G2P avec une couverture réduite sur les termes peu fréquents).

Objectif

Curez une liste de termes de spécialité clinique, générez de l'audio d'évaluation pour celle-ci via Magpie TTS avec un pipeline IPA à deux niveaux, et écrivez un manifest au format NeMo balisé avec les champs d'extension clinique (term, entity_category, ipa_source, voice_id, noise_level, context_type). Le résultat est l'entrée de la Stage 3.

À la fin, l'utilisateur dispose de :

$EVAL_DIR/cycle<N>/
├── audio/<slug>.wav        clips synthétisés
├── manifest.jsonl          format NeMo + extension clinique
├── term_seed.csv           l'entrée cuée
└── pronunciation_overrides.csv   ajouté au fur et à mesure des cycles

($EVAL_DIR est le choix de l'utilisateur — ce skill n'impose pas une structure. La structure ci-dessus est une recommandation, non une exigence.)

Quand utiliser ce skill

Activez sur des phrases utilisateur comme :

  • "Construire un benchmark de reconnaissance vocale clinique"
  • "Curer des noms de médicaments / procédures pour l'évaluation ASR"
  • "Générer de l'audio d'évaluation pour les termes médicaux"
  • "Créer un manifest NeMo à partir de termes cliniques"
  • "Ajouter des termes d'oncologie / cardiologie / orthopédie à mon benchmark"
  • "Auditionner la prononciation TTS pour ces noms de médicaments"
  • "Créer un manifest de cycle-N"

N'activez pas quand (aussi : si le message mentionne auth, API key, gRPC, streaming, riva-build, NIM deploy, NGC, ou Docker, routez selon les puces ci-dessous et arrêtez) :

  • L'utilisateur a déjà un manifest et veut le scorer → /digital-health-clinical-asr-eval
  • L'utilisateur veut affiner sur un manifest existant → /digital-health-clinical-asr-finetune
  • L'utilisateur pose des questions TTS / SSML / voice-cloning / voice-catalog génériques → /read-aloud (ou /riva-tts)
  • TTS/ASR auth / API keys / gRPC / streaming/riva-tts ou /riva-asr
  • NIM deploy ou riva-build / riva-deploy flags → /riva-asr-custom ou /riva-tts-custom
  • NGC / Docker / NVIDIA Container Toolkit/riva-nim-setup
  • L'utilisateur pose des questions génériques sur les données synthétiques → /data-designer

Prérequis

  • /digital-health-clinical-asr-setup complétéNVIDIA_API_KEY exporté, dépendances Python installées, les six skills en amont confirmés.
  • /read-aloud (ou /riva-tts) accessible. Magpie hébergée via NVCF est le défaut. Magpie NIM auto-hébergée fonctionne mais ajoute /riva-nim-setup à la chaîne de prérequis.
  • /data-designer accessible. Le template de secours est acceptable pour un premier cycle si /data-designer est indisponible, mais balisez ces lignes pour que les cycles futurs puissent régénérer.
  • Un répertoire de travail que l'utilisateur possède. Le skill recommande $EVAL_DIR/cycle<N>/ mais ne l'impose pas.

Instructions

2a. Entrevue de spécialité → term_seed.csv

Posez une question à la fois. L'objectif est de révéler 4–10 termes candidats avec la bonne entity_category, non d'écrire un manuel.

Questions, dans l'ordre :

  1. Pour quelle spécialité / flux de travail est-ce ? (dictation en oncologie, rapport ICU, admission psy, post-op ortho, …)
  2. Quels modes de défaillance ASR avez-vous observés ? — noms de médicaments, procédures multi-mots, abréviations, conditions composées.
  3. Quels termes reviennent tous les jours par rapport aux difficiles ? — les termes quotidiens courants deviennent la ligne de base de santé ; les termes quotidiens difficiles deviennent le signal.

Proposez 4–10 termes candidats avec entity_category. Confirmez avec l'utilisateur avant d'écrire. Ensuite écrivez term_seed.csv :

term,entity_category
cefazolin,drug
acetabular reamer,procedure
tibial plateau,anatomy
femoroacetabular impingement,condition
hemoglobin a1c,lab
respiratory therapist,role

Le vocabulaire des catégories est fixe. KER en dépend. Valeurs autorisées :

drug | procedure | anatomy | condition | lab | role

Si l'utilisateur propose une nouvelle catégorie, repoussez : soit elle correspond à l'une des six, soit la méthodologie a besoin d'une extension délibérée (qui est le travail d'un cycle futur, non un ajout ad-hoc ponctuel).

2b. Génération de phrases via /data-designer

Briefez /data-designer avec :

Pour chaque ligne de term_seed.csv, générez une ou plusieurs phrases anglaises naturelles intégrant term de manière adaptée à la entity_category de la ligne. Schéma de sortie : {term, entity_category, sentence, context_type}. Générez 3–5 variantes de context_type par terme. Vocabulaire initial de context_type : dictation, handoff, chart_note, history. Longueur de phrase 10–30 mots.

La sortie de cette étape est un fichier de variantes de phrases par terme. N'importe quel nom de fichier convient — choisissez-en un et utilisez-le de manière cohérente dans le répertoire de cycle.

Template de secours. Si /data-designer est indisponible, utilisez un template de secours à 4 entrées (un par context_type) et remplacez term mécaniquement. Balisez ces lignes dans le manifest (context_type est défini, la phrase est juste moins naturelle) pour qu'un cycle futur puisse régénérer.

2c. Balisage IPA à deux niveaux (le levier de qualité porteur de charge)

Chaque terme passe par un pipeline à 3 niveaux, dans l'ordre :

  1. Overridepronunciation_overrides.csv porte l'IPA vérifiée que l'équipe a auditée. Si term correspond à une ligne ici, l'override l'emporte.
  2. Merriam-Webster — pour les termes sans override, récupérez la respelling MW, convertissez en IPA, validez contre l'ensemble de phonèmes en-US de Magpie. Si les deux réussissent, le terme est balisé merriam-webster.
  3. Magpie G2P (secours) — si ni l'override ni MW ne produit un IPA valide, le texte brut est passé au G2P neural de Magpie au moment de la synthèse. La ligne est balisée magpie_g2p.

Chaque ligne du manifest porte le balise ipa_source (override | merriam-webster | magpie_g2p). Le delta entre les lignes merriam-webster et magpie_g2p dans le leaderboard de la Stage 3 est la preuve que la stratégie de prononciation fonctionne — appelez-le explicitement quand vous produisez le leaderboard.

Trois choix de recherche MW — tous balisent merriam-webster. A : API JSON dictionaryapi.com + DICTIONARY_API_KEY (gratuit sur dictionaryapi.com) — recommandé pour utilisation autonome. B : web scrape de merriam-webster.com — pas de clé, fragile aux changements HTML du site ; recette inline dans references/pronunciation-pipeline.md. C : ignorer MW, revenir à Magpie G2P avec une couverture plus faible des termes peu fréquents. Les deux recettes + la table complète respelling→IPA vivent dans references/pronunciation-pipeline.md. La fonction du chemin A prend api_key comme arg (ne lit jamais os.environ) ; passez None pour ignorer MW.

Schéma de pronunciation_overrides.csv :

term,ipa,verified_by,verified_at,notes
cefazolin,sɛfəˈzoʊlɪn,brandoing,2026-05-13,confirmé contre la respelling MW + test auditif

Ajout uniquement au fur et à mesure des cycles. Relancer la construction plus tard récupère automatiquement les nouvelles entrées.

2d. Synthèse en mode QA (ne pas ignorer ce portail)

Avant d'exécuter le produit cartésien complet, synthétisez une wav par terme avec : première voix, bruit propre, contexte par défaut. Auditionnez chaque clip avec l'utilisateur.

Pour chaque terme balisé magpie_g2p, proposez un candidat IPA en utilisant les motifs de suffixes cliniques et validez contre l'ensemble de phonèmes en-US de Magpie avant de suggérer :

Suffixe Motif d'accentuation (exemple)
-mycin …ˈmaɪsɪn (vancomycin, gentamicin)
-prazole …ˈpreɪzoʊl (esomeprazole, omeprazole)
-statin …ˈstætɪn (atorvastatin, rosuvastatin)
-sartan …ˈsɑːrtən (losartan, valsartan)
-azole …ˈeɪzoʊl (fluconazole, ketoconazole)
-cillin …ˈsɪlɪn (amoxicillin, piperacillin)
-parin …ˈpɛərɪn (enoxaparin, heparin)

Motif de validation de phonème — testez en direct le G2P neural en-US de Magpie avec un candidat IPA. Si Magpie accepte le SSML, l'IPA est dans son inventaire. Utilisez les motifs de suffixes ci-dessus comme pré-filtre (heuristique bon marché) et le test direct pour confirmer avant de vous engager sur un override. La recette magpie_validates_ipa(ipa, api_key, voice_id) — un appel de synthèse gRPC NVCF minimal qui retourne True/False échoue-fermé — est dans references/pronunciation-pipeline.md.

Appelez-la une fois par candidat IPA avant de le montrer à l'utilisateur. Avec approbation utilisateur, ajoutez l'IPA vérifié à pronunciation_overrides.csv. Le ipa_source de la ligne bascule de magpie_g2p à override à la génération suivante du manifest.

Portail d'audition HITL avant l'étape 2e — échoue-fermé. Ne synthétisez pas le produit cartésien complet, ne promouvez aucun candidat IPA organisé vers pronunciation_overrides.csv, et n'avancez pas vers la Stage 3 jusqu'à ce que l'une des conditions suivantes se soit explicitement produite en conversation :

  1. L'utilisateur confirme qu'il a auditionné les clips QA et rapporte son verdict par clip (ou par groupe : "l'ensemble MW sonne bien", "corriger pembrolizumab", etc.). Fournissez les commandes afplay (macOS) ou paplay/aplay (Linux) pour que l'utilisateur puisse les jouer — puis arrêtez et attendez sa réponse après écoute. Approbation papier seule via une AskUserQuestion — cliquer "Promouvoir tous" ou "Verrouiller" sans audition — ne satisfait pas ce portail. Valider une IPA avec Magpie prouve qu'elle est dans l'inventaire de phonèmes ; cela ne prouve pas qu'elle correspond à la prononciation voulue. Seules les oreilles de l'utilisateur le font.
  2. L'utilisateur opte explicitement de sauter l'audition pour ce cycle, en langage délibéré (par ex. "passer l'audition, accepter le risque que les mispronunciations diluent le signal KER de la Stage 3 — enregistrer comme caveat de cycle-N"), non comme effet secondaire d'un simple clic. Enregistrez le saut dans une note de niveau cycle (par ex. eval/cycle<N>/cycle_notes.md) pour qu'un opérateur futur puisse voir que l'audition a été reportée.

Magpie NVCF rate-limite agressivement sur les emplois > 100 lignes, et une refonte coûte à la fois des crédits API et du temps horloge — mais le risque plus grand est de livrer un manifest avec de l'audio de référence mal prononcé qui corrompt silencieusement le signal KER de la Stage 3. Le temps passé à auditionner est moins cher que relancer le cycle.

2e. Génération complète du benchmark

Après verrouillage des prononciations, générez le produit cartésien complet |terms| × |voices| × |noise_levels| × |context_types|. Défauts : 2–4 voix Magpie en-US (Mia/Jason/Ray), [clean, snr_15db, snr_5db], [dictation, handoff, chart_note, history].

Synthèse autonome — /read-aloud non requise. La recette synthesize_row(row, all_overrides, out_dir, api_key) — ouvre un stream gRPC NVCF, enveloppe les overrides dans du SSML via render_sentence_with_overrides, écrit PCM mono 16-bit vers <out_dir>/audio/<slug>.wav — est dans references/pronunciation-pipeline.md (§Synthesis call). Invariant clé : all_overrides porte toute entrée de pronunciation_overrides.csv (y compris les overrides de mots de contexte comme intravenously) pour que le rendu enveloppe tout override dont le texte verbatim apparaît dans row['text']. Envelopper uniquement row['term'] supprime silencieusement les overrides de mots de contexte.

L'injection de bruit (clean → snr_15dbsnr_5db) et le schéma du manifest (champs canoniques NeMo + extension clinique, plus tests pré-vol et vérification d'existence d'audio) vivent tous dans references/manifest-schema.md.

Avertissez quand product > 100 lignes. Magpie NVCF rate-limite avec ~5–10% RESOURCE_EXHAUSTED drops sur gros emplois. Relancez les lignes supprimées.

Checklist d'achèvement de la Stage 2

Ne considérez pas la Stage 2 comme faite jusqu'à ce que les cinq sous-étapes aient tourné. Les agents arrêtent souvent après 2a ou 2b ; l'objectif est un manifest synthétisé plus une passation :

  • 2aterm_seed.csv, 4–10 termes, entity_category ∈ {drug, procedure, anatomy, condition, lab, role}
  • 2b — 3–5 variantes context_type de phrase par terme
  • 2c — chaque terme balisé ipa_source ∈ {override, merriam-webster, magpie_g2p}
  • 2d — wavs QA auditionnées, overrides IPA verrouillés avec approbation utilisateur explicite
  • 2emanifest.jsonl + audio par ligne pour le produit cartésien
  • Passation — nommez /digital-health-clinical-asr-eval comme skill suivant et KER comme sa métrique vedette

Les écritures vont uniquement dans le $EVAL_DIR/cycle<N>/ choisi par l'utilisateur. N'écrivez nulle part ailleurs, ne modifiez l'env, ni n'installez de packages — ceux-ci appartiennent à /digital-health-clinical-asr-setup.

Exemples

Scénario A — benchmark oncologie frais. Utilisateur : "Nous voyons des noms de chimiothérapies mal retranscrits. Par où commencer ?" → Étape 2a : confirmez que la spécialité est l'oncologie, demandez lesquels médicaments (biologiques d'immunothérapie, agents platines, taxanes). Proposez ~10 candidats : cisplatin, paclitaxel, pembrolizumab, nivolumab, carboplatin, docetaxel, bevacizumab, trastuzumab, cetuximab, pemetrexed. Écrivez term_seed.csv avec tout entity_category=drug. Étape 2b : briefez /data-designer pour 4 variantes de contexte chacun = 40 phrases. Étape 2c : recherche MW pour chacune — les biologiques comme pembrolizumab reviennent probablement à magpie_g2p ; les agents platines touchent probablement MW. Étape 2d : synthétisez une wav QA par terme, guidez l'utilisateur à travers les clips pembrolizumab etc., proposez des candidats IPA avec motifs d'accentuation -mab. Étape 2e : avec approbation, lancez 10 termes × 2 voix × 2 niveaux bruit × 3 contextes = 120 lignes.

Scénario B — ajout à un cycle existant. Utilisateur : "J'ai un manifest de cycle-1 et je veux ajouter 5 procédures de plus." → Relancez seulement les étapes 2a (entrevue de spécialité juste pour les nouveaux termes), 2b (génération de phrase pour les ajouts), 2c (pipeline IPA pour les ajouts), 2d (audition des nouveaux termes), et 2e (synthèse seulement des lignes des nouveaux termes). Ajoutez au manifest.jsonl existant. Ne régénérez pas l'audio pour les termes existants — l'isolation de cycle est intentionnelle pour que les leaderboards diffent le cycle N par rapport au cycle N+1 proprement.

Artefacts produits

  • term_seed.csv — termes curés avec entity_category
  • pronunciation_overrides.csv — IPA vérifiée, ajouable au fur et à mesure des cycles
  • manifest.jsonl — format NeMo avec champs d'extension clinique (un objet JSON par ligne)
  • audio/<slug>.wav — clips synthétisés, un par ligne du manifest

Dépannage

  • TTS rate-limit drops (RESOURCE_EXHAUSTED) sur génération >100 lignes → attendu sur Magpie NVCF. Confirmez que le backoff exponentiel est actif dans /read-aloud ; attendez ~5–10% drops sur gros emplois et relancez pour les lacunes.
  • Toutes les lignes ipa_source balisées magpie_g2p → la recherche MW échoue partout, ou les candidats IPA échouent la validation de phonème. Re-vérifiez le chemin MW configuré (DICTIONARY_API_KEY pour A ; accessibilité HTTPS + parser pour B), puis vérifiez les candidats contre l'inventaire de phonèmes en-US de Magpie.
  • Magpie malprononce un terme même avec l'override IPA → d'abord vérifiez que l'IPA est dans l'inventaire de phonèmes en-US de Magpie et que l'enveloppe SSML est syntaxiquement valide. Si les deux vérifient, le bug TTS sous-jacent est détenu par /read-aloud (/riva-tts) — routez là pour diagnostic. Ce skill fournit le mécanisme d'override mais ne détient pas le G2P neural ou le parser SSML.
  • Les variantes de phrase de /data-designer sont fades / ressemblent à des templates → vérifiez le brief ; le prompt schema-only produit parfois des résultats stéréotypés. Ajoutez 1–2 exemples en contexte au brief et relancez.
  • Les fichiers audio existent mais manifest.jsonl est court → l'écrivain du manifest a sauté les lignes dont la synthèse a retourné une erreur NVCF. Relancez la construction avec seulement les lignes manquantes.

Pour tout ce qui n'est pas dans cette liste, identifiez quel skill en amont est impliqué et routez là. Le skill digital-health-clinical-asr-build détient la méthodologie, non les internals TTS ou DataDesigner.

Limitations

  • Anglais uniquement par défaut. L'inventaire de phonèmes en-US de Magpie est ce que le pipeline IPA à deux niveaux valide contre. D'autres locales ont besoin d'un ensemble de phonèmes en amont différent + format CSV d'override.
  • Six catégories d'entité fixes. Étendre entity_category est un changement de méthodologie délibéré, non une tweak ponctuelle — les breakdowns KER, sections leaderboard, et scripts de finetune en aval clés dépendent du vocabulaire.
  • Cycles initiaux minuscules. Sous ~20 termes, le split de leaderboard par-ipa_source n'aura pas assez de lignes dans chaque bucket pour être statistiquement significatif. Construisez un cycle significatif même si cela coûte une session.
  • Magpie NVCF rate-limits. ~5–10% drops sur gros emplois ; budgétisez une passe de relance.

Étapes suivantes

  • Avant : /digital-health-clinical-asr-eval — transcrire le manifest, scorer WER/CER/KER/SER, produire le leaderboard à cinq sections.
  • Retour au setup (si quelque chose dans l'env est cassé) : /digital-health-clinical-asr-setup.
  • Latéral pour débogage TTS-spécifique : /read-aloud ou /riva-tts.

Références

  • references/manifest-schema.md — champs canoniques NeMo + extension clinique ; tests pré-vol et vérifications d'existence d'audio ; règles de stabilité inter-cycles

Skills similaires