Skip to content

Commit 658b6d5

Browse files
Merge pull request #2881 from jasonrandrews/review2
first tech review of DGX Spark voice assistant
2 parents 7623124 + aa1d458 commit 658b6d5

9 files changed

Lines changed: 545 additions & 700 deletions

File tree

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,31 @@
11
---
2-
title: Understanding Offline Voice Assistants
2+
title: Learn about offline voice assistants
33
weight: 2
44

55
### FIXED, DO NOT MODIFY
66
layout: learningpathall
77
---
88

9-
## Why Build an Offline Voice Assistant?
9+
## Why build an offline voice assistant?
1010

1111
Voice-based AI assistants are becoming essential in customer support, productivity tools, and embedded interfaces. For example, a retail kiosk might need to answer product-related questions verbally without relying on internet access. However, many of these systems depend heavily on cloud services for speech recognition and language understanding, raising concerns around latency, cost, and data privacy.
1212

1313
In addition, a healthcare terminal or legal consultation assistant may need to handle voice queries involving sensitive personal information, where sending audio data to the cloud would violate privacy requirements. Running your voice assistant entirely offline solves these problems.
1414

1515
You avoid unpredictable latency caused by network fluctuations, prevent sensitive voice data from leaving the local machine, and eliminate recurring API costs that make large-scale deployment expensive. It also boosts trust for on-device deployments and compliance-sensitive industries.
1616

17-
By combining local speech-to-text (STT) with a locally hosted large language model (LLM), you gain full control over the pipeline and eliminate API dependencies. This gives you full control to experiment, customize, and scalewithout relying on external APIs.
17+
By combining local speech-to-text (STT) with a locally hosted large language model (LLM), you gain complete control over the pipeline and eliminate API dependencies. You can experiment, customize, and scale without relying on external services.
1818

19-
## Common Development Challenges:
19+
## What are some common development challenges?
2020

21-
While the benefits are clear, building a local voice assistant involves several engineering challenges:
21+
While the benefits are clear, building a local voice assistant involves several engineering challenges.
2222

23-
- Managing audio stream segmentation and speech detection in real-time: It's hard to reliably identify when the user starts and stops speaking, especially with natural pauses and background noise.
24-
25-
- Avoiding latency or misfires in STT/LLM integration: Timing mismatches can cause delayed responses or repeated input, reducing the conversational quality.
26-
27-
- Keeping the pipeline responsive on local hardware without overloading resources: You need to carefully balance CPU/GPU workloads so that inference doesn't block audio capture or processing.
23+
Real-time audio segmentation requires reliably identifying when users start and stop speaking, accounting for natural pauses and background noise. Timing mismatches between STT and LLM components can cause delayed responses or repeated input, reducing conversational quality. You also need to balance CPU/GPU workloads to keep the pipeline responsive without overloading resources or blocking audio capture.
2824

2925
## Why use Arm and DGX Spark?
3026

31-
Arm-powered platforms like [DGX Spark](https://www.nvidia.com/en-gb/products/workstations/dgx-spark/) allow efficient parallelism: use CPU cores for audio preprocessing and whisper inference, while offloading LLM reasoning to powerful GPUs. This architecture balances throughput and energy efficiency—ideal for private, on-prem AI workloads. Check this [learning path](https://learn.arm.com/learning-paths/laptops-and-desktops/dgx_spark_llamacpp/1_gb10_introduction/) to understand the CPU and GPU architecture of DGX Spark.
27+
Arm-powered platforms like [DGX Spark](https://www.nvidia.com/en-gb/products/workstations/dgx-spark/) allow efficient parallelism: use CPU cores for audio preprocessing and whisper inference, while offloading LLM reasoning to powerful GPUs. This architecture balances throughput and energy efficiency—ideal for private, on-premises AI workloads. To understand the CPU and GPU architecture of DGX Spark, refer to [Unlock quantized LLM performance on Arm-based NVIDIA DGX Spark](/learning-paths/laptops-and-desktops/dgx_spark_llamacpp/).
3228

33-
DGX Spark also supports standard USB interfaces, making it easy to connect consumer-grade microphones for development or deployment. This makes it viable not just for data center use, but also for edge inference or desktop-style prototyping.
29+
DGX Spark also supports standard USB interfaces, making it easy to connect consumer-grade microphones for development or deployment. This makes it viable for edge inference and desktop-style prototyping.
3430

3531
In this Learning Path, you’ll build a complete, offline voice chatbot prototype using PyAudio, faster-whisper, and vLLM on an Arm-based system—resulting in a fully functional assistant that runs entirely on local hardware with no internet dependency.

content/learning-paths/laptops-and-desktops/dgx_spark_voicechatbot/2_setup.md

Lines changed: 56 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,46 @@
11
---
2-
title: Installing faster-whisper for Local Speech Recognition
2+
title: Install faster-whisper for local speech recognition
33
weight: 3
44

55
### FIXED, DO NOT MODIFY
66
layout: learningpathall
77
---
88

9-
## Installing faster-whisper for Local Speech Recognition
10-
119
[Faster‑whisper](https://github.com/SYSTRAN/faster-whisper) is a high‑performance reimplementation of OpenAI Whisper, designed to significantly reduce transcription latency and memory usage. It is well suited for local and real‑time speech‑to‑text (STT) pipelines, especially when running on CPU‑only systems or hybrid CPU/GPU environments.
1210

13-
In this Learning Path, faster‑whisper serves as the STT engine that converts raw microphone input into structured text. At this stage, the goal is to install faster‑whisper correctly and verify that it can transcribe audio reliably. Detailed tuning and integration will be covered in later modules.
11+
You'll use faster‑whisper as the STT engine to convert raw microphone input into structured text. At this stage, the goal is to install faster‑whisper correctly and verify that it can transcribe audio reliably. Detailed tuning and integration are covered in later sections.
1412

1513
### Install build dependencies
1614

17-
While some Python packages such as sounddevice and webrtcvad previously had compatibility issues with newer Python versions, these have been resolved. This Learning Path uses ***Python 3.12***, which has been tested and confirmed to work reliably with all required dependencies.
15+
While some Python packages such as sounddevice and webrtcvad previously had compatibility issues with newer Python versions, these have been resolved. Use Python 3.12, which has been tested and confirmed to work reliably with all required dependencies.
1816

1917
Install Python 3.12 and build dependencies:
2018

2119
```bash
2220
sudo apt update
2321
sudo apt install python3.12 python3.12-venv python3.12-dev -y
24-
sudo apt install portaudio19-dev ffmpeg -y
22+
sudo apt install gcc portaudio19-dev ffmpeg -y
2523
```
2624

27-
### Create and Activate Python Environment
25+
## Create and activate Python environment
2826

2927
In particular, [pyaudio](https://pypi.org/project/PyAudio/) (used for real-time microphone capture) depends on the PortAudio library and the Python C API. These must match the version of Python you're using.
3028

3129
Now that the system libraries are in place and audio input is verified, it's time to set up an isolated Python environment for your voice assistant project. This will prevent dependency conflicts and make your installation reproducible.
3230

3331
```bash
34-
python3.12 -m venv voice_ass_env
35-
source voice_ass_env/bin/activate
32+
python3.12 -m venv va_env
33+
source va_env/bin/activate
3634
python3 -m pip install --upgrade pip
3735
```
3836

39-
Before install the package, it will be worst to check the Python version in your virtual environment.
37+
Before installing the package, check the Python version in your virtual environment.
4038

4139
```bash
4240
python3 --version
4341
```
4442

45-
Expected output should be `3.12.x` or higher.
43+
Expected output is `3.12.x` or higher:
4644
```log
4745
Python 3.12.3
4846
```
@@ -55,16 +53,16 @@ pip install requests webrtcvad sounddevice==0.5.3
5553
```
5654

5755
{{% notice Note %}}
58-
While sounddevice==0.5.4 is available, it introduces callback-related errors during audio stream cleanup that may confuse beginners.
59-
For this Learning Path, we recommend sounddevice==0.5.3, which is stable and avoids these warnings.
56+
While sounddevice==0.5.4 is available, it introduces callback-related errors during audio stream cleanup that may confuse beginners.
57+
Use sounddevice==0.5.3, which is stable and avoids these warnings.
6058
{{% /notice %}}
6159

62-
Verify the pyaudio version by:
60+
Verify the pyaudio version:
6361
```bash
6462
python -c "import pyaudio; print(pyaudio.__version__)"
6563
```
6664

67-
Expected output should be:
65+
Expected output:
6866
```log
6967
0.2.14
7068
```
@@ -73,7 +71,7 @@ Expected output should be:
7371

7472
Once your system dependencies are installed, you can test that your audio hardware is functioning properly. This ensures that your audio input is accessible by Python through the sounddevice module.
7573

76-
Now plug in your USB microphone and run the following Python code to verify that it is detected and functioning correctly:
74+
Now plug in your USB microphone and create a file named `microphone.py` with the following Python code to verify that it is detected and functioning correctly.
7775

7876
```python
7977
import sounddevice as sd
@@ -93,21 +91,25 @@ sd.wait()
9391
print(" Playback complete.")
9492
```
9593

94+
Run the example code to check the microphone.
95+
96+
```console
97+
python3 ./microphone.py
98+
```
99+
96100
DGX Spark will record the audio for 5 seconds and immediately play back the captured audio.
101+
97102
If you do not hear any playback, check your USB connection and verify the installation steps above.
98103

99104
Once you’ve confirmed that your microphone is working and your environment is set up, you’re ready to test real-time transcription and move on to the next phase.
100105

101-
### Sample: Real-time Transcription with faster-whisper
106+
### Sample: Real-time transcription with faster-whisper
107+
108+
Verify that your Whisper model works with live microphone input. This example records a 10-second audio clip using the system microphone, transcribes it using faster-whisper, and prints the transcribed text with timestamps.
102109

103-
Now let's verify that your Whisper model works with live microphone input. This example records a 10-second audio clip using the system microphone, transcribes it using faster-whisper, and prints the transcribed text with timestamps.
110+
The code below records a fixed-duration mono audio clip using the sounddevice module and transcribes it using the faster-whisper model. The `record_audio()` function starts the microphone and records a 10-second audio segment, returning the data as a NumPy array. The `WhisperModel("small.en")` call loads the small English model from faster-whisper, using `compute_type="int8"` to ensure compatibility with CPU-only systems. The `transcribe_audio()` function processes the recorded audio and prints the transcription results along with start and end timestamps for each spoken segment. The while True loop continuously records and transcribes in real time until interrupted, allowing you to speak multiple utterances across iterations. The script continues running in 10-second cycles until stopped with Ctrl+C.
104111

105-
This script records a fixed-duration mono audio clip using the sounddevice module and transcribes it using the faster-whisper model. The overall flow includes several key steps:
106-
- The `record_audio()` function starts the microphone and records a 10-second audio segment, returning the data as a NumPy array.
107-
- The `WhisperModel("small.en")` call loads the ***small English model*** from faster-whisper, using `compute_type`=***"int8"*** to ensure compatibility with CPU-only systems.
108-
- The `transcribe_audio()` function processes the recorded audio and prints the transcription results along with start and end timestamps for each spoken segment.
109-
- The while True loop continuously records and transcribes in real time until interrupted, allowing the user to speak multiple utterances across iterations.
110-
- The script will continue running in 10-second cycles until stopped with ***Ctrl+C***.
112+
Copy the code to a file named `transcribe.py`.
111113

112114
```python
113115
import sounddevice as sd
@@ -142,49 +144,60 @@ if __name__ == "__main__":
142144
print(" Stopped by user.")
143145
```
144146

147+
Run the example code.
148+
149+
```console
150+
python3 ./transcribe.py
151+
```
152+
153+
The output shows the main parts of the program;
154+
155+
```output
156+
Recording for 10 seconds...
157+
Recording complete.
158+
Transcribing...
159+
[0.00s - 10.00s] One, two, three, four, five, six, check,
160+
Done.
161+
```
162+
145163
{{% notice Note %}}
146-
To stop the script, press ***Ctrl+C*** during any transcription loop.The current 10-second recording will complete and transcribe before the program exits cleanly.
147-
Avoid using ***Ctrl+Z***, which suspends the process instead of terminating it.
164+
To stop the script, press Ctrl+C during any transcription loop. The current 10-second recording completes and transcribes before the program exits cleanly.
165+
Avoid using Ctrl+Z, which suspends the process instead of terminating it.
148166
{{% /notice %}}
149167

150168

151169
### Troubleshooting
152170

153171
This section lists common issues you may encounter when setting up local speech-to-text, along with clear checks and fixes.
154172

155-
***Problem 1: Callback-related errors with sounddevice***
173+
**Problem 1: Callback-related errors with sounddevice**
156174

157175
If you encounter errors like:
158176

159177
```log
160178
AttributeError: '_CallbackContext' object has no attribute 'data'
161179
```
162180

163-
***Cause***
164-
This is a known issue introduced in sounddevice==0.5.4, related to internal callback cleanup.
181+
**Cause:** This is a known issue introduced in sounddevice==0.5.4, related to internal callback cleanup.
165182

166-
***Fix***
167-
Use the stable version recommended in this Learning Path:
183+
**Fix:** Use the stable version:
168184
```bash
169185
pip install sounddevice==0.5.3
170186
```
171187

172-
***Problem 2: No sound playback after recording***
188+
**Problem 2: No sound playback after recording**
173189

174190
You can record audio without errors, but nothing is played back.
175191

176-
***Check:***
177-
- Verify that your USB microphone or headset is selected as the default input/output device.
178-
- Ensure the system volume is not muted.
192+
Verify that your USB microphone or headset is selected as the default input/output device. Also ensure the system volume is not muted.
179193

180-
***Fix***
181-
List all available audio devices:
194+
**Fix:** List all available audio devices:
182195

183196
```bash
184197
python -m sounddevice
185198
```
186199

187-
You should see an output similar to:
200+
The output is similar to:
188201
```log
189202
0 NVIDIA: HDMI 0 (hw:0,3), ALSA (0 in, 8 out)
190203
1 NVIDIA: HDMI 1 (hw:0,7), ALSA (0 in, 8 out)
@@ -201,18 +214,16 @@ If your microphone or headset is listed but not active, try explicitly selecting
201214

202215
```bash
203216
import sounddevice as sd
204-
205-
sd.default.device = 4 # Set to your desired device index
217+
sd.default.device = 4
206218
```
207219

208-
Other fixes to try:
220+
Other things to try:
209221
- Increase system volume
210-
- Replug the device
222+
- Remove the device and plug it in again
211223
- Reboot your system to refresh device mappings
212224

213-
214-
### Next Module
225+
## What you've accomplished and what's next
215226

216227
Once your transcription prints correctly in the terminal and playback works as expected, you’ve successfully completed the setup for local STT using faster-whisper.
217228

218-
In the next module, youll enhance this basic transcription loop by adding real-time audio segmentation, turn detection, and background threading to support natural voice interactions.
229+
In the next section, you'll enhance this basic transcription loop by adding real-time audio segmentation, turn detection, and background threading to support natural voice interactions.

0 commit comments

Comments
 (0)