# Jetson AI Lab — Full Documentation > Complete reference for deploying generative AI on NVIDIA Jetson edge devices (Orin Nano, AGX Orin, Thor). This file contains the full text of all tutorials and model documentation. Generated: 2026-08-11 Source: https://www.jetson-ai-lab.com --- ## Tutorials ### Setup #### Introduction to NVIDIA Jetson URL: https://www.jetson-ai-lab.com/tutorials/intro-to-jetson/ Description: NVIDIA Jetson™ is a powerful platform for developing innovative edge AI and robotics solutions across industries. Tags: introduction, jetson-thor, jetson-orin, agx-orin, orin-nx, orin-nano, jetpack, physical-ai A visual landing page introducing the NVIDIA Jetson platform: the two current generations (Thor and Orin), every series within them, the developer kits and production modules, JetPack 7.2 on Jetson Linux, and a side-by-side comparison of Jetson Thor and NVIDIA DGX Spark. See the full page: [/tutorials/intro-to-jetson/](/tutorials/intro-to-jetson/) --- #### Getting Started with Jetson URL: https://www.jetson-ai-lab.com/tutorials/getting-started-with-jetson/ Description: An onboarding guide for new NVIDIA Jetson developers, covering the official developer kit user guides and remote development with VS Code or Cursor over SSH. Tags: setup, getting-started, ssh, cursor, vscode, user-guide import Tabs from '../../../components/Tabs.astro'; This guide is the recommended starting point once you have an NVIDIA Jetson developer kit in hand. It first directs you to the official Quick Start Guide for your developer kit to complete the initial hardware and software setup, then walks through establishing a remote development workflow from your workstation over SSH, including a full IDE experience with VS Code or Cursor. If you are new to the Jetson platform, review [Introduction to NVIDIA Jetson](/tutorials/intro-to-jetson/) first for an overview of the hardware generations, developer kits, and the JetPack software stack. ## Official Developer Kit Quick Start Guides Firmware flashing, first boot, and JetPack installation are documented in the official Quick Start Guides on **docs.nvidia.com**. Select the guide that corresponds to your developer kit and complete the setup before continuing.
Thor Generation
Jetson AGX Thor Developer Kit — Quick Start Guide
Orin Generation
Jetson AGX Orin Developer Kit — Quick Start Guide
Orin Generation
Jetson Orin Nano Developer Kit — Quick Start Guide
Connect over SSH. Open a terminal on your workstation (PowerShell or Command Prompt on Windows; Terminal on Mac/Linux) and connect, replacing USERNAME and JETSON_IP with your values:
{"ssh USERNAME@JETSON_IP"}
📘 Tip
Orin developer kits expose a fixed address 192.168.55.1 over USB-C (USB Device Mode), which is convenient for a first connection before the device is on your network. If that address is not reachable, connect the Jetson to Wi-Fi or Ethernet and SSH using its network IP instead.
Connect to a network so the Jetson has internet access for downloading models, packages, and skills:
While SSH'd into the Jetson, connect to Wi-Fi:
{"sudo nmcli device wifi connect WIFI_SSID password WIFI_PASSWORD"}
Plug an Ethernet cable into the Jetson. Most networks assign an IP address automatically via DHCP.
Find the Jetson's network IP and reconnect using it (ignore 192.168.55.1, which is the USB connection):
{"hostname -I"}
💡 Tip
Some Wi-Fi networks block device-to-device connections. If SSH fails over Wi-Fi, use Ethernet or a dedicated local router.
Install the Remote - SSH extension:
Ctrl+Shift+X), search for "Remote - SSH" by Microsoft, and install it.
Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P on Mac) and select "Remote-SSH: Connect to Host..."
Enter the SSH connection string — for example: jetson@192.168.1.42
{"USERNAME@JETSON_IP"}
When prompted, select Linux as the platform for the remote host:
Enter the password when prompted:
The editor connects and installs a lightweight server on the Jetson automatically.
Once connected, you'll see "SSH: <IP address>" in the bottom-left corner. Use Open Folder to browse and edit files on the Jetson, and open the integrated terminal (Ctrl+`) to run commands.
💡 Tip — Save your SSH config for one-click access
Add the Jetson to your SSH config file (~/.ssh/config):
{"Host jetson\n HostName 192.168.1.42\n User jetson"}
Replace the IP and username with your values. After this, select "jetson" from the host list in VS Code/Cursor — or type ssh jetson in a terminal.
📘 Where to get the images
Prebuilt Yocto images are published on the JetPack SDK downloads page. Under Yocto Images, use the button for your device: Yocto for Jetson AGX Thor, Yocto for Jetson AGX Orin, or Yocto for Jetson Orin Nano. If you'd rather build the image yourself, jump to Build your own Yocto image.
⚠️ Install the NVMe drive first (NVMe targets)
For the two NVMe targets (AGX Thor and Orin Nano), install the NVMe drive in the Jetson before putting the device into recovery mode. The flash script writes the root filesystem to the storage target described by the MACHINE configuration.
💡 Just want to run AI workloads?
If you're not specifically interested in Yocto and just want to get models running quickly, the standard JetPack flow in Getting Started with Jetson is the easier path.
📘 Notes
If gsettings is unavailable (a non-desktop host), this automount step does not apply. If the host has the tlp power-management package installed, remove it and reboot the host before flashing: sudo apt remove tlp && sudo reboot.
{"export MACHINE=\"jetson-agx-thor-devkit\""}
{"export MACHINE=\"p3737-0000-p3701-0005\""}
{"export MACHINE=\"jetson-orin-nano-devkit-nvme\""}
💡 Tip
Use a fresh empty directory if you unpack more than one target so the contents don't mix.
For kits with RECOVERY and RESET buttons (Thor AGX devkit, Orin AGX devkit):
For the Jetson Orin Nano developer kit, use the recovery pins on the J14 button header (located below the Jetson module):
See Orin Nano Developer Kit: Force Recovery Mode for the official steps.
⚠️ APX vs Tegra On-Platform Operator
A Tegra On-Platform Operator device is the USB serial support interface, not the recovery-mode device used for flashing. If APX is missing, check the cable, the recovery USB port, and the recovery-mode button/pin sequence.
📘 If you see could not retrieve board information
If the flash fails early with an error like:
{"Found Jetson device in recovery mode at USB 3-1\nERR: could not retrieve board information"}
Power-cycle the developer kit (unplug power, plug it back in), re-enter Force Recovery Mode from power-off, confirm APX appears in lsusb -d 0955:, and run sudo ./initrd-flash again.
⏳ Don't disconnect during flashing
Flashing can take several minutes, particularly the final step that writes the QSPI flash. Keep the USB cable connected and the board powered until it completes. The script writes a host log named log.initrd-flash.YYYY-MM-DD-HH.MM.SS; for Orin targets, device-side logs may also be collected into a device-logs-YYYY-MM-DD-HH.MM.SS directory.
⚠️ Change the default login
The tegrademo image is a reference / demo image with passwordless root for convenience. Before using it or any derivative beyond evaluation, set passwords, remove debug tweaks, and review the security configuration.
📘 AGX Orin: use an external SSD for vLLM
The unused portion of the 64 GB AGX Orin eMMC provides approximately 28 GB after formatting. This is useful for smaller containers and model caches, but the current NVIDIA AI-IOT vLLM image expands beyond that capacity. For vLLM on AGX Orin, install an NVMe SSD or connect a USB SSD and use that device for /data instead of creating the eMMC data partition below.
⚠️ Confirm the free space before changing the partition table
The following procedure creates a partition only in currently unallocated space. Do not delete, resize, or format any existing A/B, EFI, recovery, or reserved partition. A later full-device flash may recreate the original partition table, so keep important data backed up.
{"lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINTS\nfdisk -l /dev/nvme0n1"}
{"lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINTS\nfdisk -l /dev/mmcblk0"}
{"lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINTS\nfdisk -l /dev/nvme0n1"}
{"fdisk /dev/nvme0n1"}
{"fdisk /dev/mmcblk0"}
{"fdisk /dev/nvme0n1"}
📘 The IP address may change after reboot
If the Jetson receives its address through DHCP, it may come back with a different IP address. If SSH no longer connects to the previous address, check the DHCP lease table on your router or network, or use the serial console and run ip -br address to find the new address.
{"export DATA_PARTITION=/dev/nvme0n1p13"}
{"export DATA_PARTITION=/dev/mmcblk0p17"}
{"export DATA_PARTITION=/dev/nvme0n1p17"}
📘 Live VLM WebUI needs a model backend
Live VLM WebUI provides the browser interface and camera pipeline; it does not serve a model by itself. Connect it to Ollama, vLLM, SGLang, or another OpenAI-compatible local or cloud API. For a small local-storage setup, start with Ollama and a compact model.
{"0007:01:00.0 Non-Volatile memory controller: Marvell Technology Group Ltd. Device 1322 (rev 02)"}
---
### Format and Set Up Auto-mount
1. Run `lsblk` to find the device name:
```bash
lsblk
```
The output should look like:
{"NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT\nloop0 7:0 0 16M 1 loop\nmmcblk1 179:0 0 59.5G 0 disk\n├─mmcblk1p1 179:1 0 58G 0 part /\n├─mmcblk1p2 179:2 0 128M 0 part\n├─mmcblk1p3 179:3 0 768K 0 part\n├─mmcblk1p4 179:4 0 31.6M 0 part\n├─mmcblk1p5 179:5 0 128M 0 part\n├─mmcblk1p6 179:6 0 768K 0 part\n├─mmcblk1p7 179:7 0 31.6M 0 part\n├─mmcblk1p8 179:8 0 80M 0 part\n├─mmcblk1p9 179:9 0 512K 0 part\n├─mmcblk1p10 179:10 0 64M 0 part\n├─mmcblk1p11 179:11 0 80M 0 part\n├─mmcblk1p12 179:12 0 512K 0 part\n├─mmcblk1p13 179:13 0 64M 0 part\n└─mmcblk1p14 179:14 0 879.5M 0 part\nzram0 251:0 0 1.8G 0 disk [SWAP]\nzram1 251:1 0 1.8G 0 disk [SWAP]\nzram2 251:2 0 1.8G 0 disk [SWAP]\nzram3 251:3 0 1.8G 0 disk [SWAP]\nnvme0n1 259:0 0 238.5G 0 disk"}
Identify the device corresponding to your SSD. In this case, it is `nvme0n1`.
2. **Format the SSD**, create a mount point, and mount it:
```bash
sudo mkfs.ext4 /dev/nvme0n1
```
> You can choose any name for the mount point directory. We use `/ssd` here, but in `jetson-containers`' [setup.md](https://github.com/dusty-nv/jetson-containers/blob/master/docs/setup.md) documentation, `/mnt` is used.
```bash
sudo mkdir /ssd
sudo mount /dev/nvme0n1 /ssd
```
3. **Set up auto-mount** to ensure the mount persists after boot:
First, identify the UUID for your SSD:
```bash
lsblk -f
```
Then, add a new entry to the `fstab` file:
```bash
sudo vi /etc/fstab
```
Insert the following line, replacing the UUID with the value found from `lsblk -f`:
```
UUID=************-****-****-****-******** /ssd/ ext4 defaults 0 2
```
4. **Change ownership** of the `/ssd` directory:
```bash
sudo chown ${USER}:${USER} /ssd
```
---
## Docker
### Install nvidia-container Package
📘 Note
If you used an NVIDIA-supplied SD card image to flash your SD card, all necessary JetPack components (including nvidia-containers) and Docker are already pre-installed, so this step can be skipped.
ℹ️ JetPack 6.x users
If you flash Jetson Linux (L4T) R36.x (JetPack 6.x) on your Jetson using SDK Manager, and install nvidia-container using apt, on JetPack 6.x it no longer automatically installs Docker.
Therefore, you need to run the following to manually install Docker and set it up:
⚠️ Jetson Thor Unified Memory
Jetson Thor shares its 128 GB memory between CPU and GPU. The OS, desktop environment, and background processes typically consume 4–6 GB, leaving ~115 GB available for training. All default configurations in this tutorial are tuned to stay well within this limit. If you increase batch size, sequence length, or use a larger model, monitor memory with tegrastats or jtop to avoid hitting the system OOM killer.
| Method | Model | Measured Memory | Training Time | Best For |
|---|---|---|---|---|
| Full SFT | Qwen3.5 4B | ~42 GB | ~5 min (1 epoch, 500 samples) | Maximum quality |
| LoRA | Qwen3.5 9B | ~50 GB | ~3.5 min (1 epoch, 512 samples) | Good balance of quality and efficiency |
| QLoRA (4-bit) | Qwen3.5 27B | ~28 GB | ~10 min (1 epoch, 512 samples) | Largest models with least memory |
These times are rough guides for the defaults in each section below; larger --dataset_size or more --num_epochs will take proportionally longer.
💡 How to choose
All three methods produce models in standard Hugging Face SafeTensors format that can be deployed with vLLM, Ollama, llama.cpp, or TensorRT-LLM.
Tips for your own dataset
input empty ("") for tasks that don't need additional context⚠️ Jetson Thor Unified Memory
Jetson Thor shares its 128 GB memory between CPU and GPU. The OS, desktop, and other processes typically use 4–6 GB, so your training process should stay under ~115 GB to avoid the system OOM killer.
💡 Understanding Batch Size and Memory
Two parameters control how many samples the model processes per optimizer update:
--batch_size — samples processed at once on the GPU (directly affects memory usage)--gradient_accumulation_steps — how many mini-batches to accumulate before updating weightsThe effective batch size = batch_size × gradient_accumulation_steps. Training quality depends on the effective batch size, not the per-device batch size. So you can lower --batch_size to save memory and raise --gradient_accumulation_steps to compensate — the model learns identically, just processes fewer samples per forward pass.
| batch_size | accum_steps | Effective Batch | Memory (Qwen3.5 4B Full SFT) |
|---|---|---|---|
| 8 | 1 | 8 | ~87 GB (may OOM with desktop running) |
| 4 | 2 | 8 | ~42 GB (default, safe) |
| 2 | 4 | 8 | ~25–30 GB (conservative) |
| 1 | 8 | 8 | ~18–22 GB (minimum) |
To override the defaults, pass both flags together:
python full_sft_finetuning.py --batch_size 2 --gradient_accumulation_steps 4 --output_dir ./finetuned_model
| Precision | Memory savings (vs FP16) |
Jetson Orin CC 8.7 ( sm_87) |
Jetson Thorsm_110 |
|---|---|---|---|
| FP16 | Baseline | Supported | Supported |
| FP8 | 2x reduction | Not available | Supported |
| INT4 AWQ | 4x reduction | Supported | Supported |
| NVFP4 | 4x reduction | Not available | Supported |
Use /workspace, not $HOME
Inside the container $HOME is /root, which is not on the mounted volume. Always use /workspace/... so your ONNX files appear on the host automatically. When you exit the container, the workspace will be at ~/tensorrt-edgellm-workspace (or wherever you ran docker run from).
💡 Exported on Jetson Thor?
Both models' ONNX files are already on your Thor host (they landed in tensorrt-edgellm-workspace/ via the Docker volume mount). Skip the Thor scp below — you only need to copy Qwen3-4B-Instruct ONNX to the Orin Nano.
Why must this run on the target device?
TensorRT compiles ONNX graphs into engine binaries that are optimized for the exact GPU they run on: kernel selection, memory layout, and fused operations are all hardware-specific. An engine built on Thor (SM110) will not load on Orin Nano (SM87), and vice versa. Unlike the ONNX files from Step 1 (which are portable), engines must be built on the same device that will execute them.
💡 Thor users who exported on-device
Exit the Docker container (exit). Because WORKSPACE_DIR was set to /workspace/tensorrt-edgellm-workspace, the ONNX files are already on the host in the directory where you ran docker run. Fix root-owned permissions, then proceed:
nvidia-cuda-toolkitcuda-toolkit-* package from NVIDIA’s repo (as in the commands above), not the Ubuntu nvidia-cuda-toolkit package, which conflicts with JetPack CUDA libraries.
🟢 Jetson Thor: 8B VLM with NVFP4 quantization
Cosmos Reason2 8B is an 8B vision-language model (LLM + visual encoder). NVFP4 is a Thor-exclusive precision (SM110+) that reduces weights to ~4 GB. This section runs entirely on Jetson Thor. If you only have an Orin Nano, skip to Step 4.
💡 Sample images
The repo ships test images at ~/TensorRT-Edge-LLM/examples/multimodal/pics/ including red_panda.jpeg, giant_panda.jpeg, woman_and_dog.jpeg, and database_er.jpeg.
🟠 Jetson Orin Nano 8 GB: 4B LLM with INT4 AWQ quantization
INT4 AWQ reduces Qwen3-4B-Instruct to ~2 GB of weights, leaving ample room for the KV cache and OS within Orin Nano's 8 GB unified memory. This section runs entirely on Jetson Orin Nano. Ensure you completed Step 2 on your Orin Nano first.
Memory guidance for Orin Nano INT4 builds
Pass --externalize-weights int4_ffn to tensorrt-edgellm-export for dense INT4 checkpoints to reduce peak engine-build memory. For MoE checkpoints add int4_moe to that flag.
Benchmark context
The released Edge-LLM benchmark tables use default TensorRT Edge-LLM inference settings on Jetson AGX Thor. Local results can vary with Jetson model, power mode, memory pressure, thermal state, CUDA/TensorRT version, batch size, prompt length, and generation length.
pip install on Jetson (Thor container)?AttributeError: module 'torch._C' has no attribute '_dlpack_exchange_api'. The NVIDIA PyTorch container includes a Jetson-built torch. The setup in this tutorial uses --system-site-packages on the venv so that build is visible, pip3 install --no-deps . so pip does not overwrite torch, and a filtered requirements.txt (with torch lines removed) to pull in the remaining packages (transformers, datasets, onnx, etc.) without replacing torch or torchvision.
make crashes on Orin NanoUnified memory sizing. Quantization loads the full BF16 model before compressing it, so the sizing constraint comes from the base model rather than the output. Qwen3.6-27B is 52 GB of BF16 weights, which fits comfortably on a 128 GB Thor. Size your model against free memory on that basis: on a 32 GB device, stay at or below about 8B parameters.
Accept the calibration dataset licence first. ModelOpt 0.45 and newer calibrate on cnn_nemotron_v2_mix by default, which includes nvidia/Nemotron-Post-Training-Dataset-v2. That dataset is gated: accept its licence on its Hugging Face page, then make your token available inside the container with hf auth login or -e HF_TOKEN. Without it the run stops immediately with DatasetNotFoundError. This is the same calibration data NVIDIA uses for its own published NVFP4 checkpoints.
This model thinks before it answers. Qwen3.6 reasons at length before producing an answer. A single graduate-level question can take over 12,000 tokens. {'--reasoning-parser qwen3'} puts that reasoning in a separate reasoning_content field so content holds just the answer, and the larger {'--max-model-len'} gives it room to finish. Without enough headroom the model is cut off mid-thought and content comes back empty.
Startup takes a while the first time. vLLM reads the quantized weights quickly (18.77 GiB in 12.3 seconds in our run), but then spends several minutes on torch.compile, FP4 kernel autotuning, and CUDA graph capture before the server answers. Watch the log rather than assuming a hang. The very first run also pulls the ~30 GB image. The /root/.cache/vllm mount above is where vLLM keeps its compile and autotune caches; with {'--rm'} and no mount they are discarded when the container exits. On a board with other services resident, lower {'--gpu-memory-utilization'}.
| Requirement | Details |
|---|---|
| Jetson device | Jetson AGX Thor running JetPack 7 |
| ASR service | NVIDIA RIVA ARM64 quick start initialized with the Parakeet ASR model |
| LLM / VLM service | Cosmos-Reason2-8B weights available at ~/models/cosmos-reason2-8b and served by vLLM |
| TTS service | NVIDIA RIVA ARM64 quick start initialized with the Magpie TTS model |
| Client browser | A PC browser on the same network, or a browser on Jetson Thor, with microphone and camera access |
| Setting | Value |
|---|---|
| Server Address | localhost:50051 |
| ASR Language | en-US |
| ASR Model | parakeet-1.1b-en-US-asr-streaming-silero-vad-sortformer |
| Setting | Value |
|---|---|
| API Base URL | http://localhost:8010/v1 |
| Model | nvidia/cosmos-reason2-8b-fp8 |
| Utility Model | nvidia/cosmos-reason2-8b-fp8 |
| Enable Streaming Responses | Checked |
| Include Conversation History | Checked |
| Enable Vision (VLM) | Video Input |
| System Prompt | See below |
| Setting | Value |
|---|---|
| RIVA Server | localhost:50051 |
| TTS Model | magpie_tts_ensemble_Magpie-Multilingual |
| Language | English (US) |
| Sample Rate (Hz) | 22050 |
| Quality | High (Better) |
| Start speaking before LLM finishes | Checked |
| Words before first speech | 10 |
| Setting | Value |
|---|---|
| Camera Device | Default (browser) |
| Microphone Device | Default (browser) |
| Speaker Device | Default (browser) |
| Setting | Value |
|---|---|
| Start sessions with microphone muted | Unchecked |
| Barge-in | Unchecked |
| Session Directory | Default (sessions) |
| Lever | Why It Helps |
|---|---|
| Short system prompt | Reduces prompt tokens and encourages concise responses |
| Streaming responses | Allows TTS to start before the full response is complete |
| Words before first speech | Lower values start speech earlier, but can sound less natural |
| VAD sensitivity | Improves turn detection in noisy rooms |
| Max model length | Reduces KV cache memory pressure |
| GPU memory utilization | Leaves headroom for RIVA and the app |
multi-modal-ai-studio: command not found8092 is already in use
Some useful Telegram commands:
| Command | What it does |
| --- | --- |
| `/status` | Show session info, token usage, and context size |
| `/help` | List all available commands |
| `/new` | Start a fresh session |
| `/stop` | Stop the current agent run |
| `/model` | Switch models |
---
#### Reachy Mini Jetson Assistant
URL: https://www.jetson-ai-lab.com/tutorials/reachy-mini-jetson-assistant/
Description: Use Jetson agent skills to build a memory-optimized multimodal application on Jetson Orin Nano 8GB.
Tags: reachy-mini, jetson-orin-nano, robotics, vlm, stt, tts, face-tracking, llama.cpp, jetson-device-skills, multimodal
The [Reachy Mini Jetson Assistant](https://github.com/NVIDIA-AI-IOT/reachy-mini-jetson-assistant) is a fully local voice and vision robot assistant for [Reachy Mini Lite](https://www.pollen-robotics.com/reachy-mini/) powered by NVIDIA Jetson. It listens through the robot microphone, captures camera frames, reasons with a vision-language model, speaks with text-to-speech, tracks the person in front of it, and drives expressive head, body, and antenna movements.
The interesting part is not only that the entire AI pipeline runs locally. It is that the complete stack can run on a **Jetson Orin Nano 8GB** with proper memory optimization:
```text
[Mic] -> [Silero VAD] -> [faster-whisper STT] --+
[USB Camera] -> [Frame Ring Buffer] ------------+-> [VLM stream] -> [TTS stream] -> [Speaker + Robot]
+-> [Web UI via WebSocket]
```
[Jetson Device Skills](https://github.com/NVIDIA-AI-IOT/jetson-device-skills) are applicable across Jetson devices. In this tutorial, we walk through how those skills were used to deploy a conversational AI application on Jetson Orin Nano 8GB and validate the memory decisions that make the pipeline practical on the smallest Orin Nano target.
## What You Will Build
You will run a local Reachy Mini assistant with:
- **Vision-language reasoning** with Cosmos-Reason2-2B GGUF Q4_K_M served by `llama.cpp`
- **Speech-to-text** with `faster-whisper` and CUDA-enabled CTranslate2
- **Text-to-speech** with Kokoro ONNX and CUDA ONNX Runtime
- **Voice activity detection** with Silero VAD
- **Face detection and tracking** with OpenCV YuNet
- **Reachy Mini motion control** with face tracking and TTS-synchronized gestures
- **Browser UI** with live camera, conversation state, and telemetry
## Why Memory Optimization Matters
The NVIDIA Technical Blog post [Maximizing Memory Efficiency to Run Bigger Models on NVIDIA Jetson](https://developer.nvidia.com/blog/maximizing-memory-efficiency-to-run-bigger-models-on-nvidia-jetson/) presents the Reachy Mini assistant as a stack-wide transition from an Orin NX 16GB-class configuration to a complete Orin Nano 8GB deployment.
The Orin Nano has a real deployment budget of about **7.6GB usable unified memory**, and this application runs several memory-hungry components at the same time. The point is not to optimize one layer. The system fits because every layer is chosen for the budget.
| Optimization layer | Before: larger-memory configuration | After: Orin Nano 8GB configuration | Why it matters |
| --- | --- | --- | --- |
| BSP and OS services | Ubuntu Desktop with a full GNOME session | Headless `multi-user.target` | Saves memory that would otherwise be consumed by desktop services |
| Inference framework | Heavier serving framework | `llama.cpp` | Keeps the VLM serving overhead low |
| VLM precision | Cosmos Reason2 2B FP16 | Cosmos Reason2 2B GGUF Q4_K_M | Reduces runtime memory |
## How Jetson Device Skills Helped
Jetson Device Skills provided an agent-guided workflow for bringing up the application on a live Jetson. We used them to inspect the Orin Nano 8GB system, identify memory pressure, choose a low-memory VLM runtime, and verify the result after tuning. The skills produced the evidence and recommendations; the Reachy application used those findings to choose the runtime, model format, headless deployment, and memory-conscious application settings.
If you are customizing the Jetson image before flashing, also look at [Jetson BSP Skills](https://github.com/NVIDIA-AI-IOT/jetson-bsp-skills). Those skills focus on BSP and image-build workflows, while the Jetson Device Skills used here operate after the device has booted and help inspect, tune, and validate a live Jetson deployment.
The table below keeps the skills story simple: what the skills showed, what we chose, and what changed.
| Area | What Jetson skills showed | Decision | Evidence / impact |
| --- | --- | --- | --- |
| Device budget | `jetson-diagnostic` confirmed the Orin Nano 8GB target; `jetson-memory-audit` showed active memory pressure | Treat the live Orin Nano memory budget as the design constraint | Baseline memory was about 223 MB available with about 2 GB swap in use |
| OS footprint | `jetson-diagnostic` recommended headless mode to reduce desktop service overhead | Keep the robot deployment headless | Headless mode saved about 0.7 GB |
| VLM runtime | `jetson-inference-mem-tune` recommended `llama.cpp` for a tight-memory VLM server workload | Serve Cosmos Reason2 with `llama.cpp` | Lower serving overhead leaves memory for the other models |
| VLM model format | `jetson-inference-mem-tune` pointed to the GGUF 4-bit path for Orin Nano | Use Cosmos Reason2 2B GGUF Q4_K_M | The VLM footprint drops from about 6.6GB to about 2.2GB |
## Prepare Reachy Mini USB Access
Connect Reachy Mini Lite to the Jetson over USB, then add udev rules so the SDK can access the serial ports without root:
```bash
echo 'SUBSYSTEM=="tty", ATTRS{idVendor}=="2e8a", ATTRS{idProduct}=="000a", MODE="0666", SYMLINK+="reachy_mini"' \
| sudo tee /etc/udev/rules.d/99-reachy-mini.rules
sudo udevadm control --reload-rules && sudo udevadm trigger
```
Add your user to the `dialout` group and reboot:
```bash
sudo usermod -aG dialout $USER
sudo reboot
```
After reboot, verify the device is visible:
```bash
ls -la /dev/ttyACM*
```
## Add NVMe Swap
## Test Robot Movement
The NVIDIA Jetson empowers you to bring your innovative ideas to life.
It's a powerful, compact edge AI computer with plenty of examples and learning resources to help your team build an impressive AI project at a hackathon. See [examples of successful hackathon projects](/community?tag=Hackathon).
Explore the tips, guides, and resources below to get started and make the most of your Jetson experience.
Good luck, have fun, and happy hacking!
## Initial Setup
Ideally, your Jetson developer kit comes pre-setup. But you can also set it up yourself.
Check the default username and password with the person or organization who provided the hardware.
jetsonjetsonThe system is typically set up on a microSD card (for Orin Nano), and the device may also have an NVMe SSD attached for additional storage.
💡 Tip
If an SSD is available, see SSD + Docker Setup to move your Docker data directory to the SSD for faster container performance.
If the Jetson has not been set up, go through the initial setup guide that matches your hardware:
A headless setup with Jetson's USB Device Mode provides an easy way to connect your laptop directly to a Jetson with minimal cabling.
Follow these steps:
Take the Jetson developer kit out of the box and connect the bundled power supply.
Find a USB cable to connect the Jetson to your PC (USB-C end goes into the Jetson).
You should see a "L4T-README" drive automatically mounted on your PC.
Open a terminal on your PC and SSH into the Jetson:
🔰 What is SSH?
SSH (Secure Shell) lets you remotely control the Jetson from your own laptop's terminal — as if you were typing directly on the Jetson. No monitor or keyboard needs to be plugged into the Jetson itself.
On Windows, open PowerShell or Command Prompt. On Mac/Linux, open Terminal. Then type:
{"ssh USERNAME@192.168.55.1"}
📘 Note
Replace USERNAME with the username set on the Jetson. Check with the person or organization who provided the hardware for the username and password. You will be prompted for the password after running the command.
The address 192.168.55.1 is a fixed IP that the Jetson assigns itself over the USB cable — you do not need to look it up.
When Jetson is connected to a PC, it acts as a USB Composite Device that presents several USB device classes:
When connected to a Windows PC, "Device Manager" in "Devices by connection" view shows something like the following:
You can also get Jetson on a Wi-Fi network to have Internet access and allow your team members to simultaneously access Jetson.
If you have a PC monitor, DisplayPort cable, USB keyboard, and mouse, you can use Jetson as a standalone computer and do all the work on it.
🔰 Why do I need this?
The USB connection only lets one PC talk to the Jetson and does not provide internet. Connecting to Wi-Fi or Ethernet gives the Jetson its own IP address on the local network, enabling internet access and multi-user SSH.
While SSH'd into the Jetson via USB, run this command to connect to Wi-Fi:
{"sudo nmcli device wifi connect WIFI_SSID password WIFI_PASSWORD"}
Replace WIFI_SSID with your Wi-Fi network name and WIFI_PASSWORD with the password.
If an Ethernet cable is available, simply plug it into the Ethernet port on the Jetson. Most networks will automatically assign an IP address via DHCP — no extra commands needed.
{"hostname -I"}
This prints the IP address(es) assigned to the Jetson. Look for an address like `192.168.x.x` or `10.x.x.x` (ignore `192.168.55.1` — that's the USB connection).
### SSH over the Network
Once the Jetson is on your Wi-Fi or Ethernet network, **you no longer need the USB cable**. Any team member on the **same network** can SSH into the Jetson directly from their own laptop:
{"ssh USERNAME@JETSON_IP"}
Replace `USERNAME` with your Jetson's username and `JETSON_IP` with the address you found above (e.g. `ssh jetson@192.168.1.42`).
🔰 No USB cable required
The USB cable was only needed for the initial setup — to connect the Jetson to Wi-Fi or Ethernet. Once the Jetson has a network IP address, you can unplug the USB cable and SSH over the network from any laptop. Multiple team members can connect at the same time, each from their own machine.
💡 Tip
Sometimes, the Wi-Fi network policy blocks device-to-device connections (like SSH).
USB Device Mode still lets you connect via the USB cable, but limits access to one PC. If your team needs multiple PCs to access Jetson simultaneously but Wi-Fi blocks SSH, bring a portable Wi-Fi router to create a local network, or use an Ethernet cable to a shared switch/router.
Install the Remote - SSH extension:
Ctrl+Shift+X), search for "Remote - SSH" by Microsoft, and install it.
Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P on Mac) and select "Remote-SSH: Connect to Host..."
Enter the SSH connection string — for example: jetson@192.168.1.42
{"USERNAME@JETSON_IP"}
When prompted, select Linux as the platform for the remote host:
Enter the password when prompted:
The editor will connect and install a lightweight server on the Jetson automatically.
Once connected, you'll see "SSH: <IP address>" in the bottom-left corner. Use Open Folder to browse and edit files on the Jetson, and open the integrated terminal (Ctrl+`) to run commands — all from the comfort of your laptop's IDE.
💡 Tip — Save your SSH config for one-click access
To avoid typing the IP address every time, add the Jetson to your SSH config file (~/.ssh/config):
{"Host jetson\n HostName 192.168.1.42\n User jetson"}
Replace the IP and username with your values. After this, you can simply select "jetson" from the host list in VS Code/Cursor — or type ssh jetson in a terminal.
Check your power mode:
{"nvpmodel -q"}
Install jtop (jetson-stats) to monitor resource utilization:
{"sudo apt install -y python3-pip\nsudo pip3 install -U jetson-stats"}
The CTRL tab in jtop lets you change the power mode under NVP modes.
Install jtop:
{"sudo apt install -y python3-pip\nsudo pip3 install -U jetson-stats"}
Use a USB power bank that supports 12V output via Power Delivery (PD) with a USB PD to DC power jack adapter cable.