Fangjun Kuang
Committed by GitHub

Inverse text normalization API of streaming ASR for various programming languages (#1022)

正在显示 64 个修改的文件 包含 849 行增加55 行删除
... ... @@ -66,7 +66,9 @@ echo '----------streaming zipformer ctc----------'
rm -rf sherpa-onnx-*
echo '----------streaming zipformer transducer----------'
./run-zipformer-transducer-itn.sh
./run-zipformer-transducer.sh
rm -f itn*
rm -rf sherpa-onnx-*
echo '----------streaming NeMo transducer----------'
... ...
... ... @@ -2,7 +2,13 @@
cd dotnet-examples/
cd ./offline-decode-files
cd ./online-decode-files
./run-transducer-itn.sh
./run-zipformer2-ctc.sh
./run-transducer.sh
./run-paraformer.sh
cd ../offline-decode-files
./run-paraformer-itn.sh
./run-telespeech-ctc.sh
./run-nemo-ctc.sh
... ... @@ -27,11 +33,6 @@ cd ../streaming-hlg-decoding/
cd ../spoken-language-identification
./run.sh
cd ../online-decode-files
./run-zipformer2-ctc.sh
./run-transducer.sh
./run-paraformer.sh
cd ../offline-tts
./run-aishell3.sh
./run-piper.sh
... ...
... ... @@ -70,6 +70,13 @@ curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/s
tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm -f itn*
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
node test_asr_streaming_transducer_itn.js
node test_asr_streaming_transducer.js
rm -rf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20
... ... @@ -120,6 +127,8 @@ rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
node ./test_asr_non_streaming_paraformer.js
rm -f itn*
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
... ...
... ... @@ -15,6 +15,8 @@ curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/s
ls -lh
tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
rm sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
rm -f itn*
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
node ./test-offline-paraformer-itn.js
... ... @@ -57,7 +59,15 @@ rm -rf sherpa-onnx-streaming-paraformer-bilingual-zh-en
curl -LS -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm -f itn*
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
node ./test-online-transducer-itn.js
node ./test-online-transducer.js
rm -rf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20
curl -LS -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
... ...
... ... @@ -2,6 +2,8 @@ name: build-wheels-aarch64
on:
push:
branches:
- wheel
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
workflow_dispatch:
... ...
... ... @@ -2,6 +2,8 @@ name: build-wheels-armv7l
on:
push:
branches:
- wheel
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
workflow_dispatch:
... ...
... ... @@ -2,6 +2,8 @@ name: build-wheels-linux
on:
push:
branches:
- wheel
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
workflow_dispatch:
... ...
... ... @@ -2,6 +2,8 @@ name: build-wheels-macos-arm64
on:
push:
branches:
- wheel
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
workflow_dispatch:
... ... @@ -84,7 +86,7 @@ jobs:
run: |
opts='--break-system-packages'
v=${{ matrix.python-version }}
if [[ $v == cp38 || $v == cp39 ]]; then
if [[ $v == cp37 || $v == cp38 || $v == cp39 ]]; then
opts=''
fi
... ...
... ... @@ -101,7 +101,7 @@ jobs:
run: |
opts='--break-system-packages'
v=${{ matrix.python-version }}
if [[ $v == cp38 || $v == cp39 ]]; then
if [[ $v == cp37 || $v == cp38 || $v == cp39 ]]; then
opts=''
fi
... ...
... ... @@ -2,6 +2,8 @@ name: build-wheels-win32
on:
push:
branches:
- wheel
tags:
- 'v[0-9]+.[0-9]+.[0-9]+*'
workflow_dispatch:
... ...
... ... @@ -173,6 +173,9 @@ jobs:
shell: bash
run: |
cd ./java-api-examples
./run-inverse-text-normalization-transducer.sh
rm -rf sherpa-onnx-streaming-*
./run-streaming-decode-file-ctc.sh
# Delete model files to save space
rm -rf sherpa-onnx-streaming-*
... ...
... ... @@ -187,6 +187,9 @@ jobs:
./run-transducer.sh
rm -rf sherpa-onnx-streaming-zipformer-en-2023-06-26
./run-transducer-itn.sh
rm -rf sherpa-onnx-streaming-*
echo "Test paraformer"
./run-paraformer.sh
rm -rf sherpa-onnx-streaming-paraformer-bilingual-zh-en
... ...
... ... @@ -7,7 +7,8 @@ project(sherpa-onnx)
# Remember to update
# ./nodejs-addon-examples
# ./dart-api-examples/
set(SHERPA_ONNX_VERSION "1.9.30")
# ./sherpa-onnx/flutter/CHANGELOG.md
set(SHERPA_ONNX_VERSION "1.10.0")
# Disable warning about
#
... ...
... ... @@ -196,6 +196,9 @@ class MainActivity : AppCompatActivity() {
// See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
// for a list of available models
val type = 0
var ruleFsts : String?
ruleFsts = null
Log.i(TAG, "Select model type $type")
val config = OnlineRecognizerConfig(
featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80),
... ... @@ -205,6 +208,10 @@ class MainActivity : AppCompatActivity() {
enableEndpoint = true,
)
if (ruleFsts != null) {
config.ruleFsts = ruleFsts
}
recognizer = OnlineRecognizer(
assetManager = application.assets,
config = config,
... ...
... ... @@ -194,6 +194,8 @@ class MainActivity : AppCompatActivity() {
// See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
// for a list of available models
val firstType = 9
val firstRuleFsts: String?
firstRuleFsts = null
Log.i(TAG, "Select model type $firstType for the first pass")
val config = OnlineRecognizerConfig(
featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80),
... ... @@ -201,6 +203,9 @@ class MainActivity : AppCompatActivity() {
endpointConfig = getEndpointConfig(),
enableEndpoint = true,
)
if (firstRuleFsts != null) {
config.ruleFsts = firstRuleFsts;
}
onlineRecognizer = OnlineRecognizer(
assetManager = application.assets,
... ... @@ -213,6 +218,8 @@ class MainActivity : AppCompatActivity() {
// See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
// for a list of available models
val secondType = 0
var secondRuleFsts: String?
secondRuleFsts = null
Log.i(TAG, "Select model type $secondType for the second pass")
val config = OfflineRecognizerConfig(
... ... @@ -220,6 +227,10 @@ class MainActivity : AppCompatActivity() {
modelConfig = getOfflineModelConfig(type = secondType)!!,
)
if (secondRuleFsts != null) {
config.ruleFsts = secondRuleFsts
}
offlineRecognizer = OfflineRecognizer(
assetManager = application.assets,
config = config,
... ...
... ... @@ -200,12 +200,17 @@ class MainActivity : AppCompatActivity() {
// See https://k2-fsa.github.io/sherpa/onnx/pretrained_models/index.html
// for a list of available models
val asrModelType = 0
val asrRuleFsts: String?
asrRuleFsts = null
Log.i(TAG, "Select model type ${asrModelType} for ASR")
val config = OfflineRecognizerConfig(
featConfig = getFeatureConfig(sampleRate = sampleRateInHz, featureDim = 80),
modelConfig = getOfflineModelConfig(type = asrModelType)!!,
)
if (asrRuleFsts != null) {
config.ruleFsts = asrRuleFsts;
}
offlineRecognizer = OfflineRecognizer(
assetManager = application.assets,
... ...
... ... @@ -63,23 +63,15 @@ function(download_kaldi_decoder)
kaldi-decoder-core
kaldifst_core
fst
fstfar
DESTINATION ..)
if(SHERPA_ONNX_ENABLE_TTS)
install(TARGETS
fstfar
DESTINATION ..)
endif()
else()
install(TARGETS
kaldi-decoder-core
kaldifst_core
fst
fstfar
DESTINATION lib)
if(SHERPA_ONNX_ENABLE_TTS)
install(TARGETS
fstfar
DESTINATION lib)
endif()
endif()
if(WIN32 AND BUILD_SHARED_LIBS)
... ... @@ -87,12 +79,8 @@ function(download_kaldi_decoder)
kaldi-decoder-core
kaldifst_core
fst
fstfar
DESTINATION bin)
if(SHERPA_ONNX_ENABLE_TTS)
install(TARGETS
fstfar
DESTINATION bin)
endif()
endif()
endfunction()
... ...
... ... @@ -10,7 +10,7 @@ environment:
# Add regular dependencies here.
dependencies:
sherpa_onnx: ^1.9.30
sherpa_onnx: ^1.10.0
path: ^1.9.0
args: ^2.5.0
... ...
... ... @@ -15,6 +15,7 @@ void main(List<String> arguments) async {
..addOption('decoder', help: 'Path to decoder model')
..addOption('joiner', help: 'Path to joiner model')
..addOption('tokens', help: 'Path to tokens.txt')
..addOption('rule-fsts', help: 'Path to rule fsts', defaultsTo: '')
..addOption('input-wav', help: 'Path to input.wav to transcribe');
final res = parser.parse(arguments);
... ... @@ -31,6 +32,7 @@ void main(List<String> arguments) async {
final decoder = res['decoder'] as String;
final joiner = res['joiner'] as String;
final tokens = res['tokens'] as String;
final ruleFsts = res['rule-fsts'] as String;
final inputWav = res['input-wav'] as String;
final transducer = sherpa_onnx.OnlineTransducerModelConfig(
... ... @@ -45,7 +47,10 @@ void main(List<String> arguments) async {
debug: true,
numThreads: 1,
);
final config = sherpa_onnx.OnlineRecognizerConfig(model: modelConfig);
final config = sherpa_onnx.OnlineRecognizerConfig(
model: modelConfig,
ruleFsts: ruleFsts,
);
final recognizer = sherpa_onnx.OnlineRecognizer(config);
final waveData = sherpa_onnx.readWave(inputWav);
... ...
... ... @@ -11,7 +11,7 @@ environment:
# Add regular dependencies here.
dependencies:
sherpa_onnx: ^1.9.30
sherpa_onnx: ^1.10.0
path: ^1.9.0
args: ^2.5.0
... ...
#!/usr/bin/env bash
set -ex
dart pub get
if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
fi
if [ ! -f ./itn-zh-number.wav ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
fi
if [ ! -f ./itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
dart run \
./bin/zipformer-transducer.dart \
--encoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx \
--decoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx \
--joiner ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx \
--tokens ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt \
--rule-fsts ./itn_zh_number.fst \
--input-wav ./itn-zh-number.wav
... ...
... ... @@ -8,7 +8,7 @@ environment:
# Add regular dependencies here.
dependencies:
sherpa_onnx: ^1.9.30
sherpa_onnx: ^1.10.0
path: ^1.9.0
args: ^2.5.0
... ...
... ... @@ -9,7 +9,7 @@ environment:
sdk: ^3.4.0
dependencies:
sherpa_onnx: ^1.9.30
sherpa_onnx: ^1.10.0
path: ^1.9.0
args: ^2.5.0
... ...
... ... @@ -85,6 +85,10 @@ larger than this value. Used only when --enable-endpoint is true.")]
[Option("hotwords-score", Required = false, Default = 1.5F, HelpText = "hotwords score")]
public float HotwordsScore { get; set; }
[Option("rule-fsts", Required = false, Default = "",
HelpText = "If not empty, path to rule fst for inverse text normalization")]
public string RuleFsts { get; set; }
[Option("files", Required = true, HelpText = "Audio files for decoding")]
public IEnumerable<string> Files { get; set; }
... ... @@ -189,6 +193,7 @@ to download pre-trained streaming models.
config.Rule3MinUtteranceLength = options.Rule3MinUtteranceLength;
config.HotwordsFile = options.HotwordsFile;
config.HotwordsScore = options.HotwordsScore;
config.RuleFsts = options.RuleFsts;
OnlineRecognizer recognizer = new OnlineRecognizer(config);
... ...
#!/usr/bin/env bash
# Please refer to
# https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/zipformer-transducer-models.html#csukuangfj-sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20-bilingual-chinese-english
# to download the model files
set -ex
if [ ! -d ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20 ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
fi
if [ ! -f ./itn-zh-number.wav ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
fi
if [ ! -f ./itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
dotnet run -c Release \
--tokens ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt \
--encoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx \
--decoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.int8.onnx \
--joiner ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx \
--decoding-method greedy_search \
--files ./itn-zh-number.wav
... ...
... ... @@ -30,6 +30,8 @@ func main() {
flag.StringVar(&config.ModelConfig.Provider, "provider", "cpu", "Provider to use")
flag.StringVar(&config.DecodingMethod, "decoding-method", "greedy_search", "Decoding method. Possible values: greedy_search, modified_beam_search")
flag.IntVar(&config.MaxActivePaths, "max-active-paths", 4, "Used only when --decoding-method is modified_beam_search")
flag.StringVar(&config.RuleFsts, "rule-fsts", "", "If not empty, path to rule fst for inverse text normalization")
flag.StringVar(&config.RuleFars, "rule-fars", "", "If not empty, path to rule fst archives for inverse text normalization")
flag.Parse()
... ...
#!/usr/bin/env bash
set -ex
if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
fi
if [ ! -f ./itn-zh-number.wav ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
fi
if [ ! -f ./itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
go mod tidy
go build
./streaming-decode-files \
--encoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx \
--decoder ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx \
--joiner ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx \
--tokens ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt \
--model-type zipformer \
--rule-fsts ./itn_zh_number.fst \
--debug 0 \
./itn-zh-number.wav
... ...
// Copyright 2024 Xiaomi Corporation
// This file shows how to use a streaming transducer
// to decode files with inverse text normalization.
import com.k2fsa.sherpa.onnx.*;
public class InverseTextNormalizationStreamingTransducer {
public static void main(String[] args) {
// please refer to
// https://k2-fsa.github.io/sherpa/onnx/pretrained_models/online-transducer/zipformer-transducer-models.html#csukuangfj-sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20-bilingual-chinese-english
// to download model files
String encoder =
"./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx";
String decoder =
"./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx";
String joiner =
"./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx";
String tokens = "./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt";
// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
String waveFilename = "./itn-zh-number.wav";
// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
String ruleFsts = "./itn_zh_number.fst";
WaveReader reader = new WaveReader(waveFilename);
OnlineTransducerModelConfig transducer =
OnlineTransducerModelConfig.builder()
.setEncoder(encoder)
.setDecoder(decoder)
.setJoiner(joiner)
.build();
OnlineModelConfig modelConfig =
OnlineModelConfig.builder()
.setTransducer(transducer)
.setTokens(tokens)
.setNumThreads(1)
.setDebug(true)
.build();
OnlineRecognizerConfig config =
OnlineRecognizerConfig.builder()
.setOnlineModelConfig(modelConfig)
.setDecodingMethod("greedy_search")
.setRuleFsts(ruleFsts)
.build();
OnlineRecognizer recognizer = new OnlineRecognizer(config);
OnlineStream stream = recognizer.createStream();
stream.acceptWaveform(reader.getSamples(), reader.getSampleRate());
float[] tailPaddings = new float[(int) (0.8 * reader.getSampleRate())];
stream.acceptWaveform(tailPaddings, reader.getSampleRate());
while (recognizer.isReady(stream)) {
recognizer.decode(stream);
}
String text = recognizer.getResult(stream).getText();
System.out.printf("filename:%s\nresult:%s\n", waveFilename, text);
stream.release();
recognizer.release();
}
}
... ...
#!/usr/bin/env bash
set -ex
if [[ ! -f ../build/lib/libsherpa-onnx-jni.dylib && ! -f ../build/lib/libsherpa-onnx-jni.so ]]; then
mkdir -p ../build
pushd ../build
cmake \
-DSHERPA_ONNX_ENABLE_PYTHON=OFF \
-DSHERPA_ONNX_ENABLE_TESTS=OFF \
-DSHERPA_ONNX_ENABLE_CHECK=OFF \
-DBUILD_SHARED_LIBS=ON \
-DSHERPA_ONNX_ENABLE_PORTAUDIO=OFF \
-DSHERPA_ONNX_ENABLE_JNI=ON \
..
make -j4
ls -lh lib
popd
fi
if [ ! -f ../sherpa-onnx/java-api/build/sherpa-onnx.jar ]; then
pushd ../sherpa-onnx/java-api
make
popd
fi
if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
fi
if [ ! -f ./itn-zh-number.wav ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
fi
if [ ! -f ./itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
java \
-Djava.library.path=$PWD/../build/lib \
-cp ../sherpa-onnx/java-api/build/sherpa-onnx.jar \
InverseTextNormalizationStreamingTransducer.java
... ...
... ... @@ -203,7 +203,7 @@ function testOfflineAsr() {
java -Djava.library.path=../build/lib -jar $out_filename
}
function testInverseTextNormalizationAsr() {
function testInverseTextNormalizationOfflineAsr() {
if [ ! -f ./sherpa-onnx-paraformer-zh-2023-03-28/tokens.txt ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
tar xvf sherpa-onnx-paraformer-zh-2023-03-28.tar.bz2
... ... @@ -218,9 +218,9 @@ function testInverseTextNormalizationAsr() {
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
out_filename=test_offline_asr.jar
out_filename=test_itn_offline_asr.jar
kotlinc-jvm -include-runtime -d $out_filename \
test_itn_asr.kt \
test_itn_offline_asr.kt \
FeatureConfig.kt \
OfflineRecognizer.kt \
OfflineStream.kt \
... ... @@ -231,6 +231,34 @@ function testInverseTextNormalizationAsr() {
java -Djava.library.path=../build/lib -jar $out_filename
}
function testInverseTextNormalizationOnlineAsr() {
if [ ! -f ./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
tar xvf sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
rm sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2
fi
if [ ! -f ./itn-zh-number.wav ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
fi
if [ ! -f ./itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
out_filename=test_itn_online_asr.jar
kotlinc-jvm -include-runtime -d $out_filename \
test_itn_online_asr.kt \
FeatureConfig.kt \
OnlineRecognizer.kt \
OnlineStream.kt \
WaveReader.kt \
faked-asset-manager.kt
ls -lh $out_filename
java -Djava.library.path=../build/lib -jar $out_filename
}
function testPunctuation() {
if [ ! -f ./sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12/model.onnx ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/punctuation-models/sherpa-onnx-punct-ct-transformer-zh-en-vocab272727-2024-04-12.tar.bz2
... ... @@ -257,4 +285,5 @@ testAudioTagging
testSpokenLanguageIdentification
testOfflineAsr
testPunctuation
testInverseTextNormalizationAsr
testInverseTextNormalizationOfflineAsr
testInverseTextNormalizationOnlineAsr
... ...
package com.k2fsa.sherpa.onnx
fun main() {
test()
}
fun test() {
val recognizer = createOnlineRecognizer()
val waveFilename = "./itn-zh-number.wav";
val objArray = WaveReader.readWaveFromFile(
filename = waveFilename,
)
val samples: FloatArray = objArray[0] as FloatArray
val sampleRate: Int = objArray[1] as Int
val stream = recognizer.createStream()
stream.acceptWaveform(samples, sampleRate=sampleRate)
while (recognizer.isReady(stream)) {
recognizer.decode(stream)
}
val result = recognizer.getResult(stream).text
println(result)
stream.release()
recognizer.release()
}
fun createOnlineRecognizer(): OnlineRecognizer {
val config = OnlineRecognizerConfig(
featConfig = getFeatureConfig(sampleRate = 16000, featureDim = 80),
modelConfig = getModelConfig(8)!!,
)
config.ruleFsts = "./itn_zh_number.fst"
println(config)
return OnlineRecognizer(config = config)
}
... ...
{
"dependencies": {
"sherpa-onnx-node": "^1.9.30"
"sherpa-onnx-node": "^1.10.0"
}
}
... ...
// Copyright (c) 2024 Xiaomi Corporation
const sherpa_onnx = require('sherpa-onnx-node');
// Please download test files from
// https://github.com/k2-fsa/sherpa-onnx/releases/tag/asr-models
const config = {
'featConfig': {
'sampleRate': 16000,
'featureDim': 80,
},
'modelConfig': {
'transducer': {
'encoder':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx',
'decoder':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx',
'joiner':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx',
},
'tokens':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt',
'numThreads': 2,
'provider': 'cpu',
'debug': 1,
},
// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
ruleFsts: './itn_zh_number.fst',
};
// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
const waveFilename = './itn-zh-number.wav';
const recognizer = new sherpa_onnx.OnlineRecognizer(config);
console.log('Started')
let start = Date.now();
const stream = recognizer.createStream();
const wave = sherpa_onnx.readWave(waveFilename);
stream.acceptWaveform({sampleRate: wave.sampleRate, samples: wave.samples});
const tailPadding = new Float32Array(wave.sampleRate * 0.4);
stream.acceptWaveform({samples: tailPadding, sampleRate: wave.sampleRate});
while (recognizer.isReady(stream)) {
recognizer.decode(stream);
}
result = recognizer.getResult(stream)
let stop = Date.now();
console.log('Done')
const elapsed_seconds = (stop - start) / 1000;
const duration = wave.samples.length / wave.sampleRate;
const real_time_factor = elapsed_seconds / duration;
console.log('Wave duration', duration.toFixed(3), 'secodns')
console.log('Elapsed', elapsed_seconds.toFixed(3), 'secodns')
console.log(
`RTF = ${elapsed_seconds.toFixed(3)}/${duration.toFixed(3)} =`,
real_time_factor.toFixed(3))
console.log(waveFilename)
console.log('result\n', result)
... ...
// Copyright (c) 2023-2024 Xiaomi Corporation (authors: Fangjun Kuang)
//
const portAudio = require('naudiodon2');
// console.log(portAudio.getDevices());
const sherpa_onnx = require('sherpa-onnx-node');
function createOnlineRecognizer() {
const config = {
'featConfig': {
'sampleRate': 16000,
'featureDim': 80,
},
'modelConfig': {
'transducer': {
'encoder':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.onnx',
'decoder':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx',
'joiner':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.onnx',
},
'tokens':
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt',
'numThreads': 2,
'provider': 'cpu',
'debug': 1,
},
'decodingMethod': 'greedy_search',
'maxActivePaths': 4,
'enableEndpoint': true,
'rule1MinTrailingSilence': 2.4,
'rule2MinTrailingSilence': 1.2,
'rule3MinUtteranceLength': 20,
// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
ruleFsts: './itn_zh_number.fst',
};
return new sherpa_onnx.OnlineRecognizer(config);
}
const recognizer = createOnlineRecognizer();
const stream = recognizer.createStream();
let lastText = '';
let segmentIndex = 0;
const ai = new portAudio.AudioIO({
inOptions: {
channelCount: 1,
closeOnError: true, // Close the stream if an audio error is detected, if
// set false then just log the error
deviceId: -1, // Use -1 or omit the deviceId to select the default device
sampleFormat: portAudio.SampleFormatFloat32,
sampleRate: recognizer.config.featConfig.sampleRate
}
});
const display = new sherpa_onnx.Display(50);
ai.on('data', data => {
const samples = new Float32Array(data.buffer);
stream.acceptWaveform(
{sampleRate: recognizer.config.featConfig.sampleRate, samples: samples});
while (recognizer.isReady(stream)) {
recognizer.decode(stream);
}
const isEndpoint = recognizer.isEndpoint(stream);
const text = recognizer.getResult(stream).text.toLowerCase();
if (text.length > 0 && lastText != text) {
lastText = text;
display.print(segmentIndex, lastText);
}
if (isEndpoint) {
if (text.length > 0) {
lastText = text;
segmentIndex += 1;
}
recognizer.reset(stream)
}
});
ai.start();
console.log('Started! Please speak')
... ...
// Copyright (c) 2023 Xiaomi Corporation (authors: Fangjun Kuang)
//
const fs = require('fs');
const {Readable} = require('stream');
const wav = require('wav');
const sherpa_onnx = require('sherpa-onnx');
function createOnlineRecognizer() {
let onlineTransducerModelConfig = {
encoder:
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/encoder-epoch-99-avg-1.int8.onnx',
decoder:
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/decoder-epoch-99-avg-1.onnx',
joiner:
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/joiner-epoch-99-avg-1.int8.onnx',
};
let onlineParaformerModelConfig = {
encoder: '',
decoder: '',
};
let onlineZipformer2CtcModelConfig = {
model: '',
};
let onlineModelConfig = {
transducer: onlineTransducerModelConfig,
paraformer: onlineParaformerModelConfig,
zipformer2Ctc: onlineZipformer2CtcModelConfig,
tokens:
'./sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20/tokens.txt',
numThreads: 1,
provider: 'cpu',
debug: 1,
modelType: 'zipformer',
};
let featureConfig = {
sampleRate: 16000,
featureDim: 80,
};
let recognizerConfig = {
featConfig: featureConfig,
modelConfig: onlineModelConfig,
decodingMethod: 'greedy_search',
maxActivePaths: 4,
enableEndpoint: 1,
rule1MinTrailingSilence: 2.4,
rule2MinTrailingSilence: 1.2,
rule3MinUtteranceLength: 20,
hotwordsFile: '',
hotwordsScore: 1.5,
ctcFstDecoderConfig: {
graph: '',
maxActive: 3000,
},
// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
ruleFsts: './itn_zh_number.fst',
};
return sherpa_onnx.createOnlineRecognizer(recognizerConfig);
}
const recognizer = createOnlineRecognizer();
const stream = recognizer.createStream();
// https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn-zh-number.wav
const waveFilename = './itn-zh-number.wav';
const reader = new wav.Reader();
const readable = new Readable().wrap(reader);
function decode(samples) {
stream.acceptWaveform(recognizer.config.featConfig.sampleRate, samples);
while (recognizer.isReady(stream)) {
recognizer.decode(stream);
}
const text = recognizer.getResult(stream).text;
console.log(text);
}
reader.on('format', ({audioFormat, bitDepth, channels, sampleRate}) => {
if (sampleRate != recognizer.config.featConfig.sampleRate) {
throw new Error(`Only support sampleRate ${
recognizer.config.featConfig.sampleRate}. Given ${sampleRate}`);
}
if (audioFormat != 1) {
throw new Error(`Only support PCM format. Given ${audioFormat}`);
}
if (channels != 1) {
throw new Error(`Only a single channel. Given ${channel}`);
}
if (bitDepth != 16) {
throw new Error(`Only support 16-bit samples. Given ${bitDepth}`);
}
});
fs.createReadStream(waveFilename, {'highWaterMark': 4096})
.pipe(reader)
.on('finish', function(err) {
// tail padding
const floatSamples =
new Float32Array(recognizer.config.featConfig.sampleRate * 0.5);
decode(floatSamples);
stream.free();
recognizer.free();
});
readable.on('readable', function() {
let chunk;
while ((chunk = readable.read()) != null) {
const int16Samples = new Int16Array(
chunk.buffer, chunk.byteOffset,
chunk.length / Int16Array.BYTES_PER_ELEMENT);
const floatSamples = new Float32Array(int16Samples.length);
for (let i = 0; i < floatSamples.length; i++) {
floatSamples[i] = int16Samples[i] / 32768.0;
}
decode(floatSamples);
}
});
... ...
... ... @@ -71,6 +71,17 @@ git checkout .
pushd android/SherpaOnnx2Pass/app/src/main/java/com/k2fsa/sherpa/onnx
sed -i.bak s/"firstType = 9/firstType = $type1/" ./MainActivity.kt
sed -i.bak s/"secondType = 0/secondType = $type2/" ./MainActivity.kt
{% if first.rule_fsts %}
rule_fsts={{ first.rule_fsts }}
sed -i.bak s%"firstRuleFsts = null"%"firstRuleFsts = \"$rule_fsts\""% ./MainActivity.kt
{% endif %}
{% if second.rule_fsts %}
rule_fsts={{ second.rule_fsts }}
sed -i.bak s%"secondRuleFsts = null"%"secondRuleFsts = \"$rule_fsts\""% ./MainActivity.kt
{% endif %}
git diff
popd
... ...
... ... @@ -54,6 +54,12 @@ popd
git checkout .
pushd android/SherpaOnnx/app/src/main/java/com/k2fsa/sherpa/onnx
sed -i.bak s/"type = 0/type = $type/" ./MainActivity.kt
{% if model.rule_fsts %}
rule_fsts={{ model.rule_fsts }}
sed -i.bak s%"ruleFsts = null"%"ruleFsts = \"$rule_fsts\""% ./MainActivity.kt
{% endif %}
git diff
popd
... ... @@ -84,6 +90,7 @@ for arch in arm64-v8a armeabi-v7a x86_64 x86; do
done
rm -rf ./android/SherpaOnnx/app/src/main/assets/$model_name
rm -rf ./android/SherpaOnnx/app/src/main/assets/*.fst
{% endfor %}
git checkout .
... ...
... ... @@ -56,6 +56,12 @@ popd
git checkout .
pushd android/SherpaOnnxVadAsr/app/src/main/java/com/k2fsa/sherpa/onnx
sed -i.bak s/"asrModelType = 0/asrModelType = $type/" ./MainActivity.kt
{% if model.rule_fsts %}
rule_fsts={{ model.rule_fsts }}
sed -i.bak s%"asrRuleFsts = null"%"asrRuleFsts = \"$rule_fsts\""% ./MainActivity.kt
{% endif %}
git diff
popd
... ...
... ... @@ -41,6 +41,7 @@ class Model:
# cmd is used to remove extra file from the model directory
cmd: str = ""
rule_fsts: str = ""
def get_2nd_models():
... ... @@ -70,7 +71,11 @@ def get_2nd_models():
idx=0,
lang="zh",
short_name="paraformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -fv README.md
... ... @@ -87,7 +92,11 @@ def get_2nd_models():
idx=4,
lang="zh",
short_name="zipformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -rfv test_wavs
... ... @@ -117,7 +126,11 @@ def get_1st_models():
idx=8,
lang="bilingual_zh_en",
short_name="zipformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -fv decoder-epoch-99-avg-1.int8.onnx
rm -fv encoder-epoch-99-avg-1.onnx
... ... @@ -160,7 +173,11 @@ def get_1st_models():
idx=3,
lang="zh",
short_name="zipformer2",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -fv exp/encoder-epoch-12-avg-4-chunk-16-left-128.onnx
rm -fv exp/decoder-epoch-12-avg-4-chunk-16-left-128.int8.onnx
... ... @@ -202,7 +219,11 @@ def get_1st_models():
idx=9,
lang="zh",
short_name="small_zipformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -fv encoder-epoch-99-avg-1.onnx
rm -fv decoder-epoch-99-avg-1.int8.onnx
... ...
... ... @@ -42,6 +42,8 @@ class Model:
# cmd is used to remove extra file from the model directory
cmd: str = ""
rule_fsts: str = ""
def get_models():
models = [
... ... @@ -50,7 +52,11 @@ def get_models():
idx=8,
lang="bilingual_zh_en",
short_name="zipformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -fv decoder-epoch-99-avg-1.int8.onnx
rm -fv encoder-epoch-99-avg-1.onnx
... ... @@ -93,7 +99,11 @@ def get_models():
idx=3,
lang="zh",
short_name="zipformer2",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -fv exp/encoder-epoch-12-avg-4-chunk-16-left-128.onnx
rm -fv exp/decoder-epoch-12-avg-4-chunk-16-left-128.int8.onnx
... ... @@ -135,7 +145,11 @@ def get_models():
idx=9,
lang="zh",
short_name="small_zipformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -fv encoder-epoch-99-avg-1.onnx
rm -fv decoder-epoch-99-avg-1.int8.onnx
... ...
... ... @@ -42,6 +42,8 @@ class Model:
# cmd is used to remove extra file from the model directory
cmd: str = ""
rule_fsts: str = ""
# See get_2nd_models() in ./generate-asr-2pass-apk-script.py
def get_models():
... ... @@ -71,7 +73,11 @@ def get_models():
idx=0,
lang="zh",
short_name="paraformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -v README.md
... ... @@ -88,7 +94,11 @@ def get_models():
idx=4,
lang="zh",
short_name="zipformer",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -rfv test_wavs
... ... @@ -171,7 +181,11 @@ def get_models():
idx=11,
lang="zh",
short_name="telespeech",
rule_fsts="itn_zh_number.fst",
cmd="""
if [ ! -f itn_zh_number.fst ]; then
curl -SL -O https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/itn_zh_number.fst
fi
pushd $model_name
rm -rfv test_wavs
... ...
... ... @@ -26,6 +26,8 @@ namespace SherpaOnnx
HotwordsFile = "";
HotwordsScore = 1.5F;
CtcFstDecoderConfig = new OnlineCtcFstDecoderConfig();
RuleFsts = "";
RuleFars = "";
}
public FeatureConfig FeatConfig;
public OnlineModelConfig ModelConfig;
... ... @@ -64,5 +66,11 @@ namespace SherpaOnnx
public float HotwordsScore;
public OnlineCtcFstDecoderConfig CtcFstDecoderConfig;
[MarshalAs(UnmanagedType.LPStr)]
public string RuleFsts;
[MarshalAs(UnmanagedType.LPStr)]
public string RuleFars;
}
}
... ...
../../../../go-api-examples/streaming-decode-files/run-transducer-itn.sh
\ No newline at end of file
... ...
... ... @@ -79,8 +79,8 @@ function osx() {
mkdir t
cd t
wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_x86_64.whl
unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_x86_64.whl
wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_x86_64.whl
unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_x86_64.whl
cp -v sherpa_onnx/lib/*.dylib $dst/
... ... @@ -93,8 +93,8 @@ function osx() {
mkdir t
cd t
wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_arm64.whl
unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-macosx_11_0_arm64.whl
wget -q https://huggingface.co/csukuangfj/sherpa-onnx-wheels/resolve/main/sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_arm64.whl
unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp39-cp39-macosx_11_0_arm64.whl
cp -v sherpa_onnx/lib/*.dylib $dst/
... ... @@ -126,7 +126,6 @@ function windows() {
unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win_amd64.whl
cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll $dst
cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.lib $dst
cd ..
rm -rf t
... ... @@ -139,7 +138,6 @@ function windows() {
unzip ./sherpa_onnx-${SHERPA_ONNX_VERSION}-cp38-cp38-win32.whl
cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.dll $dst
cp -v sherpa_onnx-${SHERPA_ONNX_VERSION}.data/data/bin/*.lib $dst
cd ..
rm -rf t
... ...
... ... @@ -127,7 +127,11 @@ type OnlineRecognizerConfig struct {
Rule1MinTrailingSilence float32
Rule2MinTrailingSilence float32
Rule3MinUtteranceLength float32
HotwordsFile string
HotwordsScore float32
CtcFstDecoderConfig OnlineCtcFstDecoderConfig
RuleFsts string
RuleFars string
}
// It contains the recognition result for a online stream.
... ... @@ -204,6 +208,17 @@ func NewOnlineRecognizer(config *OnlineRecognizerConfig) *OnlineRecognizer {
c.rule2_min_trailing_silence = C.float(config.Rule2MinTrailingSilence)
c.rule3_min_utterance_length = C.float(config.Rule3MinUtteranceLength)
c.hotwords_file = C.CString(config.HotwordsFile)
defer C.free(unsafe.Pointer(c.hotwords_file))
c.hotwords_score = C.float(config.HotwordsScore)
c.rule_fsts = C.CString(config.RuleFsts)
defer C.free(unsafe.Pointer(c.rule_fsts))
c.rule_fars = C.CString(config.RuleFars)
defer C.free(unsafe.Pointer(c.rule_fars))
c.ctc_fst_decoder_config.graph = C.CString(config.CtcFstDecoderConfig.Graph)
defer C.free(unsafe.Pointer(c.ctc_fst_decoder_config.graph))
c.ctc_fst_decoder_config.max_active = C.int(config.CtcFstDecoderConfig.MaxActive)
... ...
... ... @@ -189,6 +189,8 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper(
rule3MinUtteranceLength);
SHERPA_ONNX_ASSIGN_ATTR_STR(hotwords_file, hotwordsFile);
SHERPA_ONNX_ASSIGN_ATTR_FLOAT(hotwords_score, hotwordsScore);
SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fsts, ruleFsts);
SHERPA_ONNX_ASSIGN_ATTR_STR(rule_fars, ruleFars);
c.ctc_fst_decoder_config = GetCtcFstDecoderConfig(o);
... ... @@ -246,6 +248,14 @@ static Napi::External<SherpaOnnxOnlineRecognizer> CreateOnlineRecognizerWrapper(
delete[] c.hotwords_file;
}
if (c.rule_fsts) {
delete[] c.rule_fsts;
}
if (c.rule_fars) {
delete[] c.rule_fars;
}
if (c.ctc_fst_decoder_config.graph) {
delete[] c.ctc_fst_decoder_config.graph;
}
... ...
... ... @@ -110,6 +110,9 @@ SherpaOnnxOnlineRecognizer *CreateOnlineRecognizer(
recognizer_config.ctc_fst_decoder_config.max_active =
SHERPA_ONNX_OR(config->ctc_fst_decoder_config.max_active, 3000);
recognizer_config.rule_fsts = SHERPA_ONNX_OR(config->rule_fsts, "");
recognizer_config.rule_fars = SHERPA_ONNX_OR(config->rule_fars, "");
if (config->model_config.debug) {
SHERPA_ONNX_LOGE("%s\n", recognizer_config.ToString().c_str());
}
... ...
... ... @@ -144,6 +144,8 @@ SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerConfig {
float hotwords_score;
SherpaOnnxOnlineCtcFstDecoderConfig ctc_fst_decoder_config;
const char *rule_fsts;
const char *rule_fars;
} SherpaOnnxOnlineRecognizerConfig;
SHERPA_ONNX_API typedef struct SherpaOnnxOnlineRecognizerResult {
... ...
... ... @@ -190,9 +190,10 @@ if(NOT BUILD_SHARED_LIBS AND APPLE)
target_link_libraries(sherpa-onnx-core "-framework Foundation")
endif()
target_link_libraries(sherpa-onnx-core fstfar fst)
if(SHERPA_ONNX_ENABLE_TTS)
target_link_libraries(sherpa-onnx-core piper_phonemize)
target_link_libraries(sherpa-onnx-core fstfar fst)
target_link_libraries(sherpa-onnx-core cppjieba)
endif()
... ...
... ... @@ -425,9 +425,6 @@ std::string OfflineRecognizerImpl::ApplyInverseTextNormalization(
if (!itn_list_.empty()) {
for (const auto &tn : itn_list_) {
text = tn->Normalize(text);
if (config_.model_config.debug) {
SHERPA_ONNX_LOGE("After inverse text normalization: %s", text.c_str());
}
}
}
... ...
... ... @@ -4,6 +4,8 @@
#include "sherpa-onnx/csrc/online-recognizer-impl.h"
#include <utility>
#if __ANDROID_API__ >= 9
#include <strstream>
... ... @@ -186,9 +188,6 @@ std::string OnlineRecognizerImpl::ApplyInverseTextNormalization(
if (!itn_list_.empty()) {
for (const auto &tn : itn_list_) {
text = tn->Normalize(text);
if (config_.model_config.debug) {
SHERPA_ONNX_LOGE("After inverse text normalization: %s", text.c_str());
}
}
}
... ...
## 1.10.0
* Add inverse text normalization
## 1.9.30
* Add TTS
... ...
... ... @@ -111,11 +111,13 @@ class OnlineRecognizerConfig {
this.hotwordsFile = '',
this.hotwordsScore = 1.5,
this.ctcFstDecoderConfig = const OnlineCtcFstDecoderConfig(),
this.ruleFsts = '',
this.ruleFars = '',
});
@override
String toString() {
return 'OnlineRecognizerConfig(feat: $feat, model: $model, decodingMethod: $decodingMethod, maxActivePaths: $maxActivePaths, enableEndpoint: $enableEndpoint, rule1MinTrailingSilence: $rule1MinTrailingSilence, rule2MinTrailingSilence: $rule2MinTrailingSilence, rule3MinUtteranceLength: $rule3MinUtteranceLength, hotwordsFile: $hotwordsFile, hotwordsScore: $hotwordsScore, ctcFstDecoderConfig: $ctcFstDecoderConfig)';
return 'OnlineRecognizerConfig(feat: $feat, model: $model, decodingMethod: $decodingMethod, maxActivePaths: $maxActivePaths, enableEndpoint: $enableEndpoint, rule1MinTrailingSilence: $rule1MinTrailingSilence, rule2MinTrailingSilence: $rule2MinTrailingSilence, rule3MinUtteranceLength: $rule3MinUtteranceLength, hotwordsFile: $hotwordsFile, hotwordsScore: $hotwordsScore, ctcFstDecoderConfig: $ctcFstDecoderConfig, ruleFsts: $ruleFsts, ruleFars: $ruleFars)';
}
final FeatureConfig feat;
... ... @@ -137,6 +139,8 @@ class OnlineRecognizerConfig {
final double hotwordsScore;
final OnlineCtcFstDecoderConfig ctcFstDecoderConfig;
final String ruleFsts;
final String ruleFars;
}
class OnlineRecognizerResult {
... ... @@ -201,9 +205,13 @@ class OnlineRecognizer {
c.ref.ctcFstDecoderConfig.graph =
config.ctcFstDecoderConfig.graph.toNativeUtf8();
c.ref.ctcFstDecoderConfig.maxActive = config.ctcFstDecoderConfig.maxActive;
c.ref.ruleFsts = config.ruleFsts.toNativeUtf8();
c.ref.ruleFars = config.ruleFars.toNativeUtf8();
final ptr = SherpaOnnxBindings.createOnlineRecognizer?.call(c) ?? nullptr;
calloc.free(c.ref.ruleFars);
calloc.free(c.ref.ruleFsts);
calloc.free(c.ref.ctcFstDecoderConfig.graph);
calloc.free(c.ref.hotwordsFile);
calloc.free(c.ref.decodingMethod);
... ...
... ... @@ -205,6 +205,9 @@ final class SherpaOnnxOnlineRecognizerConfig extends Struct {
external double hotwordsScore;
external SherpaOnnxOnlineCtcFstDecoderConfig ctcFstDecoderConfig;
external Pointer<Utf8> ruleFsts;
external Pointer<Utf8> ruleFars;
}
final class SherpaOnnxSileroVadModelConfig extends Struct {
... ...
... ... @@ -15,6 +15,8 @@ public class OnlineRecognizerConfig {
private final int maxActivePaths;
private final String hotwordsFile;
private final float hotwordsScore;
private final String ruleFsts;
private final String ruleFars;
private OnlineRecognizerConfig(Builder builder) {
this.featConfig = builder.featConfig;
... ... @@ -27,6 +29,8 @@ public class OnlineRecognizerConfig {
this.maxActivePaths = builder.maxActivePaths;
this.hotwordsFile = builder.hotwordsFile;
this.hotwordsScore = builder.hotwordsScore;
this.ruleFsts = builder.ruleFsts;
this.ruleFars = builder.ruleFars;
}
public static Builder builder() {
... ... @@ -48,6 +52,8 @@ public class OnlineRecognizerConfig {
private int maxActivePaths = 4;
private String hotwordsFile = "";
private float hotwordsScore = 1.5f;
private String ruleFsts = "";
private String ruleFars = "";
public OnlineRecognizerConfig build() {
return new OnlineRecognizerConfig(this);
... ... @@ -102,5 +108,15 @@ public class OnlineRecognizerConfig {
this.hotwordsScore = hotwordsScore;
return this;
}
public Builder setRuleFsts(String ruleFsts) {
this.ruleFsts = ruleFsts;
return this;
}
public Builder setRuleFars(String ruleFars) {
this.ruleFars = ruleFars;
return this;
}
}
}
... ...
... ... @@ -37,6 +37,18 @@ static OnlineRecognizerConfig GetConfig(JNIEnv *env, jobject config) {
fid = env->GetFieldID(cls, "hotwordsScore", "F");
ans.hotwords_score = env->GetFloatField(config, fid);
fid = env->GetFieldID(cls, "ruleFsts", "Ljava/lang/String;");
s = (jstring)env->GetObjectField(config, fid);
p = env->GetStringUTFChars(s, nullptr);
ans.rule_fsts = p;
env->ReleaseStringUTFChars(s, p);
fid = env->GetFieldID(cls, "ruleFars", "Ljava/lang/String;");
s = (jstring)env->GetObjectField(config, fid);
p = env->GetStringUTFChars(s, nullptr);
ans.rule_fars = p;
env->ReleaseStringUTFChars(s, p);
//---------- feat config ----------
fid = env->GetFieldID(cls, "featConfig",
"Lcom/k2fsa/sherpa/onnx/FeatureConfig;");
... ...
... ... @@ -69,6 +69,8 @@ data class OnlineRecognizerConfig(
var maxActivePaths: Int = 4,
var hotwordsFile: String = "",
var hotwordsScore: Float = 1.5f,
var ruleFsts: String = "",
var ruleFars: String = "",
)
data class OnlineRecognizerResult(
... ...
... ... @@ -135,7 +135,9 @@ func sherpaOnnxOnlineRecognizerConfig(
maxActivePaths: Int = 4,
hotwordsFile: String = "",
hotwordsScore: Float = 1.5,
ctcFstDecoderConfig: SherpaOnnxOnlineCtcFstDecoderConfig = sherpaOnnxOnlineCtcFstDecoderConfig()
ctcFstDecoderConfig: SherpaOnnxOnlineCtcFstDecoderConfig = sherpaOnnxOnlineCtcFstDecoderConfig(),
ruleFsts: String = "",
ruleFars: String = ""
) -> SherpaOnnxOnlineRecognizerConfig {
return SherpaOnnxOnlineRecognizerConfig(
feat_config: featConfig,
... ... @@ -148,7 +150,9 @@ func sherpaOnnxOnlineRecognizerConfig(
rule3_min_utterance_length: rule3MinUtteranceLength,
hotwords_file: toCPointer(hotwordsFile),
hotwords_score: hotwordsScore,
ctc_fst_decoder_config: ctcFstDecoderConfig
ctc_fst_decoder_config: ctcFstDecoderConfig,
rule_fsts: toCPointer(ruleFsts),
rule_fars: toCPointer(ruleFars)
)
}
... ...
... ... @@ -40,6 +40,8 @@ string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exp
string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ")
string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ")
message(STATUS "MY_FLAGS: ${MY_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_FLAGS}")
set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} ${MY_FLAGS}")
... ...
... ... @@ -239,7 +239,7 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
const ctcFstDecoder = initSherpaOnnxOnlineCtcFstDecoderConfig(
config.ctcFstDecoderConfig, Module)
const len = feat.len + model.len + 8 * 4 + ctcFstDecoder.len;
const len = feat.len + model.len + 8 * 4 + ctcFstDecoder.len + 2 * 4;
const ptr = Module._malloc(len);
let offset = 0;
... ... @@ -251,7 +251,10 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
const decodingMethodLen = Module.lengthBytesUTF8(config.decodingMethod) + 1;
const hotwordsFileLen = Module.lengthBytesUTF8(config.hotwordsFile) + 1;
const bufferLen = decodingMethodLen + hotwordsFileLen;
const ruleFstsFileLen = Module.lengthBytesUTF8(config.ruleFsts || '') + 1;
const ruleFarsFileLen = Module.lengthBytesUTF8(config.ruleFars || '') + 1;
const bufferLen =
decodingMethodLen + hotwordsFileLen + ruleFstsFileLen + ruleFarsFileLen;
const buffer = Module._malloc(bufferLen);
offset = 0;
... ... @@ -259,6 +262,13 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
offset += decodingMethodLen;
Module.stringToUTF8(config.hotwordsFile, buffer + offset, hotwordsFileLen);
offset += hotwordsFileLen;
Module.stringToUTF8(config.ruleFsts || '', buffer + offset, ruleFstsFileLen);
offset += ruleFstsFileLen;
Module.stringToUTF8(config.ruleFars || '', buffer + offset, ruleFarsFileLen);
offset += ruleFarsFileLen;
offset = feat.len + model.len;
Module.setValue(ptr + offset, buffer, 'i8*'); // decoding method
... ... @@ -286,6 +296,16 @@ function initSherpaOnnxOnlineRecognizerConfig(config, Module) {
offset += 4;
Module._CopyHeap(ctcFstDecoder.ptr, ctcFstDecoder.len, ptr + offset);
offset += ctcFstDecoder.len;
Module.setValue(
ptr + offset, buffer + decodingMethodLen + hotwordsFileLen, 'i8*');
offset += 4;
Module.setValue(
ptr + offset,
buffer + decodingMethodLen + hotwordsFileLen + ruleFstsFileLen, 'i8*');
offset += 4;
return {
buffer: buffer, ptr: ptr, len: len, feat: feat, model: model,
... ... @@ -363,7 +383,9 @@ function createOnlineRecognizer(Module, myConfig) {
ctcFstDecoderConfig: {
graph: '',
maxActive: 3000,
}
},
ruleFsts: '',
ruleFars: '',
};
if (myConfig) {
recognizerConfig = myConfig;
... ...
... ... @@ -26,7 +26,7 @@ static_assert(sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) == 2 * 4, "");
static_assert(sizeof(SherpaOnnxOnlineRecognizerConfig) ==
sizeof(SherpaOnnxFeatureConfig) +
sizeof(SherpaOnnxOnlineModelConfig) + 8 * 4 +
sizeof(SherpaOnnxOnlineCtcFstDecoderConfig),
sizeof(SherpaOnnxOnlineCtcFstDecoderConfig) + 2 * 4,
"");
void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) {
... ... @@ -71,6 +71,8 @@ void MyPrint(SherpaOnnxOnlineRecognizerConfig *config) {
config->rule3_min_utterance_length);
fprintf(stdout, "hotwords_file: %s\n", config->hotwords_file);
fprintf(stdout, "hotwords_score: %.2f\n", config->hotwords_score);
fprintf(stdout, "rule_fsts: %s\n", config->rule_fsts);
fprintf(stdout, "rule_fars: %s\n", config->rule_fars);
fprintf(stdout, "----------ctc fst decoder config----------\n");
fprintf(stdout, "graph: %s\n", config->ctc_fst_decoder_config.graph);
... ...
... ... @@ -31,6 +31,7 @@ string(APPEND MY_FLAGS " -sSTACK_SIZE=10485760 ")
string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exported_functions}] ")
string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ")
string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ")
message(STATUS "MY_FLAGS: ${MY_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}")
... ... @@ -51,4 +52,4 @@ install(
"$<TARGET_FILE_DIR:sherpa-onnx-wasm-kws-main>/sherpa-onnx-wasm-kws-main.data"
DESTINATION
bin/wasm
)
\ No newline at end of file
)
... ...
... ... @@ -31,6 +31,8 @@ string(APPEND MY_FLAGS " -sEXPORTED_FUNCTIONS=[_CopyHeap,_malloc,_free,${all_exp
string(APPEND MY_FLAGS "--preload-file ${CMAKE_CURRENT_SOURCE_DIR}/assets@. ")
string(APPEND MY_FLAGS " -sEXPORTED_RUNTIME_METHODS=['ccall','stringToUTF8','setValue','getValue','lengthBytesUTF8','UTF8ToString'] ")
message(STATUS "MY_FLAGS: ${MY_FLAGS}")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MY_FLAGS}")
set(CMAKE_EXECUTBLE_LINKER_FLAGS "${CMAKE_EXECUTBLE_LINKER_FLAGS} ${MY_FLAGS}")
... ...