timliau commited on
Commit
5795f0d
·
verified ·
1 Parent(s): 058afb3

Add model card with research background and usage instructions

Browse files
Files changed (1) hide show
  1. README.md +122 -0
README.md ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ language:
3
+ - en
4
+ - zh
5
+ license: apache-2.0
6
+ library_name: transformers
7
+ pipeline_tag: automatic-speech-recognition
8
+ tags:
9
+ - whisper
10
+ - code-switching
11
+ - asr
12
+ - peft
13
+ - lora
14
+ - mandarin
15
+ - english
16
+ - customer-service
17
+ datasets:
18
+ - CAiRE/ASCEND
19
+ base_model: openai/whisper-small
20
+ ---
21
+
22
+ # Whisper-Small for English-Chinese Code-Switching ASR
23
+
24
+ Fine-tuned [openai/whisper-small](https://huggingface.co/openai/whisper-small) (244M params) for **English-Chinese (Mandarin) code-switching** automatic speech recognition, targeting **customer service** use cases.
25
+
26
+ ## Training Recipe
27
+
28
+ | Component | Detail |
29
+ |-----------|--------|
30
+ | **Base Model** | `openai/whisper-small` (244M params) |
31
+ | **Method** | LoRA (r=32, α=64) on `q_proj`, `v_proj`, `k_proj`, `out_proj` |
32
+ | **Dataset** | [CAiRE/ASCEND](https://huggingface.co/datasets/CAiRE/ASCEND) — 10.62h spontaneous EN-ZH code-switching |
33
+ | **Key Trick** | Switching Tokenizer: language-aware prefix tokens per utterance |
34
+ | **Optimizer** | AdamW, lr=1e-3, warmup=100 steps |
35
+ | **Epochs** | 10 |
36
+ | **Batch Size** | 8 × 2 gradient accumulation = 16 effective |
37
+ | **Hardware** | A10G (24GB VRAM) |
38
+
39
+ ### Literature Basis
40
+
41
+ This model implements findings from multiple papers:
42
+
43
+ 1. **"Improving Code Switching with SFT and GELU Adapters"** ([2506.00291](https://arxiv.org/abs/2506.00291)) — Switching Tokenizer trick reduces ASCEND Total MER from 25.5% → 17.1% (→ 9.4% with GELU adapters)
44
+ 2. **"LoRA-Whisper: Parameter-Efficient Multilingual ASR"** ([2406.06619](https://arxiv.org/abs/2406.06619)) — LoRA r=32 optimal, matches full fine-tuning at 5% trainable params
45
+ 3. **"CS-Dialogue"** ([2502.18913](https://arxiv.org/abs/2502.18913)) — Whisper-Medium fine-tuned achieves 7.53% MER on 104h code-switching dialogue
46
+
47
+ ### Critical Design Decisions
48
+
49
+ - **`forced_decoder_ids = None`**: Disabled so the model can handle code-switching (default forces single language)
50
+ - **`suppress_tokens = []`**: Allow all tokens including both language tokens
51
+ - **Language-aware tokenization**: Chinese utterances use `<|zh|>` prefix, English use `<|en|>`, mixed use `<|zh|>` (matrix language)
52
+ - **No new tokens added**: Adding tokens to Whisper's tokenizer breaks pretrained embeddings (per 2506.00291)
53
+
54
+ ## Usage
55
+
56
+ ### Inference
57
+
58
+ ```python
59
+ from transformers import WhisperProcessor, WhisperForConditionalGeneration
60
+ from peft import PeftModel
61
+ import torch
62
+
63
+ # Load base model + LoRA adapter
64
+ processor = WhisperProcessor.from_pretrained("timliau/whisper-small-zh-en-code-switching")
65
+ base_model = WhisperForConditionalGeneration.from_pretrained("openai/whisper-small")
66
+ model = PeftModel.from_pretrained(base_model, "timliau/whisper-small-zh-en-code-switching")
67
+ model = model.merge_and_unload() # merge LoRA for faster inference
68
+
69
+ # Disable forced language
70
+ model.config.forced_decoder_ids = None
71
+ model.config.suppress_tokens = []
72
+
73
+ # Transcribe
74
+ import librosa
75
+ audio, sr = librosa.load("your_audio.wav", sr=16000)
76
+ input_features = processor.feature_extractor(audio, sampling_rate=16000, return_tensors="pt").input_features
77
+
78
+ with torch.no_grad():
79
+ predicted_ids = model.generate(input_features)
80
+
81
+ transcription = processor.tokenizer.batch_decode(predicted_ids, skip_special_tokens=True)[0]
82
+ print(transcription)
83
+ # Example output: "我刚刚跟customer service讲了一下他们说可以refund"
84
+ ```
85
+
86
+ ### Training
87
+
88
+ ```bash
89
+ pip install transformers datasets peft accelerate evaluate jiwer librosa soundfile torch trackio
90
+ python train.py
91
+ ```
92
+
93
+ ## Dataset: CAiRE/ASCEND
94
+
95
+ - **10.62 hours** of spontaneous code-switching conversation
96
+ - **23 bilingual speakers** from Hong Kong
97
+ - **3 splits**: train (~8.5h), validation (~1h), test (~1h)
98
+ - **Language labels**: `zh`, `en`, `mixed` per utterance
99
+
100
+ | Language | Train Count |
101
+ |----------|-------------|
102
+ | mixed | ~5,000 |
103
+ | zh | ~3,500 |
104
+ | en | ~1,500 |
105
+
106
+ ## Improving Further
107
+
108
+ For better performance, consider:
109
+
110
+ 1. **Scale up base model**: Use `openai/whisper-large-v3` (1.5B params) — literature shows larger = better for code-switching
111
+ 2. **Add GELU encoder adapters**: The paper's Part 2 (GELU adapters) pushes MER from 17.1% → 9.4%
112
+ 3. **More data**: Apply for [SEAME](https://catalog.ldc.upenn.edu/) (115h EN-ZH CS) or [CS-Dialogue](https://arxiv.org/abs/2502.18913) (104h)
113
+ 4. **SenseVoice alternative**: [FunAudioLLM/SenseVoiceSmall](https://huggingface.co/FunAudioLLM/SenseVoiceSmall) achieves 6.71% MER zero-shot on code-switching + has built-in emotion detection (great for customer service)
114
+ 5. **Domain adaptation**: Fine-tune further on your own customer service call recordings
115
+
116
+ ## Evaluation Metrics
117
+
118
+ The standard metric for code-switching ASR is **Mixed Error Rate (MER)** — a combination of Word Error Rate (WER) for English segments and Character Error Rate (CER) for Chinese segments.
119
+
120
+ ## License
121
+
122
+ Apache 2.0 (same as Whisper)