From a7152733b2333f24adc9d204d74e7ef53669527a Mon Sep 17 00:00:00 2001 From: Dita Aji Pratama Date: Tue, 15 Sep 2026 14:59:25 +0700 Subject: [PATCH] Create a configuration --- README.md | 28 ++++++++++++++++++++++------ config/__init__.py | 0 config/asr.py | 12 ++++++++++++ config/model.py | 8 ++++++++ core/__init__.py | 0 core/args_parser.py | 14 -------------- core/argsroom.py | 5 +++++ stt_runner.py | 31 +++++++++++++++++-------------- 8 files changed, 64 insertions(+), 34 deletions(-) create mode 100644 config/__init__.py create mode 100644 config/asr.py create mode 100644 config/model.py create mode 100644 core/__init__.py delete mode 100644 core/args_parser.py create mode 100644 core/argsroom.py diff --git a/README.md b/README.md index e3e1728..7b3e0da 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,27 @@ python3 -m venv .venv ## Usage ```bash -python stt_runner.py \ - --conv-frontend=path/conv_frontend.onnx \ - --encoder=path/encoder.onnx \ - --decoder=path/decoder.onnx \ - --tokenizer=path/tokenizer \ - audio1.wav audio2.wav ... +python stt_runner.py [--language=Indonesian] audio1.wav audio2.wav ... ``` +## Configuration + +Model paths and inference parameters are hardcoded in `config/`: + +- `config/model.py` — model paths (conv_frontend, encoder, decoder, tokenizer under `models/`) +- `config/asr.py` — inference params: `LANGUAGE`, `HOTWORDS`, `NUM_THREADS`, `PROVIDER`, `SAMPLE_RATE`, `FEATURE_DIM`, `MAX_TOTAL_LEN`, `MAX_NEW_TOKENS` + +`LANGUAGE` defaults to `""` (all languages / auto-detect). Passing `--language` on the CLI overrides it. + +## Download Model (Qwen3-ASR 1.7B int8) + +```bash +BASE="https://modelscope.cn/models/zengshuishui/Qwen3-ASR-onnx/resolve/master" +mkdir -p models/model_1.7B models/tokenizer +wget -O models/model_1.7B/conv_frontend.onnx "$BASE/model_1.7B/conv_frontend.onnx" +wget -O models/model_1.7B/encoder.int8.onnx "$BASE/model_1.7B/encoder.int8.onnx" +wget -O models/model_1.7B/decoder.int8.onnx "$BASE/model_1.7B/decoder.int8.onnx" +for f in vocab.json merges.txt tokenizer_config.json preprocessor_config.json config.json chat_template.json; do + wget -O "models/tokenizer/$f" "$BASE/tokenizer/$f" +done +``` \ No newline at end of file diff --git a/config/__init__.py b/config/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/config/asr.py b/config/asr.py new file mode 100644 index 0000000..0d42732 --- /dev/null +++ b/config/asr.py @@ -0,0 +1,12 @@ +NUM_THREADS = 2 +SAMPLE_RATE = 16000 +FEATURE_DIM = 128 +PROVIDER = "cpu" +MAX_TOTAL_LEN = 2048 +MAX_NEW_TOKENS = 256 + +LANGUAGE = "" # "" = support all languages / auto-detect +HOTWORDS = "" # Comma-separated hotword phrases, e.g. "AcmeCorp, FooBar". + # Biases the model to transcribe these phrases correctly, + # useful for brand/product/person names the model may + # otherwise mishear. Leave empty to disable. diff --git a/config/model.py b/config/model.py new file mode 100644 index 0000000..6738487 --- /dev/null +++ b/config/model.py @@ -0,0 +1,8 @@ +from pathlib import Path + +MODEL_DIR = Path(__file__).resolve().parent.parent / "models" + +CONV_FRONTEND = MODEL_DIR / "model_1.7B" / "conv_frontend.onnx" +ENCODER = MODEL_DIR / "model_1.7B" / "encoder.int8.onnx" +DECODER = MODEL_DIR / "model_1.7B" / "decoder.int8.onnx" +TOKENIZER = MODEL_DIR / "tokenizer" \ No newline at end of file diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/args_parser.py b/core/args_parser.py deleted file mode 100644 index c7af05d..0000000 --- a/core/args_parser.py +++ /dev/null @@ -1,14 +0,0 @@ -import argparse - -parser = argparse.ArgumentParser() -parser.add_argument("--conv-frontend", type=str, required=True) -parser.add_argument("--encoder", type=str, required=True) -parser.add_argument("--decoder", type=str, required=True) -parser.add_argument("--tokenizer", type=str, required=True) -parser.add_argument("--language", type=str, default="", help="Force language, e.g. Indonesian, English, Chinese") -parser.add_argument("--hotwords", type=str, default="", help="Comma-separated hotword phrases, e.g. 'foo,bar'") -parser.add_argument("--num-threads", type=int, default=2) -parser.add_argument("--provider", type=str, default="cpu", choices=["cpu", "cuda"]) -parser.add_argument("--max-total-len", type=int, default=2048) -parser.add_argument("--max-new-tokens", type=int, default=256) -parser.add_argument("sounds", nargs="+", help="Audio files to transcribe") diff --git a/core/argsroom.py b/core/argsroom.py new file mode 100644 index 0000000..313f3ce --- /dev/null +++ b/core/argsroom.py @@ -0,0 +1,5 @@ +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument("--language", type=str, default=None, help="Force language, overrides config LANGUAGE (e.g. Indonesian, English, Chinese)") +parser.add_argument("sounds", nargs="+", help="Audio files to transcribe") diff --git a/stt_runner.py b/stt_runner.py index 54d4247..8ac1cb6 100644 --- a/stt_runner.py +++ b/stt_runner.py @@ -1,23 +1,25 @@ import sys from pathlib import Path import sherpa_onnx, soundfile as sf -from core import args_parser as ap +from core import argsroom as ap +from config.model import CONV_FRONTEND, ENCODER, DECODER, TOKENIZER +from config.asr import LANGUAGE, HOTWORDS, NUM_THREADS, SAMPLE_RATE, FEATURE_DIM, PROVIDER, MAX_TOTAL_LEN, MAX_NEW_TOKENS def stt_run(args): print("Recognize...") recognizer = sherpa_onnx.OfflineRecognizer.from_qwen3_asr( # qwen3 asr - conv_frontend = args.conv_frontend, - encoder = args.encoder, - decoder = args.decoder, - tokenizer = args.tokenizer, - hotwords = args.hotwords, - num_threads = args.num_threads, - sample_rate = 16000, - feature_dim = 128, - provider = args.provider, - max_total_len = args.max_total_len, - max_new_tokens = args.max_new_tokens, + conv_frontend = str(CONV_FRONTEND), + encoder = str(ENCODER), + decoder = str(DECODER), + tokenizer = str(TOKENIZER), + hotwords = HOTWORDS, + num_threads = NUM_THREADS, + sample_rate = SAMPLE_RATE, + feature_dim = FEATURE_DIM, + provider = PROVIDER, + max_total_len = MAX_TOTAL_LEN, + max_new_tokens = MAX_NEW_TOKENS, ) print("Recognizer ready!") @@ -31,8 +33,9 @@ def stt_run(args): stream = recognizer.create_stream() - if args.language: - stream.set_option("language", args.language) + language = args.language if args.language is not None else LANGUAGE + if language: + stream.set_option("language", language) stream.accept_waveform(sr, audio) recognizer.decode_stream(stream) # Inference execution for `stream.result`