First commit
This commit is contained in:
commit
66a2b136f6
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.env
|
||||||
|
.venv
|
||||||
|
**/__pycache__
|
||||||
|
*.pyc
|
||||||
22
README.md
Normal file
22
README.md
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# STT Runner
|
||||||
|
|
||||||
|
Speech-to-Text transcription using sherpa-onnx + Qwen3-ASR.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 -m venv .venv
|
||||||
|
.venv/bin/pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## 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 ...
|
||||||
|
```
|
||||||
|
|
||||||
14
core/args_parser.py
Normal file
14
core/args_parser.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
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")
|
||||||
2
requirements.txt
Normal file
2
requirements.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
sherpa-onnx
|
||||||
|
soundfile
|
||||||
52
stt_runner.py
Normal file
52
stt_runner.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
import sherpa_onnx, soundfile as sf
|
||||||
|
from core import args_parser as ap
|
||||||
|
|
||||||
|
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,
|
||||||
|
)
|
||||||
|
print("Recognizer ready!")
|
||||||
|
|
||||||
|
for f in args.sounds: # Multi-file
|
||||||
|
if not Path(f).is_file():
|
||||||
|
print(f"Skip. file not found: {f}", file=sys.stderr)
|
||||||
|
continue
|
||||||
|
|
||||||
|
audio, sr = sf.read(f, dtype="float32", always_2d=True)
|
||||||
|
audio = audio[:, 0]
|
||||||
|
|
||||||
|
stream = recognizer.create_stream()
|
||||||
|
|
||||||
|
if args.language:
|
||||||
|
stream.set_option("language", args.language)
|
||||||
|
stream.accept_waveform(sr, audio)
|
||||||
|
|
||||||
|
recognizer.decode_stream(stream) # Inference execution for `stream.result`
|
||||||
|
|
||||||
|
text = stream.result.text
|
||||||
|
|
||||||
|
if "<asr_text>" in text: # qwen3 asr format
|
||||||
|
text = text.split("<asr_text>", 1)[1]
|
||||||
|
|
||||||
|
print()
|
||||||
|
print(f"File : {f}")
|
||||||
|
print(f"Duration : {len(audio) / sr:.2f} s")
|
||||||
|
print(f"Result : {text}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
stt_run( ap.parser.parse_args() )
|
||||||
Loading…
Reference in New Issue
Block a user