Audio8-ASR-0.1B-onnx-runtime / transcribe_file.py
chua's picture
Clarify language field behavior
73357a5
Raw
History Blame Contribute Delete
4.66 kB
#!/usr/bin/env python3
from __future__ import annotations
import argparse
import json
import os
from pathlib import Path
from typing import Any
from asr_onnx_runtime import OnnxAsrEngine, OnnxCacheAsrEngine
APP_DIR = Path(__file__).resolve().parent
BUNDLE_CANDIDATES = (
"model_bundle",
)
def default_bundle_dir() -> Path:
env_value = os.environ.get("AUDIO8_ASR_BUNDLE")
if env_value:
return Path(env_value).expanduser()
for name in BUNDLE_CANDIDATES:
candidate = APP_DIR / name
if (candidate / "metadata.json").exists():
return candidate
return APP_DIR / "model_bundle"
def transcribe_file(
audio_path: str | Path,
*,
bundle_dir: str | Path | None = None,
backend: str = "onnx_cache",
cache_precision: str = "int8",
audio_precision: str = "int8",
language: str | None = None,
max_new_tokens: int = 128,
provider: str = "CPUExecutionProvider",
threads: int | None = None,
hotwords: str | list[str] | None = None,
hotword_topk: int = 50,
hotword_start_boost: float = 6.0,
hotword_continuation_boost: float = 8.0,
) -> dict[str, Any]:
bundle_path = Path(bundle_dir).expanduser() if bundle_dir is not None else default_bundle_dir()
audio_file = Path(audio_path).expanduser()
if backend == "onnx":
engine = OnnxAsrEngine(
bundle_path,
provider=provider,
intra_op_num_threads=threads,
audio_precision=audio_precision,
)
elif backend == "onnx_cache":
engine = OnnxCacheAsrEngine(
bundle_path,
provider=provider,
intra_op_num_threads=threads,
cache_precision=cache_precision,
audio_precision=audio_precision,
)
else:
raise ValueError(f"Unsupported backend: {backend}")
return engine.transcribe(
audio_file.read_bytes(),
language=language,
max_new_tokens=max_new_tokens,
hotwords=hotwords,
hotword_topk=hotword_topk,
hotword_start_boost=hotword_start_boost,
hotword_continuation_boost=hotword_continuation_boost,
)
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="Transcribe one audio file with the Audio8 ASR ONNX runtime.")
parser.add_argument("audio", type=Path, help="Audio file path. WAV is recommended; librosa/soundfile handle common formats.")
parser.add_argument("--bundle_dir", type=Path, default=default_bundle_dir())
parser.add_argument("--backend", choices=["onnx_cache", "onnx"], default=os.environ.get("ASR_BACKEND", "onnx_cache"))
parser.add_argument("--cache_precision", choices=["fp32", "int8", "int4", "auto"], default=os.environ.get("ASR_CACHE_PRECISION", "int8"))
parser.add_argument("--audio_precision", choices=["fp32", "int8", "auto"], default=os.environ.get("ASR_AUDIO_PRECISION", "int8"))
parser.add_argument(
"--language",
default=None,
help="Compatibility field; the current ONNX runtime ignores it and infers language from audio.",
)
parser.add_argument("--max_new_tokens", type=int, default=128)
parser.add_argument("--provider", default=os.environ.get("ORT_PROVIDER", "CPUExecutionProvider"))
parser.add_argument("--threads", type=int, default=int(os.environ.get("ORT_THREADS", "0")))
parser.add_argument("--hotwords", default=None, help="Comma separated hotwords, disabled when omitted.")
parser.add_argument("--hotword_topk", type=int, default=50)
parser.add_argument("--hotword_start_boost", type=float, default=6.0)
parser.add_argument("--hotword_continuation_boost", type=float, default=8.0)
parser.add_argument("--json", action="store_true", help="Print the full result JSON instead of only transcript text.")
return parser.parse_args()
def main() -> None:
args = parse_args()
result = transcribe_file(
args.audio,
bundle_dir=args.bundle_dir,
backend=args.backend,
cache_precision=args.cache_precision,
audio_precision=args.audio_precision,
language=args.language or None,
max_new_tokens=args.max_new_tokens,
provider=args.provider,
threads=args.threads if args.threads > 0 else None,
hotwords=args.hotwords or None,
hotword_topk=args.hotword_topk,
hotword_start_boost=args.hotword_start_boost,
hotword_continuation_boost=args.hotword_continuation_boost,
)
if args.json:
print(json.dumps(result, ensure_ascii=False, indent=2))
else:
print(result.get("text", ""))
if __name__ == "__main__":
main()