Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
136 lines
6.1 KiB
Markdown
136 lines
6.1 KiB
Markdown
# SenseVoice-Small Community ASR
|
|
|
|
Default model-manager downloads use the published GGUF package when available;
|
|
the original source/conversion instructions below remain valid for manual use.
|
|
|
|
`sense_asr` is a native audio.cpp port of SenseVoice-Small, a multilingual
|
|
speech-to-text model from FunAudioLLM that reads audio through a 50-block SAN-M
|
|
encoder and a CTC head. It recognizes 23 language tags and emits rich
|
|
`<|event|>/<|emotion|>/<|language|>` meta tags, with optional inverse text
|
|
normalization (ITN). The port adapts the SenseVoice llama.cpp runtime
|
|
(`sensevoice-server.cpp`) into the framework layout and uses the bundled
|
|
silero_vad for audio segmentation instead of the reference FSMN-VAD.
|
|
|
|
## Capabilities
|
|
|
|
| Field | Value |
|
|
|---|---|
|
|
| Task | `asr` |
|
|
| Modes | `offline`, buffered `streaming` |
|
|
| Languages | `auto`, `zh`, `en`, `yue`, `ja`, `ko`, `pt`, `ru`, `es`, `it`, `fr`, `de`, `nl`, `pl`, `tr`, `ar`, `hi`, `vi`, `th`, `id`, `ms`, `fa`, `nospeech` |
|
|
| Input | WAV; audio.cpp converts to 16 kHz mono |
|
|
| Output | Transcript, detected language, event/emotion tags |
|
|
| Frontend | 80-mel filterbank + LFR (140ms context), Kaldi-compatible |
|
|
| Encoder | SAN-M, 1 stem + 49 main blocks + 20 timestamp-prediction blocks, 4 heads, 512-wide, kernel 11 |
|
|
| Decoding | CTC greedy collapse with SentencePiece detok |
|
|
| ITN | Query token 14 (`withitn`) on, 15 (`woitn`) off; on by default |
|
|
| Package | `sensevoice_small_q8` Q8 GGUF |
|
|
|
|
The `language` request option hard-codes a language ID query token when one of
|
|
the model's native tags (`zh`, `en`, `yue`, `ja`, `ko`, `nospeech`) is given;
|
|
the rest of the tags fall back to `auto`. `keep_tags` keeps the
|
|
`<|event|>/<|emotion|>/<|language|>` tags inline in the output text.
|
|
|
|
## Install
|
|
|
|
Install the default package:
|
|
|
|
Download the standalone GGUF directly from
|
|
[FunAudioLLM/SenseVoiceSmall-GGUF-audiocpp](https://huggingface.co/FunAudioLLM/SenseVoiceSmall-GGUF-audiocpp)
|
|
(such as `sensevoice-small-q8-audiocpp-v1.gguf`) and point `--model` at the file.
|
|
|
|
## Run (offline)
|
|
|
|
```bash
|
|
audiocpp_cli --task asr --family sense_asr \
|
|
--model models/SenseVoice-Small-GGUF/sensevoice-small-q8-audiocpp-v1.gguf \
|
|
--backend cpu --audio samples/zh.wav
|
|
```
|
|
|
|
`audio_chunk_mode=auto` (default) segments long audio with the bundled silero
|
|
VAD; `audio_chunk_mode=fixed` splits on `audio_chunk_duration_sec`; `none` runs the
|
|
whole clip as one encoder pass. Chunk transcripts are joined at ASCII word
|
|
boundaries so CJK output stays space-free.
|
|
|
|
## Run (streaming)
|
|
|
|
```bash
|
|
audiocpp_cli --task asr --family sense_asr \
|
|
--model models/SenseVoice-Small-GGUF/sensevoice-small-q8-audiocpp-v1.gguf \
|
|
--backend cpu --mode streaming --audio - \
|
|
--request-option audio_chunk_duration_sec=5 --request-option audio_chunk_mode=none \
|
|
< 16k_s16.pcm
|
|
```
|
|
|
|
Buffered streaming holds accumulated PCM and transcribes one fixed window per
|
|
`audio_chunk_duration_sec`; each window yields a `partial_text` delta and
|
|
`finalize()` returns the full accumulated transcript. The SenseVoice service
|
|
also runs through `audiocpp_server` with
|
|
`POST /v1/audio/transcriptions/live` for chunked PCM ingest with SSE deltas.
|
|
|
|
## Run as a server (offline & streaming)
|
|
|
|
Start the WebUI-enabled server with the SenseVoice model:
|
|
|
|
```bash
|
|
audiocpp_server --ui --backend cpu \
|
|
--config <(echo '{"models":[{"id":"sense_asr","family":"sense_asr","path":"models/SenseVoice-Small-GGUF/sensevoice-small-q8-audiocpp-v1.gguf","task":"asr","mode":"streaming"}]}')
|
|
```
|
|
|
|
Then open http://127.0.0.1:8080 and select "SenseVoice-Small (asr, 流式, 社区)" from the ASR tab.
|
|
|
|
Or load the model dynamically via the WebUI's model manager (click "📥 加载模型" after selecting the model).
|
|
|
|
For headless API-only mode without WebUI:
|
|
|
|
```bash
|
|
audiocpp_server --backend cpu \
|
|
--config <(echo '{"models":[{"id":"sense_asr","family":"sense_asr","path":"models/SenseVoice-Small-GGUF/sensevoice-small-q8-audiocpp-v1.gguf","task":"asr","mode":"streaming"}],"ui":false}')
|
|
```
|
|
|
|
Then use the OpenAI-compatible endpoint:
|
|
|
|
```bash
|
|
# Offline transcription
|
|
curl -X POST http://127.0.0.1:8080/v1/audio/transcriptions \
|
|
-F 'model=sense_asr' -F 'file=@assets/resources/3.wav'
|
|
|
|
# Streaming transcription (SSE) — requires chunked transfer encoding
|
|
curl -X POST http://127.0.0.1:8080/v1/audio/transcriptions/live \
|
|
-H 'Accept: text/event-stream' \
|
|
-H 'Transfer-Encoding: chunked' \
|
|
-F 'model=sense_asr' -F 'file=@assets/resources/3.wav'
|
|
```
|
|
|
|
## Request options
|
|
|
|
| Option | Values | Default | Meaning |
|
|
|---|---|---|---|
|
|
| `language` | auto\|zh\|en\|yue\|ja\|ko\|pt\|ru\|... | `auto` | Recognition language; `auto` lets the model infer it |
|
|
| `enable_itn` | true\|false | `true` | Inverse text normalization via the withitn query token |
|
|
| `keep_tags` | true\|false | `false` | Keep `<|...|>` meta tags inline |
|
|
| `audio_chunk_mode` | `auto`, `fixed`, `vad`, `none` | `auto` | Offline chunk mode: auto, fixed, vad, or none. Streaming always uses fixed-duration windows. |
|
|
| `audio_chunk_duration_sec` | seconds | `30` | Positive duration rounding to at least one sample; sets fixed windows and the VAD maximum chunk length. |
|
|
|
|
Session options: `sense_asr.weight_type` (native\|f32\|f16\|bf16\|q8_0),
|
|
`sense_asr.encoder_graph_arena_mb`, and `sense_asr.vad_model_path` (defaults to
|
|
the bundled `assets/framework/models/silero_vad`).
|
|
|
|
## Source and conversion
|
|
|
|
The port is based on the SenseVoice llama.cpp runtime at
|
|
`/workspace/SenseVoice/runtime/llama.cpp/sensevoice-server/`
|
|
(`sensevoice-server.cpp`): 80-mel filterbank + LFR, the SAN-M encoder, CTC
|
|
collapse, and SentencePiece detok. The reference FSMN-VAD and HTTP server layer
|
|
are replaced by the framework session plus the bundled silero_vad. The GGUF is
|
|
produced by that runtime's `export_sensevoice_gguf.py` script and carries the
|
|
`sv.*` metadata keys and `cmvn.shift`/`cmvn.scale` tensors (the offline fbank
|
|
path applies no CMVN, matching the reference offline engine).
|
|
|
|
## Verification notes
|
|
|
|
A 6-second Chinese sample (`sample.wav`) transcribes to `我想问我在滨海新区有房。`
|
|
in the offline path, matching the reference `llama-funasr-sensevoice` output
|
|
exactly. Streaming with 3-second windows emits per-window partials
|
|
(`我想问。` then `我在滨海新区有房。`) and the joined final transcript with a
|
|
~1.75s TTFT on CPU.
|