关于 deepstream-dev
deepstream-dev 是用于开发 NVIDIA DeepStream 应用和管线的技能。它强调查阅版本相关资料、仅添加所需组件,并提供管线配置与故障排查指导。
主要功能
- 01DeepStream 管线设计指导
- 02GStreamer 元素与属性参考
- 03Service Maker API 指导
- 04配置与故障排查资料
- 05源、接收端和元数据规则
适用场景
- 01构建视频推理管线
- 02配置流媒体源和输出接收端
- 03添加所需的跟踪或消息组件
- 04排查 DeepStream 管线与模型问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ nvidia/ skills --skill deepstream-dev安装后在 Claude Code 中输入/deepstream-dev确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
BENCHMARK.mdskill-card.mdskill.oms.sigevals/evals.jsonreferences/best_practices.mdbuffer_apis.mddocker_containers.mdgstreamer_plugins.mdkafka_messaging.mdmedia_extractor_advanced.mdmetamux_config.mdnvds_msgapi_adapter.mdnvinfer_config.mdrest_api_dynamic.mdservice_maker_api.mdstreaming_sources.mdtracker_config.mdtroubleshooting.mduse_cases_pipelines.mdutilities_config.md详细介绍
DeepStream 开发技能
此技能需要访问下方 references/ 目录中列出的所有参考文档。执行工作流前,请确保这些文档均可用。
此技能启用后,生成代码前务必阅读相关参考文档。切勿依赖记忆——参考文档包含有关确切属性名称、正确 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)
典型管道流程
Source → Stream Muxer → Inference → [Tracker] → OSD → Renderer
[方括号]中的组件为可选项——只有用户明确要求时才添加。
| 阶段 | 作用 | 关键元素 | 是否必需? |
|---|---|---|---|
| 源 | 从文件、RTSP、摄像头输入 | nvurisrcbin(首选)、nvmultiurisrcbin、filesrc | 是 |
| 流复用器 | 将多个流合并为批次以供推理 | nvstreammux | 是 |
| 推理 | 执行 TensorRT 模型 | nvinfer、nvinferserver | 是 |
| 跟踪器 | 跨帧跟踪多个对象 | nvtracker | 仅在用户要求时 |
| OSD | 绘制边界框、标签和叠加内容 | nvosdbin | 是(用于可视化) |
| 渲染器 | 显示或保存输出 | nveglglessink、nv3dsink、filesink | 是 |
内存模型
DeepStream 使用 NVIDIA Video Memory Manager(NVMM)进行零拷贝 GPU 缓冲区传输。Caps 字符串使用 memory:NVMM 表示 GPU 内存(例如,video/x-raw(memory:NVMM), format=NV12)。
关键规则
-
只添加用户要求的组件:切勿添加用户未要求的管道元素。
- 跟踪器(
nvtracker):仅当用户明确要求跟踪或跨帧对象 ID 时才添加 - 次级 GIE:仅当用户要求分类或属性提取时才添加
- 分析(
nvdsanalytics):仅当用户要求越线检测、ROI 计数等功能时才添加 - 消息代理(
nvmsgbroker/nvmsgconv):仅当用户要求 Kafka/云消息传递时才添加 - 如有疑问,请构建最小可用管道,让用户再提出其他需求
- 跟踪器(
-
源默认使用
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 语法:使用
"sink_%u"模板,切勿使用字面 Pad 名称pipeline.link(("decoder", "mux"), ("", "sink_%u")) # CORRECT # pipeline.link(("decoder", "mux"), ("", "sink_0")) # WRONG - will fail -
平台检测与输出端选择:
import platform sink_type = "nv3dsink" if platform.processor() == "aarch64" else "nveglglessink"- 对于 WSL2 Ubuntu 24 Docker,必须覆盖此默认选择。
- WSL2 + Ubuntu 24 Docker:如果
/proc/version包含microsoft或wsl,且/etc/os-release中的VERSION_ID="24.04",生成的应用绝不能创建显示分支或显示输出端(nveglglessink、nv3dsink等),即使提示词要求显示也不例外。此情况不要依赖--no-display标志。仅生成编码后的 MP4 输出(nvv4l2h264enc->h264parse->mp4mux/qtmux->filesink),并让默认运行路径写入带注释的视频文件。在生成的README.md中,明确说明 WSL2 Ubuntu 24 Docker 只能输出 MP4,因为已知问题导致显示输出端被禁用。如果用户明确要求显示,则添加内联代码注释和 README 说明,解释:Display requested but disabled due to WSL2 Ubuntu 24 Docker limitation — MP4 output generated instead. - 非 WSL 目标:不要在生成的应用或 README 中添加 WSL 专属行为或 WSL 限制说明。使用上述常规平台显示输出端选择。
-
缓冲区克隆:始终为异步处理克隆缓冲区
tensor = buffer.extract(0).clone() # CRITICAL -
队列类型:
queue.Queue→ 与threading.Thread配合使用multiprocessing.Queue→ 与multiprocessing.Process配合使用- 使用错误的类型会导致数据静默丢失!
-
nvinfer 配置格式:
- YAML:使用
property:节(不是model:),格式为key: value,冒号后有空格 - INI:使用
[property]节,格式为key=value,使用等号 - 节名必须为
property
- YAML:使用
-
nvmsgbroker 是输出端:不能有下游元素;使用
tee拆分流水线 -
使用 tee 拆分或动态源时,所有输出端都需要 async=0:这对状态转换至关重要
# 使用 tee 拆分或动态源时,所有输出端都必须设置 async=0 pipeline.add("nveglglessink", "sink", { "sync": 0, "qos": 0, "async": 0 # 至关重要——可防止状态转换死锁 })缺少此设置时的症状:流水线停留在 PAUSED 状态,不显示视频。
-
内置探针的附加位置:
measure_fps_probe只能附加到处理元素(例如nvinfer、nvosdbin),不能附加到输出端。附加到输出端会引发RuntimeError: Probe failure。 -
动态 ONNX 模型需要
infer-dims:当 ONNX 模型具有动态输入形状时(例如在 Ultralytics YOLO 中使用dynamic=True导出,或具有动态批次/高度/宽度轴),必须在 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 的原始张量。自定义解析器和
cluster-mode必须与实际输出相匹配:
| 模型代际 | 输出张量形状 | 字段 | 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(无) |
如何在运行时识别:在自定义解析器中记录 inferDims.d[0] 和 inferDims.d[1]。
d={84, 8400}→ NMS 前(v8/v11 风格)d={300, 6}→ NMS 后(v10/v26+ 风格) 不匹配的表现:如果对 post-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;不要为了绕过导入缺失而将 pyservicemaker 管线代码改写为非 pyservicemaker 代码。生成的代码和 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、访问元数据、探针、EventMessageUserMetadata |
| references/use_cases_pipelines.md | 构建 Pipeline:简单播放、多重推理、级联 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 数据丢失 | 将 multiprocessing.Queue 与 Process 配合使用 |
| 配置解析失败 | 在 YAML 中使用 property:,而不是 model: |
is-classifier 弃用警告 | 对分类器使用 network-type: 1,而不是 is-classifier: 1;对检测器省略两者 |
min-boxes 未知键警告 | 在 class-attrs-* 部分使用驼峰形式的 minBoxes,而不是 min-boxes |
| 次级 GIE 未激活 | 设置 process-mode: 2,检查 operate-on-gie-id |
| Tee/动态源卡在 PAUSED 状态 | 对所有 sink 元素设置 async: 0 |
| WSL2 Ubuntu 24 请求显示 sink | 由于已知错误,请勿使用显示 sink;使用 filesink 写入 MP4,并在 README 中说明 WSL 的限制 |
| RTSP 无数据/重新连接 | 使用 ffplay 测试 URL,检查凭据 |
RuntimeError: Probe failure | measure_fps_probe 无法附加到 sink 元素;请改用 nvinfer 或 nvosdbin |
setDimensions 维度为负值/引擎构建失败 | 为动态 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 绑定不同) |