Views
No views yet
/v1/realtime WebSocket endpoint and a stateful Python API, plus offline WAV
inference.Aria voice.mlx-community/NemotronLabs-VoiceChat-11B-bf16 | BF16 |
| mlx-community/NemotronLabs-VoiceChat-11B-8bit | 8-bit |
| mlx-community/NemotronLabs-VoiceChat-11B-4bit | 4-bit |pip install -U mlx-vlmmlx-vlm server:mlx_vlm.server --host 127.0.0.1 --port 8080ws://127.0.0.1:8080/v1/realtimesession.created after accepting the connection. Configure
the session before sending audio:1{
2 "type": "session.update",
3 "session": {
4 "model": "mlx-community/NemotronLabs-VoiceChat-11B-8bit",
5 "system_prompt": "Be concise and answer in one sentence.",
6 "seed": 0
7 }
8}session.updated, send any number of base64-encoded PCM16 chunks. Chunk
boundaries may be arbitrary; the server advances the model on complete 1,280
sample (80 ms) frames.1{
2 "type": "input_audio_buffer.append",
3 "audio": "<base64 PCM16>",
4 "sample_rate": 16000
5}1{
2 "type": "input_audio_buffer.commit",
3 "pad_partial": true
4}| Event | Contents |
|---|---|
response.text.delta | Assistant token, incremental text, and cumulative text |
conversation.item.input_audio_transcription.delta | Incremental and cumulative user transcript |
response.function.delta | Raw function-channel token and text delta |
response.audio.delta | Base64 PCM16 audio at 22,050 Hz plus raw audio codes |
response.done | The committed session has finished |
response.cancelled | The session was cancelled |
error | Request or inference error details |
session.cancel or response.cancel to stop without committing. A client
may also send session.ping and receive session.pong.sounddevice:pip install -U sounddevice1python examples/nemotron_voicechat_microphone.py \
2 mlx-community/NemotronLabs-VoiceChat-11B-8bit--list-devices, --input-device, and --output-device to select audio
devices. Headphones are strongly recommended: the example keeps listening while
the assistant speaks and does not perform acoustic echo cancellation.mlx_vlm.load interface,
then create a model-specific VoiceChat session.delta contains the
incremental update.1import numpy as np
2from mlx_audio.audio_io import write as write_audio
3from mlx_audio.stt.utils import load_audio
4
5from mlx_vlm import load
6
7model, processor = load(
8 "mlx-community/NemotronLabs-VoiceChat-11B-8bit"
9)
10voicechat = model.create_session(processor)
11stream = voicechat.create_streaming_session(
12 system_prompt="Be concise and answer in one sentence.",
13 seed=0,
14)
15
16input_audio = load_audio("input.wav", sr=16_000).squeeze()
17audio_chunks = []
18
19def handle(events):
20 for event in events:
21 if event.kind == "assistant_text_delta":
22 print(event.delta or "", end="", flush=True)
23 elif event.kind == "user_transcript_delta":
24 print(f"\n[user] {event.text}")
25 elif event.kind == "function_delta":
26 print(f"\n[function] {event.delta}")
27 elif event.kind == "audio":
28 audio_chunks.append(np.asarray(event.samples, dtype=np.float32))
29
30for offset in range(0, input_audio.shape[0], 1_280):
31 handle(
32 stream.push_audio(
33 input_audio[offset : offset + 1_280],
34 sample_rate=16_000,
35 )
36 )
37handle(stream.flush(pad_partial=True))
38
39response_audio = (
40 np.concatenate(audio_chunks)
41 if audio_chunks
42 else np.zeros(0, dtype=np.float32)
43)
44write_audio("response.wav", response_audio, 22_050)1stream = voicechat.create_streaming_session(
2 use_language_cache=False,
3 use_perception_cache=False,
4)1result = voicechat.generate(
2 "input.wav",
3 system_prompt="Be concise and answer in one sentence.",
4 extra_decoding_seconds=3,
5 seed=0,
6)
7
8print(result.user_transcript)
9print(result.text)
10# result.audio is mono float PCM at result.sample_rate (22,050 Hz)./v1/realtime currently allows one active VoiceChat WebSocket at a time.Aria voice.