Kimi K3 is here. Try it now
transcription

Qwen LogoQwen3 ASR 1.7B Streaming

Real-time streaming speech-to-text from Qwen3-ASR 1.7B over WebSocket, featuring batch-level accuracy, sub-second finals, and 30+ languages.

Model details

Example usage

Stream 16 kHz mono PCM16 audio over a WebSocket as base64 input_audio_buffer.append frames and end a turn with input_audio_buffer.commit or automatic voice-activity detection (VAD). The server returns type:"transcription" messages — revisable partials (is_final:false) during the turn and a final (is_final:true) at each endpoint. Responses match the streaming-Whisper format.

We've shown that Qwen3-ASR-1.7B can comfortably keep real-time through up to 64 concurrent streams on both NVIDIA RTX 6000 and H100 GPUs, with P95 finalization latency under 0.50 seconds.

Input

1import asyncio, base64, json, os, wave
2import websockets
3
4URL = "wss://model-<id>.api.baseten.co/environments/production/websocket"
5KEY = os.environ["BASETEN_API_KEY"]
6SR = 16_000
7CHUNK = int(SR * 0.1) * 2  # 100 ms of PCM16
8HEADERS = {"Authorization": f"Api-Key {KEY}"}
9
10
11async def transcribe(path):
12    with wave.open(path, "rb") as w:  # 16 kHz mono PCM16 WAV
13        pcm = w.readframes(w.getnframes())
14    async with websockets.connect(URL, additional_headers=HEADERS) as ws:
15        await ws.send(json.dumps({
16            "whisper_params": {"audio_language": "auto"},
17            "streaming_params": {
18                "enable_partial_transcripts": True,
19                "partial_transcript_interval_s": 0.5,
20            },
21        }))
22
23        async def send():
24            for i in range(0, len(pcm), CHUNK):
25                chunk = base64.b64encode(pcm[i:i + CHUNK]).decode()
26                await ws.send(json.dumps({
27                    "type": "input_audio_buffer.append",
28                    "audio": chunk,
29                }))
30                await asyncio.sleep(0.1)  # real-time pace
31            await ws.send(json.dumps(
32                {"type": "input_audio_buffer.commit"}
33            ))
34
35        asyncio.create_task(send())
36        while True:
37            msg = json.loads(await ws.recv())
38            if msg.get("type") != "transcription":
39                continue
40            text = " ".join(s["text"] for s in msg.get("segments", []))
41            print(("final:" if msg["is_final"] else "partial:"), text)
42            if msg.get("is_final") and msg.get("is_end_of_audio_flush"):
43                break
44
45
46asyncio.run(transcribe("example.wav"))
JSON output
1{
2    "type": "transcription",
3    "is_final": false,
4    "transcription_num": 0,
5    "language_code": "English",
6    "segments": [
7        {
8            "start_time": 0,
9            "end_time": 3.2,
10            "text": "<current hypothesis>"
11        }
12    ]
13}

🔥 Trending models