使用 Python pyservicemaker API 进行 NVIDIA DeepStream SDK 开发。适用于构建视频分析流水线、基于 GStreamer 的视频处理、集成 TensorRT 推理、目标检测与追踪,以及集成 Kafka 或消息代理(Message Broker)等场景。
DeepStream 开发 Skill
当此 Skill 激活时,在生成代码前务必阅读相关的参考文档。切勿仅凭记忆编码——参考文档中包含了具体的属性名称、正确的 API 用法以及常见坑点的关键细节。
SDK 与架构快速参考
DeepStream SDK 版本要求
- GStreamer: 1.24.2
- NVIDIA Driver: 590+
- CUDA: 13.1
- TensorRT: 10.14.1.48
- 支持平台: Ubuntu 24.04 (x86_64 与 ARM64/Jetson)
典型流水线流程(Pipeline Flow)
Source → Stream Muxer → Inference → [Tracker] → OSD → Renderer
[方括号] 中的组件为可选组件——仅在用户明确要求时才添加。
| 阶段 | 作用 | 关键元素 | 是否必需? |
|---|---|---|---|
| Source(数据源) | 输入文件、RTSP 流、摄像头 | nvurisrcbin(首选)、nvmultiurisrcbin、filesrc |
是 |
| Stream Muxer(流复用器) | 对多路流进行 Batch 批处理以供推理 | nvstreammux |
是 |
| Inference(推理) | 执行 TensorRT 模型推理 | nvinfer、nvinferserver |
是 |
| Tracker(追踪器) | 跨帧多目标追踪 | nvtracker |
仅在明确要求时添加 |
| OSD(画面叠加) | 绘制检测框、标签与叠加信息 | nvosdbin |
是(用于可视化) |
| Renderer(渲染器) | 画面显示或输出保存 | nveglglessink、nv3dsink、filesink |
是 |
内存模型
DeepStream 采用 NVIDIA 视频内存管理器(NVMM)来实现 GPU 缓冲区的零拷贝传输。Caps 字符串中使用 memory:NVMM 来标识 GPU 内存(例如 video/x-raw(memory:NVMM), format=NV12)。
核心规则
-
仅按需添加组件:切勿自行添加用户未要求的流水线元素。
- 追踪器 (
nvtracker):仅在用户显式要求跨帧追踪或目标 ID 时添加 - 二级推理引擎(Secondary GIEs):仅在用户要求分类或属性提取时添加
- 分析模块 (
nvdsanalytics):仅在用户要求越界检测、ROI 区域计数等分析功能时添加 - 消息代理 (
nvmsgbroker/nvmsgconv):仅在用户要求连接 Kafka 或云端消息队列时添加 - 如有疑问,优先构建最小可运行流水线(Minimal Working Pipeline),后续再根据用户需求补充
- 追踪器 (
-
数据源默认使用
nvurisrcbin:当用户提到“摄像头”、“流”、“视频”或提供文件路径时:- 始终优先使用
nvurisrcbin——它可以透明兼容 RTSP、HTTP 以及本地文件 (file://) - 仅在用户显式需要底层的裸文件源控制时,才使用
filesrc+qtdemux+ 解析器(parser) - 对于 RTSP / 实时流数据源,还需在
nvstreammux上设置live-source=1,并在 sink 上设置sync=0 - 将本地路径转换为 URI 格式:
"file://" + os.path.abspath(path)
- 始终优先使用
-
元数据迭代:使用
.frame_items与.object_items(返回的是迭代器,非列表)- 绝不要对它们使用
len()函数——请通过遍历来计数 - 迭代器只能被消费一次
- 绝不要对它们使用
-
请求 Pad(Request Pad)语法:使用
"sink_%u"模板,切勿使用字面量 pad 名称pipeline.link(("decoder", "mux"), ("", "sink_%u")) # 正确 # pipeline.link(("decoder", "mux"), ("", "sink_0")) # 错误 - 将导致失败 -
Sink 元素的平台检测:
import platform sink_type = "nv3dsink" if platform.processor() == "aarch64" else "nveglglessink" -
缓冲区克隆:异步处理时务必克隆缓冲区
tensor = buffer.extract(0).clone() # 关键步骤 -
队列类型匹配:
queue.Queue→ 搭配threading.Thread使用multiprocessing.Queue→ 搭配multiprocessing.Process使用- 选错队列类型会导致静默数据丢失!
-
nvinfer 配置格式:
- YAML:使用
property:节点(不是model:),冒号后需加空格(key: value) - INI:使用
[property]节,使用等号分割(key=value) - 节点/节名称必须为
property
- YAML:使用
-
nvmsgbroker 属于 SINK 节点:其下方不能挂载后续元素——需使用
tee组件拆分流水线 -
Tee 拆分或动态源场景下,所有 Sink 必须设置
async=0:这对状态切换至关重要# 使用 tee 拆分或动态源时,所有 sink 必须设置 "async": 0 pipeline.add("nveglglessink", "sink", { "sync": 0, "qos": 0, "async": 0 # 关键设置 - 避免状态切换引发死锁 })未配置时的现象:流水线卡在 PAUSED 状态,无法显示视频画面。
-
内置 Probe 挂载限制:
measure_fps_probe只能挂载到处理元素(如nvinfer、nvosdbin)上,不能挂载到 sink 元素上。挂载到 sink 元素会触发RuntimeError: Probe failure。 -
动态 ONNX 模型必须配置
infer-dims:当 ONNX 模型带有动态输入维度时(例如在 Ultralytics YOLO 中导出时使用了dynamic=True,或者存在动态 batch/height/width 轴),必须在 nvinfer 配置中显式指定infer-dims=C;H;W。如果不配置,TensorRT 会识别到动态维度的-1并报错setDimensions: Error Code 3。常见配置值:- YOLO 模型 (640 输入):
infer-dims=3;640;640 - 416 输入的模型:
infer-dims=3;416;416 - 1280 输入的模型:
infer-dims=3;1280;1280
- YOLO 模型 (640 输入):
-
Ultralytics YOLO 输出格式取决于模型代别——较新的模型(v10+/v26+)直接输出 NMS 后结果;较旧的模型(v8/v11)输出未经 NMS 的原始 Tensor。自定义解析器与
cluster-mode必须与实际输出匹配:
| 模型代别 | 输出 Tensor 形状 | 字段说明 | cluster-mode |
|---|---|---|---|
| v8 / v11 | [batch, 84, 8400] |
[features(4+80), anchors] — 原始 cx/cy/w/h + 类别得分,未经 NMS |
2 (NMS) |
| v10 / v26+ | [batch, 300, 6] |
[max_det, (x1,y1,x2,y2,conf,cls)] — 已完成 NMS,像素级坐标 |
4 (none) |
如何在运行时判断:在自定义解析器内打印 inferDims.d[0] 与 inferDims.d[1] 的日志。
d={84, 8400}→ 未经过 NMS(v8/v11 风格)d={300, 6}→ 已完成 NMS(v10/v26+ 风格)
配置不匹配的现象:若对后 NMS 的 [N, 6] 输出错误配置了 cluster-mode: 2,边界框会出现 45° 或 135° 的偏移(因为 DeepStream 的 NMS 机制对已经最终确定的坐标进行了二次错误处理)。
如果发现检测框倾斜或旋转,还需检查 references/nvinfer_config.md 中关于 OBB / rotation_angle 的注意事项:对于非 OBB 模型,请使用 obj{} 值初始化 NvDsInferObjectDetectionInfo 并保持 rotation_angle = 0;若仅声明 NvDsInferObjectDetectionInfo obj; 则会导致字段未初始化。
- 虚拟环境必须包含
pyservicemaker:pyservicemaker默认安装在系统全局环境,标准 Python 虚拟环境无法直接访问。当任务需要虚拟环境时(例如安装模型下载/转换所需的 pip 依赖),务必在虚拟环境内部安装pyservicemaker与pyyaml。生成的代码和 README 中的虚拟环境配置必须包含:
未配置时的现象:在虚拟环境中运行应用时抛出python3 -m venv venv source venv/bin/activate pip install /opt/nvidia/deepstream/deepstream/service-maker/python/pyservicemaker*.whl pyyaml pip install -r requirements.txt # 其他依赖ModuleNotFoundError: No module named 'pyservicemaker'。
关键路径
- 模型目录:
/opt/nvidia/deepstream/deepstream/samples/models/ - 主检测器:
/opt/nvidia/deepstream/deepstream/samples/models/Primary_Detector/resnet18_trafficcamnet_pruned.onnx - 追踪器动态库:
/opt/nvidia/deepstream/deepstream/lib/libnvds_nvmultiobjecttracker.so - Kafka 动态库:
/opt/nvidia/deepstream/deepstream/lib/libnvds_kafka_proto.so - 示例配置目录:
/opt/nvidia/deepstream/deepstream/samples/configs/deepstream-app/
参考文档
重要提示:始终阅读这些文档以获取完整细节。切勿凭借记忆生成代码。
| 文档 | 适用场景 |
|---|---|
| references/gstreamer_plugins.md | 查询插件属性(包含全量属性列表) |
| references/service_maker_api.md | 使用 Pipeline/Flow API、元数据访问、Probe 挂载、EventMessageUserMetadata |
| references/use_cases_pipelines.md | 构建流水线:简单播放、多模型推理、级联 GIE |
| references/streaming_sources.md | 使用 nvurisrcbin 接入本地文件、HTTP MP4、HLS、MPEG-DASH 或 RTSP 数据源 |
| references/kafka_messaging.md | Kafka / 消息代理配置、nvmsgconv/nvmsgbroker 配置、msg2p-newapi |
| references/best_practices.md | 设计模式、常见坑点与反模式 |
| references/buffer_apis.md | BufferProvider/Feeder(缓冲区注入)、BufferRetriever/Receiver(缓冲区提取) |
| references/media_extractor_advanced.md | MediaExtractor、MediaChunk、FrameSampler 用法 |
| references/utilities_config.md | PerfMonitor、EngineFileMonitor、SourceConfig、SensorInfo、SmartRecordConfig 配置 |
| references/nvinfer_config.md | nvinfer 配置文件格式与全量参数 |
| references/tracker_config.md | nvtracker 配置,包含 NvDCF/IOU/DeepSORT/NvSORT |
| references/troubleshooting.md | 常见报错信息与排查方案 |
| references/rest_api_dynamic.md | REST API、动态源添加/移除、nvmultiurisrcbin 用法 |
| references/metamux_config.md | nvdsmetamux 配置、多模型并行推理、元数据合并、数据源 ID 过滤 |
| references/docker_containers.md | Docker 镜像、Dockerfile 示例、pyservicemaker 安装、容器启动命令 |
| references/nvds_msgapi_adapter.md | 构建自定义协议适配器:nvds_msgapi |
常见报错速查
| 报错信息 | 解决方案 |
|---|---|
iterator has no len() |
通过遍历进行计数,不要对迭代器调用 len() |
pad template not found |
使用 "sink_%u" 模板,而不是写死 "sink_0" |
| 队列数据丢失(Queue data loss) | 配合 Process 使用时改用 multiprocessing.Queue |
| 配置文件解析失败(Config parse failed) | YAML 中使用 property: 节点,而不是 model: |
is-classifier 弃用警告(deprecation warning) |
分类器使用 network-type: 1 替代 is-classifier: 1;检测器则两者都无需配置 |
min-boxes 未知键警告(unknown key warning) |
在 class-attrs-* 节中使用驼峰命名 minBoxes,而非 min-boxes |
| 二级推理引擎(Secondary GIE)未生效 | 设置 process-mode: 2,并检查 operate-on-gie-id 配置 |
| Tee 拆分 / 动态源卡在 PAUSED 状态 | 给所有 Sink 元素配置 async: 0 |
| RTSP 无数据 / 无限重连 | 使用 ffplay 测试 RTSP URL,检查认证信息 |
RuntimeError: Probe failure |
measure_fps_probe 不能挂载到 Sink 元素,请改用 nvinfer 或 nvosdbin |
setDimensions 负数维度 / Engine 构建失败 |
动态 ONNX 模型需添加 infer-dims=C;H;W(例如 infer-dims=3;640;640) |
虚拟环境中报错 No module named 'pyservicemaker' |
在虚拟环境内执行 pip install /opt/nvidia/deepstream/deepstream/service-maker/python/pyservicemaker*.whl pyyaml |
AttributeError: object has no attribute 'obj_label' |
在 pyservicemaker 中使用 obj_meta.label 而非 obj_meta.obj_label(C API 与 Python 绑定命名存在差异) |
<!-- Signing refresh marker. -->




