unknown commited on
Commit
675f962
·
2 Parent(s): fa16b79255bb80

Update ASR LLM Agent

Browse files
README.md CHANGED
@@ -11,22 +11,21 @@ pinned: false
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
 
14
-
15
  ## ASR LLM Agent Upgrade
16
 
17
- This version adds an LLM-based diagnosis layer on top of alignment/event statistics:
18
 
19
- - `analysis/llm_analyzer.py`: sends representative ASR error cases + aggregate stats to an LLM
20
  - `pipeline/run_analysis.py`: optionally runs LLM diagnosis when `OPENAI_API_KEY` is set
21
- - `scripts/run_diagnostic.py`: regenerate `llm_diagnosis.json` and `diagnostic_report.md`
22
- - `report.md`: now includes LLM semantic findings and priority actions
23
 
24
  ### What the LLM adds
25
 
26
  Compared with rule-only classification, the LLM layer can:
27
 
28
  - separate surface-form differences from true semantic distortions
29
- - identify meaning-preserving paraphrases vs business-critical errors
30
  - infer likely causes from representative cases
31
  - propose prioritized, actionable improvement suggestions
32
 
@@ -34,7 +33,7 @@ Compared with rule-only classification, the LLM layer can:
34
 
35
  ```bash
36
  export OPENAI_API_KEY=your_key
37
- python pipeline/run_all.py --manifest data/manifest.jsonl --model_name openai/whisper-small --llm_model gpt-4.1-mini
38
  ```
39
 
40
  Or rerun diagnosis only for an existing run:
@@ -44,10 +43,9 @@ export OPENAI_API_KEY=your_key
44
  python scripts/run_diagnostic.py --run_id <run_id> --model gpt-4.1-mini
45
  ```
46
 
47
-
48
  ## Qwen3-ASR
49
 
50
- This project now supports `Qwen/Qwen3-ASR-0.6B` and `Qwen/Qwen3-ASR-1.7B` via the `qwen-asr` package.
51
 
52
  Install the runtime dependency:
53
 
 
11
 
12
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
13
 
 
14
  ## ASR LLM Agent Upgrade
15
 
16
+ This version adds an LLM-based diagnosis layer on top of alignment and event statistics:
17
 
18
+ - `analysis/llm_analyzer.py`: sends representative ASR error cases and aggregate stats to an LLM
19
  - `pipeline/run_analysis.py`: optionally runs LLM diagnosis when `OPENAI_API_KEY` is set
20
+ - `scripts/run_diagnostic.py`: regenerates `llm_diagnosis.json` and `diagnostic_report.md`
21
+ - `report.md`: includes LLM semantic findings and priority actions
22
 
23
  ### What the LLM adds
24
 
25
  Compared with rule-only classification, the LLM layer can:
26
 
27
  - separate surface-form differences from true semantic distortions
28
+ - identify meaning-preserving paraphrases versus business-critical errors
29
  - infer likely causes from representative cases
30
  - propose prioritized, actionable improvement suggestions
31
 
 
33
 
34
  ```bash
35
  export OPENAI_API_KEY=your_key
36
+ python pipeline/run_all.py --manifest data/manifest.jsonl --model_name openai/whisper-small --llm_model gpt-4.1-mini
37
  ```
38
 
39
  Or rerun diagnosis only for an existing run:
 
43
  python scripts/run_diagnostic.py --run_id <run_id> --model gpt-4.1-mini
44
  ```
45
 
 
46
  ## Qwen3-ASR
47
 
48
+ This project supports `Qwen/Qwen3-ASR-0.6B` and `Qwen/Qwen3-ASR-1.7B` via the `qwen-asr` package.
49
 
50
  Install the runtime dependency:
51
 
data/manifest.jsonl DELETED
@@ -1,2 +0,0 @@
1
- {"utt_id":"u001","audio_uri":"data/audio/u001.wav","ref_text":"今天天气很好","meta":{"device":"mobile","domain":"daily","speaker":"spk1"}}
2
- {"utt_id":"u002","audio_uri":"data/audio/u002.wav","ref_text":"我们下午三点开会","meta":{"device":"farfield","domain":"meeting","speaker":"spk2"}}
 
 
 
data/manifest_hf.jsonl DELETED
@@ -1,50 +0,0 @@
1
- {"utt_id": "fsicoli_common_voice_22_0_00000", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00000.wav", "ref_text": "巴顿是位于美国加利福尼亚州阿马多尔县的一个非建制地区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
2
- {"utt_id": "fsicoli_common_voice_22_0_00001", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00001.wav", "ref_text": "恩骑尉,是中国清朝时的爵名。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
3
- {"utt_id": "fsicoli_common_voice_22_0_00002", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00002.wav", "ref_text": "仙台盐釜港是位于日本宫城县、内的海港,由宫城县政府负责港务营运。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
4
- {"utt_id": "fsicoli_common_voice_22_0_00003", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00003.wav", "ref_text": "利马的阳台是西班牙殖民时期和共和国时期建造的文化遗产。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
5
- {"utt_id": "fsicoli_common_voice_22_0_00004", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00004.wav", "ref_text": "成山,字屏临,号进斋,满洲正蓝旗人。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
6
- {"utt_id": "fsicoli_common_voice_22_0_00005", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00005.wav", "ref_text": "嘉靖十一年任福建龙溪县知县。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
7
- {"utt_id": "fsicoli_common_voice_22_0_00006", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00006.wav", "ref_text": "科莫巴比是位于美国亚利桑那州皮马县的一个人口普查指定地区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
8
- {"utt_id": "fsicoli_common_voice_22_0_00007", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00007.wav", "ref_text": "历史上明永乐皇帝、清干隆皇帝等曾经多次到访,并留下牌匾和诗句。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
9
- {"utt_id": "fsicoli_common_voice_22_0_00008", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00008.wav", "ref_text": "小花仙动画角色列表记录了所有在中国大陆动画《小花仙》系列中出场角色的详细介绍。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
10
- {"utt_id": "fsicoli_common_voice_22_0_00009", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00009.wav", "ref_text": "妳不要再去那里了", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
11
- {"utt_id": "fsicoli_common_voice_22_0_00010", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00010.wav", "ref_text": "银座松竹广场是位于日本东京都中央区筑地一丁目的摩天大楼。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
12
- {"utt_id": "fsicoli_common_voice_22_0_00011", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00011.wav", "ref_text": "儿童权利监察使办公室设于华沙。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
13
- {"utt_id": "fsicoli_common_voice_22_0_00012", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00012.wav", "ref_text": "灰阶音乐是位于香港的一家独立唱片厂牌和音乐出版公司。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
14
- {"utt_id": "fsicoli_common_voice_22_0_00013", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00013.wav", "ref_text": "梁士济,字遂良,广东广州府南海县人,明朝、南明政治人物。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
15
- {"utt_id": "fsicoli_common_voice_22_0_00014", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00014.wav", "ref_text": "姜涛曾就读轩尼诗道官立下午小学、邓肇坚维多利亚官立中学和青年学院。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
16
- {"utt_id": "fsicoli_common_voice_22_0_00015", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00015.wav", "ref_text": "上海江南长兴重工有限责任公司简称长兴重工,厂区位于上海长兴岛船舶制造基地。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
17
- {"utt_id": "fsicoli_common_voice_22_0_00016", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00016.wav", "ref_text": "卢启贤是香港的亿万富翁企业家和慈善家。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
18
- {"utt_id": "fsicoli_common_voice_22_0_00017", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00017.wav", "ref_text": "在这类故事的早期版本里,女人的猪脸外观是由巫术导致的。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
19
- {"utt_id": "fsicoli_common_voice_22_0_00018", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00018.wav", "ref_text": "事件起因据信是天然气爆炸。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
20
- {"utt_id": "fsicoli_common_voice_22_0_00019", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00019.wav", "ref_text": "在工作了九年后,伯爵不幸去世。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
21
- {"utt_id": "fsicoli_common_voice_22_0_00020", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00020.wav", "ref_text": "整个系统称为键接合。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
22
- {"utt_id": "fsicoli_common_voice_22_0_00021", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00021.wav", "ref_text": "大和和纪,日本漫画家,代表作有《窈窕淑女》、《源氏物语》等。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
23
- {"utt_id": "fsicoli_common_voice_22_0_00022", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00022.wav", "ref_text": "事后三天,赵宇被福州市公安局晋安分局以涉嫌故意伤害罪刑事拘留。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
24
- {"utt_id": "fsicoli_common_voice_22_0_00023", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00023.wav", "ref_text": "由春岗互通向萝岗方向排列", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
25
- {"utt_id": "fsicoli_common_voice_22_0_00024", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00024.wav", "ref_text": "弘光帝即位,让刘文照袭封新乐伯,南京沦陷后寄居在高邮,开辟农田种菜直到去世。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "bcb4464171113dd9b51f371c3eecea06771fde83e7e3239ad0516469c6dcdf80170d26c7d1b1ef2476c45b51bfb4ee5549f07d7002bcfcec9b371a30c873b92d", "gender": "male_masculine", "accent": "", "age": "twenties", "locale": "zh-CN"}}
26
- {"utt_id": "fsicoli_common_voice_22_0_00025", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00025.wav", "ref_text": "露露夫人终究与三姐弟达成了协议。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
27
- {"utt_id": "fsicoli_common_voice_22_0_00026", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00026.wav", "ref_text": "武定州,中国唐朝时设置的州。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
28
- {"utt_id": "fsicoli_common_voice_22_0_00027", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00027.wav", "ref_text": "宝陀寺,可以指", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
29
- {"utt_id": "fsicoli_common_voice_22_0_00028", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00028.wav", "ref_text": "去札幌啤酒博物馆", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
30
- {"utt_id": "fsicoli_common_voice_22_0_00029", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00029.wav", "ref_text": "洛莱塔是位于美国加利福尼亚州洪堡县的一个人口普查指定地区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
31
- {"utt_id": "fsicoli_common_voice_22_0_00030", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00030.wav", "ref_text": "许州人。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
32
- {"utt_id": "fsicoli_common_voice_22_0_00031", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00031.wav", "ref_text": "班纳镇区为美国堪萨斯州杰克逊县辖下的镇区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
33
- {"utt_id": "fsicoli_common_voice_22_0_00032", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00032.wav", "ref_text": "范家庄遗址,位于山东省潍坊市坊子区坊城街道。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
34
- {"utt_id": "fsicoli_common_voice_22_0_00033", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00033.wav", "ref_text": "郭新立,河北安国人,出生于北京,中国教育人物,现任山东大学党委书记。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "99a4cee094a7058f27e615982d793da9039f8916c4cb0934eafecb601214cb89657ddee22f688a38782a72f5b6622a323ed6dca74f6663430f8cb3c0804563ea", "gender": "male_masculine", "accent": "出生地:31 上海市", "age": "teens", "locale": "zh-CN"}}
35
- {"utt_id": "fsicoli_common_voice_22_0_00034", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00034.wav", "ref_text": "龟山风景区管理处是下辖的一个类似乡级单位。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
36
- {"utt_id": "fsicoli_common_voice_22_0_00035", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00035.wav", "ref_text": "后来他随着李成栋反正,历任光禄卿、户部右侍郎,兵部左侍郎,永历二年晋兵部尚书。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
37
- {"utt_id": "fsicoli_common_voice_22_0_00036", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00036.wav", "ref_text": "同年加入中国人民解放军。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
38
- {"utt_id": "fsicoli_common_voice_22_0_00037", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00037.wav", "ref_text": "由马可、许亚军领衔主演,并由岳红、柯蓝、王策、孙爽联合主演。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
39
- {"utt_id": "fsicoli_common_voice_22_0_00038", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00038.wav", "ref_text": "生于崎玉县川越市,女子美术大学肄业。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
40
- {"utt_id": "fsicoli_common_voice_22_0_00039", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00039.wav", "ref_text": "旧福布斯敦是位于美国加利福尼亚州比尤特县的一个非建制地区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
41
- {"utt_id": "fsicoli_common_voice_22_0_00040", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00040.wav", "ref_text": "大厅供穆斯林祈祷,这也是他们见面以结束禁食的地方。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
42
- {"utt_id": "fsicoli_common_voice_22_0_00041", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00041.wav", "ref_text": "我们就没办法改善", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
43
- {"utt_id": "fsicoli_common_voice_22_0_00042", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00042.wav", "ref_text": "四号镇区是位于美国阿肯色州本顿县的一个镇区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
44
- {"utt_id": "fsicoli_common_voice_22_0_00043", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00043.wav", "ref_text": "格梅林后来出版了若干本关于化学、制药科学、矿物学和植物学的教科书。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "22950d9b987d2554c0d7130808cc60fcb5255d92bb579ad138f4da5e2d5fc52b02d4639e4fe708ef5b820a04812fd3f530e3ea93abfac3e55c8dc2ad22696403", "gender": "", "accent": "", "age": "", "locale": "zh-CN"}}
45
- {"utt_id": "fsicoli_common_voice_22_0_00044", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00044.wav", "ref_text": "同年获选澳门十大杰出运动员,是首位获奖的篮球员。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "3c71635420e0de3a0272e28a63d340dbaaeb5d99e246668955f38c25279dfdbbd8eec8cc8663601fe11d6cfd81a45f9a2e8a5d55379220fe71d24a00bee0effb", "gender": "male_masculine", "accent": "出生地:42 湖北省", "age": "thirties", "locale": "zh-CN"}}
46
- {"utt_id": "fsicoli_common_voice_22_0_00045", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00045.wav", "ref_text": "阿尔德斯普林斯是位于美国加利福尼亚州弗雷斯诺县的一个非建制地区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "3c71635420e0de3a0272e28a63d340dbaaeb5d99e246668955f38c25279dfdbbd8eec8cc8663601fe11d6cfd81a45f9a2e8a5d55379220fe71d24a00bee0effb", "gender": "male_masculine", "accent": "出生地:42 湖北省", "age": "thirties", "locale": "zh-CN"}}
47
- {"utt_id": "fsicoli_common_voice_22_0_00046", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00046.wav", "ref_text": "巴特勒是位于美国亚利桑那州莫哈维县的一个非建制地区。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "3c71635420e0de3a0272e28a63d340dbaaeb5d99e246668955f38c25279dfdbbd8eec8cc8663601fe11d6cfd81a45f9a2e8a5d55379220fe71d24a00bee0effb", "gender": "male_masculine", "accent": "出生地:42 湖北省", "age": "thirties", "locale": "zh-CN"}}
48
- {"utt_id": "fsicoli_common_voice_22_0_00047", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00047.wav", "ref_text": "最后放弃", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "3c71635420e0de3a0272e28a63d340dbaaeb5d99e246668955f38c25279dfdbbd8eec8cc8663601fe11d6cfd81a45f9a2e8a5d55379220fe71d24a00bee0effb", "gender": "male_masculine", "accent": "出生地:42 湖北省", "age": "thirties", "locale": "zh-CN"}}
49
- {"utt_id": "fsicoli_common_voice_22_0_00048", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00048.wav", "ref_text": "薄刀峰林场,是下辖的一个类似乡级单位。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "3c71635420e0de3a0272e28a63d340dbaaeb5d99e246668955f38c25279dfdbbd8eec8cc8663601fe11d6cfd81a45f9a2e8a5d55379220fe71d24a00bee0effb", "gender": "male_masculine", "accent": "出生地:42 湖北省", "age": "thirties", "locale": "zh-CN"}}
50
- {"utt_id": "fsicoli_common_voice_22_0_00049", "audio_uri": "C:\\Users\\hp\\Desktop\\ASR Agent\\ASR_AGENT_\\data\\hf_audio\\fsicoli_common_voice_22_0_00049.wav", "ref_text": "该季他第一次出赛是在九局上担任普林斯·菲尔德的代跑。", "meta": {"dataset_id": "fsicoli/common_voice_22_0", "dataset_config": "zh-CN", "split": "validation", "text_field": "sentence", "sample_rate": 48000, "client_id": "dfacf81ef98f2b80ebf3a932d8c926f7fa65ffaa8dfc35edefc1344d0e4096cc52dd6cd86f2b29d9ae8dc8bf25d4ac3e0fd6133ed370de7f4e6df6d89193c9b4", "gender": "male_masculine", "accent": "出生地:35 福建省", "age": "twenties", "locale": "zh-CN"}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
pipeline/run_all.py CHANGED
@@ -6,26 +6,36 @@ from pipeline.run_analysis import run_analysis
6
  from pipeline.run_asr import run_asr
7
 
8
 
9
- def main():
 
 
 
10
  ap = argparse.ArgumentParser()
11
  ap.add_argument("--manifest", required=True)
12
  ap.add_argument("--model_name", default="openai/whisper-small")
13
  ap.add_argument("--device", default="cpu")
14
- ap.add_argument("--backend", default="auto", choices=["auto", "whisper_transformers", "qwen3_asr"])
 
 
15
  ap.add_argument("--llm_model", default="gpt-4.1-mini")
16
  ap.add_argument("--disable_llm", action="store_true")
17
- ap.add_argument("--language", default="zh")
18
  args = ap.parse_args()
19
 
20
  run_id = run_asr(
21
  manifest_path=args.manifest,
 
22
  model_repo_id=args.model_name,
23
  device=args.device,
24
  asr_config={"language": args.language},
25
  backend=args.backend,
26
  )
27
- run_analysis(run_id, llm_enabled=not args.disable_llm, llm_model=args.llm_model)
28
- print(f"Done. Run: runs/{run_id}")
 
 
 
 
 
29
 
30
 
31
  if __name__ == "__main__":
 
6
  from pipeline.run_asr import run_asr
7
 
8
 
9
+ BACKEND_CHOICES = ["auto", "whisper_transformers", "qwen3_asr"]
10
+
11
+
12
+ def main() -> None:
13
  ap = argparse.ArgumentParser()
14
  ap.add_argument("--manifest", required=True)
15
  ap.add_argument("--model_name", default="openai/whisper-small")
16
  ap.add_argument("--device", default="cpu")
17
+ ap.add_argument("--backend", default="auto", choices=BACKEND_CHOICES)
18
+ ap.add_argument("--language", default="zh")
19
+ ap.add_argument("--out_root", default="runs")
20
  ap.add_argument("--llm_model", default="gpt-4.1-mini")
21
  ap.add_argument("--disable_llm", action="store_true")
 
22
  args = ap.parse_args()
23
 
24
  run_id = run_asr(
25
  manifest_path=args.manifest,
26
+ out_root=args.out_root,
27
  model_repo_id=args.model_name,
28
  device=args.device,
29
  asr_config={"language": args.language},
30
  backend=args.backend,
31
  )
32
+ run_analysis(
33
+ run_id,
34
+ out_root=args.out_root,
35
+ llm_enabled=not args.disable_llm,
36
+ llm_model=args.llm_model,
37
+ )
38
+ print(f"Done. Run: {args.out_root}/{run_id}")
39
 
40
 
41
  if __name__ == "__main__":
scripts/run_hf_job.py CHANGED
@@ -5,9 +5,7 @@ import json
5
  import os
6
  import sys
7
  from pathlib import Path
8
- from typing import Optional, Dict, Any
9
-
10
- import pandas as pd
11
 
12
  # Ensure project root is on sys.path
13
  PROJECT_ROOT = Path(__file__).resolve().parents[1]
@@ -29,11 +27,6 @@ def build_manifest_from_hf(
29
  num_samples: int,
30
  out_manifest: Path,
31
  ) -> int:
32
- """
33
- Robust HF loader for datasets with audio.
34
- Uses streaming=True and materializes audio to local wav files.
35
- Works well for Common Voice-like datasets when dataset scripts are supported.
36
- """
37
  from datasets import load_dataset
38
  import soundfile as sf
39
 
@@ -96,7 +89,6 @@ def build_manifest_from_hf(
96
  "text_field": text_field,
97
  "sample_rate": sr,
98
  }
99
-
100
  for k in ["client_id", "gender", "accent", "age", "locale"]:
101
  if k in item:
102
  meta[k] = item.get(k)
@@ -121,61 +113,7 @@ def build_manifest_from_hf(
121
  return len(records)
122
 
123
 
124
- def run_diagnostic_pipeline(run_id: str, runs_dir: str = "runs") -> None:
125
- """
126
- Generate:
127
- - root_cause.json
128
- - diagnostic_report.md
129
- under runs/<run_id>/
130
- """
131
- from analysis.root_cause import infer_root_causes
132
- from report.diagnostic_report import generate_report_with_openai
133
- from openai import OpenAI
134
-
135
- run_dir = Path(runs_dir) / run_id
136
-
137
- # aligned.jsonl
138
- aligned_path = run_dir / "aligned.jsonl"
139
- aligned_rows = []
140
- if aligned_path.exists():
141
- with aligned_path.open("r", encoding="utf-8") as f:
142
- for line in f:
143
- line = line.strip()
144
- if line:
145
- aligned_rows.append(json.loads(line))
146
- df_align = pd.DataFrame(aligned_rows)
147
-
148
- # events.parquet
149
- events_path = run_dir / "events.parquet"
150
- df_events = pd.read_parquet(events_path) if events_path.exists() else pd.DataFrame()
151
-
152
- # summary.json
153
- summary_path = run_dir / "summary.json"
154
- summary = json.loads(summary_path.read_text(encoding="utf-8")) if summary_path.exists() else {}
155
-
156
- # Rule/statistics-based diagnosis
157
- root_cause = infer_root_causes(df_events, df_align)
158
- (run_dir / "root_cause.json").write_text(
159
- json.dumps(root_cause, ensure_ascii=False, indent=2),
160
- encoding="utf-8"
161
- )
162
-
163
- # LLM report
164
- api_key = os.getenv("OPENAI_API_KEY", "").strip()
165
- if not api_key:
166
- report_text = (
167
- "# Diagnostic Report\n\n"
168
- "OPENAI_API_KEY is not set, so only root_cause.json was generated.\n\n"
169
- "Please add OPENAI_API_KEY in Hugging Face Space Settings → Secrets."
170
- )
171
- else:
172
- client = OpenAI(api_key=api_key)
173
- report_text = generate_report_with_openai(root_cause, summary, client)
174
-
175
- (run_dir / "diagnostic_report.md").write_text(report_text, encoding="utf-8")
176
-
177
-
178
- def main():
179
  ap = argparse.ArgumentParser()
180
  ap.add_argument("--dataset_id", required=True)
181
  ap.add_argument("--dataset_config", default="")
@@ -186,7 +124,9 @@ def main():
186
  ap.add_argument("--model_repo_id", required=True)
187
  ap.add_argument("--backend", default="auto", choices=["auto", "whisper_transformers", "qwen3_asr"])
188
  ap.add_argument("--language", default="zh")
189
-
 
 
190
  ap.add_argument("--out_root", default="runs")
191
  args = ap.parse_args()
192
 
@@ -196,7 +136,7 @@ def main():
196
  data_dir.mkdir(parents=True, exist_ok=True)
197
  manifest_path = data_dir / "manifest_hf.jsonl"
198
 
199
- print("[1/5] Building manifest from Hugging Face dataset...")
200
  n = build_manifest_from_hf(
201
  dataset_id=args.dataset_id,
202
  dataset_config=args.dataset_config.strip() or None,
@@ -207,28 +147,30 @@ def main():
207
  )
208
  print(f" - Wrote {n} samples to {manifest_path}")
209
 
210
- print("[2/5] Running ASR inference...")
211
  from pipeline.run_asr import run_asr
212
 
213
  run_id = run_asr(
214
  manifest_path=str(manifest_path),
215
  out_root=args.out_root,
216
  model_repo_id=args.model_repo_id,
217
- device="cpu",
218
  asr_config={"language": args.language},
219
  backend=args.backend,
220
  )
221
  print(f" - ASR done. run_id={run_id}")
222
 
223
- print("[3/5] Running analysis (align/events/report)...")
224
  from pipeline.run_analysis import run_analysis
225
 
226
- run_analysis(run_id, out_root=args.out_root)
227
-
228
- print("[4/5] Running diagnostic report...")
229
- run_diagnostic_pipeline(run_id, runs_dir=args.out_root)
 
 
230
 
231
- print("[5/5] Done.")
232
  print(f"Run directory: {Path(args.out_root) / run_id}")
233
 
234
 
 
5
  import os
6
  import sys
7
  from pathlib import Path
8
+ from typing import Any, Dict, Optional
 
 
9
 
10
  # Ensure project root is on sys.path
11
  PROJECT_ROOT = Path(__file__).resolve().parents[1]
 
27
  num_samples: int,
28
  out_manifest: Path,
29
  ) -> int:
 
 
 
 
 
30
  from datasets import load_dataset
31
  import soundfile as sf
32
 
 
89
  "text_field": text_field,
90
  "sample_rate": sr,
91
  }
 
92
  for k in ["client_id", "gender", "accent", "age", "locale"]:
93
  if k in item:
94
  meta[k] = item.get(k)
 
113
  return len(records)
114
 
115
 
116
+ def main() -> None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  ap = argparse.ArgumentParser()
118
  ap.add_argument("--dataset_id", required=True)
119
  ap.add_argument("--dataset_config", default="")
 
124
  ap.add_argument("--model_repo_id", required=True)
125
  ap.add_argument("--backend", default="auto", choices=["auto", "whisper_transformers", "qwen3_asr"])
126
  ap.add_argument("--language", default="zh")
127
+ ap.add_argument("--device", default="cpu")
128
+ ap.add_argument("--llm_model", default="gpt-4.1-mini")
129
+ ap.add_argument("--disable_llm", action="store_true")
130
  ap.add_argument("--out_root", default="runs")
131
  args = ap.parse_args()
132
 
 
136
  data_dir.mkdir(parents=True, exist_ok=True)
137
  manifest_path = data_dir / "manifest_hf.jsonl"
138
 
139
+ print("[1/4] Building manifest from Hugging Face dataset...")
140
  n = build_manifest_from_hf(
141
  dataset_id=args.dataset_id,
142
  dataset_config=args.dataset_config.strip() or None,
 
147
  )
148
  print(f" - Wrote {n} samples to {manifest_path}")
149
 
150
+ print("[2/4] Running ASR inference...")
151
  from pipeline.run_asr import run_asr
152
 
153
  run_id = run_asr(
154
  manifest_path=str(manifest_path),
155
  out_root=args.out_root,
156
  model_repo_id=args.model_repo_id,
157
+ device=args.device,
158
  asr_config={"language": args.language},
159
  backend=args.backend,
160
  )
161
  print(f" - ASR done. run_id={run_id}")
162
 
163
+ print("[3/4] Running analysis and diagnosis...")
164
  from pipeline.run_analysis import run_analysis
165
 
166
+ run_analysis(
167
+ run_id,
168
+ out_root=args.out_root,
169
+ llm_enabled=not args.disable_llm,
170
+ llm_model=args.llm_model,
171
+ )
172
 
173
+ print("[4/4] Done.")
174
  print(f"Run directory: {Path(args.out_root) / run_id}")
175
 
176
 
ui/app.py CHANGED
@@ -4,6 +4,7 @@ import json
4
  import subprocess
5
  import sys
6
  from pathlib import Path
 
7
 
8
  import gradio as gr
9
  import pandas as pd
@@ -13,9 +14,10 @@ RUNS_DIR = Path("runs")
13
  SEMANTIC_JUDGEMENTS = ["ALL", "语义基本等价", "轻微偏差", "明显偏差", "严重失真", "不确定"]
14
  SEVERITIES = ["ALL", "high", "medium", "low"]
15
  BUSINESS_IMPACTS = ["ALL", "high", "medium", "low"]
 
16
 
17
 
18
- def list_runs():
19
  if not RUNS_DIR.exists():
20
  return []
21
  return sorted(
@@ -41,7 +43,7 @@ def _read_jsonl(path: Path):
41
 
42
 
43
  def _normalize_semantic_cell(xs):
44
- def _clean_seq(seq):
45
  out = []
46
  for x in seq:
47
  if x is None:
@@ -95,6 +97,21 @@ def _normalize_semantic_df(df: pd.DataFrame) -> pd.DataFrame:
95
  return out
96
 
97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  def load_run(run_id: str):
99
  run_dir = RUNS_DIR / run_id
100
  meta = _read_json(run_dir / "run_meta.json", {})
@@ -110,10 +127,11 @@ def load_run(run_id: str):
110
  return meta, summary, df_align, df_events, df_semantic, llm_diagnosis, diagnostic_text
111
 
112
 
113
- def build_summary_md(meta, summary, df_semantic: pd.DataFrame | None = None):
114
  lines = []
115
  lines.append(f"### Run ID: `{meta.get('run_id')}`")
116
  lines.append(f"- Model: `{meta.get('model_info')}`")
 
117
  if "wer_mean" in summary and summary["wer_mean"] is not None:
118
  lines.append(f"- WER(mean): **{summary['wer_mean']:.4f}**")
119
  if "cer_mean" in summary and summary["cer_mean"] is not None:
@@ -129,7 +147,7 @@ def build_summary_md(meta, summary, df_semantic: pd.DataFrame | None = None):
129
  return "\n".join(lines)
130
 
131
 
132
- def build_semantic_overview_md(df_semantic: pd.DataFrame, llm_diagnosis: dict):
133
  if df_semantic is None or len(df_semantic) == 0:
134
  return "### Semantic Overview\n暂无 per-utterance LLM 语义诊断结果。请先用配置了 `OPENAI_API_KEY` 的流程跑分析。"
135
  lines = ["### Semantic Overview"]
@@ -175,13 +193,13 @@ def _head_semantic(df_semantic: pd.DataFrame) -> pd.DataFrame:
175
  "semantic_error_types_str", "reason", "ref_text", "hyp_text",
176
  ]
177
  cols = [c for c in cols if c in df_semantic.columns]
178
- return df_semantic.sort_values([c for c in ["business_impact", "severity", "cer"] if c in df_semantic.columns], ascending=[True, True, False][:len([c for c in ["business_impact", "severity", "cer"] if c in df_semantic.columns])]).head(100)[cols]
179
 
180
 
181
  def on_select_run(run_id):
182
  if not run_id:
183
  empty = pd.DataFrame()
184
- return "", empty, empty, empty, "", "No diagnostic report yet.", gr.update(choices=[]), gr.update(choices=[])
185
 
186
  meta, summary, df_align, df_events, df_semantic, llm_diagnosis, diagnostic_text = load_run(run_id)
187
  md = build_summary_md(meta, summary, df_semantic)
@@ -261,10 +279,7 @@ def search_semantic(run_id, judgement, severity, business_impact, semantic_type,
261
  if min_cer is not None and "cer" in q.columns:
262
  q = q[q["cer"].fillna(0) >= float(min_cer)]
263
 
264
- order_cols = [c for c in ["business_impact", "severity", "cer"] if c in q.columns]
265
- if order_cols:
266
- q = q.sort_values(order_cols, ascending=[True, True, False][:len(order_cols)])
267
-
268
  cols = [
269
  "utt_id", "semantic_judgement", "severity", "business_impact", "wer", "cer",
270
  "semantic_error_types_str", "reason", "improvement_suggestions_str", "domain", "accent",
@@ -278,6 +293,7 @@ def apply_backend_preset(backend, model_repo_id, language):
278
  backend = str(backend or "auto").strip()
279
  model_repo_id = str(model_repo_id or "").strip()
280
  language = str(language or "").strip()
 
281
  if backend == "qwen3_asr":
282
  if (not model_repo_id) or ("qwen3-asr" not in model_repo_id.lower()):
283
  model_repo_id = "Qwen/Qwen3-ASR-0.6B"
@@ -285,16 +301,20 @@ def apply_backend_preset(backend, model_repo_id, language):
285
  language = "zh"
286
  info = "Qwen3-ASR 已启用。建议模型:Qwen/Qwen3-ASR-0.6B 或 Qwen/Qwen3-ASR-1.7B。若环境未安装 qwen-asr,任务会失败。"
287
  return model_repo_id, language, info
 
288
  if backend == "whisper_transformers":
289
  if (not model_repo_id) or ("whisper" not in model_repo_id.lower()):
290
  model_repo_id = "openai/whisper-small"
 
 
291
  info = "Whisper Transformers 已启用。"
292
- return model_repo_id, language or "zh", info
 
293
  info = "backend=auto:会根据模型名自动选择适配器;模型名包含 qwen3-asr 时会走 Qwen3-ASR Adapter。"
294
  return model_repo_id or "openai/whisper-small", language or "zh", info
295
 
296
 
297
- def run_hf_job(dataset_id, dataset_config, split, text_field, model_repo_id, backend, language, num_samples):
298
  model_repo_id, language, preset_info = apply_backend_preset(backend, model_repo_id, language)
299
  cmd = [
300
  sys.executable,
@@ -305,16 +325,19 @@ def run_hf_job(dataset_id, dataset_config, split, text_field, model_repo_id, bac
305
  "--model_repo_id", model_repo_id.strip(),
306
  "--backend", str(backend).strip(),
307
  "--language", language.strip(),
 
 
308
  "--num", str(int(num_samples)),
309
  ]
 
 
310
  if dataset_config and dataset_config.strip():
311
  cmd += ["--dataset_config", dataset_config.strip()]
312
 
313
  p = subprocess.run(cmd, capture_output=True, text=True)
314
- out = (p.stdout or "") + ("\n" + (p.stderr or "") if p.stderr else "")
315
  if p.returncode != 0:
316
- out = preset_info + "\n\n" + out
317
- out += "\n\n[HINT] If you see 401/403 for Common Voice: set HF_TOKEN in Space Settings → Secrets, and accept dataset terms on HF."
318
  empty = pd.DataFrame()
319
  return out, gr.update(), "", empty, empty, empty, "", "No diagnostic report yet.", gr.update(), gr.update()
320
 
@@ -325,7 +348,6 @@ def run_hf_job(dataset_id, dataset_config, split, text_field, model_repo_id, bac
325
  else:
326
  md, align_view, events_view, semantic_view, semantic_md, diagnostic_text, type_dd, domain_dd = "", pd.DataFrame(), pd.DataFrame(), pd.DataFrame(), "", "No diagnostic report yet.", gr.update(), gr.update()
327
 
328
- out = preset_info + "\n\n" + out
329
  return out, gr.update(choices=runs, value=latest), md, align_view, events_view, semantic_view, semantic_md, diagnostic_text, type_dd, domain_dd
330
 
331
 
@@ -335,7 +357,7 @@ with gr.Blocks() as demo:
335
  with gr.Accordion("Run from Hugging Face", open=True):
336
  gr.Markdown(
337
  "Fill in a dataset and an ASR model, then click **Run**. "
338
- "If the dataset is gated, set `HF_TOKEN` in Space **Settings Secrets**. "
339
  "For LLM semantic diagnostics, make sure `OPENAI_API_KEY` is available."
340
  )
341
  with gr.Row():
@@ -347,8 +369,12 @@ with gr.Blocks() as demo:
347
  num_samples = gr.Number(label="Num samples", value=50, precision=0)
348
  with gr.Row():
349
  model_repo_id = gr.Textbox(label="HF model repo id", value="openai/whisper-small")
350
- backend = gr.Dropdown(label="ASR backend", choices=["auto", "whisper_transformers", "qwen3_asr"], value="auto")
351
  language = gr.Textbox(label="Language", value="zh")
 
 
 
 
352
  run_btn = gr.Button("Run")
353
  backend_info = gr.Markdown("backend=auto:会根据模型名自动选择适配器;模型名包含 qwen3-asr 时会走 Qwen3-ASR Adapter。")
354
  logs = gr.Textbox(label="Logs", lines=16)
@@ -421,6 +447,6 @@ with gr.Blocks() as demo:
421
 
422
  run_btn.click(
423
  run_hf_job,
424
- inputs=[dataset_id, dataset_config, split, text_field, model_repo_id, backend, language, num_samples],
425
  outputs=[logs, run_dd, summary_md, align_tbl, events_tbl, semantic_tbl, semantic_overview_md, diagnostic_md, semantic_type, semantic_domain],
426
  )
 
4
  import subprocess
5
  import sys
6
  from pathlib import Path
7
+ from typing import Iterable
8
 
9
  import gradio as gr
10
  import pandas as pd
 
14
  SEMANTIC_JUDGEMENTS = ["ALL", "语义基本等价", "轻微偏差", "明显偏差", "严重失真", "不确定"]
15
  SEVERITIES = ["ALL", "high", "medium", "low"]
16
  BUSINESS_IMPACTS = ["ALL", "high", "medium", "low"]
17
+ _BACKEND_CHOICES = ["auto", "whisper_transformers", "qwen3_asr"]
18
 
19
 
20
+ def list_runs() -> list[str]:
21
  if not RUNS_DIR.exists():
22
  return []
23
  return sorted(
 
43
 
44
 
45
  def _normalize_semantic_cell(xs):
46
+ def _clean_seq(seq: Iterable):
47
  out = []
48
  for x in seq:
49
  if x is None:
 
97
  return out
98
 
99
 
100
+ def _apply_priority_order(df: pd.DataFrame) -> pd.DataFrame:
101
+ if df is None or len(df) == 0:
102
+ return df
103
+ out = df.copy()
104
+ if "business_impact" in out.columns:
105
+ out["business_impact"] = pd.Categorical(out["business_impact"], categories=["high", "medium", "low"], ordered=True)
106
+ if "severity" in out.columns:
107
+ out["severity"] = pd.Categorical(out["severity"], categories=["high", "medium", "low"], ordered=True)
108
+ order_cols = [c for c in ["business_impact", "severity", "cer"] if c in out.columns]
109
+ if order_cols:
110
+ ascending = [True if c != "cer" else False for c in order_cols]
111
+ out = out.sort_values(order_cols, ascending=ascending, na_position="last")
112
+ return out
113
+
114
+
115
  def load_run(run_id: str):
116
  run_dir = RUNS_DIR / run_id
117
  meta = _read_json(run_dir / "run_meta.json", {})
 
127
  return meta, summary, df_align, df_events, df_semantic, llm_diagnosis, diagnostic_text
128
 
129
 
130
+ def build_summary_md(meta, summary, df_semantic: pd.DataFrame | None = None) -> str:
131
  lines = []
132
  lines.append(f"### Run ID: `{meta.get('run_id')}`")
133
  lines.append(f"- Model: `{meta.get('model_info')}`")
134
+ lines.append(f"- Backend: `{meta.get('backend', 'unknown')}`")
135
  if "wer_mean" in summary and summary["wer_mean"] is not None:
136
  lines.append(f"- WER(mean): **{summary['wer_mean']:.4f}**")
137
  if "cer_mean" in summary and summary["cer_mean"] is not None:
 
147
  return "\n".join(lines)
148
 
149
 
150
+ def build_semantic_overview_md(df_semantic: pd.DataFrame, llm_diagnosis: dict) -> str:
151
  if df_semantic is None or len(df_semantic) == 0:
152
  return "### Semantic Overview\n暂无 per-utterance LLM 语义诊断结果。请先用配置了 `OPENAI_API_KEY` 的流程跑分析。"
153
  lines = ["### Semantic Overview"]
 
193
  "semantic_error_types_str", "reason", "ref_text", "hyp_text",
194
  ]
195
  cols = [c for c in cols if c in df_semantic.columns]
196
+ return _apply_priority_order(df_semantic).head(100)[cols]
197
 
198
 
199
  def on_select_run(run_id):
200
  if not run_id:
201
  empty = pd.DataFrame()
202
+ return "", empty, empty, empty, "", "No diagnostic report yet.", gr.update(choices=["ALL"], value="ALL"), gr.update(choices=["ALL"], value="ALL")
203
 
204
  meta, summary, df_align, df_events, df_semantic, llm_diagnosis, diagnostic_text = load_run(run_id)
205
  md = build_summary_md(meta, summary, df_semantic)
 
279
  if min_cer is not None and "cer" in q.columns:
280
  q = q[q["cer"].fillna(0) >= float(min_cer)]
281
 
282
+ q = _apply_priority_order(q)
 
 
 
283
  cols = [
284
  "utt_id", "semantic_judgement", "severity", "business_impact", "wer", "cer",
285
  "semantic_error_types_str", "reason", "improvement_suggestions_str", "domain", "accent",
 
293
  backend = str(backend or "auto").strip()
294
  model_repo_id = str(model_repo_id or "").strip()
295
  language = str(language or "").strip()
296
+
297
  if backend == "qwen3_asr":
298
  if (not model_repo_id) or ("qwen3-asr" not in model_repo_id.lower()):
299
  model_repo_id = "Qwen/Qwen3-ASR-0.6B"
 
301
  language = "zh"
302
  info = "Qwen3-ASR 已启用。建议模型:Qwen/Qwen3-ASR-0.6B 或 Qwen/Qwen3-ASR-1.7B。若环境未安装 qwen-asr,任务会失败。"
303
  return model_repo_id, language, info
304
+
305
  if backend == "whisper_transformers":
306
  if (not model_repo_id) or ("whisper" not in model_repo_id.lower()):
307
  model_repo_id = "openai/whisper-small"
308
+ if not language:
309
+ language = "zh"
310
  info = "Whisper Transformers 已启用。"
311
+ return model_repo_id, language, info
312
+
313
  info = "backend=auto:会根据模型名自动选择适配器;模型名包含 qwen3-asr 时会走 Qwen3-ASR Adapter。"
314
  return model_repo_id or "openai/whisper-small", language or "zh", info
315
 
316
 
317
+ def run_hf_job(dataset_id, dataset_config, split, text_field, model_repo_id, backend, language, device, llm_model, disable_llm, num_samples):
318
  model_repo_id, language, preset_info = apply_backend_preset(backend, model_repo_id, language)
319
  cmd = [
320
  sys.executable,
 
325
  "--model_repo_id", model_repo_id.strip(),
326
  "--backend", str(backend).strip(),
327
  "--language", language.strip(),
328
+ "--device", str(device).strip(),
329
+ "--llm_model", str(llm_model).strip(),
330
  "--num", str(int(num_samples)),
331
  ]
332
+ if disable_llm:
333
+ cmd.append("--disable_llm")
334
  if dataset_config and dataset_config.strip():
335
  cmd += ["--dataset_config", dataset_config.strip()]
336
 
337
  p = subprocess.run(cmd, capture_output=True, text=True)
338
+ out = preset_info + "\n\n" + (p.stdout or "") + ("\n" + (p.stderr or "") if p.stderr else "")
339
  if p.returncode != 0:
340
+ out += "\n\n[HINT] If you see 401/403 for Common Voice: set HF_TOKEN in Space Settings -> Secrets, and accept dataset terms on HF."
 
341
  empty = pd.DataFrame()
342
  return out, gr.update(), "", empty, empty, empty, "", "No diagnostic report yet.", gr.update(), gr.update()
343
 
 
348
  else:
349
  md, align_view, events_view, semantic_view, semantic_md, diagnostic_text, type_dd, domain_dd = "", pd.DataFrame(), pd.DataFrame(), pd.DataFrame(), "", "No diagnostic report yet.", gr.update(), gr.update()
350
 
 
351
  return out, gr.update(choices=runs, value=latest), md, align_view, events_view, semantic_view, semantic_md, diagnostic_text, type_dd, domain_dd
352
 
353
 
 
357
  with gr.Accordion("Run from Hugging Face", open=True):
358
  gr.Markdown(
359
  "Fill in a dataset and an ASR model, then click **Run**. "
360
+ "If the dataset is gated, set `HF_TOKEN` in Space **Settings -> Secrets**. "
361
  "For LLM semantic diagnostics, make sure `OPENAI_API_KEY` is available."
362
  )
363
  with gr.Row():
 
369
  num_samples = gr.Number(label="Num samples", value=50, precision=0)
370
  with gr.Row():
371
  model_repo_id = gr.Textbox(label="HF model repo id", value="openai/whisper-small")
372
+ backend = gr.Dropdown(label="ASR backend", choices=_BACKEND_CHOICES, value="auto")
373
  language = gr.Textbox(label="Language", value="zh")
374
+ with gr.Row():
375
+ device = gr.Dropdown(label="Device", choices=["cpu", "cuda"], value="cpu")
376
+ llm_model = gr.Textbox(label="LLM model", value="gpt-4.1-mini")
377
+ disable_llm = gr.Checkbox(label="Disable LLM diagnosis", value=False)
378
  run_btn = gr.Button("Run")
379
  backend_info = gr.Markdown("backend=auto:会根据模型名自动选择适配器;模型名包含 qwen3-asr 时会走 Qwen3-ASR Adapter。")
380
  logs = gr.Textbox(label="Logs", lines=16)
 
447
 
448
  run_btn.click(
449
  run_hf_job,
450
+ inputs=[dataset_id, dataset_config, split, text_field, model_repo_id, backend, language, device, llm_model, disable_llm, num_samples],
451
  outputs=[logs, run_dd, summary_md, align_tbl, events_tbl, semantic_tbl, semantic_overview_md, diagnostic_md, semantic_type, semantic_domain],
452
  )