📱 你的实时视觉系统,已替你拆解好

用大白话说:这一页帮你搞懂「我这套系统到底在干嘛、为什么会卡、我之前调的那些参数有没有用」。

这一页是我替你做好的功课:把你那套 cpu_model_stream.py 系统,用大白话加图,从头讲到尾。

你出门在外,看这一页就够了,不用打开任何源码文件。

等你回家坐在电脑前,想对着代码看的时候,再去翻原文件也不迟。

这一页在讲什么
你的系统其实就干一件事:
从网上接一路视频进来(比如无人机直播过来的画面),实时用 YOLO(说人话:一个专门认东西的 AI 模型)扫一遍,把认出来的东西用框圈起来,再把画面推回去给观众看。
同时它还会拉一个大模型来复核一下:「这个人到底戴没戴安全帽?」
下面我把整条链路、5 个同时在跑的线程、还有你最头疼的三个毛病(画面延迟 / 通道堵住 / 多路一起跑就卡),一次给你讲清楚。
看不懂术语
这一页会冒出 NVENC / NVDEC / TensorRT / INT8 / FP16 这些吓人的词。
别慌,去 术语表 + 官方文档链接 那一页,每个词都有一句话的人话解释,还能直接跳去官方文档。
等你回家想改代码了,那一页也能帮你快速把概念捡回来。

一、一张图看懂整条链路

先看全景。一段视频从「网络那头」跑到「观众的屏幕上」,中间要过 7 道关。

图里的颜色是有讲究的:蓝色=正常干活的环节;黄色=最容易堵车的地方,你要盯紧它俩;绿色=在后台自己忙活、不挡道的分支。

① 网络流 RTMP / RTSP 视频源 ② 拉流 + 解码 CPU 软解 · 隐患点 ③ 主线程读帧 阻塞读 · 拉流慢则卡 ④ GPU 推理(每 N 帧) device=0 · batch=1 ⑤ 原始帧入队 队列满 → 丢帧 ⑥ 推流线程编码 CPU 软编码 libx264 · 隐患点 ⑦ 观众看到视频 推的是原始帧 异步分支:绘制 / 富化 / 大模型核验 与主链路并行,不阻塞
图 1:端到端 7 段链路(黄=隐患点,绿=后台并行)

把这 7 段配上人话,就是下面这样:

最下面那个绿色的分支,是画框、判断安全帽、叫大模型复核这些活。它们在旁边自己忙,不会挡住主流程。

二、其实是 5 个线程在同时跑

你可能以为程序是「一条线从头跑到尾」。其实不是。

它是 5 拨人在同时干活。线程(说人话:一个能独立干活的「小工」,几个小工可以同时开工)。

主线程是工头,负责拉视频和喊模型干活;剩下 4 个小工是它派出去的,各忙各的。

主线程(读流 + 隔帧推理 + 派发) process_stream 推流线程 编码推送 RTMP 绘制线程 画框 → 带框帧 富化线程 安全帽 / 计数 大模型线程池 qwen3-vl-4b 核验
图 2:5 个并行线程,主线程是源头

这 5 个小工分别干什么,看下面这张表:

哪个小工它负责干啥用的是 CPU 还是显卡
主线程把视频拉进来、每隔 N 帧喊一次 YOLO、再把画面分给别人读画面用 CPU,认东西用显卡
推流线程把画面压缩成视频,发回去给观众看CPU 硬扛(很吃 CPU)
绘制线程把认出来的框画到画面上CPU
富化线程按几何位置判断「这人戴没戴安全帽」,顺便数人数CPU
大模型线程池把框里那一小块抠出来,拿给大模型问「这真的是个人吗」显卡(最多同时问 2 个)

三、你跑的到底是 TensorRT 还是 PyTorch?

这就是你之前一直纠结的量化(说人话:给模型「减肥」,让显卡跑得更快,代价是可能看得没那么准)问题。

结论我直接给你,你不用翻代码:

一句话
你之前折腾的「量化成 .engine 提速 / 换 INT8」到底生没生效,只取决于一件事:任务配置里存的那个模型路径,结尾是 .pt 还是 .engine
想知道答案很简单,回家打开数据库看一眼那个任务的模型路径后缀就行了。

四、你三个痛点的真正根因

你一直说「延迟高、通道堵、多路卡」。

我查下来,根子不在模型慢,而在整个结构的搭法上。

下面四条,每条我都标出了真相是什么。

1. 通道堵塞:真源在读帧,不在推流

问题出在第 ③ 步——读画面这一步是会干等的

ffmpeg 那边一张画面没给过来,主线程就只能杵在那儿等着。它一等,后面的模型推理也跟着停摆。

你之前在推流那一端做的「队伍满了就丢几张」,其实只是治标。

因为源头没有拆开:只要解码一慢,整条主线程就得跟着卡。

2. 延迟高:大概率不是模型,是 CPU 软编码

看第 ⑥ 步,推流编码用的是 libx264,这是让 CPU 硬扛的软件编码

打个比方:这就像让一个会计用算盘去算一整个工厂的账。

多路视频一起跑的时候,CPU 会先被压垮,而且它比模型推理慢得多。

所以你要真想降延迟,该做的是把编码这活搬到显卡上去(NVENC,说人话:显卡里专门管压缩视频的小硬件),而不是去调 imgsz 那个参数。

3. 多任务「并行」是假象

推理那里写死了 device=0batch=1

这意味着:多路任务在显卡上其实是排队一个一个来的,根本不是同时跑。

再加上每个任务都新建一份模型、各占一块显存,显存很快就见底了。

想要真正的并行,得靠「把多路画面凑成一批一起算 + 大家共用同一个模型」。

4. 「增加推理间隔」的真相

你之前用「隔几帧才检测一次」来提速,这招确实能快。

但有个事你可能没意识到:那些被跳过的画面上,显示的不是「没检测到」,而是上一次检测的旧框

所以画面看起来会「慢半拍」——框跟不上人。

这不是漏检,是在拿旧结果凑数。本质上,你是用「不够及时」换来了「跑得更快」。

五、旋钮分类:治标 vs 治本

你之前调过的那一堆参数,其实分两类。

这一节最重要,因为它决定了你到底是在绕开问题,还是在解决问题

属于哪一类具体做法要付出什么代价
牺牲质量换速度(治标)把图缩小(降 imgsz)、隔几帧才检测一次、把判定门槛调高(提 conf 阈值)会漏看东西 / 框慢半拍 / 小的东西直接没了
改架构(治本)让解码单独开一个小工去做、用 NVDEC 让显卡来解码、用 NVENC 让显卡来编码、把图片预处理也搬到显卡上、把多路画面凑成一批一起算得动代码,麻烦一点,但精度一点不丢
核心结论
你之前干的那些事——「把 .pt 量化成 .engine、把图缩小、隔帧检测、把置信度门槛提高」——全都是在拿准确度换速度。
换句话说:你不是让它变强了,你是让它变得又快又马虎。
想要又快又不丢东西,就得动结构:把解码和编码搬到显卡上去,让各段活儿能同时干、互相不等。
这才叫治本。

六、手机上怎么用这一页

出门不用带源码,带手机就行。
第一步,看「图 1」,把 7 段链路记住。
第二步,看「第四节」,把三个痛点的真正原因记住。
第三步,看「第五节」,分清哪些是治标、哪些是治本。
什么时候算吃透了?
当你能不看任何东西,张嘴就说出「视频从网络到观众要过哪几段、哪一段最容易卡、我之前调的那些参数属于治标还是治本」——这一页你就学完了。