Skip to content

Commit 06b61cc

Browse files
shawl336xiao
and
xiao
authored
Allow more online models to load tokens file from the memory (#1352)
Co-authored-by: xiao <shawl336@6163.com>
1 parent 73c90ec commit 06b61cc

15 files changed

+735
-15
lines changed

.github/workflows/c-api-from-buffer.yaml

+96
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,99 @@ jobs:
120120
./streaming-zipformer-buffered-tokens-hotwords-c-api
121121
122122
rm -rf sherpa-onnx-streaming-zipformer-*
123+
124+
- name: Test streaming paraformer with tokens loaded from buffers
125+
shell: bash
126+
run: |
127+
gcc -o streaming-paraformer-buffered-tokens-c-api ./c-api-examples/streaming-paraformer-buffered-tokens-c-api.c \
128+
-I ./build/install/include \
129+
-L ./build/install/lib/ \
130+
-l sherpa-onnx-c-api \
131+
-l onnxruntime
132+
133+
ls -lh streaming-paraformer-buffered-tokens-c-api
134+
135+
if [[ ${{ matrix.os }} == ubuntu-latest ]]; then
136+
ldd ./streaming-paraformer-buffered-tokens-c-api
137+
echo "----"
138+
readelf -d ./streaming-paraformer-buffered-tokens-c-api
139+
fi
140+
141+
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2
142+
tar xvf sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2
143+
rm sherpa-onnx-streaming-paraformer-bilingual-zh-en.tar.bz2
144+
145+
ls -lh sherpa-onnx-streaming-paraformer-bilingual-zh-en
146+
echo "---"
147+
ls -lh sherpa-onnx-streaming-paraformer-bilingual-zh-en/test_wavs
148+
149+
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
150+
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
151+
152+
./streaming-paraformer-buffered-tokens-c-api
153+
154+
rm -rf sherpa-onnx-streaming-paraformer-*
155+
156+
- name: Test streaming ctc with tokens loaded from buffers
157+
shell: bash
158+
run: |
159+
gcc -o streaming-ctc-buffered-tokens-c-api ./c-api-examples/streaming-ctc-buffered-tokens-c-api.c \
160+
-I ./build/install/include \
161+
-L ./build/install/lib/ \
162+
-l sherpa-onnx-c-api \
163+
-l onnxruntime
164+
165+
ls -lh streaming-ctc-buffered-tokens-c-api
166+
167+
if [[ ${{ matrix.os }} == ubuntu-latest ]]; then
168+
ldd ./streaming-ctc-buffered-tokens-c-api
169+
echo "----"
170+
readelf -d ./streaming-ctc-buffered-tokens-c-api
171+
fi
172+
173+
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-ctc-multi-zh-hans-2023-12-13.tar.bz2
174+
tar xvf sherpa-onnx-streaming-zipformer-ctc-multi-zh-hans-2023-12-13.tar.bz2
175+
rm sherpa-onnx-streaming-zipformer-ctc-multi-zh-hans-2023-12-13.tar.bz2
176+
177+
ls -lh sherpa-onnx-streaming-zipformer-ctc-multi-zh-hans-2023-12-13
178+
echo "---"
179+
ls -lh sherpa-onnx-streaming-zipformer-ctc-multi-zh-hans-2023-12-13/test_wavs
180+
181+
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
182+
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
183+
184+
./streaming-ctc-buffered-tokens-c-api
185+
186+
rm -rf sherpa-onnx-streaming-ctc-*
187+
188+
- name: Test keywords spotting with tokens and keywords loaded from buffers
189+
shell: bash
190+
run: |
191+
gcc -o keywords-spotter-buffered-tokens-keywords-c-api ./c-api-examples/keywords-spotter-buffered-tokens-keywords-c-api.c \
192+
-I ./build/install/include \
193+
-L ./build/install/lib/ \
194+
-l sherpa-onnx-c-api \
195+
-l onnxruntime
196+
197+
ls -lh keywords-spotter-buffered-tokens-keywords-c-api
198+
199+
if [[ ${{ matrix.os }} == ubuntu-latest ]]; then
200+
ldd ./keywords-spotter-buffered-tokens-keywords-c-api
201+
echo "----"
202+
readelf -d ./keywords-spotter-buffered-tokens-keywords-c-api
203+
fi
204+
205+
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile.tar.bz2
206+
tar xvf sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile.tar.bz2
207+
rm sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile.tar.bz2
208+
209+
ls -lh sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile
210+
echo "---"
211+
ls -lh sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile/test_wavs
212+
213+
export LD_LIBRARY_PATH=$PWD/build/install/lib:$LD_LIBRARY_PATH
214+
export DYLD_LIBRARY_PATH=$PWD/build/install/lib:$DYLD_LIBRARY_PATH
215+
216+
./keywords-spotter-buffered-tokens-keywords-c-api
217+
218+
rm -rf sherpa-onnx-kws-zipformer-*

c-api-examples/CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,18 @@ add_executable(streaming-zipformer-buffered-tokens-hotwords-c-api
5252
streaming-zipformer-buffered-tokens-hotwords-c-api.c)
5353
target_link_libraries(streaming-zipformer-buffered-tokens-hotwords-c-api sherpa-onnx-c-api)
5454

55+
add_executable(streaming-paraformer-buffered-tokens-c-api
56+
streaming-paraformer-buffered-tokens-c-api.c)
57+
target_link_libraries(streaming-paraformer-buffered-tokens-c-api sherpa-onnx-c-api)
58+
59+
add_executable(streaming-ctc-buffered-tokens-c-api
60+
streaming-ctc-buffered-tokens-c-api.c)
61+
target_link_libraries(streaming-ctc-buffered-tokens-c-api sherpa-onnx-c-api)
62+
63+
add_executable(keywords-spotter-buffered-tokens-keywords-c-api
64+
keywords-spotter-buffered-tokens-keywords-c-api.c)
65+
target_link_libraries(keywords-spotter-buffered-tokens-keywords-c-api sherpa-onnx-c-api)
66+
5567
if(SHERPA_ONNX_HAS_ALSA)
5668
add_subdirectory(./asr-microphone-example)
5769
elseif((UNIX AND NOT APPLE) OR LINUX)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
// c-api-examples/keywords-spotter-buffered-tokens-keywords-c-api.c
2+
//
3+
// Copyright (c) 2024 Xiaomi Corporation
4+
// Copyright (c) 2024 Luo Xiao
5+
6+
//
7+
// This file demonstrates how to use keywords spotter with sherpa-onnx's C
8+
// API and with tokens and keywords loaded from buffered strings instead of from
9+
// external files API.
10+
// clang-format off
11+
//
12+
// wget https://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile.tar.bz2
13+
// tar xvf sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile.tar.bz2
14+
// rm sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile.tar.bz2
15+
//
16+
// clang-format on
17+
18+
#include <stdio.h>
19+
#include <stdlib.h>
20+
#include <string.h>
21+
22+
#include "sherpa-onnx/c-api/c-api.h"
23+
24+
static size_t ReadFile(const char *filename, const char **buffer_out) {
25+
FILE *file = fopen(filename, "r");
26+
if (file == NULL) {
27+
fprintf(stderr, "Failed to open %s\n", filename);
28+
return -1;
29+
}
30+
fseek(file, 0L, SEEK_END);
31+
long size = ftell(file);
32+
rewind(file);
33+
*buffer_out = malloc(size);
34+
if (*buffer_out == NULL) {
35+
fclose(file);
36+
fprintf(stderr, "Memory error\n");
37+
return -1;
38+
}
39+
size_t read_bytes = fread(*buffer_out, 1, size, file);
40+
if (read_bytes != size) {
41+
printf("Errors occured in reading the file %s\n", filename);
42+
free((void *)*buffer_out);
43+
*buffer_out = NULL;
44+
fclose(file);
45+
return -1;
46+
}
47+
fclose(file);
48+
return read_bytes;
49+
}
50+
51+
int32_t main() {
52+
const char *wav_filename =
53+
"sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile/test_wavs/"
54+
"6.wav";
55+
const char *encoder_filename =
56+
"sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile/"
57+
"encoder-epoch-12-avg-2-chunk-16-left-64.int8.onnx";
58+
const char *decoder_filename =
59+
"sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile/"
60+
"decoder-epoch-12-avg-2-chunk-16-left-64.onnx";
61+
const char *joiner_filename =
62+
"sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile/"
63+
"joiner-epoch-12-avg-2-chunk-16-left-64.int8.onnx";
64+
const char *provider = "cpu";
65+
const char *tokens_filename =
66+
"sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile/tokens.txt";
67+
const char *keywords_filename =
68+
"sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01-mobile/test_wavs/"
69+
"test_keywords.txt";
70+
const SherpaOnnxWave *wave = SherpaOnnxReadWave(wav_filename);
71+
if (wave == NULL) {
72+
fprintf(stderr, "Failed to read %s\n", wav_filename);
73+
return -1;
74+
}
75+
76+
// reading tokens and keywords to buffers
77+
const char *tokens_buf;
78+
size_t token_buf_size = ReadFile(tokens_filename, &tokens_buf);
79+
if (token_buf_size < 1) {
80+
fprintf(stderr, "Please check your tokens.txt!\n");
81+
free((void *)tokens_buf);
82+
return -1;
83+
}
84+
const char *keywords_buf;
85+
size_t keywords_buf_size = ReadFile(keywords_filename, &keywords_buf);
86+
if (keywords_buf_size < 1) {
87+
fprintf(stderr, "Please check your keywords.txt!\n");
88+
free((void *)keywords_buf);
89+
return -1;
90+
}
91+
92+
// Zipformer config
93+
SherpaOnnxOnlineTransducerModelConfig zipformer_config;
94+
memset(&zipformer_config, 0, sizeof(zipformer_config));
95+
zipformer_config.encoder = encoder_filename;
96+
zipformer_config.decoder = decoder_filename;
97+
zipformer_config.joiner = joiner_filename;
98+
99+
// Online model config
100+
SherpaOnnxOnlineModelConfig online_model_config;
101+
memset(&online_model_config, 0, sizeof(online_model_config));
102+
online_model_config.debug = 1;
103+
online_model_config.num_threads = 1;
104+
online_model_config.provider = provider;
105+
online_model_config.tokens_buf = tokens_buf;
106+
online_model_config.tokens_buf_size = token_buf_size;
107+
online_model_config.transducer = zipformer_config;
108+
109+
// Keywords-spotter config
110+
SherpaOnnxKeywordSpotterConfig keywords_spotter_config;
111+
memset(&keywords_spotter_config, 0, sizeof(keywords_spotter_config));
112+
keywords_spotter_config.max_active_paths = 4;
113+
keywords_spotter_config.keywords_threshold = 0.1;
114+
keywords_spotter_config.keywords_score = 3.0;
115+
keywords_spotter_config.model_config = online_model_config;
116+
keywords_spotter_config.keywords_buf = keywords_buf;
117+
keywords_spotter_config.keywords_buf_size = keywords_buf_size;
118+
119+
SherpaOnnxKeywordSpotter *keywords_spotter =
120+
SherpaOnnxCreateKeywordSpotter(&keywords_spotter_config);
121+
122+
free((void *)tokens_buf);
123+
tokens_buf = NULL;
124+
free((void *)keywords_buf);
125+
keywords_buf = NULL;
126+
127+
if (keywords_spotter == NULL) {
128+
fprintf(stderr, "Please check your config!\n");
129+
SherpaOnnxFreeWave(wave);
130+
return -1;
131+
}
132+
133+
SherpaOnnxOnlineStream *stream =
134+
SherpaOnnxCreateKeywordStream(keywords_spotter);
135+
136+
const SherpaOnnxDisplay *display = SherpaOnnxCreateDisplay(50);
137+
int32_t segment_id = 0;
138+
139+
// simulate streaming. You can choose an arbitrary N
140+
#define N 3200
141+
142+
fprintf(stderr, "sample rate: %d, num samples: %d, duration: %.2f s\n",
143+
wave->sample_rate, wave->num_samples,
144+
(float)wave->num_samples / wave->sample_rate);
145+
146+
int32_t k = 0;
147+
while (k < wave->num_samples) {
148+
int32_t start = k;
149+
int32_t end =
150+
(start + N > wave->num_samples) ? wave->num_samples : (start + N);
151+
k += N;
152+
153+
SherpaOnnxOnlineStreamAcceptWaveform(stream, wave->sample_rate,
154+
wave->samples + start, end - start);
155+
while (SherpaOnnxIsKeywordStreamReady(keywords_spotter, stream)) {
156+
SherpaOnnxDecodeKeywordStream(keywords_spotter, stream);
157+
}
158+
159+
const SherpaOnnxKeywordResult *r =
160+
SherpaOnnxGetKeywordResult(keywords_spotter, stream);
161+
162+
if (strlen(r->keyword)) {
163+
SherpaOnnxPrint(display, segment_id, r->keyword);
164+
}
165+
166+
SherpaOnnxDestroyKeywordResult(r);
167+
}
168+
169+
// add some tail padding
170+
float tail_paddings[4800] = {0}; // 0.3 seconds at 16 kHz sample rate
171+
SherpaOnnxOnlineStreamAcceptWaveform(stream, wave->sample_rate, tail_paddings,
172+
4800);
173+
174+
SherpaOnnxFreeWave(wave);
175+
176+
SherpaOnnxOnlineStreamInputFinished(stream);
177+
while (SherpaOnnxIsKeywordStreamReady(keywords_spotter, stream)) {
178+
SherpaOnnxDecodeKeywordStream(keywords_spotter, stream);
179+
}
180+
181+
const SherpaOnnxKeywordResult *r =
182+
SherpaOnnxGetKeywordResult(keywords_spotter, stream);
183+
184+
if (strlen(r->keyword)) {
185+
SherpaOnnxPrint(display, segment_id, r->keyword);
186+
}
187+
188+
SherpaOnnxDestroyKeywordResult(r);
189+
190+
SherpaOnnxDestroyDisplay(display);
191+
SherpaOnnxDestroyOnlineStream(stream);
192+
SherpaOnnxDestroyKeywordSpotter(keywords_spotter);
193+
fprintf(stderr, "\n");
194+
195+
return 0;
196+
}

0 commit comments

Comments
 (0)