ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Jetson 上 Docker 跑 yolov5:环境构建与摄像头推理实战

Jetson 上 Docker 跑 yolov5:环境构建与摄像头推理实战 简介这份资源面向在 NVIDIA Jetson 系列如 Jetson Nano上部署目标检测的开发者提供一套用于构建 YOLOv5 推理 Docker 镜像的工程文件解决 Jetson 平台环境配置繁琐、依赖版本易冲突的问题。压缩包共 9 个文件约 4KB包含 Dockerfile 与 patch 补丁用于镜像构建build.sh、run.sh 两个 Shell 脚本分别负责编译镜像和调用摄像头推理另有 README 说明、LICENSE 授权文件及若干 txt 配置记录整体结构精简、开箱即用。目前已有 52 人学习下载。借助这套文件读者可快速在 Jetson 上拉起带 NVIDIA runtime 的容器直接检测 /dev/video0 摄像头画面并支持挂载自定义权重如 my-weights.pt替换模型省去手动配置 PyTorch 与 CUDA 环境的重复劳动适合具备一定 Linux 与容器基础、希望快速验证边缘端 YOLOv5 推理效果的开发者参考。1. 为什么要在 Jetson 上用 Docker 跑 yolov5一次把环境折腾清楚手里有一块 NVIDIA Jetson想跑 yolov5 做目标检测最省事的路径其实不是 pip install 一堆依赖而是直接用 Docker 把整个推理环境封起来。这份资源就是一个专门为 Jetson 平台准备的 yolov5 推理 Dockerfile 包里面包含 Dockerfile、build.sh、run.sh、is_docker.patch、LICENSE、README 等文件目标很明确在 Jetson 上构建一个名为 yolov5 的镜像然后直接调用 /dev/video0 摄像头做实时检测。它解决的是 Jetson 上 CUDA、cuDNN、PyTorch、torchvision 版本互相打架的老问题适合已经有一块 Jetson Nano、Xavier 或 Orin想快速验证 yolov5 推理效果又不想把系统环境搞乱的人。下面按「资源是什么 → 怎么构建 → 怎么跑 → 坑在哪 → 怎么进阶」的顺序拆一遍。2. 拆开这个 Dockerfile 包文件清单与 Jetson 基础镜像选型2.1 压缩包里到底有什么拿到用于 NVIDIA Jetson 上 yolov5 推理的 Dockerfile.zip之后先别急着解压就 build。把文件列出来看一眼心里有个数文件作用Dockerfile核心构建脚本定义基础镜像、依赖安装、代码拷贝build.sh封装 docker build默认构建名为 yolov5 的镜像run.sh封装 docker run挂载摄像头、显示、权重等is_docker.patch补丁文件让 yolov5 代码识别自己跑在容器里README.md原始说明包含构建和运行命令LICENSE开源协议.gitignore忽略规则标签.txt / 资源内容.txt辅助说明文件这个包不是 yolov5 源码本身而是一层「构建外壳」。它假设你已经把 yolov5 代码放在某个目录或者 Dockerfile 里会去拉取。常见做法是 Dockerfile 里用git clone拉 ultralytics/yolov5或者 COPY 本地已下载的源码。不管哪种先确认 Dockerfile 里的路径和你的实际目录对得上。2.2 为什么基础镜像必须选 l4t 而不是 ubuntuJetson 是 ARM64 架构GPU 驱动和 CUDA 是打包在 NVIDIA 的 L4TLinux for Tegra里的不是普通 x86 上那种单独装驱动的方式。如果你用ubuntu:20.04做基础镜像里面没有 Jetson 的 CUDA 运行时--runtime nvidia也挂不进去。所以 Dockerfile 里基础镜像通常是nvcr.io/nvidia/l4t-pytorch或者nvcr.io/nvidia/l4t-base再加 PyTorch wheel。选型理由很直接l4t-pytorch 镜像已经预装了对应 JetPack 版本的 PyTorch 和 torchvision省去自己编译 ARM64 wheel 的麻烦。Jetson Nano 常见 JetPack 4.6 对应 l4t-pytorch:r32.7.1-pth1.10-py3 这类标签。如果你的 JetPack 版本和镜像标签不匹配后面 import torch 会直接报 CUDA 不可用。提示先跑cat /etc/nv_tegra_release确认 L4T 版本再决定 Dockerfile 里 FROM 哪一行。版本对不上是后面 90% 玄学问题的根源。2.3 Dockerfile 关键层拆解一个典型的 Jetson yolov5 Dockerfile 会长这样我按层说明# 基础镜像必须匹配 JetPack/L4T 版本 FROM nvcr.io/nvidia/l4t-pytorch:r32.7.1-pth1.10-py3 # 安装系统依赖opencv 相关库不能少 RUN apt-get update apt-get install -y \ python3-pip python3-dev \ libopenblas-base libopenmpi-dev \ libjpeg-dev zlib1g-dev \ rm -rf /var/lib/apt/lists/* # 安装 yolov5 推理需要的 python 包 RUN pip3 install --no-cache-dir \ numpy opencv-python \ pyyaml tqdm matplotlib WORKDIR /opt # 拉取 yolov5 源码也可改成 COPY 本地目录 RUN git clone https://github.com/ultralytics/yolov5.git WORKDIR /opt/yolov5 RUN pip3 install --no-cache-dir -r requirements.txt # 应用补丁让代码在容器内正常工作 COPY is_docker.patch /opt/yolov5/ RUN git apply is_docker.patch || true CMD [python3, detect.py, --source, 0]逻辑说明FROM 决定 CUDA 和 PyTorch 版本apt 层装 OpenCV 依赖pip 层装推理包git clone 拉源码patch 解决容器内路径或显示问题。参数上--no-cache-dir减小镜像体积git apply ... || true是防止补丁已应用导致构建中断。2.4 build.sh 做了什么build.sh一般就一行核心命令#!/bin/bash docker build -t yolov5 .但实际用的时候Jetson 上构建慢网络拉包容易断。常见做法是加上--network host让构建时走宿主机网络或者提前把 pip 源换成国内镜像。如果构建失败README 里提到用--no-cache清缓存./build.sh --no-cache对应脚本里应该把参数透传给 docker build。这一步的坑在于Jetson Nano 内存只有 4GBpip 安装 torch 相关包时可能 OOM建议先加 swap 或者用预装 PyTorch 的 l4t 镜像避免重装。3. 从 build 到 run把摄像头检测跑起来的完整命令链3.1 构建镜像前的三项检查在敲./build.sh之前先确认三件事否则大概率翻车第一Docker 是否已安装并配置 nvidia runtime。跑docker info | grep -i runtime应该看到nvidia。没有的话需要改/etc/docker/daemon.json加default-runtime: nvidia然后重启 docker。第二当前用户是否在 docker 组。groups里没有 docker 就得sudo usermod -aG docker $USER然后重新登录否则每条命令都要 sudo。第三磁盘空间。Jetson 板载 eMMC 通常只有 16GBl4t-pytorch 镜像本身就好几个 G构建完可能爆盘。用df -h看一眼不够就挂个 USB 盘或者清理旧镜像。3.2 执行构建与失败排查检查完就构建chmod x build.sh run.sh ./build.sh构建过程会拉基础镜像、装依赖、clone yolov5。Jetson Nano 上这一步可能 20 分钟到 1 小时。如果中途报错先看错误类型拉基础镜像超时网络问题换源或重试。pip 安装 Killed内存不足加 swap。git clone 失败网络或仓库地址问题。git apply报错补丁和源码版本不匹配可以手动看 patch 内容再决定是否跳过。构建失败后按 README 建议清缓存重来./build.sh --no-cache--no-cache会强制每一层重新执行适合依赖层被污染的情况但耗时更长。3.3 run.sh 与摄像头设备映射构建成功后run.sh负责把容器跑起来。核心是设备映射和显示转发#!/bin/bash xhost local:docker docker run -it --rm \ --runtime nvidia \ --network host \ --device /dev/video0:/dev/video0:mrw \ -e DISPLAY$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ yolov5逐项说明--runtime nvidia让容器能用 Jetson GPU--network host共享宿主机网络方便某些需要联网的场景--device /dev/video0把摄像头透传进容器:mrw是读写权限-e DISPLAY和-v /tmp/.X11-unix让容器里的 OpenCV 窗口能显示到宿主机桌面xhost local:docker是放行 X11 访问。注意xhost local:docker会放宽 X11 权限用完可以xhost -local:docker收回。在多人共用的 Jetson 上尤其要留意。3.4 用自带权重跑一次检测默认 run.sh 可能用 yolov5 官方权重。如果你想确认整条链路通不通先跑默认的./run.sh容器启动后会执行 detect.pysource 指向 0 即 /dev/video0。如果窗口弹出并画出检测框说明 CUDA、摄像头、显示三件事都对了。如果窗口黑屏或者报cannot open display回到 3.3 检查 X11 转发。3.5 换成自己的权重README 里给了自定义权重的做法。假设你训练好的权重叫my-weights.pt放在宿主机/path/to/weightsmkdir -p /path/to/weights cp my-weights.pt /path/to/weights xhost local:docker docker run -it --rm \ --runtime nvidia \ --network host \ --device /dev/video0:/dev/video0:mrw \ -e DISPLAY$DISPLAY \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -v /path/to/weights:/weights \ yolov5 \ python3 detect.py --weights /weights/my-weights.pt --source 0关键变化是加了一个-v /path/to/weights:/weights把宿主机权重目录挂进容器然后在命令末尾覆盖 CMD指定--weights和--source。这样不用重建镜像就能换模型。参数上--source 0是摄像头也可以换成--source /videos/test.mp4跑视频文件或者--source /images跑图片目录。4. 避坑与排查Jetson 上跑 yolov5 容器的五条血泪经验4.1 现象容器里 torch.cuda.is_available() 返回 False原因基础镜像的 L4T 版本和宿主机 JetPack 不匹配或者 docker 没有用 nvidia runtime 启动。Jetson 的 CUDA 不是容器内自带的而是通过 runtime 从宿主机挂进去的。解决先cat /etc/nv_tegra_release看宿主机 L4T 版本再确认 Dockerfile 的 FROM 标签对应同一版本。然后检查docker run是否带了--runtime nvidia以及/etc/docker/daemon.json里 default-runtime 是否为 nvidia。4.2 现象构建到 pip install 时进程被 Killed原因Jetson Nano 内存 4GBpip 编译或安装大包时内存耗尽OOM killer 直接杀进程。解决临时加 swap。常见做法是创建一个 4GB swap 文件sudo fallocate -l 4G /swapfile sudo chmod 600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile构建完可以sudo swapoff /swapfile关掉。另一个办法是直接用预装 PyTorch 的 l4t-pytorch 镜像避免在容器里重装 torch。4.3 现象run.sh 报 cannot open display 或窗口不弹出原因X11 转发没配好。容器里的 OpenCV 需要访问宿主机的 X serverDISPLAY环境变量和/tmp/.X11-unix挂载缺一不可。解决确认宿主机当前桌面会话下echo $DISPLAY有值通常是:0或:1run 命令里-e DISPLAY$DISPLAY要传对。xhost local:docker必须在 run 之前执行。如果是 SSH 远程连 JetsonX11 转发更麻烦建议直接接显示器操作。4.4 现象摄像头打不开报 /dev/video0 不存在或权限拒绝原因设备映射路径不对或者宿主机上摄像头不是 video0。也可能是权限问题容器内用户没有读写权限。解决宿主机先ls /dev/video*确认摄像头编号可能是 video1。run 命令里--device改成实际路径。权限上:mrw已经给了读写如果还不行检查宿主机/dev/video0的属组必要时sudo chmod 666 /dev/video0临时验证。4.5 现象换了自定义权重后检测结果全是乱框或没有框原因权重和 yolov5 代码版本不匹配或者类别数、输入尺寸对不上。yolov5 不同版本的模型结构有差异用 v6 的权重跑 v7 的代码可能加载失败或输出错乱。解决确认训练权重时用的 yolov5 版本和容器里 clone 的代码版本一致。可以在 detect.py 里加--img-size显式指定输入尺寸和训练时保持一致。如果权重是自定义数据集训练的还要确认--classes或 data yaml 里的类别名对得上。5. 进阶把镜像做小、把推理做稳的几个实操技巧5.1 多阶段构建压缩镜像体积Jetson 存储紧张镜像能小则小。常见做法是用多阶段构建把编译依赖留在构建阶段运行阶段只拷贝必要文件# 构建阶段 FROM nvcr.io/nvidia/l4t-pytorch:r32.7.1-pth1.10-py3 AS builder RUN pip3 install --no-cache-dir -r requirements.txt # 运行阶段 FROM nvcr.io/nvidia/l4t-pytorch:r32.7.1-pth1.10-py3 COPY --frombuilder /usr/local/lib/python3.6/dist-packages /usr/local/lib/python3.6/dist-packages COPY --frombuilder /opt/yolov5 /opt/yolov5 WORKDIR /opt/yolov5 CMD [python3, detect.py, --source, 0]这样构建阶段的临时文件和缓存不会进最终镜像。参数上注意 Python 路径要和基础镜像里的版本一致Jetson JetPack 4.x 通常是 Python 3.6。5.2 用 TensorRT 加速推理yolov5 在 Jetson 上直接跑 PyTorch 推理帧率有限Nano 上可能只有几帧。进阶做法是导出 TensorRT enginepython3 export.py --weights my-weights.pt --include engine --device 0然后在 detect.py 里指定--weights my-weights.engine。TensorRT 会针对 Jetson GPU 做层融合和精度校准帧率通常能翻倍。注意 engine 文件是和具体设备、TensorRT 版本绑定的换设备要重新导出。5.3 验证推理是否真的走了 GPU有时候你以为在用 GPU其实 PyTorch 悄悄回退到 CPU 了。跑一次检测时在容器里开另一个终端docker exec -it container_id bash python3 -c import torch; print(torch.cuda.is_available(), torch.cuda.get_device_name(0))输出应该是True和 Jetson 的 GPU 名称。如果 False回到 4.1 排查。另一个办法是跑 detect.py 时加--device 0显式指定避免自动选择出错。5.4 一个我踩过的坑有次在 Jetson Nano 上构建怎么都跑不起来最后发现是 Dockerfile 里 clone 的 yolov5 是最新 master而 l4t-pytorch 镜像里的 PyTorch 版本太老某些新算子不支持。从那以后我每次构建前都强制在 Dockerfile 里 checkout 一个和 PyTorch 版本匹配的 yolov5 tag而不是直接用 master。这个习惯帮我省了很多次重新构建的时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表