尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Jetson Orin NX环境配置全攻略:从JetPack到PyTorch避坑指南

Jetson Orin NX环境配置全攻略:从JetPack到PyTorch避坑指南 我拿到Jetson Orin NX开发者套件时第一反应是这不就是一台装了Ubuntu的小电脑吗刷个系统、装个PyTorch、跑通demo前前后后应该不会超过一小时。结果从点亮板子到torch.cuda.is_available()输出True我整整折腾了两个晚上。中间踩过的坑——版本对不上、官方源下载慢、pip装错架构的包——积累起来足够写一本《Jetson环境配置排错手册》。这篇文章就是来填这个坑的。我会从JetPack的选型开始一路讲到PyTorch、torchvision版本对齐、全链路验证把我在Orin NX上实际遇到过的问题和解决办法全部摊开。文章面向所有刚刚入手Orin NX、被环境配置劝退过的开发者无论你打算在上面跑分类模型、做目标检测还是部署大模型推理只要按照这条路线走至少能少熬两个夜。1. 动手前先搞清楚的几个版本问题JetPack、L4T和CUDA的对应关系很多人拿到Orin NX之后绕过的第一个弯就是没搞清楚JetPack到底是什么、L4T和JetPack又是什么关系。JetPack不是某个单一的SDK它是NVIDIA为Jetson平台打包的一整套软件集合里面包含了Linux内核、Ubuntu操作系统叫L4TLinux for Tegra、CUDA、cuDNN、TensorRT、OpenCV、Vulkan驱动等一系列组件。所以JetPack的版本号一旦变了整个软件栈也跟着变。我在配置时最深刻的教训就是不要乱装最新版先查清楚版本兼容矩阵。下面是JetPack 5和JetPack 6几个关键版本的实际对应关系这是我在配置Orin NX时反复核对过的JetPack版本L4T版本Ubuntu版本CUDA版本TensorRT版本JetPack 5.0.235.1.0Ubuntu 20.04CUDA 11.48.4.1JetPack 5.1.135.3.1Ubuntu 20.04CUDA 11.48.5.2JetPack 5.1.235.4.1Ubuntu 20.04CUDA 11.48.5.2JetPack 6.036.3.0Ubuntu 22.04CUDA 12.28.6.1如果你是第一次上手我强烈建议选JetPack 5.1.2。原因很简单大部分第三方教程、预编译wheel包、社区答复都是基于JetPack 5.x写的PyTorch官方论坛里给出的Jetson专用安装包也明确标注了JetPack 5.x对应版本。JetPack 6.0虽然系统更新、CUDA版本也更高但网上适配资料相对少很多库的预编译包还没跟上。还有一个容易忽视的硬件细节Jetson Orin NX模组有8GB和16GB两个版本虽然环境配置的步骤完全一致但16GB版的功耗墙更高对散热要求也更严格。如果你用的是开发套件Developer Kit官方载板的风扇转速策略偏保守跑大模型时芯片很容易过热降频从而配置明明没问题性能却跑不满。这一步需要在系统装好后用jetson_clocks手动拉高性能我在第3章会专门讲。提示判断你的板子当前跑的是哪个JetPack版本最简单的方法是在终端执行apt show nvidia-jetpack或者查看/etc/nv_tegra_release文件。别只看Ubuntu版本号Ubuntu 20.04既可能配JetPack 5.0.2也可能配5.1.2。2. 刷机阶段SDK Manager和手动烧录的取舍与翻车处理Orin NX拿到手之后第一步是把JetPack系统装到板子上。官方推荐的路径是通过SDK Manager工具在x86的Ubuntu主机上把系统刷进开发板。但我必须说清楚SDK Manager并不是一条轻松的路线它要求你有一台装了Ubuntu 20.04或22.04的主机而且需要注册并登录NVIDIA开发者账号。没有Linux主机的话这一路基本走不通。我当时的处理方案是直接下载官方提供的JetPack 5.1.2系统镜像用balenaEtcher把镜像写入一张128GB的TF卡插到Orin NX上直接启动。这种方式对Windows用户非常友好缺点是系统装在TF卡上读写速度不如NVMe SSD后续装PyTorch、跑数据集时会明显感觉到吞吐瓶颈。如果你手头有M.2 NVMe硬盘我建议后续把系统迁移到SSD上迁移方法可以用dd直接整盘拷贝也可以用NVIDIA的官方工具做系统克隆具体操作网上很多这里不展开。如果你坚持走SDK Manager几个我实测过的坑值得重点说第一个坑是恢复模式的识别。Orin NX进入恢复模式的方式是按住载板上的Recovery按键不放再插上USB-C线连接主机最后上电。SDK Manager经常会卡在Device not detected这一步。排查思路很简单先执行lsusb看有没有出现NVIDIA相关的USB设备通常是0955:7d21如果看不到说明恢复模式没进对。我当时是Recovery键按得太早系统已经正常启动了自然进不去恢复模式。正确顺序是板子断电按住Recovery键不要松手插入USB-C线然后接入电源保持2秒再松开Recovery键。第二个坑是刷机过程容易断连。SDK Manager刷写系统时会格式化整个存储介质、写入镜像、然后自动在板子上配置分区。整个过程中板子和主机的USB连接不能被其他操作干扰。我第一次刷的时候插着HDMI线和无线键鼠接收器结果在Writing to target阶段直接断连报了个莫名其妙的错误码。后来把USB设备全部拔掉只保留电源、USB线和网线一次就刷通了。第三个坑是网络环境。SDK Manager刷完系统后会自动去下载CUDA、cuDNN等组件这个下载源在国外经常卡在某一两个包上以极慢的速度爬行。我的建议是刷机时只勾选Host Machine和Target里的系统镜像其他的运行时组件等系统启动后再单独配置不然SDK Manager卡死你都不知道是网络问题还是软件问题。关于网络问题多说一句如果你所在的网络环境访问官方源特别慢可以尝试手动烧录镜像后在板子上把apt源切换到国内镜像。这个操作不影响系统稳定性和安全性只是把下载源替换成国内服务器然后在本地重新验证签名。我用的是阿里云镜像源整体速度提升非常明显下面一章会给出具体的配置命令。3. 系统落地后的头等大事扩容、换源、CUDA环境变量和性能模式系统能正常开机进入Ubuntu桌面或者命令行之后先别急着装PyTorch。这时候的裸系统离能跑深度学习还很远按顺序做完下面四件事后面的路子才会顺。3.1 磁盘扩容官方镜像默认不会吃满你的存储如果你是手动烧录镜像到TF卡或SSD上的启动后第一件事就是看看磁盘分区情况。执行df -h如果显示根分区的总容量远小于你的存储卡实际容量说明系统镜像自带的分区表只给根分区划分了默认大小剩下一大截是未分配空间。JetPack的正常设计是首次启动时自动扩容但某些版本或者某些第三方刷写方式下自动扩容并不会生效。手动扩容很简单我用的是GParted图形界面工具也可以直接用命令行sudo growpart /dev/mmcblk0 1然后sudo resize2fs /dev/mmcblk0p1。具体哪个设备节点取决于系统装在哪个介质上TF卡通常是mmcblk0NVMe通常是nvme0n1。这一步不做的话装完PyTorch、再解压几个数据集磁盘瞬间就红了。3.2 换源让apt和pip的速度回到正常水平Jetson的apt源默认指向英伟达和Ubuntu官方服务器国内访问速度极其感人。我实测下载一个普通的依赖包都要等半天更别提后面要装的那几百MB的PyTorch。换源的核心思路是把/etc/apt/sources.list里的源地址替换成国内镜像再顺手把pip源也换掉。我当时的操作是sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak sudo sed -i s/ports.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sudo sed -i s/archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sudo apt updatepip源的话在~/.pip/pip.conf没有就创建里写入[global] index-url https://mirrors.aliyun.com/pypi/simple/ trusted-host mirrors.aliyun.com如果你用的是清华源还是中科大源效果都差不多。重点是你得知道镜像源只是加速下载不会改变包的内容和依赖关系所以在Jetson上换源是安全的。3.3 CUDA环境变量nvcc永远报command not found刷完JetPack系统里其实已经装好了CUDA 11.4但终端执行nvcc --version大概率会报错。这是因为Jetson镜像里的CUDA默认安装在/usr/local/cuda但它的bin目录并没有加入PATH环境变量。不是没装好是Shell不知道去哪找它。在~/.bashrc文件末尾追加export PATH/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH/usr/local/cuda/lib64:$LD_LIBRARY_PATH export CUDA_HOME/usr/local/cuda然后source ~/.bashrc再执行nvcc --version就能看到CUDA 11.4的版本信息了。这个环境变量在后续编译torchvision、运行包含CUDA扩展的模型代码时非常关键很多人在这一步漏了配置导致后续编译任何CUDA相关代码都报找不到libcudart.so实际上就是动态库路径没对上。3.4 开启性能模式别让风扇策略拖后腿Orin NX默认工作在低功耗模式CPU和GPU频率都被限制在一个保守范围。跑深度学习模型时性能表现会明显低于预期。执行sudo jetson_clocks这个命令会临时把所有CPU/GPU核心提升到最高频率。不过它只对当前开机状态有效重启后需要重新执行。我自己写了一个开机自启动的systemd服务来干这件事[Unit] DescriptionEnable max performance on Jetson Aftermulti-user.target [Service] Typeoneshot ExecStart/usr/bin/jetson_clocks RemainAfterExityes [Install] WantedBymulti-user.target文件放在/etc/systemd/system/jetson-clocks.service然后sudo systemctl enable jetson-clocks即可。这样每次开机自动拉满性能不用手动操作。4. PyTorch安装的正路为什么直接pip install torch必挂到了这篇攻略最核心的阶段装PyTorch。我估计80%的人卡在这一步都是同一个原因——直接执行了pip install torch。Jetson的主处理器是ARM架构aarch64和普通电脑的x86_64架构完全不同。PyPI上默认的torch包是为x86_64和Windows/Mac编译的虽然PyPI上也有aarch64的torch版本但那是给树莓派等通用ARM Linux用的没有针对Jetson的CUDA算力做适配。直接装的话要么pip找不到合适的版本要么装上之后torch.cuda.is_available()返回False因为包内部根本不包含Jetson的CUDA驱动支持。正确的做法是装NVIDIA官方维护的预编译wheel包。NVIDIA在开发者论坛上专门开了一个帖子长期更新针对不同JetPack版本的PyTorch、torchvision、torchaudio的whl文件下载地址。我配置JetPack 5.1.2时实际执行的命令是这样的sudo apt-get update sudo apt-get install -y python3-pip libopenblas-dev libopenmpi-dev libomp-dev pip3 install --no-cache-dir torch2.0.0a07a0e703.nv23.01这里有几个细节值得展开为什么不直接pip install torch而要先装那一堆lib库我的理解是PyTorch在Jetson上依赖OpenBLAS和OpenMPI做CPU和分布式计算加速libomp是OpenMP运行时库多核推理时性能差距非常大。漏装的话PyTorch能装上但运行时会报缺少libgomp.so.1之类的动态库错误。为什么wheel版本带nv或者特定版本号NVIDIA发布的wheel URL会像这样https://developer.download.nvidia.com/compute/redist/jp/v51/pytorch/torch-2.0.0a07a0e703.nv23.01-cp38-cp38-linux_aarch64.whl。注意中间有cp38这代表Python 3.8。Jetson的JetPack 5.x系统默认Python就是3.8不要自己升级Python到3.10或3.11否则所有whl包的cp38标记都会对不上坑会连环踩。不要用sudo pip安装在这条命令里我特意用了pip3 install而没有加sudo因为Jetson系统自带的Python 3.8是系统级Python如果直接用root权限往系统路径里塞包后续升级系统或安装其他库时很容易出现包版本冲突。推荐的方案是给当前用户创建一个虚拟环境python3 -m venv ~/jetson_env source ~/jetson_env/bin/activate pip install --no-cache-dir torch2.0.0a07a0e703.nv23.01我在实际使用中裸系统里直接装包也不至于崩但只要你后面开始装opencv、numpy、scipy、matplotlib这些深度学习常用库版本冲突的机会就会成倍增长。虚拟环境多花两分钟后面能帮你省下半天的时间。还有一类问题是下载超时和连接重置。如果你处在官方下载源访问较慢的网络环境可以先在电脑浏览器上把whl文件下载下来通过U盘或者scp传到板子上然后本地pip install ./torch-xxx.whl。这个方法看起来原始但在大文件下载场景下比用wget断点续传靠谱太多我实际用了很多次。5. torchvision和torchaudio的版本对齐版本不匹配的各种死法装完PyTorch大部分人立刻想跑模型结果import torchvision直接报错。这一步又劝退了很多人因为torchvision的安装不能随便选版本必须和PyTorch版本严格对齐。PyTorch和torchvision的对应关系是官方绑定的PyTorch 2.0对应torchvision 0.15PyTorch 1.13对应torchvision 0.14。如果你在x86电脑上习惯了pip install torchvision自动解析依赖在Jetson上这套行不通因为PyPI上的通用torchvision不会正确匹配Jetson的CUDA版本。你想装一个能用的版本最好是同时从NVIDIA论坛链接下载对应的wheel。我实际安装时的指令这样pip install torchvision0.15.1a08ac987b.nv23.01这个版本号需要到NVIDIA论坛帖子里找到和你PyTorch版本精确对应那一行。注意看whl文件名里的cp38-cp38-linux_aarch64标记和PyTorch的whl一样只有Python 3.8和ARM架构是完全匹配的。如果在版本对齐上偷懒报错会非常诡异。我的一个朋友直接pip install torchvision装上了PyPI上的某个aarch64版本表面看一切正常但一调用torchvision.models.resnet18(pretrainedTrue)就报undefined symbol: _ZN2at6detail...。这种错误就是典型的C符号对不上只能用版本对齐解决网上没有任何其他奇技淫巧。如果NVIDIA只提供了源码包或者你想尝试更新的版本还可以从源码编译torchvision。这条路我不太推荐新手走因为Jetson的CPU编译能力有限我实测从源码编译torchvision 0.14在默认配置下跑了将近四十分钟过程中内存占用也很高。如果你确实需要编译记得先设置好CUDA环境变量第3.3节做的就是这个准备再执行git clone -b v0.15.1 https://github.com/pytorch/vision.git cd vision python setup.py build develop编译前务必确保有至少8GB的磁盘空间以及系统swap足够大否则编译到一半进程会被OOM杀死。关于swap我下一步会讲。torchaudio的情况和torchvision类似如果不是做语音处理可以先不装需要时再去论坛找对齐的wheel。我见过很多人一上来就把三个库全部装齐其实很多项目根本用不上torchaudio反而是多出来的一个潜在版本冲突点。6. 跑通第一个模型的必经之路验证GPU、确认版本、测试完整链路所有库都装好之后别急着上大模型。先用一段最小的代码验证整条链路是否真的通了。我在这一步踩过一个特别隐蔽的坑就是import torch能成功但torch.cuda.is_available()返回False。import torch print(PyTorch 版本:, torch.__version__) print(CUDA 是否可用:, torch.cuda.is_available()) print(GPU 名称:, torch.cuda.get_device_name(0) if torch.cuda.is_available() else 无)正常状态下应该输出PyTorch 版本: 2.0.0a07a0e703.nv23.01、CUDA 是否可用: True、GPU 名称: NVIDIA Orin NX实际名称可能是Orin或NVIDIA Tegra Xn不同jetpack版本显示不同。如果输出的是False百分之九十的原因是你装的torch不是NVIDIA提供的Jetson版本而是通用ARM Linux版本。这种版本在树莓派上可以正常用CPU跑模型但根本不包含CUDA支持。检查方法是打印torch.version.cuda如果显示为空或者和系统CUDA版本对不上基本可以确认是装错包了回到第4章重新下载正确的wheel。链路验证通过之后我习惯用一个小模型跑一次推理确认GPU真的参与了计算。一个标准做法是import torch import torchvision.models as models model models.resnet18(weightsmodels.ResNet18_Weights.DEFAULT) model model.cuda().eval() x torch.randn(1, 3, 224, 224).cuda() with torch.no_grad(): y model(x) print(推理输出形状:, y.shape)这段代码能在GPU上跑通说明PyTorch的CUDA算子库ATen正常、cuDNN的卷积算子正常、显存分配正常。我再加一个观察技巧跑推理的同时在另一个终端看GPU占用执行sudo tegrastats这里会持续输出CPU频率、GPU频率、内存占用、温度等信息。如果你的GPU频率在推理期间能稳定跳到1.2GHz以上说明设备确实在满负荷工作而不是在CPU端模拟计算。这个工具比nvidia-smi在Jetson上更实用因为Jetson没有独立的nvidia-smi命令tegrastats才是原生的监控工具。跑完整链路后顺带验证一下CPU推理和GPU推理的速度差异。拿ResNet18对同一张224x224的输入各跑50次统计平均耗时。在Orin NX上GPU推理通常能做到CPU推理耗时的六分之一到十分之一。这个对比不仅让你心里有底气还能在向别人展示平台性能时拿出实打实的数据。7. 我踩过的几个低频但真要命的坑swap不足、Python版本、Docker容器、意外断电核心链路跑通只是开始。真正让我头疼的往往是那些装完软件之后隔三差五冒出来的小毛病。这里集中写几个低频但一旦中招就特别耗时的问题遇到的概率不高但中了任何一个都很要命。7.1 swap空间不足导致编译被OOM杀死Orin NX的内存是LPDDR5统一内存PyTorch和CUDA会共享这块内存。虽然16GB版的内存不算小但在编译大型库、加载大模型、跑数据增强时内存依然会被迅速打满。系统默认的swap空间很小一旦内存耗尽内核的OOM Killer会直接杀掉占用最高的进程表现在你的终端上就是Killed一个词没有任何其他报错。解决方法是手动扩大swap。我个人的经验是至少加到8GBsudo fallocate -l 8G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile如果重启后swap失效还需要在/etc/fstab里加一行/swapfile swap swap defaults 0 0。我当初编译一些大的C扩展时被Killed折磨了一下午加了swap之后世界清净了。7.2 不要手痒升级Python版本JetPack 5.1.2的系统Python是3.8NVIDIA所有预编译库都针对这个版本。我看到很多教程第一步就是升级到Python 3.10在Jetson上这基本等于自掘坟墓。你可能觉得Python 3.10更新、特性更多但所有whl包里的cp38标记会直接让你寸步难行。就算你保留系统Python、另装一个Python 3.10编译OpenCV、PyTorch扩展时依然会出各种兼容性报错。如果你确实需要更新Python版本的特性我的建议是使用miniforge安装一个独立的conda环境在conda环境里管理Python版本和库系统Python保持不动。不过这么做的代价是conda环境里的包大部分需要走conda源或者编译速度比直接用系统的Pip慢不少我个人最终放弃了这条路老老实实呆在Python 3.8。7.3 Docker容器的诱惑与坑NVIDIA官方提供了Jetson容器的支持理论上可以用nvcr.io/nvidia/l4t-pytorch这样的容器镜像直接跑深度学习的开发环境。这种方式的优势是环境隔离、版本干净非常适合在不同项目之间切换。但实际上我在Orin NX上跑Docker容器时发现容器里的PyTorch版本是NVIDIA预先固定好的你想装一个新的包往往需要同时升级容器里的CUDA依赖层而容器镜像动辄几个GB拉取一次要等很久。我的最终选择是物理环境虚拟环境混用日常项目用venv管理需要干净环境测试时再用Docker。如果你也是第一次配置不建议在Docker上花费太多时间——先把物理环境跑通容器化是后话。7.4 意外断电后的系统损坏Jetson开发板用TF卡和SSD启动时环境配置耗电量大如果供电不足或者手不小心碰掉电源线很容易导致文件系统损坏。我亲身经历过一次中断apt install的瞬间断电重启后直接进入initramfs的busybox界面也就是系统无法正常挂载根文件系统。这是最让我头疼的一次故障。修复方法倒不复杂如果有备份镜像直接重新刷机最快如果没有备份可以尝试在initramfs界面执行fsck /dev/mmcblk0p1修复文件系统然后重启。但实际上环境配置完一次不容易所以我后来给自己定了一条规矩在Jetson上做重要安装操作时接一个UPS或者至少确保电源线没有松动同时定期用dd备份系统盘镜像。板子上的数据永远比重新配置省下的那点时间值钱。8. 配置完成后的性能基准测试与日常使用心得所有环境都配好、第一个模型跑通之后我建议再做一次简单的性能基准测试把平台能力记录下来。不是为了跑分好看而是以后排查问题时有个对照基线模型跑得异常慢时能快速判断是环境退化了还是代码本身的问题。我平时的测试方式是用现成的脚本比如用torch的torch.utils.bottleneck去分析模型各层的耗时或者手工构建一个简单的大矩阵乘法import torch import time a torch.randn(4096, 4096, devicecuda) b torch.randn(4096, 4096, devicecuda) # 预热 for _ in range(10): torch.matmul(a, b) torch.cuda.synchronize() # 计时 t0 time.time() for _ in range(50): torch.matmul(a, b) torch.cuda.synchronize() print(f4096x4096矩阵乘法平均耗时: {(time.time() - t0) / 50 * 1000:.2f} ms)Orin NX在满频状态下跑这个矩阵乘法单次耗时一般在几毫秒到十几毫秒之间具体数值和功耗模式、散热状态、当前CPU/GPU负载都有关。个人经验是把sudo jetson_clocks开着跑比默认模式能快出将近30%。日常开发中还有一个非常实用的工具是jetson-stats以系统服务方式运行提供网页监控页面。安装方式sudo pip install jetson-stats sudo jtopjtop是一个类似htop的交互界面可以看到CPU每核心频率、GPU频率、内存/显存占用、温度、供电状态还会列出当前正在运行的关键进程。我用它最多的场景是确认模型推理时GPU到底有没有跑起来以及瓦数是否达到预期上限。从JetPack刷机到PyTorch全链路跑通整个过程比配置普通服务器麻烦得多但Jetson平台的魅力在于所有CUDA生态都在一块巴掌大的板子上。这套环境一旦配好后面所有深度学习相关的项目都会变得非常顺手。根据我个人经验环境配置里的大多数问题都不是能力问题而是信息差问题——知道正确版本号、正确wheel链接、正确环境变量一切都能水到渠成。希望这篇攻略能帮你跨过那些我踩过的坑。
返回列表