1. 从零到一为什么选择EasyDL加Jetson Nano这条技术路线搞过边缘端视觉项目的人都有一个共同的痛模型训练和硬件部署之间隔着一道巨大的鸿沟。训练的时候在服务器上跑得好好的模型一到嵌入式设备上就各种水土不服——推理速度慢、内存爆掉、算子不支持折腾几天都跑不起来。我自己在这个坑里来回摔了好几次后来摸索出一套相对省心的组合方案用EasyDL做目标检测模型的训练再把它部署到Jetson Nano上。这套方案最大的好处是训练侧几乎不需要写代码部署侧又有成熟的推理框架可以调用特别适合那些算法基础一般但需要快速出原型的开发者。先说说EasyDL是什么。它是百度飞桨生态下的一个零门槛AI开发平台核心卖点就是可视化操作——你不需要写训练脚本不需要配环境上传标注好的数据集选好模型类型和训练参数点一下“开始训练”就行。对于目标检测任务它支持物体检测模型底层用的是PP-YOLO系列或者YOLOv3的变体精度和速度在同类轻量模型中算是比较均衡的。而Jetson Nano是英伟达推出的一款边缘计算开发板四核ARM Cortex-A57处理器加128核Maxwell GPU4GB内存功耗只有5到10瓦价格也亲民是做边缘视觉推理的经典选择。那为什么要把这两个东西凑到一起原因很直接EasyDL解决了“不会训模型”的问题Jetson Nano解决了“没有推理硬件”的问题。你可以在EasyDL上花几个小时训练出一个可用的检测模型然后导出成ONNX或者TensorRT格式再在Jetson Nano上用TensorRT或者DeepStream做加速推理。整个流程走通之后从数据标注到边缘部署快的话一天之内就能搞定。这套方案特别适合做智能安防、工业质检、零售分析这类场景的原型验证也适合学生做课程设计或者竞赛项目。不过我得提前说清楚这条路虽然门槛低但坑并不少。EasyDL导出的模型格式和Jetson Nano上的推理引擎之间需要做转换转换过程中经常会遇到算子不支持、输入输出维度对不上、精度损失等问题。后面我会把这些坑一个个拆开讲把每个环节的操作细节和注意事项都交代清楚。2. 数据集准备与EasyDL训练全流程拆解2.1 数据采集与标注的实操要点目标检测任务的数据集质量直接决定了模型的上限这一点在EasyDL上尤其明显因为它的自动化程度高你很难在训练过程中做精细的调参来弥补数据缺陷。我一般建议至少准备200到500张图片每个类别至少150个标注框否则模型很容易过拟合或者漏检严重。数据采集阶段要注意几个事情。第一图片的多样性要够同一个目标在不同角度、不同光照、不同背景下都要有样本。比如你要检测安全帽不能只拍正面戴帽子的照片还要有侧面、背面、远距离、部分遮挡的情况。第二图片分辨率不要太高建议控制在1280x720以内因为Jetson Nano的推理分辨率通常不会超过640x640太高的分辨率在训练时会被压缩反而浪费标注精力。第三负样本要适量加入也就是那些不包含目标物体的图片比例大概占总数的10%到20%这样可以降低误检率。标注工具我用的是LabelImg开源免费支持Pascal VOC和YOLO格式导出。标注的时候有几个细节要注意边界框要尽量贴紧目标边缘不要留太多空白对于被遮挡的目标如果可见部分超过50%还是要标出来对于模糊不清的目标宁可不标也不要标错因为错误标注对模型的伤害比漏标更大。标注完成后EasyDL支持直接导入VOC格式的压缩包也可以用它自带的标注工具在线标注但在线标注效率比较低不推荐大规模使用。2.2 EasyDL平台上的模型训练配置数据准备好之后登录EasyDL平台创建一个物体检测项目。在数据导入环节把标注好的压缩包上传上去平台会自动解析标注文件并生成数据集概览。这里有一个容易忽略的点EasyDL会自动把数据集按比例划分成训练集和验证集默认是8比2但你可以在高级设置里手动调整。我的经验是如果数据量少于300张建议用9比1让更多数据参与训练如果数据量超过1000张8比2甚至7比3都可以。训练配置环节有几个关键参数需要关注。第一个是网络类型EasyDL提供高精度和轻量级两种选择。高精度模型精度更高但推理速度慢轻量级模型速度快但精度会降一些。对于Jetson Nano部署场景我强烈建议选轻量级因为Nano的算力有限高精度模型跑起来帧率会很难看。第二个是训练轮数epoch默认是100轮但实际测试下来大部分任务在50到80轮就收敛了你可以先跑50轮看看验证集上的mAP曲线如果还在上升就继续加轮数。第三个是批量大小batch size这个取决于你的数据集大小和平台资源一般保持默认就行。训练启动之后EasyDL会显示实时的损失曲线和精度曲线。这里要提醒一句不要只看训练集上的精度一定要关注验证集上的表现。如果训练集精度一直在涨但验证集精度停滞甚至下降那就是过拟合了需要增加数据量或者减少训练轮数。训练完成后平台会给出模型评估报告包括mAP、精确率、召回率等指标。一般来说mAP在0.7以上就算可用0.8以上算不错0.9以上就非常好了。2.3 模型导出与格式选择训练完成后最重要的一步是导出模型。EasyDL支持多种导出格式包括ONNX、TensorRT、Paddle Inference等。对于Jetson Nano部署我推荐两个方案一是导出ONNX然后在Jetson Nano上用TensorRT做转换和推理二是直接导出TensorRT引擎文件但这个需要你在导出时指定目标设备的算力版本操作稍微复杂一些。导出ONNX的时候要注意opset版本建议选opset 11或者12太新的版本TensorRT可能不支持太旧的版本又会丢失一些算子信息。导出完成后你会得到一个.onnx文件和一个标签文件label.txt标签文件里记录了每个类别对应的名称和ID后面在Jetson Nano上做后处理的时候会用到。这里有一个非常关键的注意事项EasyDL导出的ONNX模型默认输入尺寸是640x640但实际部署时你可以根据需求调整。如果Jetson Nano的帧率不够可以降到416x416甚至320x320精度会降一些但速度会明显提升。输入尺寸的调整需要在导出时指定导出后就不能改了所以要想清楚再操作。3. Jetson Nano环境搭建与模型部署实战3.1 系统烧录与基础环境配置Jetson Nano拿到手之后第一件事是烧录系统。你需要一张至少32GB的microSD卡推荐用Class 10以上的高速卡因为系统和模型文件都放在卡上卡的速度直接影响读写性能。烧录工具用官方的SDK Manager或者balenaEtcher都行镜像文件从官方渠道下载。烧录完成后把卡插入Nano接上显示器、键盘、鼠标上电启动按照提示完成初始设置。系统起来之后第一件事是换源和更新。默认的软件源在国内访问速度很慢建议换成国内镜像源具体操作是编辑/etc/apt/sources.list文件把里面的网址替换成国内镜像地址。换源之后执行sudo apt update sudo apt upgrade这个过程可能需要十几分钟耐心等待。接下来是安装基础依赖。Jetson Nano默认已经装了CUDA和cuDNN但TensorRT可能需要手动安装或者更新。你可以用dpkg -l | grep tensorrt查看当前版本如果版本太低建议从官方渠道下载对应JetPack版本的TensorRT重新安装。另外Python环境建议用Python 3.6或者3.8太新的版本可能会有兼容性问题。pip安装包的时候记得加--no-cache-dir参数因为Nano的存储空间有限缓存文件会占用不少空间。还有一个容易被忽略的点Jetson Nano的默认功耗模式是5WGPU频率被限制在较低水平。如果你对推理速度有要求可以切换到10W模式命令是sudo nvpmodel -m 0然后用sudo jetson_clocks把频率锁定在最高。这样做的代价是发热增加建议加一个小风扇或者散热片否则长时间跑推理可能会降频。3.2 ONNX模型转TensorRT引擎模型部署的核心步骤是把ONNX模型转成TensorRT引擎。TensorRT是英伟达的推理加速库它会对模型做算子融合、精度量化、内存优化等一系列操作让模型在Nano上跑得更快。转换的过程可以用Python脚本完成也可以用trtexec命令行工具。我用的是Python脚本方式因为更灵活可以在转换时指定各种参数。核心代码大概长这样import tensorrt as trt TRT_LOGGER trt.Logger(trt.Logger.WARNING) builder trt.Builder(TRT_LOGGER) network builder.create_network(1 int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser trt.OnnxParser(network, TRT_LOGGER) with open(model.onnx, rb) as f: parser.parse(f.read()) config builder.create_builder_config() config.max_workspace_size 1 30 # 1GB config.set_flag(trt.BuilderFlag.FP16) # 开启FP16量化 engine builder.build_engine(network, config) with open(model.trt, wb) as f: f.write(engine.serialize())这段代码的关键点有几个。第一EXPLICIT_BATCH标志必须加否则batch维度会出问题。第二max_workspace_size设置成1GBNano的内存有限不要设太大。第三FP16量化标志建议开启可以让推理速度提升30%到50%精度损失通常在1%以内完全可以接受。转换过程中最常见的报错是“unsupported operator”也就是ONNX里有TensorRT不支持的算子。遇到这种情况你需要找到对应的算子要么在导出ONNX时替换成支持的算子要么在TensorRT里自定义插件。EasyDL导出的模型一般不会有太冷门的算子但如果你自己改了网络结构就要注意这个问题。3.3 推理脚本编写与性能调优引擎文件生成之后就可以写推理脚本了。推理脚本的核心流程是读取图片、预处理、送入引擎推理、后处理、输出结果。预处理主要是resize和归一化后处理主要是解析输出张量、做NMS非极大值抑制、画框。预处理的时候要注意EasyDL训练时用的归一化参数是均值和标准差都是0.5也就是把像素值从0到255映射到-1到1之间。如果你在推理时用了不同的归一化方式精度会明显下降。后处理的NMS阈值一般设0.5置信度阈值设0.3到0.5之间具体值要根据实际场景调。如果误检多就提高置信度阈值如果漏检多就降低阈值。性能调优方面有几个实用的技巧。第一用多线程或者多进程做预处理和后处理让GPU专注于推理这样可以提升整体吞吐量。第二如果输入图片尺寸比较大可以先缩放到模型输入尺寸再送入引擎不要在引擎内部做resize。第三如果帧率还是不够可以考虑降低输入分辨率或者减少模型层数但这需要重新训练模型。实测下来一个轻量级的PP-YOLO模型在Jetson Nano上输入640x640FP16精度推理速度大概在15到20帧每秒。如果降到416x416可以到25到30帧每秒。这个速度对于大部分实时检测场景已经够用了。4. 常见问题排查与避坑经验实录4.1 模型转换与推理阶段的典型报错在ONNX转TensorRT的过程中最常遇到的报错是维度不匹配。比如ONNX模型的输入是[1, 3, 640, 640]但TensorRT期望的是[1, 640, 640, 3]这时候就需要在转换脚本里显式指定输入维度。还有一种情况是输出层的维度对不上这通常是因为EasyDL导出的ONNX包含了后处理算子而TensorRT又自己做了一遍后处理导致重复。解决办法是在导出ONNX时去掉后处理部分只保留主干网络。推理阶段的报错主要集中在内存不足上。Jetson Nano只有4GB内存系统和各种服务占掉一部分留给模型推理的可能只有2GB左右。如果你的模型比较大或者batch size设得太大就会报“out of memory”。解决办法是减小batch size或者用torch.cuda.empty_cache()清理缓存。另外推理脚本里不要加载不必要的库比如matplotlib、scipy这些能省不少内存。还有一个比较隐蔽的问题是精度下降。你可能会发现TensorRT推理的结果和ONNX推理的结果有差异这通常是FP16量化导致的。如果差异在可接受范围内比如mAP降了1到2个点那就没问题如果差异很大就要检查是不是某些层不适合FP16量化可以尝试把这些层设成FP32。4.2 部署后的性能瓶颈与优化方向部署完成后如果发现帧率不达标需要一步步排查瓶颈在哪里。首先用tegrastats命令查看CPU、GPU、内存的占用情况。如果GPU占用率很低但CPU占用率很高说明瓶颈在预处理或者后处理上需要优化这部分代码。如果GPU占用率很高但帧率还是低说明模型本身太重需要考虑换更轻量的模型或者降低输入分辨率。另一个常见的瓶颈是数据传输。如果推理脚本是从磁盘读取图片再送入GPU磁盘IO可能会成为瓶颈。解决办法是把图片预先加载到内存里或者用视频流代替图片序列。如果是用摄像头实时采集要注意摄像头的分辨率和帧率设置不要设得太高否则采集本身就会拖慢整体速度。还有一个容易被忽略的点是电源管理。Jetson Nano在5W模式下GPU频率被限制在较低水平推理速度会明显下降。切换到10W模式后帧率通常能提升30%以上。但要注意散热如果温度超过80度Nano会自动降频保护反而更慢。所以散热措施一定要做好至少加一个散热片最好再加个小风扇。4.3 常见问题速查表问题现象可能原因排查方法解决方案ONNX转TensorRT报unsupported operatorONNX包含TensorRT不支持的算子用Netron查看ONNX结构替换算子或自定义插件推理时报out of memorybatch size太大或模型太大用tegrastats查看内存占用减小batch size或换轻量模型推理结果与ONNX不一致FP16量化导致精度损失对比ONNX和TensorRT的输出部分层改用FP32帧率低于预期预处理后处理耗时过长用计时函数分段测量多线程处理或优化代码运行一段时间后降频温度过高触发保护用tegrastats查看温度加强散热或降低功耗模式摄像头采集卡顿分辨率或帧率设置过高检查摄像头参数降低分辨率或帧率5. 从原型到落地这套方案的适用边界与扩展思路这套EasyDL加Jetson Nano的方案我前后在好几个项目里用过有做智能门禁的有做工地安全帽检测的也有做零售货架分析的。整体感受是它非常适合快速验证想法从数据标注到边缘部署最快一天就能跑通。但如果你要做产品级的东西还有一些地方需要补强。首先是数据闭环。EasyDL训练出来的模型在实际场景中总会遇到漏检误检的情况。你需要建立一个反馈机制把部署端推理错误的样本收集起来重新标注后加入训练集再训练一轮。这个过程循环几次模型精度会有明显提升。EasyDL支持增量训练不用每次都从头开始省了不少时间。其次是多模型协同。实际场景中往往需要同时检测多种目标或者做检测加分类的组合。Jetson Nano的算力有限同时跑多个模型可能会吃力。这时候可以考虑用模型集成的方式把多个轻量模型合并成一个多任务模型或者用级联的方式先做粗检测再做细分类。最后是工程化部署。原型阶段用Python脚本跑推理没问题但产品化需要考虑稳定性、日志、远程更新等问题。建议用Docker把推理环境打包用systemd做服务管理用MQTT或者HTTP做结果上报。这样即使设备部署在远端也能方便地维护和更新。我个人在实际操作中的体会是这套方案最大的价值在于降低了边缘AI的门槛。你不需要精通深度学习框架也不需要精通嵌入式开发只要按照流程一步步走就能做出一个可用的边缘检测系统。当然坑还是有的但只要把上面提到的这些问题提前规避掉大部分都能顺利解决。