A streaming/causal drop-in audio tower for Qwen/Qwen3-ASR-0.6B: the pretrained (offline, fully bidirectional) audio encoder, fine-tuned to run append-only: each ~2 s audio block is encoded exactly once with a causal KV cache and a bounded 15 s attention window, and is never re-encoded. New audio costs one encoder pass over the new block plus an incremental decoder update; per-chunk compute is constant in stream length, memory is bounded, and streams can run indefinitely.
It is built for the minimum-compute-per-chunk regime: many concurrent streams, energy-constrained or on-device serving, and sessions of unbounded length. Per audio second it spends about 3x less than the re-compute streaming backend, at constant cost as the stream grows, in exchange for some accuracy (see the results table for the honest comparison).
This repository contains only the fine-tuned audio tower (746 MB fp32 safetensors). The decoder, adapter and feature extractor are loaded unchanged from the base model at runtime.
Long-form: 21 full MCIF/ACL conference talks (5 to 7 minutes each, 2 h total, accented scientific English), human references, Whisper text normalization:
| system | scoring contract | WER | compute per second of audio |
|---|---|---|---|
| Offline Qwen3-ASR, VAD-segmented | full file available, no latency | 7.6 | offline |
| Streaming Qwen3-ASR (windowed) | settled transcript | 8.4 | 126 GFLOPs avg, growing to 172 within each segment |
| Streaming Qwen3-ASR (windowed) | live, no rewrite, 250 ms tail cut + EOS flush | 12.6 | 126 GFLOPs avg, growing to 172 |
| Streaming Qwen3-ASR causal | settled transcript | 17.2 | 42 GFLOPs, constant |
| Streaming Qwen3-ASR causal | live, no rewrite (shipped default policy) | 17.6 | 42 GFLOPs, constant |
Short-form through the same streaming stack: LibriSpeech test-clean 3.73 / test-other 7.34 at the shipped low-latency default.
The WER numbers above use the same real-streaming replay: no right to rewrite
the past, a 250 ms live-tail cut at every non-final update, and an
end-of-stream flush. When forced-aligner word_alignments are present, the 250
ms cut uses those word timestamps; otherwise it falls back to a uniform text
approximation.
Per-committed-word latency (word spoken to word committed, audio fed at 1.0x), replayed over the 21-talk corpus:
| policy | p50 | p95 | live WER |
|---|---|---|---|
| hold 6 words / 1 stable iteration (default) | 4.1 s | 7.9 s | 17.6 |
hold 2 words (hold_back_words=2) | 2.2 s | 7.9 s | 17.8 |
The 2.2 s point sits at the 1.92 s block-cadence floor. The unstable tail is additionally visible live (~2 s behind the audio head).
pip install "whisperlivekit[qwen3-streaming]"
wlk --backend qwen3-streaming --language en \
--qwen3-streaming-audio-backend causal \
--qwen3-streaming-tower-checkpoint qfuxa/qwen3-asr-0.6b-streaming
The tower downloads automatically; the base model comes from
Qwen/Qwen3-ASR-0.6B. Works on CUDA, Apple Silicon (MPS) and CPU. See
WhisperLiveKit for the
WebSocket server, web UI and the OpenAI-compatible REST endpoint.
Standalone (no server), via the runtime package qwen3-asr-causal:
pip install "qwen3-asr-causal[streaming]"
qwen3-asr-causal transcribe audio.wav --backend hf --language en
from qwen3_asr_causal import Qwen3StreamingASR
asr = Qwen3StreamingASR(
lan="en",
qwen3_streaming_audio_backend="causal",
qwen3_streaming_tower_checkpoint="qfuxa/qwen3-asr-0.6b-streaming",
)
streamer = asr.build_streamer("en")
# feed mel chunks of any size; the encoder consumes fixed 1.92 s blocks
block_frames=96 at a
small quality cost).Derived from Qwen/Qwen3-ASR-0.6B
(Apache 2.0, © Alibaba Cloud). Modifications: the audio tower weights were
fine-tuned (embedding self-distillation, 143k steps total) to support
block-causal streaming execution; everything else is unchanged. Released under
Apache 2.0. The streaming runtime, benchmark suite and measured results live
in Qwen3-ASR-causal;
training/eval code and the experiment log are under
experiments/qwen3-causal/ in that repository.
29 commits
A streaming/causal drop-in audio tower for Qwen/Qwen3-ASR-0.6B: the pretrained (offline, fully bidirectional) audio encoder, fine-tuned to run append-only: each ~2 s audio block is encoded exactly once with a causal KV cache and a bounded 15 s attention window, and is never re-encoded. New audio costs one encoder pass over the new block plus an incremental decoder update; per-chunk compute is constant in stream length, memory is bounded, and streams can run indefinitely.
It is built for the minimum-compute-per-chunk regime: many concurrent streams, energy-constrained or on-device serving, and sessions of unbounded length. Per audio second it spends about 3x less than the re-compute streaming backend, at constant cost as the stream grows, in exchange for some accuracy (see the results table for the honest comparison).
This repository contains only the fine-tuned audio tower (746 MB fp32 safetensors). The decoder, adapter and feature extractor are loaded unchanged from the base model at runtime.
Long-form: 21 full MCIF/ACL conference talks (5 to 7 minutes each, 2 h total, accented scientific English), human references, Whisper text normalization:
| system | scoring contract | WER | compute per second of audio |
|---|---|---|---|
| Offline Qwen3-ASR, VAD-segmented | full file available, no latency | 7.6 | offline |
| Streaming Qwen3-ASR (windowed) | settled transcript | 8.4 | 126 GFLOPs avg, growing to 172 within each segment |
| Streaming Qwen3-ASR (windowed) | live, no rewrite, 250 ms tail cut + EOS flush | 12.6 | 126 GFLOPs avg, growing to 172 |
| Streaming Qwen3-ASR causal | settled transcript | 17.2 | 42 GFLOPs, constant |
| Streaming Qwen3-ASR causal | live, no rewrite (shipped default policy) | 17.6 | 42 GFLOPs, constant |
Short-form through the same streaming stack: LibriSpeech test-clean 3.73 / test-other 7.34 at the shipped low-latency default.
The WER numbers above use the same real-streaming replay: no right to rewrite
the past, a 250 ms live-tail cut at every non-final update, and an
end-of-stream flush. When forced-aligner word_alignments are present, the 250
ms cut uses those word timestamps; otherwise it falls back to a uniform text
approximation.
Per-committed-word latency (word spoken to word committed, audio fed at 1.0x), replayed over the 21-talk corpus:
| policy | p50 | p95 | live WER |
|---|---|---|---|
| hold 6 words / 1 stable iteration (default) | 4.1 s | 7.9 s | 17.6 |
hold 2 words (hold_back_words=2) | 2.2 s | 7.9 s | 17.8 |
The 2.2 s point sits at the 1.92 s block-cadence floor. The unstable tail is additionally visible live (~2 s behind the audio head).
pip install "whisperlivekit[qwen3-streaming]"
wlk --backend qwen3-streaming --language en \
--qwen3-streaming-audio-backend causal \
--qwen3-streaming-tower-checkpoint qfuxa/qwen3-asr-0.6b-streaming
The tower downloads automatically; the base model comes from
Qwen/Qwen3-ASR-0.6B. Works on CUDA, Apple Silicon (MPS) and CPU. See
WhisperLiveKit for the
WebSocket server, web UI and the OpenAI-compatible REST endpoint.
Standalone (no server), via the runtime package qwen3-asr-causal:
pip install "qwen3-asr-causal[streaming]"
qwen3-asr-causal transcribe audio.wav --backend hf --language en
from qwen3_asr_causal import Qwen3StreamingASR
asr = Qwen3StreamingASR(
lan="en",
qwen3_streaming_audio_backend="causal",
qwen3_streaming_tower_checkpoint="qfuxa/qwen3-asr-0.6b-streaming",
)
streamer = asr.build_streamer("en")
# feed mel chunks of any size; the encoder consumes fixed 1.92 s blocks
block_frames=96 at a
small quality cost).Derived from Qwen/Qwen3-ASR-0.6B
(Apache 2.0, © Alibaba Cloud). Modifications: the audio tower weights were
fine-tuned (embedding self-distillation, 143k steps total) to support
block-causal streaming execution; everything else is unchanged. Released under
Apache 2.0. The streaming runtime, benchmark suite and measured results live
in Qwen3-ASR-causal;
training/eval code and the experiment log are under
experiments/qwen3-causal/ in that repository.
29 commits