The Problem

Standard ASR systems struggle with domain-specific terminology, dialects, and language confusion in real-world audio. Fun-ASR is an 800M-parameter end-to-end speech recognition model trained on tens of millions of hours of speech, targeting these failure modes with support for 31 languages, 7 Chinese dialects, and 26 regional accents.

What This Does

This repository is a minimal working example around the Fun-ASR model. It contains two demo entry points (demo1.py, demo2.py), a model wrapper (model.py), a CTC decoding module (ctc.py), and a decode.py script for batch inference on .scp audio lists. The tools/ directory holds utilities for audio loading, forced alignment, text normalization, and data format conversion.

The project is a fork of QwenAudio/Fun-ASR (1,491 stars) with zero stars of its own. It is a thin client: the heavy lifting happens in the pretrained model loaded via from_pretrained, not in this codebase.

How It Is Wired

Execution starts at main in demo1.py:4, which reaches 12 functions and calls inferenceinference_llm, which routes through model.py's forward and eventually calls the model via self.llm.to. That is the only traced path that leaves the process—a single hop from entry point to model inference.

The import graph is small: 12 internal modules, 4 import edges, no cycles. tools/utils.py is the most-imported module (2 importers), and model.py is the hub with 3 importers, 2 outgoing calls, and an instability score of 0.67—it changes often and is depended on broadly.

The hot functions by call count are num2chn (called from 5 places), chn2num, Cardinal, cardinal2chntext, and scoreformat (3 each). These live in tools/cn_tn.py (42 functions, 14 classes) and tools/format5res.py (6 functions). tools/cn_tn.py is the largest file at 634 lines; a change there ripples through most of the text-normalization pipeline.

File-by-file map:

  • model.py — model wrapper, inference, data templating
  • ctc.py — CTC loss and argmax decoding
  • decode.py — batch inference from .scp files, writes results
  • demo1.py / demo2.py — single-file demos
  • tools/cn_tn.py — Chinese number/text conversion
  • tools/format5res.py — result formatting and scoring
  • tools/utils.py — audio loading, forced alignment
  • tools/whisper_mix_normalize.py — multilingual text normalization
  • tools/scp2jsonl.py — converts .scp lists to JSONL

How To Use It

Setup: Install dependencies from requirements.txt:

pip install -r requirements.txt

Running: demo1.py and demo2.py are the entry points. The README documents model usage via from_pretrained and generate_chatml calls, but does not document the demo scripts' arguments. finetune.sh exists for fine-tuning, and deepspeed_conf/ds_stage1.json configures DeepSpeed stage 1.

Configuration: No environment variables or config files are required for the demos. Data files in data/ show expected formats: train_wav.scp (audio paths), train_text.txt (transcripts), and JSONL examples.

Real-World Use

A typical workflow: convert an audio list to JSONL with tools/scp2jsonl.py, run batch inference via decode.py, then normalize results with tools/format5res.py and tools/cn_tn.py for Chinese text post-processing. The model handles code-switching and dialect support natively, so the pipeline is useful for call-center transcription or media captioning where terminology accuracy matters.

Code Health & Issues

Static analysis found 11 issues (3 high, 8 medium) across 5 categories:

  • High — Deep nesting: model.py, tools/format5res.py, tools/cn_tn.py have max indentation depth of 8; control flow is hard to follow. Fix with early returns and extracted inner blocks.
  • High — Duplicated code: 14 repeated 6-line blocks across decode.py, tools/scp2jsonl.py, demo1.py, demo2.py. Extract shared helpers.
  • Medium — Broad exception handling: tools/utils.py and tools/whisper_mix_normalize.py swallow errors with bare except. Catch specific exceptions.
  • Medium — File handle leak: tools/format5res.py opens files without context managers. Use with open(...).
  • Medium — Oversized files: model.py and tools/cn_tn.py exceed 600 lines each.

SDLC gaps: no test files, no CI pipeline, no lockfile. The code health audit flags missing tests and CI as high severity—any change ships with zero regression signal.

The Bottom Line

This is a functional demo harness around a capable model, not a production SDK. The code works but is unpolished: no tests, no CI, duplicated logic. Use it as a reference for integrating Fun-ASR, not as a foundation to build on directly. The model itself is the value; the repository is a thin wrapper around it.