Skip to content

Commit feb870c

Browse files
authored
Add C++ runtime for Parakeet CTC with QNN. (k2-fsa#3688)
1 parent 9961aee commit feb870c

8 files changed

Lines changed: 526 additions & 14 deletions

sherpa-onnx/csrc/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ endif()
256256

257257
if(SHERPA_ONNX_ENABLE_QNN)
258258
list(APPEND sources
259+
./qnn/offline-parakeet-ctc-model-qnn.cc
259260
./qnn/offline-sense-voice-model-qnn.cc
260261
./qnn/offline-paraformer-model-qnn.cc
261262
./qnn/offline-zipformer-transducer-model-qnn.cc

sherpa-onnx/csrc/offline-nemo-enc-dec-ctc-model-config.cc

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,48 @@
88

99
#include "sherpa-onnx/csrc/file-utils.h"
1010
#include "sherpa-onnx/csrc/macros.h"
11+
#include "sherpa-onnx/csrc/text-utils.h"
1112

1213
namespace sherpa_onnx {
1314

1415
void OfflineNemoEncDecCtcModelConfig::Register(ParseOptions *po) {
15-
po->Register("nemo-ctc-model", &model,
16-
"Path to model.onnx of Nemo EncDecCtcModel.");
16+
po->Register(
17+
"nemo-ctc-model", &model,
18+
"Path to NeMo CTC model. For qnn, use compiled model library "
19+
"(e.g. libmodel.so). For onnxruntime, use model.onnx.");
20+
21+
std::string prefix = "nemo-ctc";
22+
ParseOptions p(prefix, po);
23+
24+
qnn_config.Register(&p);
1725
}
1826

1927
bool OfflineNemoEncDecCtcModelConfig::Validate() const {
20-
if (!FileExists(model)) {
21-
SHERPA_ONNX_LOGE("NeMo model: '%s' does not exist", model.c_str());
22-
return false;
28+
if (qnn_config.context_binary.empty()) {
29+
if (model.empty()) {
30+
SHERPA_ONNX_LOGE("Please provide a NeMo CTC model");
31+
return false;
32+
}
33+
34+
if (!FileExists(model)) {
35+
SHERPA_ONNX_LOGE("NeMo model: '%s' does not exist", model.c_str());
36+
return false;
37+
}
38+
}
39+
40+
if (model.empty() && !qnn_config.context_binary.empty()) {
41+
// we require that the context_binary exists
42+
if (!FileExists(qnn_config.context_binary)) {
43+
SHERPA_ONNX_LOGE(
44+
"Model is empty, but you provide a context binary that does not "
45+
"exist");
46+
return false;
47+
}
48+
}
49+
50+
if (EndsWith(model, ".so") || EndsWith(model, ".bin") ||
51+
(model.empty() && !qnn_config.context_binary.empty())) {
52+
return qnn_config.Validate();
2353
}
2454

2555
return true;
@@ -29,7 +59,13 @@ std::string OfflineNemoEncDecCtcModelConfig::ToString() const {
2959
std::ostringstream os;
3060

3161
os << "OfflineNemoEncDecCtcModelConfig(";
32-
os << "model=\"" << model << "\")";
62+
os << "model=\"" << model << "\"";
63+
64+
if (!qnn_config.backend_lib.empty()) {
65+
os << ", qnn_config=" << qnn_config.ToString() << ", ";
66+
}
67+
68+
os << ")";
3369

3470
return os.str();
3571
}

sherpa-onnx/csrc/offline-nemo-enc-dec-ctc-model-config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
#include <string>
88

99
#include "sherpa-onnx/csrc/parse-options.h"
10+
#include "sherpa-onnx/csrc/qnn-config.h"
1011

1112
namespace sherpa_onnx {
1213

1314
struct OfflineNemoEncDecCtcModelConfig {
1415
std::string model;
16+
QnnConfig qnn_config;
1517

1618
OfflineNemoEncDecCtcModelConfig() = default;
1719
explicit OfflineNemoEncDecCtcModelConfig(const std::string &model)

sherpa-onnx/csrc/offline-recognizer-impl.cc

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767

6868
#if SHERPA_ONNX_ENABLE_QNN
6969
#include "sherpa-onnx/csrc/qnn/offline-paraformer-model-qnn.h"
70+
#include "sherpa-onnx/csrc/qnn/offline-recognizer-parakeet-ctc-qnn-impl.h"
7071
#include "sherpa-onnx/csrc/qnn/offline-recognizer-transducer-qnn-impl.h"
7172
#include "sherpa-onnx/csrc/qnn/offline-recognizer-zipformer-ctc-qnn-impl.h"
7273
#include "sherpa-onnx/csrc/qnn/offline-sense-voice-model-qnn.h"
@@ -201,10 +202,15 @@ std::unique_ptr<OfflineRecognizerImpl> OfflineRecognizerImpl::Create(
201202
return std::make_unique<
202203
OfflineRecognizerParaformerTplImpl<OfflineParaformerModelQnn>>(
203204
config);
205+
} else if (!config.model_config.nemo_ctc.model.empty() ||
206+
!config.model_config.nemo_ctc.qnn_config.context_binary
207+
.empty()) {
208+
return std::make_unique<OfflineRecognizerParakeetCtcQnnImpl>(config);
204209
} else {
205210
SHERPA_ONNX_LOGE(
206-
"Only SenseVoice, Paraformer, offline transducer, and Zipformer CTC "
207-
"models are currently supported by QNN for non-streaming ASR.");
211+
"Only SenseVoice, Paraformer, offline transducer, Zipformer CTC, "
212+
"and NeMo CTC (Parakeet) models are currently supported by QNN "
213+
"for non-streaming ASR.");
208214
SHERPA_ONNX_EXIT(-1);
209215
return nullptr;
210216
}
@@ -557,10 +563,15 @@ std::unique_ptr<OfflineRecognizerImpl> OfflineRecognizerImpl::Create(
557563
return std::make_unique<
558564
OfflineRecognizerParaformerTplImpl<OfflineParaformerModelQnn>>(
559565
mgr, config);
566+
} else if (!config.model_config.nemo_ctc.model.empty() ||
567+
!config.model_config.nemo_ctc.qnn_config.context_binary
568+
.empty()) {
569+
return std::make_unique<OfflineRecognizerParakeetCtcQnnImpl>(mgr, config);
560570
} else {
561571
SHERPA_ONNX_LOGE(
562-
"Only SenseVoice, Paraformer, offline transducer, and Zipformer CTC "
563-
"models are currently supported by QNN for non-streaming ASR.");
572+
"Only SenseVoice, Paraformer, offline transducer, Zipformer CTC, "
573+
"and NeMo CTC (Parakeet) models are currently supported by QNN "
574+
"for non-streaming ASR.");
564575
SHERPA_ONNX_EXIT(-1);
565576
return nullptr;
566577
}

0 commit comments

Comments
 (0)