NVIDIA just release Jet Pack 7.2 support for Orin! This is a great step to making the Jetson stack install much smoother and cleaner than current status. Right now, JetPack 6 only works with Ubuntu 22, which then forces you to use a ROS version that is a few years old, Python 3.10, and some contradicting PyTorch wheels that can be a bit difficult to nail correctly.
With JetPack 7.2, we now have Ubuntu 24! This means a domino effect of upgrading all other dependencies. However, although the 7.2 support is out, there are still quite some steps that haven't been documented as of right now.
These instructions should help setup faster and avoid some hours of debugging frustration.
1. CUDA has to be on your PATH, not just installed.
A fresh flash ships the CUDA 13.2 runtime, but if CUDA_HOME / PATH /
LD_LIBRARY_PATH don't point at it, torch won't find it at runtime. "Installed"
is not the same as "visible." This bit me and it's the first thing to check if
imports or nvcc behave oddly.
2. The wheels are prerelease and undocumented.
You need --pre or pip won't even see them. They are not in NVIDIA's
compatibility matrix, not in the Jetson install docs, and not what the forum
threads point you to. Without the --pre and you get nothing back and wrongly
conclude no wheel exists. It exists. You just have to ask for prereleases.
3. Stay on Python 3.12. Do not jump to 3.13.
JetPack 7.2 ships Python 3.12 and the cu132 aarch64 wheels are built for
cp312. There is no matching 3.13 wheel for this stack right now, so moving to
3.13 puts you straight back into building from source. 3.12 is the supported
island. Stay on it. (Similarily, don't bother with 3.10 wheels you might find - none of them I've tested have worked so far)
4. This is specific to my hardware: Jetson Orin NX 16GB (sm_87) on JetPack 7.2 / CUDA 13.2.
The CUDA suffix (cu132) has to match your driver, and the wheel architecture
has to match your GPU. Other Orin modules (Orin Nano, AGX Orin) are also sm_87
and will very likely work, but a different JetPack/CUDA version or a non-Orin
board (Thor is sm_110, for example) needs a different wheel. Check yours before
copying this blindly. See For other hardware.
| Board | Seeed reComputer Super, Jetson Orin NX 16GB (J401 carrier) |
| JetPack | 7.2 (L4T r39.2) |
| OS | Ubuntu 24.04 |
| CUDA | 13.2 |
| Python | 3.12 |
| GPU arch | sm_87 |
| PyTorch | torch 2.12.1+cu132, torchvision 0.27.1+cu132 (prerelease, from download.pytorch.org/whl/cu132) |
| numpy | 2.2.6 |
| ROS | ROS 2 Jazzy (system install, separate from the venv) |
| LeRobot | 0.6.0 (installed --no-deps, see below) |
Before any of the PyTorch work, you need the JP7.2 BSP flashed. There are three ways depending on your hardware, and this is the part that mostly does work. Full flashing steps live in Seeed's wiki: https://wiki.seeedstudio.com/recomputer_jetson_super_getting_started/#flash-jetpack-os
-
Standard NVIDIA devkit (host flashing): if you have a plain NVIDIA Jetson Orin devkit, grab the image the usual way from the NVIDIA Jetson download center and flash from an Ubuntu host over USB-C.
-
reComputer, ISO route (what I did): download the JP7.2 image for your exact module from the Seeed wiki link above and flash it directly. Match the module and version carefully. For the Orin NX 16GB the correct row is the JP7.2 / Orin NX 16GB image, and its SHA256 should match before you flash. This is the reliable path today.
-
Seeed developer tool: install/upgrade it and follow the same wiki page.
pip install --upgrade seeed-jetson-developer==0.2.0
Heads up: at time of writing the tool's UI did not yet list the reComputer Super + JP7.2 BSP for me, and auto-detection tried to hand me an AGX Orin image (wrong module), which failed to flash. Check that it actually offers your board and the 7.2 BSP before relying on it. If it doesn't, use the ISO route above.
Once the board boots into Ubuntu 24.04 and cat /etc/nv_tegra_release shows
R39 (JP7.2), continue below.
Skip this if you just want the steps. Here so you don't repeat the experiment.
- Plain
pip install torch: gives a wheel that reports CUDA available but is built for datacenter GPUs (sm_110/sm_121), not Orin'ssm_87. It fails withno kernel image is available for execution on the deviceon the first real operation.torch.cuda.is_available()returningTrueis not proof of anything here. - Community SBSA
cu130wheels: install, but they're alsosm_110/sm_121, and they need system libraries a fresh flash lacks (NVPL, cuDSS). Even after adding those, they still won't run a kernel onsm_87. - Jetson PyTorch container: there is no
r39image yet, so the tooling (autotag) falls back to a JetPack 6 (r36.4) image, which fails on the JP7.2 driver withCUDA error 801 (operation not supported). - The one that works:
--pre torch --extra-index-url https://download.pytorch.org/whl/cu132.cu132matches CUDA 13.2, the aarch64 build includessm_87, and--extra-index-url(not--index-url) lets numpy and the other deps still resolve from PyPI instead of failing on the CUDA index.
Depending on how you flashed, torch may fail to import with a missing
lib*.so before it even gets to CUDA. Those are system libraries the wheel
links against that a fresh JP7.2 flash does not include (NVPL for CPU BLAS/LAPACK,
cuDSS for the sparse solver). Add NVIDIA's CUDA repo, then the libs:
# NVIDIA CUDA repo (provides NVPL, cuDSS, etc.)
wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/sbsa/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt update
# NVPL: the CPU BLAS/LAPACK backend the wheel links against
sudo apt install -y nvpl
# cuDSS runtime, then put it on the linker path (it installs to a versioned subdir)
sudo apt install -y libcudss0-cuda-13
echo "/usr/lib/aarch64-linux-gnu/libcudss/13" | sudo tee /etc/ld.so.conf.d/cudss.conf
sudo ldconfigTwo gotchas:
- If
aptfails with a lock held by another process, that's first-boot auto-updates running. Let them finish or reboot. Do not delete the lock file. - If the import later complains about a different
.so, find it withfind / -name "libNAME.so*" 2>/dev/null, add its directory to a file under/etc/ld.so.conf.d/, and re-runsudo ldconfig. Same pattern every time.
The full runnable version is in install.sh. The steps, annotated:
# 1. Put CUDA 13.2 on PATH (caveat #1). Verify the dir name first:
# ls /usr/local/ | grep cuda -> point CUDA_HOME at the 13.2 dir.
export CUDA_HOME=/usr/local/cuda-13.2
export PATH=$CUDA_HOME/bin:$PATH
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:${LD_LIBRARY_PATH}
which nvcc && nvcc --version # sanity check CUDA is actually visible
# 2. Build basics + a clean Python 3.12 venv (caveat #3).
# --system-site-packages lets the venv see JetPack's TensorRT bindings.
sudo apt install -y python3.12 python3.12-venv python3.12-dev python3-pip \
build-essential cmake git pkg-config libopenblas-dev libjpeg-dev zlib1g-dev
python3.12 -m venv ~/.venvs/jetson-jp72 --system-site-packages
source ~/.venvs/jetson-jp72/bin/activate
python -m pip install --upgrade pip setuptools wheel packaging
# 3. Clear any wrong torch that snuck in, and purge the cache so pip
# doesn't reuse a bad wheel.
python -m pip uninstall -y torch torchvision torchaudio torchdata torchtext torch-tensorrt
python -m pip cache purge
# 4. THE ONE THAT WORKS: prerelease cu132 wheels (caveats #2 and #4).
# --pre is required. --extra-index-url (not --index-url) so numpy etc.
# still come from PyPI.
python -m pip install --pre torch --extra-index-url https://download.pytorch.org/whl/cu132
# 5. Prove it (see Verify). Only add torchvision AFTER torch passes.
python -m pip install --pre torchvision --extra-index-url https://download.pytorch.org/whl/cu132Persist the CUDA exports in ~/.bashrc so new terminals aren't broken (the
script does this for you).
torch.cuda.is_available() returning True is not proof. Every failing
wheel above returned True. The only test that counts is a real kernel launch.
python verify_stack.pyA clean pass prints the device as your Orin, the capability as (8, 7), and a
completed matmul, with no sm_87 is not compatible warning. If you see that
warning or a no kernel image error, you're on a wrong-arch wheel and this
particular build isn't the right one for your board.
It's the usual source of version conflicts and you almost certainly don't need it for a computer-vision or robotics stack. If you do need it later, pin it to your exact installed torch version rather than letting pip pick.
ROS goes in the system environment, not the torch venv. ROS 2 Jazzy is built
against the system Python 3.12 and its system packages (including a specific
numpy), so sourcing it inside the cu132 venv causes two Python paths and two
numpys to collide. Keep them as separate worlds that talk over ROS topics, which
is the intended architecture anyway. If a single process genuinely needs both
torch and ROS, make a --system-site-packages venv rather than pip-installing
ROS into this one.
Install (in a plain terminal, venv deactivated):
sudo apt update && sudo apt install -y locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
sudo apt install -y software-properties-common curl
sudo add-apt-repository universe -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo $VERSION_CODENAME)_all.deb"
sudo apt install -y /tmp/ros2-apt-source.deb
sudo apt update && sudo apt upgrade -y
sudo apt install -y ros-jazzy-desktop # or: ros-jazzy-ros-base ros-jazzy-turtlesim (lighter)
echo "source /opt/ros/jazzy/setup.bash" >> ~/.bashrc
source /opt/ros/jazzy/setup.bashSanity check with turtlesim, in two plain terminals (source ROS in each):
ros2 run turtlesim turtlesim_node # terminal 1
ros2 run turtlesim turtle_teleop_key # terminal 2, arrow keys to driveLeRobot belongs in the same venv as torch because it imports torch directly. The
trap: LeRobot 0.6.0 pins torch<2.12.0, but the only working Orin wheel is the
2.12.1 prerelease. A plain pip install lerobot will "resolve" that by ripping
out your cu132 build and installing a generic torch 2.11.0 that fails on the
Orin with no kernel image available. The version number even matches, so it
looks fine until the first kernel launch.
Install it without deps, then add its extras manually, skipping anything torch-related:
source ~/.venvs/jetson-jp72/bin/activate
pip install lerobot --no-deps
# add LeRobot's runtime deps, pinned to what it wants, with NO torch/torchvision:
pip install \
"cmake>=3.29,<4.2" "draccus==0.10.0" "opencv-python-headless>=4.9,<4.14" \
einops gymnasium huggingface-hub safetensors termcolor tqdm \
"numpy>=2.0,<2.3" "packaging<26.0,>=24.2" "requests<3.0,>=2.32.0"After this, pip check will still report torch, torchvision, and setuptools as
"incompatible" with LeRobot's pins. That is expected and intended: the torch pins
are the soft ceiling you are deliberately overriding (LeRobot 0.6.0 runs fine on
2.12.1 in practice), and setuptools is a cosmetic build-tool nag. Everything else
should be clean.
Never use pip install 'lerobot[extra]'. Any bracketed extras form
(lerobot[feetech], lerobot[deepdiff-dep], etc.) re-resolves the whole
dependency tree and pulls the generic torch 2.11.0 wheel, which silently
replaces your cu132 build with one that fails on the Orin. Install each extra's
underlying package by its bare name instead. The ones the SO101 path needs:
pip install feetech-servo-sdk deepdiffnumpy ABI note (from --system-site-packages). Because the venv can see
system packages, an old system pandas (built against numpy 1.26) can get
imported and crash with numpy.dtype size changed ... binary incompatibility
against your venv's numpy 2.x. Fix by installing a matching pandas into the venv
so it shadows the system one, kept inside LeRobot's numpy ceiling:
pip install --ignore-installed "pandas>=2.2,<2.3" "numpy>=2.0,<2.3"Verify the whole stack coexists (real kernel, not just is_available):
python -c "import torch, torchvision, lerobot, numpy; print('numpy', numpy.__version__); x=torch.randn(1024,1024,device='cuda'); torch.cuda.synchronize(); print('STACK OK', float((x@x).sum()), '| torch', torch.__version__, '| tv', torchvision.__version__, '| lerobot', lerobot.__version__)"STACK OK with torch still on +cu132 means torch, torchvision, and LeRobot all
share the same GPU build. The sm_87 warning is cosmetic (NVIDIA confirmed it is
being removed); the printed number is the proof the kernel ran.
LeRobot 0.6.0 ships hyphenated console scripts (not python -m lerobot.*).
lerobot-find-port # identify the arm portsSerial port permission. The quick fix that works immediately in the current
shell (NVIDIA's SO101 docs list this) is chmod, but it resets on replug:
sudo chmod 666 /dev/ttyACM0 /dev/ttyACM1The permanent fix is the dialout group, but it only takes effect after a full
logout/login (not just a new terminal):
sudo usermod -aG dialout $USERFirst-time arms need their motor IDs set, then calibration, before teleop:
lerobot-setup-motors --teleop.type=so101_leader --teleop.port=/dev/ttyACM0
lerobot-setup-motors --robot.type=so101_follower --robot.port=/dev/ttyACM1
lerobot-calibrate --teleop.type=so101_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_arm
lerobot-calibrate --robot.type=so101_follower --robot.port=/dev/ttyACM1 --robot.id=follower_armThen teleop:
lerobot-teleoperate \
--robot.type=so101_follower --robot.port=/dev/ttyACM1 --robot.id=follower_arm \
--teleop.type=so101_leader --teleop.port=/dev/ttyACM0 --teleop.id=leader_armFailure decoder: Permission denied on the port means the chmod/dialout step
above. Missing motor IDs ... found: {} on an open port means the arm is
unpowered, mis-wired, or its motors were never ID'd (lerobot-setup-motors). Arm
IDs (leader_arm, follower_arm) are labels calibration files key to, so keep
them consistent between calibrate and teleoperate. Other useful scripts:
lerobot-info, lerobot-find-cameras, lerobot-record, lerobot-train.
The whole point of moving to JP7.2 is that it fixes the top domino, and every layer below it falls into place. JP6.2 was a working stack, but only one exact combination worked, and reaching it took source builds and manual library installs. Side by side:
| Layer | JetPack 6.2 (the old way) | JetPack 7.2 (this repo) |
|---|---|---|
| Ubuntu | 22.04 | 24.04 |
| Kernel | 5.15 | 6.8 |
| Flashing | Ubuntu host required | ISO / direct image, no host |
| Python | 3.10 only (3.13 silently pulls CPU torch) | 3.12 |
| CUDA | 12.6 (not on PATH by default) | 13.2 |
| ROS | Humble (Ubuntu 22 tier 1) | Jazzy (Ubuntu 24 tier 1) |
| PyTorch | torch 2.5.0, NVIDIA redist wheel only | torch 2.12.1+cu132 (prerelease, --pre) |
| torchvision | 0.20.0, built from source (MAX_JOBS=2, arch 8.7) |
0.27.1+cu132 (prerelease wheel) |
| numpy | pinned 1.26.0 | 2.2.6 |
| cuSPARSELt | installed by hand | in the CUDA 13 toolkit |
| libcudss | missing on JP6.2, blocked torch 2.8+ | present / installable |
| LeRobot | reinstalls CPU torch unless installed last | --no-deps + bare extras (see below) |
The honest nuance: JP7.2 is not zero-friction. The working torch is a prerelease
cu132 wheel that is undocumented and invisible to normal pip listing, and
LeRobot still tries to pull a wrong-arch torch. But the base OS, CUDA, ROS, and
Python all line up cleanly now, where on JP6.2 every one of those was a fight.
The remaining friction is at the framework edge, not the platform.
This was verified only on Jetson Orin NX 16GB, JetPack 7.2, CUDA 13.2, Python 3.12. If any of those differ:
- Different Orin module (Orin Nano, AGX Orin): same
sm_87arch, so thecu132wheel should work. Verify withverify_stack.pybefore trusting it. - Different CUDA version: the wheel suffix must match. On CUDA 13.0 you'd
need
cu130, on 13.3 acu133build, and so on. Check withnvcc --versionand swap the--extra-index-urlpath accordingly. - Thor / non-Orin (
sm_110+): different architecture entirely. The datacenter wheels that fail on Orin may actually be correct for you. Don't copy the workarounds here without checking yoursm_target. - Python 3.13: no matching wheel for this stack at time of writing. Stay on 3.12 or expect to build from source.
If pip can't find a wheel, diagnose what tags it actually sees:
python -m pip index versions torch --pre --extra-index-url https://download.pytorch.org/whl/cu132
python -m pip debug --verbose | grep -A 30 "Compatible tags"That tells you whether pip sees a compatible cp312 + aarch64 wheel at all.
As of writing, this path is undocumented and relies on prerelease wheels, so
treat it as "works today, may change." If NVIDIA or Seeed publish official
JP7.2 Orin wheels or an r39 container, prefer those. Reported upstream to both.
Maintained as field notes, not official guidance. Corrections welcome.