
1. yolov5 转 TensorRT 到底在解决什么问题如果你手上有一个训练好的 yolov5s.pt直接拿 PyTorch 跑推理在 1080p 输入下单帧可能要 30ms 以上批量跑视频流时 GPU 利用率上不去、延迟还忽高忽低。yolov5 模型转 TensorRT 的核心目的就是把 PyTorch 的动态图推理换成 TensorRT 的静态 engine让算子融合、精度校准、显存复用一次性做到位实测下来同卡同输入能压到原来的三分之一甚至更低。这条链路大致分四步PyTorch 权重先导出成 ONNX 或 wts 中间格式再交给 TensorRT builder 序列化成 .engine 文件最后在自有 GPU 环境里反序列化加载做端到端推理。中间任何一步版本对不上都会在 builder 阶段直接报错退出所以版本对齐比写代码本身更关键。适合谁看这篇已经装好 CUDA、cuDNN、TensorRT能跑通 nvidia-smi 和 trtexec但卡在权重导出或 engine 序列化环节的工程同学以及想把推理服务凭证统一管起来、不想在每台机器上散落一堆 Key 的团队。我会把导出脚本、builder 参数、精度速度对比验证动作都写成可复制的形式你照着改路径就能跑。需要提前说清楚的一点TensorRT 的 engine 是跟 GPU 架构绑定的在 30 系卡上生成的 engine 拿到 40 系卡上大概率加载失败所以每换一类卡都要重新序列化一次。这不是配置问题是 TensorRT 的固有设计提前知道能省很多排查时间。另外推理服务一旦对外提供接口调用凭证的管理就会变成新问题。我这次把模型转换和凭证通道分开处理模型侧专注 engine 生成与精度验证服务侧用 TaoToken 的统一 Key 通道来管推理调用的鉴权两边解耦换模型不用动凭证换凭证也不用重编 engine。2. TaoToken 统一 Key 通道在推理服务里的前置准备模型转完之后下一步通常是把它包成一个 HTTP 或 gRPC 推理服务让业务侧调用。这时候就会遇到一个很实际的问题如果每个业务方、每台机器都各自持有一份模型服务的 Key轮换和审计会非常痛苦。TaoToken 在这里的角色是统一 Key 通道把推理服务调用凭证收敛到一处管理业务侧只认一个入口。前置准备分两块一块是模型环境一块是凭证通道。模型环境这块先确认四个组件都正常。CUDA 用nvcc -V看版本cuDNN 看头文件里的宏TensorRT 用dpkg -l | grep tensorrt或trtexec --versionOpenCV 用pkg-config --modversion opencv4。四个版本要互相兼容TensorRT 8.x 一般对应 CUDA 11.x具体对应关系查官方 release notes别凭感觉装。凭证通道这块去 TaoToken 控制台创建一个 API Key然后在接入文档里确认 Base URL 和调用方式。控制台地址是 https://taotoken.net/console API Key 管理在 https://taotoken.net/api-keys 接入文档在 https://taotoken.net/doc 。这三个页面建议都过一遍尤其是文档里的请求示例能省掉自己猜参数格式的时间。这里有个容易踩的坑很多人把模型服务的鉴权和模型本身的推理混在一起调结果排查问题时分不清是 Key 失效还是 engine 加载失败。我的做法是先用一个最小请求验证 Key 通道通不通再去接推理逻辑两层分开测。如果你后面还要做长期编码或 Agent 类任务可以顺带看下 Coding Plan 页面 https://taotoken.net/coding-plan 它和单次推理调用的计费方式不一样按自己的使用频率选。模型对话的在线验证入口在 https://taotoken.net/models 转完 engine 后想快速确认模型输出是否正常可以直接在那边试。前置准备做完你应该有一个能跑通的 TensorRT 环境、一个可用的 API Key、一份确认过的 Base URL。接下来进入实际转换。3. 可复制的 yolov5 转 TensorRT 配置与导出脚本这一节是全文最核心的部分我把权重导出、CMake 配置、builder 序列化三段都写成可直接复制的形式。版本上我用 yolov5 v5.0 配 tensorrtx这是经过大量验证的组合新版本改动大第一次跑通建议先用这个组合。先拉代码和权重git clone -b v5.0 https://github.com/ultralytics/yolov5.git git clone https://github.com/wang-xinyu/tensorrtx.git wget https://github.com/ultralytics/yolov5/releases/download/v5.0/yolov5s.pt然后把 tensorrtx 里的导出脚本复制到 yolov5 项目生成 wts 中间格式cp tensorrtx/yolov5/gen_wts.py yolov5/ cd yolov5 python gen_wts.py -w yolov5s.pt -o yolov5s.wts这一步产出的 yolov5s.wts 就是权重容器后面 builder 读它。注意 yolov5s.pt 的版本必须和代码分支一致v5.0 的代码配 v5.0 的权重混用会在加载 state_dict 时报 key 不匹配。接着配置 CMakeLists.txt把 TensorRT 路径改成你自己装的路径。在 tensorrtx/yolov5/ 目录下打开 CMakeLists.txt找到 include_directories 和 link_directories 两处改成类似include_directories(/usr/local/TensorRT-8.5.1.7/include) link_directories(/usr/local/TensorRT-8.5.1.7/lib)如果你是用 deb 包装的 TensorRT路径可能是 /usr/include/x86_64-linux-gnu 和 /usr/lib/x86_64-linux-gnu用find / -name NvInfer.h 2/dev/null定位一下最稳。编译和序列化cd tensorrtx/yolov5 mkdir build cd build cp ../../yolov5/yolov5s.wts . cmake .. make sudo ./yolov5 -s yolov5s.wts yolov5s.engine s最后那个s对应 yolov5s 模型如果你用的是 m/l/x换成对应字母如果是自定义模型用c加 depth_multiple 和 width_multiple比如c 0.17 0.25。自定义模型还要改 yololayer.h 里的 CLASS_NUM改成你自己的类别数不改的话输出维度对不上。精度模式在 yolo5.cpp 顶部控制默认可能是 FP16//#define USE_FP16 #define USE_FP32 #define DEVICE 0第一次跑通建议先用 FP32稳定之后再切 FP16 对比速度。INT8 需要校准集第一次不建议上。关于凭证通道的配置如果你要把推理服务包起来可以在服务启动脚本里用环境变量注入避免硬编码export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEY你的Key服务代码里读这两个变量拼请求头即可。这样换 Key 只改环境变量不用重编 engine也不用动模型代码。4. 验证请求与成功结果确认engine 生成之后先别急着接业务用自带的 deserialize 模式跑一遍确认推理链路是通的sudo ./yolov5 -d yolov5s.engine ../samples成功的话终端会打印每张图的检测框数量、类别和耗时类似detected 3 objects in 12.4ms。如果这一步就报错说明 engine 本身有问题先回去查序列化阶段。确认 engine 能跑之后再验证凭证通道。用一个最小请求打模型服务接口看返回是否正常。如果你用的是 TaoToken 的模型对话入口做快速验证可以直接在 https://taotoken.net/models 里发一条测试请求确认 Key 有效、Base URL 可达。两层都通了之后做一次端到端联调业务侧发请求 → 凭证通道鉴权 → 推理服务加载 engine → 返回检测结果。这一步建议记录三个指标单帧推理耗时、端到端延迟、GPU 显存占用。用nvidia-smi -l 1盯着显存用time或服务内打点测耗时。精度对比也要做。拿同一批测试图分别用 PyTorch 原模型和 TensorRT engine 跑对比 mAP 或至少对比检测框数量和类别是否一致。FP32 模式下差异应该很小FP16 可能有零点几个百分点的波动属于正常范围。如果差异很大检查预处理是否一致尤其是归一化和 letterbox 的填充方式这两处最容易引入偏差。速度对比用同一批图跑 100 次取平均排除首次加载的冷启动时间。实测下来 yolov5s 在 1080p 输入下PyTorch 大概 30ms 上下TensorRT FP16 能到 8-12ms具体数字看卡型。这个提升主要来自算子融合和 FP16 计算不是玄学。验证通过后把 engine 文件和启动脚本归档记录生成时的 TensorRT 版本、CUDA 版本、GPU 型号。下次换卡重新生成时这份记录能帮你快速对齐环境。5. 本篇常见报错排查转换过程中最容易撞上的几类报错我按实际遇到的频率排一下。第一类是what(): driver error这个基本是 TensorRT 版本和显卡驱动不匹配或者 TensorRT 版本和 CUDA 版本不匹配。先nvidia-smi看驱动版本再trtexec --version看 TensorRT 版本对照官方兼容表。别急着重装先确认版本关系。第二类是segmentation fault在序列化或反序列化时崩。最常见的原因是 FP16 在当前卡上不稳定把 yolo5.cpp 里的USE_FP16注释掉换成USE_FP32重新编译大概率能过。如果还崩检查 DEVICE 编号是不是写成了不存在的 GPU。第三类是加载 engine 时报serialization相关错误或者reading choices之类的解析失败。这通常是 engine 文件和当前 GPU 架构不匹配比如在 30 系卡上生成的 engine 拿到 40 系卡上加载。解决办法就是在新卡上重新跑一遍序列化engine 不能跨架构复用。第四类是 401 或鉴权失败这个跟模型无关是凭证通道的问题。先确认 API Key 没有过期再确认 Base URL 拼对了最后确认请求头格式符合文档要求。如果本地服务走了代理还要确认代理没有拦截请求。这类问题用最小请求单独测别和推理逻辑混在一起排查。第五类是 OAuth 或 token 刷新相关报错如果你用的是需要动态刷新的凭证方式检查刷新逻辑有没有在并发场景下重复刷新导致 token 失效。这类问题日志里通常能看到 token 相关关键字顺着查即可。第六类是local proxy failed这个一般是本地网络配置问题检查环境变量里的 http_proxy 和 https_proxy 有没有指向不可用的地址。推理服务本身不需要代理把这两个变量清掉再试。排查顺序建议先确认环境版本再确认 engine 能单独跑最后确认凭证通道通。三层分开测比一上来就端到端调要快得多。6. 把转换和凭证通道固定成可复用流程跑通一次之后别让这套流程停留在手工敲命令的状态。我的做法是写一个 shell 脚本把版本检查、权重导出、engine 序列化、验证四步串起来每次换模型只改脚本顶部的模型名和类别数两个变量。凭证通道那边同理把 Base URL 和 Key 的读取封装成一个配置加载函数服务启动时统一注入。这样模型迭代和凭证轮换互不影响团队里其他人接手也不用重新理解一遍鉴权逻辑。如果你后面要把推理服务做成长期在线的 Agent 或编码辅助能力可以看下 Coding Plan https://taotoken.net/coding-plan 它的计费和调用方式和单次推理不同按实际使用模式选更划算。API Key 的创建和管理在 https://taotoken.net/api-keys 接入细节在 https://taotoken.net/doc 这两个页面建议收藏换环境时直接查。最后留一个实用技巧engine 文件生成后算一下 md5和生成时的环境信息一起记在 README 里。下次加载失败时先比对 md5 和环境能快速判断是文件损坏还是环境变了。这个习惯帮我省过好几次重复排查的时间。