<!-- 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-ttsou/riva-asr - NIM deploy ou
riva-build/riva-deployflags →/riva-asr-customou/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-setupcomplété —NVIDIA_API_KEYexporté, 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-designeraccessible. Le template de secours est acceptable pour un premier cycle si/data-designerest 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 :
- Pour quelle spécialité / flux de travail est-ce ? (dictation en oncologie, rapport ICU, admission psy, post-op ortho, …)
- Quels modes de défaillance ASR avez-vous observés ? — noms de médicaments, procédures multi-mots, abréviations, conditions composées.
- 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égranttermde manière adaptée à laentity_categoryde la ligne. Schéma de sortie :{term, entity_category, sentence, context_type}. Générez 3–5 variantes decontext_typepar terme. Vocabulaire initial decontext_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 :
- Override —
pronunciation_overrides.csvporte l'IPA vérifiée que l'équipe a auditée. Sitermcorrespond à une ligne ici, l'override l'emporte. - 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. - 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 :
- 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 commandesafplay(macOS) oupaplay/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. - 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_15db → snr_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 :
- 2a —
term_seed.csv, 4–10 termes,entity_category ∈ {drug, procedure, anatomy, condition, lab, role} - 2b — 3–5 variantes
context_typede 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
- 2e —
manifest.jsonl+ audio par ligne pour le produit cartésien - Passation — nommez
/digital-health-clinical-asr-evalcomme 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 avecentity_categorypronunciation_overrides.csv— IPA vérifiée, ajouable au fur et à mesure des cyclesmanifest.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_sourcebaliséesmagpie_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-designersont 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.jsonlest 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_categoryest 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_sourcen'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-aloudou/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