mirror of
https://github.com/k2-fsa/sherpa-onnx.git
synced 2026-11-10 21:11:03 +08:00
Add JavaScript API for Cohere Transcribe. (#3458)
This pull request introduces support for the Cohere Transcribe model across multiple platforms, including Node.js addons, standard Node.js, and WebAssembly. Key changes include adding C++ configuration logic, implementing a setOption method for offline streams to handle language selection, and providing new example scripts for both synchronous and asynchronous transcription.
This commit is contained in:
1 parent
6864344d4b
commit
d4465bcbdf
12 files changed
+404
-14
No files matched your search
@@ -10,6 +10,16 @@ arch=$(node -p "require('os').arch()")
|
||||
platform=$(node -p "require('os').platform()")
|
||||
node_version=$(node -p "process.versions.node.split('.')[0]")
|
||||
|
||||
echo "----------Cohere Transcribe----------"
|
||||
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
tar xvf sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
rm sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
|
||||
node ./test_asr_non_streaming_cohere_transcribe.js
|
||||
node ./test_asr_non_streaming_cohere_transcribe_async.js
|
||||
|
||||
rm -rf sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01
|
||||
|
||||
if [[ "$SKIP_QWEN3" != "true" ]]; then
|
||||
echo "----------Qwen3 ASR----------"
|
||||
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-qwen3-asr-0.6B-int8-2026-03-25.tar.bz2
|
||||
|
||||
@@ -4,6 +4,7 @@ on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
- nodejs-api
|
||||
paths:
|
||||
- '.github/workflows/test-nodejs.yaml'
|
||||
- 'build-wasm-simd-nodejs.sh'
|
||||
|
||||
@@ -179,6 +179,28 @@ static SherpaOnnxOfflineQwen3ASRModelConfig GetOfflineQwen3AsrModelConfig(
|
||||
return c;
|
||||
}
|
||||
|
||||
static SherpaOnnxOfflineCohereTranscribeModelConfig
|
||||
GetOfflineCohereTranscribeModelConfig(Napi::Object obj) {
|
||||
SherpaOnnxOfflineCohereTranscribeModelConfig c;
|
||||
memset(&c, 0, sizeof(c));
|
||||
c.use_punct = 1;
|
||||
c.use_itn = 1;
|
||||
|
||||
if (!obj.Has("cohereTranscribe") || !obj.Get("cohereTranscribe").IsObject()) {
|
||||
return c;
|
||||
}
|
||||
|
||||
Napi::Object o = obj.Get("cohereTranscribe").As<Napi::Object>();
|
||||
|
||||
SHERPA_ONNX_ASSIGN_ATTR_STR(encoder, encoder);
|
||||
SHERPA_ONNX_ASSIGN_ATTR_STR(decoder, decoder);
|
||||
SHERPA_ONNX_ASSIGN_ATTR_STR(language, language);
|
||||
SHERPA_ONNX_ASSIGN_ATTR_INT32(use_punct, usePunct);
|
||||
SHERPA_ONNX_ASSIGN_ATTR_INT32(use_itn, useItn);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static SherpaOnnxOfflineDolphinModelConfig GetOfflineDolphinModelConfig(
|
||||
Napi::Object obj) {
|
||||
SherpaOnnxOfflineDolphinModelConfig c;
|
||||
@@ -353,6 +375,7 @@ static SherpaOnnxOfflineModelConfig GetOfflineModelConfig(Napi::Object obj) {
|
||||
c.funasr_nano = GetOfflineFunAsrNanoModelConfig(o);
|
||||
c.fire_red_asr_ctc = GetOfflineFireRedAsrCtcModelConfig(o);
|
||||
c.qwen3_asr = GetOfflineQwen3AsrModelConfig(o);
|
||||
c.cohere_transcribe = GetOfflineCohereTranscribeModelConfig(o);
|
||||
|
||||
SHERPA_ONNX_ASSIGN_ATTR_STR(tokens, tokens);
|
||||
SHERPA_ONNX_ASSIGN_ATTR_INT32(num_threads, numThreads);
|
||||
@@ -465,6 +488,10 @@ static void FreeConfig(const SherpaOnnxOfflineRecognizerConfig &c) {
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.qwen3_asr.tokenizer);
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.qwen3_asr.hotwords);
|
||||
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.cohere_transcribe.encoder);
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.cohere_transcribe.decoder);
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.cohere_transcribe.language);
|
||||
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.fire_red_asr_ctc.model);
|
||||
|
||||
SHERPA_ONNX_DELETE_C_STR(c.model_config.tokens);
|
||||
@@ -727,6 +754,36 @@ static void AcceptWaveformOfflineWrapper(const Napi::CallbackInfo &info) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void OfflineStreamSetOptionWrapper(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
|
||||
if (info.Length() != 3) {
|
||||
std::ostringstream os;
|
||||
os << "Expect 3 arguments. Given: " << info.Length();
|
||||
Napi::TypeError::New(env, os.str()).ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info[0].IsExternal()) {
|
||||
Napi::TypeError::New(env, "Argument 0 should be an offline stream pointer.")
|
||||
.ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!info[1].IsString() || !info[2].IsString()) {
|
||||
Napi::TypeError::New(env, "Arguments 1 and 2 should be strings.")
|
||||
.ThrowAsJavaScriptException();
|
||||
return;
|
||||
}
|
||||
|
||||
const SherpaOnnxOfflineStream *stream =
|
||||
info[0].As<Napi::External<SherpaOnnxOfflineStream>>().Data();
|
||||
|
||||
std::string key = info[1].As<Napi::String>().Utf8Value();
|
||||
std::string value = info[2].As<Napi::String>().Utf8Value();
|
||||
SherpaOnnxOfflineStreamSetOption(stream, key.c_str(), value.c_str());
|
||||
}
|
||||
|
||||
static void OfflineRecognizerSetConfigWrapper(const Napi::CallbackInfo &info) {
|
||||
Napi::Env env = info.Env();
|
||||
if (info.Length() != 2) {
|
||||
@@ -911,6 +968,9 @@ void InitNonStreamingAsr(Napi::Env env, Napi::Object exports) {
|
||||
exports.Set(Napi::String::New(env, "acceptWaveformOffline"),
|
||||
Napi::Function::New(env, AcceptWaveformOfflineWrapper));
|
||||
|
||||
exports.Set(Napi::String::New(env, "offlineStreamSetOption"),
|
||||
Napi::Function::New(env, OfflineStreamSetOptionWrapper));
|
||||
|
||||
exports.Set(Napi::String::New(env, "decodeOfflineStream"),
|
||||
Napi::Function::New(env, DecodeOfflineStreamWrapper));
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ The following tables list the examples in this folder.
|
||||
|
||||
|File| Description|
|
||||
|---|---|
|
||||
|[ ./test_speaker_identification.js]( ./test_speaker_identification.js)| Speaker identification from a file|
|
||||
|[./test_speaker_identification.js](./test_speaker_identification.js)| Speaker identification from a file|
|
||||
|
||||
## Spoken language identification
|
||||
|
||||
@@ -139,6 +139,8 @@ The following tables list the examples in this folder.
|
||||
|[./test_asr_non_streaming_medasr_ctc.js](./test_asr_non_streaming_medasr_ctc.js)|Non-streaming speech recognition from a file using a [Google MedASR](https://github.com/google-health/medasr) CTC model with greedy search|
|
||||
|[./test_asr_non_streaming_funasr_nano.js](./test_asr_non_streaming_funasr_nano.js)|Non-streaming speech recognition from a file using a [FunASR Nano](https://modelscope.cn/models/FunAudioLLM/Fun-ASR-Nano-2512) model|
|
||||
|[./test_asr_non_streaming_funasr_nano_async.js](./test_asr_non_streaming_funasr_nano_async.js)|Async non-streaming speech recognition from multiple files using a [FunASR Nano](https://modelscope.cn/models/FunAudioLLM/Fun-ASR-Nano-2512) model|
|
||||
|[./test_asr_non_streaming_cohere_transcribe.js](./test_asr_non_streaming_cohere_transcribe.js)|Non-streaming speech recognition from a file using a [Cohere Transcribe](https://cohere.com/research/papers/cohere-labs-aya-expanse-open-weights-and-multilingual-api-2025) model|
|
||||
|[./test_asr_non_streaming_cohere_transcribe_async.js](./test_asr_non_streaming_cohere_transcribe_async.js)|Async non-streaming speech recognition from multiple files using a Cohere Transcribe model|
|
||||
|[./test_asr_non_streaming_qwen3_asr.js](./test_asr_non_streaming_qwen3_asr.js)|Non-streaming speech recognition from a file using a [Qwen3 ASR](https://github.com/QwenLM/Qwen3-ASR) model|
|
||||
|[./test_asr_non_streaming_qwen3_asr_async.js](./test_asr_non_streaming_qwen3_asr_async.js)|Async non-streaming speech recognition from multiple files using a [Qwen3 ASR](https://github.com/QwenLM/Qwen3-ASR) model|
|
||||
|[./test_asr_non_streaming_nemo_canary.js](./test_asr_non_streaming_nemo_canary.js)|Non-streaming speech recognition from a file using a [NeMo](https://github.com/NVIDIA/NeMo) [Canary](https://k2-fsa.github.io/sherpa/onnx/nemo/canary.html#sherpa-onnx-nemo-canary-180m-flash-en-es-de-fr-int8-english-spanish-german-french) model|
|
||||
@@ -493,6 +495,26 @@ rm sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
|
||||
node ./test_asr_non_streaming_funasr_nano.js
|
||||
```
|
||||
|
||||
### Asynchronous non-streaming speech recognition with Cohere Transcribe models
|
||||
|
||||
```bash
|
||||
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
tar xvf sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
rm sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
|
||||
node ./test_asr_non_streaming_cohere_transcribe_async.js
|
||||
```
|
||||
|
||||
### Non-streaming speech recognition with Cohere Transcribe models
|
||||
|
||||
```bash
|
||||
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
tar xvf sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
rm sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
|
||||
node ./test_asr_non_streaming_cohere_transcribe.js
|
||||
```
|
||||
|
||||
### Asynchronous non-streaming speech recognition with Qwen3 ASR models
|
||||
|
||||
```bash
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright (c) 2026 Xiaomi Corporation
|
||||
const sherpa_onnx = require('sherpa-onnx-node');
|
||||
|
||||
const config = {
|
||||
'featConfig': {
|
||||
'sampleRate': 16000,
|
||||
'featureDim': 80,
|
||||
},
|
||||
'modelConfig': {
|
||||
'cohereTranscribe': {
|
||||
'encoder':
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/encoder.int8.onnx',
|
||||
'decoder':
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/decoder.int8.onnx',
|
||||
'usePunct': 1,
|
||||
'useItn': 1,
|
||||
},
|
||||
'tokens':
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/tokens.txt',
|
||||
'numThreads': 2,
|
||||
'provider': 'cpu',
|
||||
'debug': 0,
|
||||
}
|
||||
};
|
||||
|
||||
const waveFilename =
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/test_wavs/en.wav';
|
||||
|
||||
const recognizer = new sherpa_onnx.OfflineRecognizer(config);
|
||||
const stream = recognizer.createStream();
|
||||
stream.setOption('language', 'en');
|
||||
const wave = sherpa_onnx.readWave(waveFilename);
|
||||
stream.acceptWaveform({sampleRate: wave.sampleRate, samples: wave.samples});
|
||||
|
||||
recognizer.decode(stream);
|
||||
const result = recognizer.getResult(stream);
|
||||
console.log('result\n', result);
|
||||
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) 2026 Xiaomi Corporation
|
||||
// This file shows how to use the async API to decode multiple files
|
||||
const path = require('path');
|
||||
const sherpa_onnx = require('sherpa-onnx-node');
|
||||
|
||||
/**
|
||||
* Create an OfflineRecognizer with Cohere Transcribe asynchronously.
|
||||
*/
|
||||
async function createRecognizerAsync(modelDir, numThreads = 2, debug = 0) {
|
||||
const config = {
|
||||
featConfig: {
|
||||
sampleRate: 16000,
|
||||
featureDim: 80,
|
||||
},
|
||||
modelConfig: {
|
||||
cohereTranscribe: {
|
||||
encoder: path.join(modelDir, 'encoder.int8.onnx'),
|
||||
decoder: path.join(modelDir, 'decoder.int8.onnx'),
|
||||
usePunct: 1,
|
||||
useItn: 1,
|
||||
},
|
||||
tokens: path.join(modelDir, 'tokens.txt'),
|
||||
numThreads,
|
||||
provider: 'cpu',
|
||||
debug,
|
||||
},
|
||||
};
|
||||
|
||||
return await sherpa_onnx.OfflineRecognizer.createAsync(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a waveform and create a stream for decoding.
|
||||
*/
|
||||
function createStreamFromFile(recognizer, file, language) {
|
||||
const wave = sherpa_onnx.readWave(file);
|
||||
const stream = recognizer.createStream();
|
||||
stream.setOption('language', language);
|
||||
stream.acceptWaveform({sampleRate: wave.sampleRate, samples: wave.samples});
|
||||
return stream;
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const modelDir = './sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01';
|
||||
|
||||
const recognizer = await createRecognizerAsync(modelDir);
|
||||
|
||||
const testFiles = [
|
||||
{
|
||||
language: 'en',
|
||||
file: path.join(modelDir, 'test_wavs/en.wav'),
|
||||
},
|
||||
{
|
||||
language: 'fr',
|
||||
file: path.join(modelDir, 'test_wavs/fr.wav'),
|
||||
},
|
||||
{
|
||||
language: 'zh',
|
||||
file: path.join(modelDir, 'test_wavs/zh.wav'),
|
||||
},
|
||||
{
|
||||
language: 'de',
|
||||
file: path.join(modelDir, 'test_wavs/de.wav'),
|
||||
},
|
||||
{
|
||||
language: 'es',
|
||||
file: path.join(modelDir, 'test_wavs/es.wav'),
|
||||
},
|
||||
{
|
||||
language: 'ja',
|
||||
file: path.join(modelDir, 'test_wavs/ja.wav'),
|
||||
},
|
||||
{
|
||||
language: 'ko',
|
||||
file: path.join(modelDir, 'test_wavs/ko.wav'),
|
||||
},
|
||||
{
|
||||
language: 'vi',
|
||||
file: path.join(modelDir, 'test_wavs/vi.wav'),
|
||||
},
|
||||
{
|
||||
language: 'ar',
|
||||
file: path.join(modelDir, 'test_wavs/ar.wav'),
|
||||
},
|
||||
];
|
||||
|
||||
const streams = testFiles.map(
|
||||
entry => createStreamFromFile(recognizer, entry.file, entry.language));
|
||||
|
||||
const results =
|
||||
await Promise.all(streams.map(stream => recognizer.decodeAsync(stream)));
|
||||
|
||||
console.log('Concurrent decode results:');
|
||||
testFiles.forEach((entry, i) => {
|
||||
console.log(`${entry.language} ${entry.file}: ${results[i].text}`);
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(console.error);
|
||||
@@ -303,6 +303,23 @@ rm sherpa-onnx-funasr-nano-int8-2025-12-30.tar.bz2
|
||||
node ./test-offline-funasr-nano.js
|
||||
```
|
||||
|
||||
## ./test-offline-cohere-transcribe.js
|
||||
|
||||
[./test-offline-cohere-transcribe.js](./test-offline-cohere-transcribe.js)
|
||||
demonstrates how to decode a file with a Cohere Transcribe model. In the code
|
||||
we use
|
||||
[sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2](https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2).
|
||||
|
||||
You can use the following command to run it:
|
||||
|
||||
```bash
|
||||
wget https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
tar xvf sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
rm sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01.tar.bz2
|
||||
|
||||
node ./test-offline-cohere-transcribe.js
|
||||
```
|
||||
|
||||
## ./test-offline-qwen3-asr.js
|
||||
|
||||
[./test-offline-qwen3-asr.js](./test-offline-qwen3-asr.js) demonstrates
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright (c) 2026 Xiaomi Corporation (authors: Fangjun Kuang)
|
||||
//
|
||||
const sherpa_onnx = require('sherpa-onnx');
|
||||
|
||||
function createOfflineRecognizer() {
|
||||
const config = {
|
||||
modelConfig: {
|
||||
cohereTranscribe: {
|
||||
encoder:
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/encoder.int8.onnx',
|
||||
decoder:
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/decoder.int8.onnx',
|
||||
usePunct: 1,
|
||||
useItn: 1,
|
||||
},
|
||||
tokens:
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/tokens.txt',
|
||||
}
|
||||
};
|
||||
|
||||
return sherpa_onnx.createOfflineRecognizer(config);
|
||||
}
|
||||
|
||||
const recognizer = createOfflineRecognizer();
|
||||
const stream = recognizer.createStream();
|
||||
stream.setOption('language', 'en');
|
||||
|
||||
const waveFilename =
|
||||
'./sherpa-onnx-cohere-transcribe-14-lang-int8-2026-04-01/test_wavs/en.wav';
|
||||
const wave = sherpa_onnx.readWave(waveFilename);
|
||||
stream.acceptWaveform(wave.sampleRate, wave.samples);
|
||||
|
||||
recognizer.decode(stream);
|
||||
const text = recognizer.getResult(stream).text;
|
||||
console.log(text);
|
||||
|
||||
stream.free();
|
||||
recognizer.free();
|
||||
@@ -33,6 +33,15 @@ class OfflineStream {
|
||||
acceptWaveform(obj) {
|
||||
addon.acceptWaveformOffline(this.handle, obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a string option on the underlying offline stream.
|
||||
* @param {string} key
|
||||
* @param {string} value
|
||||
*/
|
||||
setOption(key, value) {
|
||||
addon.offlineStreamSetOption(this.handle, key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -234,9 +234,19 @@
|
||||
* @property {number} [useInverseTextNormalization]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Offline model config.
|
||||
* @typedef {Object} OfflineModelConfig
|
||||
/**
|
||||
* Offline Cohere Transcribe model config
|
||||
* @typedef {Object} OfflineCohereTranscribeModelConfig
|
||||
* @property {string} [encoder]
|
||||
* @property {string} [decoder]
|
||||
* @property {string} [language]
|
||||
* @property {number} [usePunct]
|
||||
* @property {number} [useItn]
|
||||
*/
|
||||
|
||||
/**
|
||||
* Offline model config.
|
||||
* @typedef {Object} OfflineModelConfig
|
||||
* @property {OfflineTransducerModelConfig} [transducer]
|
||||
* @property {OfflineParaformerModelConfig} [paraformer]
|
||||
* @property {OfflineZipformerCtcModelConfig} [zipformerCtc]
|
||||
@@ -245,13 +255,14 @@
|
||||
* @property {OfflineMedAsrCtcModelConfig} [medasr]
|
||||
* @property {OfflineDolphinModelConfig} [dolphin]
|
||||
* @property {OfflineNeMoCtcModelConfig} [nemoCtc]
|
||||
* @property {OfflineCanaryModelConfig} [canary]
|
||||
* @property {OfflineWhisperModelConfig} [whisper]
|
||||
* @property {OfflineFireRedAsrModelConfig} [fireRedAsr]
|
||||
* @property {OfflineMoonshineModelConfig} [moonshine]
|
||||
* @property {OfflineTdnnModelConfig} [tdnn]
|
||||
* @property {OfflineSenseVoiceModelConfig} [senseVoice]
|
||||
* @property {string} [tokens]
|
||||
* @property {OfflineCanaryModelConfig} [canary]
|
||||
* @property {OfflineWhisperModelConfig} [whisper]
|
||||
* @property {OfflineFireRedAsrModelConfig} [fireRedAsr]
|
||||
* @property {OfflineMoonshineModelConfig} [moonshine]
|
||||
* @property {OfflineTdnnModelConfig} [tdnn]
|
||||
* @property {OfflineSenseVoiceModelConfig} [senseVoice]
|
||||
* @property {OfflineCohereTranscribeModelConfig} [cohereTranscribe]
|
||||
* @property {string} [tokens]
|
||||
* @property {number} [numThreads]
|
||||
* @property {boolean|number} [debug]
|
||||
* @property {string} [provider]
|
||||
|
||||
@@ -71,6 +71,10 @@ function freeConfig(config, Module) {
|
||||
freeConfig(config.qwen3Asr, Module)
|
||||
}
|
||||
|
||||
if ('cohereTranscribe' in config) {
|
||||
freeConfig(config.cohereTranscribe, Module)
|
||||
}
|
||||
|
||||
if ('funasrNano' in config) {
|
||||
freeConfig(config.funasrNano, Module)
|
||||
}
|
||||
@@ -1215,6 +1219,47 @@ function initSherpaOnnxOfflineTdnnModelConfig(config, Module) {
|
||||
};
|
||||
}
|
||||
|
||||
function initSherpaOnnxOfflineCohereTranscribeModelConfig(config, Module) {
|
||||
const encoderLen = Module.lengthBytesUTF8(config.encoder || '') + 1;
|
||||
const decoderLen = Module.lengthBytesUTF8(config.decoder || '') + 1;
|
||||
const languageLen = Module.lengthBytesUTF8(config.language || '') + 1;
|
||||
|
||||
const n = encoderLen + decoderLen + languageLen;
|
||||
const buffer = Module._malloc(n);
|
||||
|
||||
const len = 5 * 4; // 3 pointers + 2 ints
|
||||
const ptr = Module._malloc(len);
|
||||
|
||||
let offset = 0;
|
||||
Module.stringToUTF8(config.encoder || '', buffer + offset, encoderLen);
|
||||
offset += encoderLen;
|
||||
|
||||
Module.stringToUTF8(config.decoder || '', buffer + offset, decoderLen);
|
||||
offset += decoderLen;
|
||||
|
||||
Module.stringToUTF8(config.language || '', buffer + offset, languageLen);
|
||||
offset += languageLen;
|
||||
|
||||
offset = 0;
|
||||
Module.setValue(ptr, buffer + offset, 'i8*');
|
||||
offset += encoderLen;
|
||||
|
||||
Module.setValue(ptr + 4, buffer + offset, 'i8*');
|
||||
offset += decoderLen;
|
||||
|
||||
Module.setValue(ptr + 8, buffer + offset, 'i8*');
|
||||
offset += languageLen;
|
||||
|
||||
Module.setValue(ptr + 12, config.usePunct ?? 1, 'i32');
|
||||
Module.setValue(ptr + 16, config.useItn ?? 1, 'i32');
|
||||
|
||||
return {
|
||||
buffer: buffer,
|
||||
ptr: ptr,
|
||||
len: len,
|
||||
};
|
||||
}
|
||||
|
||||
function initSherpaOnnxOfflineSenseVoiceModelConfig(config, Module) {
|
||||
const modelLen = Module.lengthBytesUTF8(config.model || '') + 1;
|
||||
const languageLen = Module.lengthBytesUTF8(config.language || '') + 1;
|
||||
@@ -1339,6 +1384,16 @@ function initSherpaOnnxOfflineModelConfig(config, Module) {
|
||||
};
|
||||
}
|
||||
|
||||
if (!('cohereTranscribe' in config)) {
|
||||
config.cohereTranscribe = {
|
||||
encoder: '',
|
||||
decoder: '',
|
||||
language: '',
|
||||
usePunct: 1,
|
||||
useItn: 1,
|
||||
};
|
||||
}
|
||||
|
||||
if (!('funasrNano' in config)) {
|
||||
config.funasrNano = {
|
||||
encoderAdaptor: '',
|
||||
@@ -1459,11 +1514,14 @@ function initSherpaOnnxOfflineModelConfig(config, Module) {
|
||||
const qwen3Asr =
|
||||
initSherpaOnnxOfflineQwen3AsrModelConfig(config.qwen3Asr, Module);
|
||||
|
||||
const cohereTranscribe = initSherpaOnnxOfflineCohereTranscribeModelConfig(
|
||||
config.cohereTranscribe, Module);
|
||||
|
||||
const len = transducer.len + paraformer.len + nemoCtc.len + whisper.len +
|
||||
tdnn.len + 8 * 4 + senseVoice.len + moonshine.len + fireRedAsr.len +
|
||||
dolphin.len + zipformerCtc.len + canary.len + wenetCtc.len +
|
||||
omnilingual.len + medasr.len + funasrNano.len + fireRedAsrCtc.len +
|
||||
qwen3Asr.len;
|
||||
qwen3Asr.len + cohereTranscribe.len;
|
||||
|
||||
const ptr = Module._malloc(len);
|
||||
|
||||
@@ -1589,6 +1647,9 @@ function initSherpaOnnxOfflineModelConfig(config, Module) {
|
||||
Module._CopyHeap(qwen3Asr.ptr, qwen3Asr.len, ptr + offset);
|
||||
offset += qwen3Asr.len;
|
||||
|
||||
Module._CopyHeap(cohereTranscribe.ptr, cohereTranscribe.len, ptr + offset);
|
||||
offset += cohereTranscribe.len;
|
||||
|
||||
return {
|
||||
buffer: buffer,
|
||||
ptr: ptr,
|
||||
@@ -1609,7 +1670,8 @@ function initSherpaOnnxOfflineModelConfig(config, Module) {
|
||||
medasr: medasr,
|
||||
funasrNano: funasrNano,
|
||||
fireRedAsrCtc: fireRedAsrCtc,
|
||||
qwen3Asr: qwen3Asr
|
||||
qwen3Asr: qwen3Asr,
|
||||
cohereTranscribe: cohereTranscribe
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ static_assert(sizeof(SherpaOnnxOfflineMedAsrCtcModelConfig) == 4, "");
|
||||
static_assert(sizeof(SherpaOnnxOfflineFireRedAsrCtcModelConfig) == 4, "");
|
||||
static_assert(sizeof(SherpaOnnxOfflineFunASRNanoModelConfig) == 13 * 4, "");
|
||||
static_assert(sizeof(SherpaOnnxOfflineQwen3ASRModelConfig) == 10 * 4, "");
|
||||
static_assert(sizeof(SherpaOnnxOfflineCohereTranscribeModelConfig) == 5 * 4,
|
||||
"");
|
||||
static_assert(sizeof(SherpaOnnxOfflineDolphinModelConfig) == 4, "");
|
||||
static_assert(sizeof(SherpaOnnxOfflineNemoEncDecCtcModelConfig) == 4, "");
|
||||
static_assert(sizeof(SherpaOnnxOfflineWhisperModelConfig) == 7 * 4, "");
|
||||
@@ -47,7 +49,8 @@ static_assert(sizeof(SherpaOnnxOfflineModelConfig) ==
|
||||
sizeof(SherpaOnnxOfflineMedAsrCtcModelConfig) +
|
||||
sizeof(SherpaOnnxOfflineFunASRNanoModelConfig) +
|
||||
sizeof(SherpaOnnxOfflineFireRedAsrCtcModelConfig) +
|
||||
sizeof(SherpaOnnxOfflineQwen3ASRModelConfig),
|
||||
sizeof(SherpaOnnxOfflineQwen3ASRModelConfig) +
|
||||
sizeof(SherpaOnnxOfflineCohereTranscribeModelConfig),
|
||||
|
||||
"");
|
||||
static_assert(sizeof(SherpaOnnxFeatureConfig) == 2 * 4, "");
|
||||
@@ -168,6 +171,8 @@ void PrintOfflineRecognizerConfig(SherpaOnnxOfflineRecognizerConfig *config) {
|
||||
auto medasr = &model_config->medasr;
|
||||
auto funasr_nano = &model_config->funasr_nano;
|
||||
auto fire_red_asr_ctc = &model_config->fire_red_asr_ctc;
|
||||
auto qwen3_asr = &model_config->qwen3_asr;
|
||||
auto cohere_transcribe = &model_config->cohere_transcribe;
|
||||
|
||||
fprintf(stdout, "----------offline transducer model config----------\n");
|
||||
fprintf(stdout, "encoder: %s\n", transducer->encoder);
|
||||
@@ -243,6 +248,25 @@ void PrintOfflineRecognizerConfig(SherpaOnnxOfflineRecognizerConfig *config) {
|
||||
fprintf(stdout, "----------offline FireRedASR CTC model config----------\n");
|
||||
fprintf(stdout, "model: %s\n", fire_red_asr_ctc->model);
|
||||
|
||||
fprintf(stdout, "----------offline Qwen3 ASR model config----------\n");
|
||||
fprintf(stdout, "conv_frontend: %s\n", qwen3_asr->conv_frontend);
|
||||
fprintf(stdout, "encoder: %s\n", qwen3_asr->encoder);
|
||||
fprintf(stdout, "decoder: %s\n", qwen3_asr->decoder);
|
||||
fprintf(stdout, "tokenizer: %s\n", qwen3_asr->tokenizer);
|
||||
fprintf(stdout, "max_total_len: %d\n", qwen3_asr->max_total_len);
|
||||
fprintf(stdout, "max_new_tokens: %d\n", qwen3_asr->max_new_tokens);
|
||||
fprintf(stdout, "temperature: %f\n", qwen3_asr->temperature);
|
||||
fprintf(stdout, "top_p: %f\n", qwen3_asr->top_p);
|
||||
fprintf(stdout, "seed: %d\n", qwen3_asr->seed);
|
||||
fprintf(stdout, "hotwords: %s\n", qwen3_asr->hotwords);
|
||||
|
||||
fprintf(stdout, "----------offline Cohere Transcribe model config----------\n");
|
||||
fprintf(stdout, "encoder: %s\n", cohere_transcribe->encoder);
|
||||
fprintf(stdout, "decoder: %s\n", cohere_transcribe->decoder);
|
||||
fprintf(stdout, "language: %s\n", cohere_transcribe->language);
|
||||
fprintf(stdout, "use_punct: %d\n", cohere_transcribe->use_punct);
|
||||
fprintf(stdout, "use_itn: %d\n", cohere_transcribe->use_itn);
|
||||
|
||||
fprintf(stdout, "tokens: %s\n", model_config->tokens);
|
||||
fprintf(stdout, "num_threads: %d\n", model_config->num_threads);
|
||||
fprintf(stdout, "provider: %s\n", model_config->provider);
|
||||
|
||||
Reference in new issue
Block a user