Orin 上用 DeepStream 跑多路检测

📅 2026/8/4 2:32:45 👁️ 阅读次数 📝 编程学习
Orin 上用 DeepStream 跑多路检测

文章目录

    • 1. 多路难点在哪
    • 2. 多路的最小链路
    • 3. 建议顺序:2 路 → 4 路,别直接 8 路
    • 4. 开始前再确认一遍
    • 5. 建议先做 2 路,再复制成 4 路
    • 6. 四路最小配置示例
      • 6.1 主配置:`ds_rtsp_multi4.txt`
      • 6.2 推理配置:`pgie_config_multi.txt`
    • 7. 跑起来后先看什么
    • 8. 容量预估
    • 9. 最常见的坑
    • 10. 没桌面时怎么看多路结果
    • 11. 多路通了以后再做什么
    • 12. 跑通后可以对照这几条
    • 13. 小结

摘要:单路 RTSP 检测通了之后,下一步通常是多路。很多人一上来就开 8 路,结果掉帧、花屏、OOM 一起来,最后分不清是网络、解码还是模型的问题。本文从 2 路扩到 4 路,把source怎么加、batch-size怎么对齐、tiled-display怎么看、容量怎么估、常见坑怎么查说清楚。适合已经跑通单路 DeepStream 的人。


1. 多路难点在哪

单路通了,不等于多路只是“复制粘贴 source”。多路真正叠加的是这几件事:

  • 每路都要解码
  • streammux 要把多路合成 batch
  • 推理要按 batch 吃进去
  • OSD / 拼屏 / 编码出口也会跟着变重
  • 网络带宽和摄像头抖动会互相拖累

所以多路不是“把 FPS 乘以路数”,而是整条链路的容量问题。DeepStream 的价值也在这里:它把多路合批这件事做成默认路径,而不是你自己用 OpenCV 开 N 个线程硬拼。

官方对deepstream-app多源和 streammux 的说明见:

  • DeepStream Reference Application
  • Gst-nvstreammux

一句话记住官方建议:streammuxprimary-giebatch-size,尽量等于输入路数。


2. 多路的最小链路

可以先这样理解:

多路 RTSP → 硬解码 → streammux 合批 → primary-gie 推理 → OSD → tiled-display / 落盘 / 推流

和单路相比,配置上多出来的核心只有三块:

变化点单路多路
source只有[source0][source0][sourceN]
batch-size通常是 1等于路数
tiled-display可关调试时建议开,方便一眼看齐

别的东西,比如模型路径、标签、OSD、功耗档,思路和单路一样。先别同时换模型、换分辨率、换推流,否则定位成本会翻倍。


3. 建议顺序:2 路 → 4 路,别直接 8 路

阶段目标先别做
2 路证明合批和拼屏没问题一上来改业务模型
4 路看内存、温度、掉帧边界同时开跟踪、二次网络、推流
再加路按板型容量推进掉帧还没定位就继续加

经验上:

  • Orin Nano:先把 2~4 路 720p 稳住,再谈更高路数
  • Orin NX:4~8 路比较常见,看模型和分辨率
  • AGX Orin:路数余量更大,但网络和散热仍然会先卡你

具体上限别背“某型号一定能跑 N 路”。输入分辨率、编码格式、模型大小、interval、是否拼屏编码,都会改结论。


4. 开始前再确认一遍

单路那篇的前置条件这里都还成立。多路额外再确认:

cat/etc/nv_tegra_releasesudonvpmodel-qdeepstream-app--versiontegrastats

然后:

  1. 每一路 RTSP 都能单独打开
    不要在 DeepStream 里才发现第 3 路密码错了。
  2. 分辨率尽量先统一
    例如都先按 1280×720 进 streammux,少留一个变量。
  3. 板子上别同时挂着重推理脚本
    多路一开,资源争用会立刻放大。

单路验证命令还是先用:

gst-launch-1.0 rtspsrclocation="rtsp://相机地址"latency=200!rtph264depay!h264parse!avdec_h264!videoconvert!autovideosink

每一路都过一遍,再进 DeepStream。

网络侧也建议先心里有个数。四路 1080p、每路大概 4~8 Mbps,交换机和 Orin 网口都未必是瓶颈,但 Wi-Fi 摄像头、跨网段录像机、共享带宽的交换机,经常会先把某一路拖死。多路掉帧时,先问一句:是四路一起慢,还是某一路先挂。


5. 建议先做 2 路,再复制成 4 路

如果你手里只有单路配置,最小改法是:

  1. 复制出[source1],改 URI
  2. streammux.batch-size改成2
  3. primary-gie.batch-size改成2
  4. pgie里的batch-size同步改成2
  5. tiled-display开成rows=1 columns=2

2 路画面齐、perf 稳之后,再复制成 4 路。这一步看起来笨,但能把“合批逻辑错了”和“板子容量不够”分开。很多人直接从 1 跳到 8,最后日志一长串,不知道从哪一行看起。

batched-push-timeout也不要乱拧。直播源通常保留一个相对合理的超时(示意里是40000微秒量级),让 muxer 在等不满 batch 时也能往下推。设得太大,某一路卡住时整批更慢;设得太激进,又容易出现不完整 batch。第一次多路,先用 sample/单路附近的默认值,确认链路通了再微调。


6. 四路最小配置示例

下面给一个4 路 RTSP + 拼屏显示的最小思路。路径按你自己的环境改。

6.1 主配置:ds_rtsp_multi4.txt

[application] enable-perf-measurement=1 perf-measurement-interval-sec=5 [tiled-display] enable=1 rows=2 columns=2 width=1280 height=720 gpu-id=0 nvbuf-memory-type=0 [source0] enable=1 type=4 uri=rtsp://相机1地址 gpu-id=0 latency=200 cudadec-memtype=0 [source1] enable=1 type=4 uri=rtsp://相机2地址 gpu-id=0 latency=200 cudadec-memtype=0 [source2] enable=1 type=4 uri=rtsp://相机3地址 gpu-id=0 latency=200 cudadec-memtype=0 [source3] enable=1 type=4 uri=rtsp://相机4地址 gpu-id=0 latency=200 cudadec-memtype=0 [streammux] gpu-id=0 live-source=1 batch-size=4 batched-push-timeout=40000 width=1280 height=720 enable-padding=0 nvbuf-memory-type=0 [primary-gie] enable=1 gpu-id=0 batch-size=4 gie-unique-id=1 config-file=pgie_config_multi.txt nvbuf-memory-type=0 [osd] enable=1 gpu-id=0 border-width=2 text-size=12 text-color=1;1;1;1 text-bg-color=0.3;0.3;0.3;1 font=Serif show-clock=0 clock-x-offset=800 clock-y-offset=820 clock-text-size=12 clock-color=1;0;0;0 nvbuf-memory-type=0 [sink0] enable=1 type=2 sync=0 source-id=0 gpu-id=0 nvbuf-memory-type=0

这里最容易写错的是:

  • source开了 4 路,但batch-size还停在 1
  • streammux.batch-sizeprimary-gie.batch-size不一致
  • tiled-displayrows * columns小于路数,看起来像少了一路
  • live-source忘了开成 1

官方也明确说过:batch 设得比路数大或小,都可能把延迟搞怪。多路第一次,先对齐,再谈“优化”。

6.2 推理配置:pgie_config_multi.txt

[property] gpu-id=0 net-scale-factor=0.003921568627451 model-color-format=0 onnx-file=/home/ubuntu/models/yolov8n.onnx model-engine-file=/home/ubuntu/models/yolov8n_b4_fp16.engine labelfile-path=/home/ubuntu/models/labels.txt batch-size=4 network-mode=2 num-detected-classes=80 interval=0 gie-unique-id=1 process-mode=1 network-type=0 cluster-mode=2 maintain-aspect-ratio=1 symmetric-padding=1 [class-attrs-all] pre-cluster-threshold=0.25 nms-iou-threshold=0.45

注意两点:

  1. engine 的 batch 最好和运行 batch 对齐
    单路建出来的batch=1engine,拿去硬跑batch=4,轻则重建、重则报错或性能很差。多路第一次,建议在目标板上按目标 batch 重新建 engine。
  2. interval是多路保命开关
    interval=0表示每帧都推推理。路数一多,先把它改成12(隔帧推理),往往比盲目换更大板子更快止血。

7. 跑起来后先看什么

deepstream-app-cds_rtsp_multi4.txt

第一遍只盯四件事:

  1. 四路是不是都有画面
  2. 框是不是都在
  3. perf 打印是否大致平稳
  4. tegrastats里内存和温度有没有顶满

建议另开一个终端:

tegrastats

重点看:

观察项正常时大概感觉危险信号
GPU有稳定占用忽高忽低且画面卡
RAM有余量持续顶满、开始杀进程
温度可控持续高温后 FPS 明显掉
网络各路延迟差不多某一路长期拖后腿

多路场景里,最慢的那一路,常常决定整条链路的体感。所以别只看平均 FPS,也要看是不是某一路经常卡住。


8. 容量预估

现场一般按这个顺序压测:

  1. 单路 720p 稳住
  2. 2 路同配置
  3. 4 路同配置
  4. 再决定要不要升分辨率、加跟踪、开编码推流

每加一档,记一张表:

路数输入模型interval端到端 FPS 感觉内存温度结论
1720pyolov8n0基线
2720pyolov8n0
4720pyolov8n0
4720pyolov8n1

如果你发现:

  • 2 路很好,4 路开始掉帧
    先降分辨率、加interval,再怀疑板型不够
  • 画面都在,但某一路长期黑屏
    先查那路相机和网络,不要先改模型
  • 一开拼屏编码推流就崩
    先关输出编码,只保留检测链路,把瓶颈拆开

选型上可以粗看:

板型多路检测常见起步备注
Orin Nano2~4 路轻量检测内存和散热先卡你
Orin NX4~8 路较常见看模型和分辨率
AGX Orin更高路数更从容仍要算解码和出口

这是经验区间,不是承诺值。合同里的“支持 N 路”,一定要写清分辨率、码率、模型和是否实时编码。

还有一个实用取舍:业务不要求每帧都检时,优先加interval,而不是先换更大模型再硬扛。隔帧检测对很多门禁、通道、仓库巡检场景足够用,却能明显降低 GPU 和温度压力。真要“每路每帧”,再回头压分辨率、换更小模型,或者上更大内存的板型。


9. 最常见的坑

现象多见原因先查什么
只显示一路source 没全开,或 tile 行列不够enablerows/columns
起得来但很卡batch 不对、分辨率太大、interval=0batch-size、输入尺寸、interval
某几路黑屏那几路 RTSP 本身有问题单独gst-launch
engine 报错/重建很久batch 和 engine 不匹配按目标 batch 重建
跑一会内存涨输出编码、泄漏、分辨率过大先简化 sink,看tegrastats
换板后全挂engine 不是本板生成目标板重建
拼屏看着花宽高和源不一致、padding 乱统一 streammux 尺寸

还有一个很典型:单路 sample 很好,多路换成自己模型后全军覆没。这时优先查:

  • parser 是否适配
  • num-detected-classes/ labels 是否对齐
  • 预处理是否和训练一致
  • batch engine 是否在本机构建

DeepStream 不会替你自动修好 YOLO 适配问题。

排障时我习惯按层剥:

  1. :每路单独gst-launch
  2. 合批batch-sizelive-source、tile 行列
  3. 推理:engine、labels、parser、interval
  4. 出口:显示 / 落盘 / 推流是否把整机拖垮

不要一上来同时改四层。多路日志本来就密,一次只动一个变量,定位会快很多。


10. 没桌面时怎么看多路结果

SSH 上去、没有显示器时,sink type=2往往不合适。多路调试可以先:

  1. 写文件
    先确认四路都有框,再谈实时看。
  2. 只看 perf + 日志
    先验证链路稳不稳,不急着盯画面。
  3. 后面再上 RTSP 出口
    多路检测 + 多路再编码推流,是另一层复杂度。

第一次多路,我更建议:先拼屏本地看,或先落盘回看。一上来就“四路进、四路出再推平台”,出问题会很难拆。


11. 多路通了以后再做什么

到这一步,后面通常才有资格谈:

  1. 跟踪(tracker)
  2. 二次分类 / 属性网络
  3. 区域告警、落图、推消息
  4. Docker 固化与开机自启
  5. 评估要不要从 Nano/NX 升到 AGX,或以后看 Thor

顺序别反。业务逻辑堆上去之前,至少先证明:

  • N 路能稳定进
  • batch 推理能稳住
  • 你知道掉帧时该降哪一档参数

12. 跑通后可以对照这几条

按上面从 2 路扩到 4 路之后,可以自己核对:

  • 单路配置能不能平稳扩到多路,而不是靠重写一整套
  • batch-size是否和路数对齐,engine 是否按目标 batch 重建
  • 拼屏里各路画面、检测框是否都能一眼看清
  • 掉帧时会不会先动interval、分辨率、功耗档,而不是先怪模型
  • 出问题时能不能按「源 → 合批 → 推理 → 出口」分层排查

这几条都过得去,多路就不再只是演示,而是可以拿去估板型、估容量了。


13. 小结

Orin 上多路 DeepStream,难点通常不在“再复制几个 source”,而在合批、容量和短板定位。先把 2 路、4 路按同一套配置跑稳,把batch-size、拼屏和tegrastats看懂,后面加跟踪和告警才没有问题。