Skip to content

Commit 79d7e13

Browse files
authored
Export GigaAM v3 to sherpa-onnx (#2901)
1 parent a6a36e8 commit 79d7e13

9 files changed

Lines changed: 812 additions & 0 deletions

.github/workflows/export-nemo-giga-am-to-onnx.yaml

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
name: export-nemo-giga-am-to-onnx
22

33
on:
4+
push:
5+
branches:
6+
- export-giga-am-v3
47
workflow_dispatch:
58

69
concurrency:
@@ -27,6 +30,7 @@ jobs:
2730
python-version: ${{ matrix.python-version }}
2831

2932
- name: Run CTC
33+
if: false
3034
shell: bash
3135
run: |
3236
pushd scripts/nemo/GigaAM
@@ -53,6 +57,7 @@ jobs:
5357
tar cjvf ${d}.tar.bz2 $d
5458
5559
- name: Run Transducer
60+
if: false
5661
shell: bash
5762
run: |
5863
pushd scripts/nemo/GigaAM
@@ -82,6 +87,7 @@ jobs:
8287
tar cjvf ${d}.tar.bz2 $d
8388
8489
- name: Run CTC v2
90+
if: false
8591
shell: bash
8692
run: |
8793
pushd scripts/nemo/GigaAM
@@ -107,6 +113,7 @@ jobs:
107113
tar cjvf ${d}.tar.bz2 $d
108114
109115
- name: Run Transducer v2
116+
if: false
110117
shell: bash
111118
run: |
112119
pushd scripts/nemo/GigaAM
@@ -134,6 +141,123 @@ jobs:
134141
135142
tar cjvf ${d}.tar.bz2 $d
136143
144+
- name: Run CTC v3
145+
if: true
146+
shell: bash
147+
run: |
148+
pushd scripts/nemo/GigaAM
149+
./run-ctc-v3.sh
150+
popd
151+
152+
d=sherpa-onnx-nemo-ctc-giga-am-v3-russian-2025-12-16
153+
mkdir $d
154+
mkdir $d/test_wavs
155+
ls -lh scripts/nemo/GigaAM/v3_ctc.onnx
156+
rm scripts/nemo/GigaAM/v3_ctc.onnx
157+
cp -v scripts/nemo/GigaAM/*.md $d/
158+
mv -v scripts/nemo/GigaAM/*.int8.onnx $d/
159+
cp -v scripts/nemo/GigaAM/LICENSE $d/
160+
mv -v scripts/nemo/GigaAM/tokens.txt $d/
161+
mv -v scripts/nemo/GigaAM/*.wav $d/test_wavs/
162+
mv -v scripts/nemo/GigaAM/run-ctc-v3.sh $d/
163+
mv -v scripts/nemo/GigaAM/*-ctc-v3.py $d/
164+
cp -v scripts/nemo/GigaAM/test-onnx-ctc.py $d/
165+
166+
ls -lh scripts/nemo/GigaAM/
167+
168+
ls -lh $d
169+
170+
tar cjvf ${d}.tar.bz2 $d
171+
172+
ls -lh *.tar.bz2
173+
174+
- name: Run CTC v3 with punctuations
175+
if: true
176+
shell: bash
177+
run: |
178+
pushd scripts/nemo/GigaAM
179+
./run-ctc-v3-punct.sh
180+
popd
181+
182+
d=sherpa-onnx-nemo-ctc-punct-giga-am-v3-russian-2025-12-16
183+
mkdir $d
184+
mkdir $d/test_wavs
185+
rm scripts/nemo/GigaAM/v3_e2e_ctc.onnx
186+
cp -v scripts/nemo/GigaAM/*.md $d/
187+
mv -v scripts/nemo/GigaAM/*.int8.onnx $d/
188+
cp -v scripts/nemo/GigaAM/LICENSE $d/
189+
mv -v scripts/nemo/GigaAM/tokens.txt $d/
190+
mv -v scripts/nemo/GigaAM/*.wav $d/test_wavs/
191+
mv -v scripts/nemo/GigaAM/run-ctc-v3-punct.sh $d/
192+
mv -v scripts/nemo/GigaAM/*-ctc-v3-punct.py $d/
193+
cp -v scripts/nemo/GigaAM/test-onnx-ctc.py $d/
194+
195+
ls -lh scripts/nemo/GigaAM/
196+
197+
ls -lh $d
198+
199+
tar cjvf ${d}.tar.bz2 $d
200+
201+
ls -lh *.tar.bz2
202+
203+
- name: Run Transducer v3
204+
if: false
205+
shell: bash
206+
run: |
207+
pushd scripts/nemo/GigaAM
208+
./run-rnnt-v3.sh
209+
popd
210+
211+
d=sherpa-onnx-nemo-transducer-giga-am-v3-russian-2025-12-16
212+
mkdir $d
213+
mkdir $d/test_wavs
214+
215+
mv -v scripts/nemo/GigaAM/encoder.int8.onnx $d/
216+
mv -v scripts/nemo/GigaAM/decoder.onnx $d/
217+
mv -v scripts/nemo/GigaAM/joiner.onnx $d/
218+
219+
cp -v scripts/nemo/GigaAM/*.md $d/
220+
cp -v scripts/nemo/GigaAM/LICENSE $d/
221+
mv -v scripts/nemo/GigaAM/tokens.txt $d/
222+
mv -v scripts/nemo/GigaAM/*.wav $d/test_wavs/
223+
mv -v scripts/nemo/GigaAM/run-rnnt-v3.sh $d/
224+
cp -v scripts/nemo/GigaAM/test-onnx-rnnt.py $d/
225+
226+
ls -lh scripts/nemo/GigaAM/
227+
228+
ls -lh $d
229+
230+
tar cjvf ${d}.tar.bz2 $d
231+
232+
- name: Run Transducer v3 with punctuations
233+
if: false
234+
shell: bash
235+
run: |
236+
pushd scripts/nemo/GigaAM
237+
./run-rnnt-v3-punct.sh
238+
popd
239+
240+
d=sherpa-onnx-nemo-transducer-punct-giga-am-v3-russian-2025-12-16
241+
mkdir $d
242+
mkdir $d/test_wavs
243+
244+
mv -v scripts/nemo/GigaAM/encoder.int8.onnx $d/
245+
mv -v scripts/nemo/GigaAM/decoder.onnx $d/
246+
mv -v scripts/nemo/GigaAM/joiner.onnx $d/
247+
248+
cp -v scripts/nemo/GigaAM/*.md $d/
249+
cp -v scripts/nemo/GigaAM/LICENSE $d/
250+
mv -v scripts/nemo/GigaAM/tokens.txt $d/
251+
mv -v scripts/nemo/GigaAM/*.wav $d/test_wavs/
252+
mv -v scripts/nemo/GigaAM/run-rnnt-v3-punct.sh $d/
253+
cp -v scripts/nemo/GigaAM/test-onnx-rnnt.py $d/
254+
255+
ls -lh scripts/nemo/GigaAM/
256+
257+
ls -lh $d
258+
259+
tar cjvf ${d}.tar.bz2 $d
260+
137261
- name: Release
138262
if: github.repository_owner == 'csukuangfj'
139263
uses: svenstaro/upload-release-action@v2
@@ -155,6 +279,7 @@ jobs:
155279
tag: asr-models
156280

157281
- name: Publish to huggingface (CTC)
282+
if: false
158283
env:
159284
HF_TOKEN: ${{ secrets.HF_TOKEN }}
160285
uses: nick-fields/retry@v3
@@ -182,6 +307,7 @@ jobs:
182307
git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d main
183308
184309
- name: Publish to huggingface (Transducer)
310+
if: false
185311
env:
186312
HF_TOKEN: ${{ secrets.HF_TOKEN }}
187313
uses: nick-fields/retry@v3
@@ -209,6 +335,7 @@ jobs:
209335
git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d main
210336
211337
- name: Publish v2 to huggingface (CTC)
338+
if: false
212339
env:
213340
HF_TOKEN: ${{ secrets.HF_TOKEN }}
214341
uses: nick-fields/retry@v3
@@ -236,6 +363,7 @@ jobs:
236363
git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d main
237364
238365
- name: Publish v2 to huggingface (Transducer)
366+
if: false
239367
env:
240368
HF_TOKEN: ${{ secrets.HF_TOKEN }}
241369
uses: nick-fields/retry@v3
@@ -261,3 +389,44 @@ jobs:
261389
git status
262390
git commit -m "add models"
263391
git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d main
392+
393+
- name: Publish v3 to huggingface
394+
if: true
395+
env:
396+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
397+
uses: nick-fields/retry@v3
398+
with:
399+
max_attempts: 5
400+
timeout_seconds: 200
401+
shell: bash
402+
command: |
403+
git config --global user.email "csukuangfj@gmail.com"
404+
git config --global user.name "Fangjun Kuang"
405+
406+
names=(
407+
sherpa-onnx-nemo-ctc-giga-am-v3-russian-2025-12-16
408+
sherpa-onnx-nemo-ctc-punct-giga-am-v3-russian-2025-12-16
409+
sherpa-onnx-nemo-transducer-giga-am-v3-russian-2025-12-16
410+
sherpa-onnx-nemo-transducer-punct-giga-am-v3-russian-2025-12-16
411+
)
412+
for d in ${names[@]}; do
413+
if [ ! -d $d ]; then
414+
echo "$d does not exist - skip it"
415+
continue;
416+
fi
417+
418+
export GIT_LFS_SKIP_SMUDGE=1
419+
export GIT_CLONE_PROTECTION_ACTIVE=false
420+
rm -rf huggingface
421+
git clone https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d huggingface
422+
cp -av $d/* ./huggingface
423+
cd huggingface
424+
git lfs track "*.onnx"
425+
git lfs track "*.wav"
426+
git status
427+
git add .
428+
git status
429+
git commit -m "add models"
430+
git push https://csukuangfj:$HF_TOKEN@huggingface.co/csukuangfj/$d main
431+
cd ..
432+
done
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env python3
2+
# Copyright 2025 Xiaomi Corp. (authors: Fangjun Kuang)
3+
4+
import gigaam
5+
import onnx
6+
import torch
7+
from onnxruntime.quantization import QuantType, quantize_dynamic
8+
9+
"""
10+
==========Input==========
11+
NodeArg(name='features', type='tensor(float)', shape=['batch_size', 64, 'seq_len'])
12+
NodeArg(name='feature_lengths', type='tensor(int64)', shape=['batch_size'])
13+
==========Output==========
14+
NodeArg(name='log_probs', type='tensor(float)', shape=['batch_size', 'seq_len', 257])
15+
"""
16+
17+
18+
def add_meta_data(filename: str, meta_data: dict[str, str]):
19+
"""Add meta data to an ONNX model. It is changed in-place.
20+
21+
Args:
22+
filename:
23+
Filename of the ONNX model to be changed.
24+
meta_data:
25+
Key-value pairs.
26+
"""
27+
model = onnx.load(filename)
28+
while len(model.metadata_props):
29+
model.metadata_props.pop()
30+
31+
for key, value in meta_data.items():
32+
meta = model.metadata_props.add()
33+
meta.key = key
34+
meta.value = str(value)
35+
36+
onnx.save(model, filename)
37+
38+
39+
"""
40+
{'model_class': 'ctc', 'sample_rate': 16000, 'preprocessor': {'_target_': 'gigaam.preprocess.FeatureExtractor',
41+
'sample_rate': 16000, 'features': 64, 'win_length': 320, 'hop_length': 160, 'mel_scale': 'htk', 'n_fft': 320,
42+
'mel_norm': None, 'center': False}, 'encoder': {'_target_': 'gigaam.encoder.ConformerEncoder', 'feat_in': 64,
43+
'n_layers': 16, 'd_model': 768, 'subsampling': 'conv1d', 'subs_kernel_size': 5, 'subsampling_factor': 4,
44+
'ff_expansion_factor': 4, 'self_attention_model': 'rotary', 'pos_emb_max_len': 5000, 'n_heads': 16,
45+
'conv_kernel_size': 5, 'flash_attn': False, 'conv_norm_type': 'layer_norm'}, 'head': {'_target_':
46+
'gigaam.decoder.CTCHead', 'feat_in': 768, 'num_classes': 257}, 'decoding': {'_target_':
47+
'gigaam.decoding.CTCGreedyDecoding', 'vocabulary': None,
48+
'model_path': '/root/.cache/gigaam/v3_e2e_ctc_tokenizer.model'},
49+
'model_name': 'v3_e2e_ctc', 'hashes': {'model': 'c15fd0dbca70363a146016d197ee0e2a',
50+
'tokenizer': '2a9cd0c246db42d076e92abb31055deb'}}
51+
"""
52+
53+
54+
def main() -> None:
55+
model_name = "v3_e2e_ctc"
56+
model = gigaam.load_model(model_name)
57+
58+
# <blk> is the last token
59+
sp = model.decoding.tokenizer.model
60+
with open("./tokens.txt", "w", encoding="utf-8") as f:
61+
for i in range(sp.vocab_size()):
62+
f.write(f"{sp.id_to_piece(i)} {i}\n")
63+
64+
f.write(f"<blk> {i+1}\n")
65+
print("Saved to tokens.txt")
66+
model.to_onnx(".")
67+
meta_data = {
68+
"vocab_size": sp.vocab_size() + 1,
69+
"normalize_type": "",
70+
"subsampling_factor": 4,
71+
"model_type": "EncDecCTCModel",
72+
"version": "1",
73+
"model_author": "https://github.com/salute-developers/GigaAM",
74+
"license": "https://github.com/salute-developers/GigaAM/blob/main/LICENSE",
75+
"language": "Russian",
76+
"comment": "v3 with puncutations",
77+
"is_giga_am": 1,
78+
}
79+
add_meta_data(f"./{model_name}.onnx", meta_data)
80+
quantize_dynamic(
81+
model_input=f"./{model_name}.onnx",
82+
model_output="./model.int8.onnx",
83+
weight_type=QuantType.QUInt8,
84+
)
85+
86+
87+
if __name__ == "__main__":
88+
main()

0 commit comments

Comments
 (0)