mcpField
D
deepstream-profile-pipeline

deepstream-profile-pipeline

github.com/nvidia测试与质量3.8k752 次安装今天更新
代码仓库

关于 deepstream-profile-pipeline

这是用于创建并测量高效 NVIDIA DeepStream 流水线的性能分析技能。它根据推理吞吐量和硬件上限推导配置,再用 Nsight Systems 命令行报告端到端及插件耗时。

主要功能

  1. 01应用面向性能的流水线默认配置
  2. 02测量推理批量大小平台点
  3. 03根据 GPU 上限推导设置
  4. 04使用 Nsight Systems 命令行分析
  5. 05报告各插件的 NVTX 耗时

适用场景

  1. 01根据目标流数量优化新流水线
  2. 02测量 GPU 与推理吞吐上限
  3. 03定位影响端到端耗时的流水线阶段

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nvidia/skills --skill deepstream-profile-pipeline

安装后在 Claude Code 中输入/deepstream-profile-pipeline确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

BENCHMARK.md
README.md
requirements.txt
skill-card.md
skill.oms.sig
evals/
evals.json
references/
boundedness-rules.md
config-derivation-rules.md
hw-ceiling-formulas.md
nsys-cli-recipes.md
nvtx-coverage.md
scripts/
capacity_report.py
tests/
__init__.py
README.md
test_capacity_report.py

详细介绍

DeepStream 性能分析技能

基于性能分析创建流水线。当用户表示希望构建高效的 DeepStream 流水线时,此技能会用两个实测数值——推理平台批次和硬件上限——取代猜测,并据此推导其他所有配置。随后使用 Nsight Systems 对端到端流水线进行性能分析,并报告各插件的 NVTX 耗时。

**与模型和流水线无关。**此技能仅假设推理元素为 nvinfer 或 nvinferserver(因此可通过标准配置设置模型维度、精度和批次参数)。它适用于检测(有或没有跟踪器)、分类、分割、VLM 和嵌入流水线。源可以是文件、RTSP、USB 摄像头,也可以是任意组合。此技能会读取用户的实际配置,以确定模型维度、目标 FPS 和源属性——不会假设任何特定模型、编解码器或分辨率。

**限制。**仅限终端操作。使用 nsys profile 进行采集,并使用 nsys stats 提取数据。 不要依赖 Nsight Lens 或任何 GUI。

触发时机

在创建流水线时,当用户的请求体现出效率诉求时,启用此技能。具体触发条件:

  • “构建一个高效 / 快速 / 性能出色 / 优化过的流水线”
  • “给我一个能在这块 GPU 上良好运行的流水线”
  • “对这个流水线进行基准测试 / 性能分析 / 测量 / 调优 / 优化”
  • “我想以 M FPS 运行 N 路流”
  • “这块 GPU 最多能处理多少路流”
  • 用户明确要求使用 nsys 或 Nsight

对于没有性能诉求的普通请求,例如“构建一个流水线”/“显示这个视频”/“保存这个流”,改用 deepstream-generate-pipeline 技能。

6 阶段流程

按顺序执行各阶段。阶段 0 在生成流水线之前执行,因此用户一开始就能获得经过性能调优的骨架。阶段 1–5 用于测量和验证。

阶段 0 — 预设应用(创建流水线时)

触发条件:编码 Agent 即将生成新的 DS 流水线,且用户的提示词表达了效率意图(见上文“触发时机”)。

操作:无需询问,预先应用以下默认值。用户无需了解这些设置,只需获得配置妥当的流水线。

参数默认值跳过条件
nvinfer.network-mode如果 int8-calib-file=<path> 指定的路径中存在校准文件,则设为 1(INT8);否则设为 2(FP16)。绝不使用 FP32。模型没有 INT8 校准文件,且用户明确要求使用“FP32”。
nvinfer.model-engine-file预构建的 .engine 路径始终设置。测量前强制进行一次预构建。
nvinfer.infer-dims与模型原生输入匹配的 3;<H>;<W>始终设置,即使 ONNX 模型具有静态形状也无妨。
nvstreammux.batch-size微基准测试优化前设为 min(N_streams, 16)—
nvstreammux.width / height模型的原生输入尺寸(从 nvinfer 配置的 infer-dims=3;H;W 中读取)用户明确要求 muxer 使用源视频原生分辨率。
nvstreammux.batched-push-timeout1e6 / source_fps µs(30 fps 时为 33333)—
nvstreammux.nvbuf-memory-type0(NVMM)—
解码器 num-extra-surfacesmin(batch_size, 5)—
解码器 cudadec-memtype0(NVMM)—
Sink基准测试版本使用 fakesink sync=False用户要求屏幕显示或磁盘录制(此时保留 OSD/tiler/encoder/sink,并生成两个版本)。
OSD + tiler省略用户要求可见输出。
Tracker ll-config-fileconfig_tracker_NvDCF_max_perf.yml(随 DS 9.0 提供的性能调优版 NvDCF 预设)不存在 Tracker。
Tracker tracker-width / height480 / 288—
Tracker enable-batch-process(位于链接的 YAML 中)1—
source 与 pgie 之间的 Queuemax-size-buffers = batch_size × 4用户未要求添加 Queue(较少见)。
Kafka/消息队列max-size-buffers=2, leaky=2不使用 Kafka。
解码侧 PerfMonitor添加(除 pgie 侧外)流水线为 nvurisrcbin → pgie 直接连接,中间没有 Queue。

**阶段 0 的作用:**如果没有此阶段,每条新生成的流水线都会从优先显示的默认配置开始,阶段 1–5 就需要花时间修复本可避免的问题。阶段 0 是一道“从一开始就不要写出糟糕流水线”的关卡。

学生 / API 用户不会看到这些参数。该技能向用户返回的内容会使用通俗英文(FPS、流数量、观察到的瓶颈),而非参数名称。

验证流程(阶段 1–5)

按顺序运行各阶段。不要跳过任何阶段;后续阶段依赖前面阶段的输出。

阶段 1 — NVTX 覆盖检查

DeepStream 插件会原生发出 NVTX 范围;自定义插件和纯 GStreamer 核心元素(queue、tee、h264parse 等)则不会。在分析性能之前,列出流水线使用的元素并逐一分类。

  • 读取流水线定义(gst-launch 字符串或 pipeline.py)。
  • 在 references/nvtx-coverage.md 中查找每个元素。
  • 将其分类为 已覆盖(在此 DS / 镜像 / nsys 组合中会发出 NVTX)或 未插桩。
  • **MVP 规则:**该技能优先使用逐插件 NVTX 作为确认依据,但不作强制要求。解码瓶颈诊断依据微基准测试特征和 nvidia-smi dmon;计算瓶颈诊断依据 CUDA 内核组合;内存复制诊断依据 cuda_gpu_mem_time_sum。NVTX 是额外的参考信息。
  • 对于未插桩的元素,该技能会报告“此版本中无法直接测量”,并继续应用封闭形式的 R1–R6 参数(这些参数根据输入推导,而非依赖逐插件性能分析数据)。
  • 此版本不包含为未插桩元素自动注入 NVTX 的功能——在最终报告中将其列为后续事项。

阶段 1 的输出:简短的覆盖情况表,例如:

nvurisrcbin       COVERED
nvstreammux       COVERED
nvinfer           COVERED
nvtracker         COVERED
queue_src         UNINSTRUMENTED — not re-tuned
fakesink          UNINSTRUMENTED — not re-tuned
阶段 2 — 硬件发现

运行 nvidia-smi,推导主机 GPU 的理论上限。最低查询要求:

# Identity + memory + compute
nvidia-smi --query-gpu=name,compute_cap,memory.total,memory.free,\
clocks.max.sm,clocks.max.memory,utilization.gpu \
--format=csv,noheader,nounits

# NVDEC / NVENC utilization (per-engine)
nvidia-smi --query-gpu=utilization.decoder,utilization.encoder \
--format=csv,noheader,nounits

# PCIe link width/gen (for H2D memcpy ceiling)
nvidia-smi --query-gpu=pcie.link.gen.current,pcie.link.width.current \
--format=csv,noheader,nounits

根据这些数据推导:

  • 解码上限(fps):NVDEC_count × 源分辨率下每个单元的 H265/H264 fps (参见 references/hw-ceiling-formulas.md 中的表格)。
  • 计算上限(TOPS):SM 数量 × 时钟频率 × 目标精度下每个时钟周期的运算数。这给出 一个上限——实际模型的性能可达到该值的 30–60%。
  • 内存带宽上限(GB/s):内存时钟频率 × 总线位宽。模型权重读取和激活值应远低于此上限。
  • Memcpy 上限(GB/s):PCIe 代际 × 通道数 × 0.8(实际值)。仅当 NVMM 出现故障,且第 5 阶段中出现 H2D/D2H 传输时才相关。

保存推导出的上限——它们将用于第 5 阶段的“实际值与理论值”部分。

完整公式和按编解码器分类的 NVDEC 吞吐量表: references/hw-ceiling-formulas.md。

阶段 3 — 仅推理微基准测试

仅运行推理阶段(source → streammux → nvinfer → fakesink),遍历 batch-size 以找到平台区间。这样可以从其他因素中隔离模型的真实峰值 FPS,并回答“一个批次中可容纳多少路流而不降低 FPS?”

遍历范围:batch-size ∈ {1, 2, 4, 8, 16, 32}(上限为 N_streams 和 GPU 内存容量)。

对于每个批次大小:

  • 设置 nvstreammux.batch-size = nvinfer.batch-size = B。
  • 设置 nvstreammux.width/height = 模型原生的 infer-dims(从 nvinfer 配置中读取)。
  • 将 fakesink sync=False 设为唯一分支。
  • 运行 30 s;从 measure_fps_probe(控制台)或 DS PerfMonitor 测量 FPS。
  • 记录 (B, fps)。

平台批次大小 = 最小的 B,使得增至 2×B 后 FPS 提升 < 5%。这就是完整流水线的目标批次大小。

如果用户的 N_streams ≤ 平台批次大小,则设置最终批次大小 = N_streams。否则设置最终 批次大小 = 平台批次大小,并注明流水线将在每个 tick 中分多个批次处理流。

阶段 4 — 推导配置

根据 (plateau_batch, HW_ceilings, N_streams, source_res, source_fps),一次性设置所有可调参数。不要一次只调一个参数——推导规则都有确定的解析形式。

按顺序设置以下参数:

  1. Streammux:batch-size = final_batch,width/height = min(source_res, infer_dims), batched-push-timeout = 1e6 / source_fps µs,nvbuf-memory-type = 0。
  2. 推理:batch-size = final_batch,network-mode = 1 (INT8) if calib file exists else 2 (FP16),interval = 0,infer-dims = 模型原生维度,model-engine-file = 预构建的 .engine 路径。
  3. 解码器(在 nvurisrcbin / nvmultiurisrcbin / nvv4l2decoder 上): num-extra-surfaces = min(final_batch, 5),cudadec-memtype = 0,nvbuf-memory-type = 0。
  4. 跟踪器(如有):enable-batch-process = 1,跟踪器分辨率为 480×288,将 ll-config-file 指向 config_tracker_NvDCF_max_perf.yml。
  5. 队列(如存在于解码器和 streammux 之间,或 streammux 和 nvinfer 之间): max-size-buffers = final_batch × 2。Kafka/消息分支:leaky=2, max-size-buffers=2。

包含每条公式及一句“原因”说明的完整推导表: references/config-derivation-rules.md。

将推导出的值写入用户的配置文件(pgie_config.yml、 tracker_config.yml、pipeline.py 源属性,以及任何 deepstream-app .txt 文件)。 始终先 Read 再 Edit。只做必要的精确修改——不要重新格式化无关行。

阶段 5 — 端到端分析与报告

在 nsys profile 下运行端到端流水线,并通过 nsys stats 提取各插件的耗时。

采集:

TS=$(date +%Y%m%d_%H%M%S)
OUT=/tmp/ds_profile_${TS}
nsys profile \
  --trace=cuda,nvtx,osrt \
  --gpu-metrics-devices=all \
  --cuda-memory-usage=true \
  --force-overwrite=true \
  --duration=30 \
  --output=${OUT} \
  <your-pipeline-launch-command>

提取:

# Per-kernel GPU time (top 10)
nsys stats --report cuda_gpu_kern_sum --format csv ${OUT}.nsys-rep | head -20

# Per-NVTX-range time (top 10) — this is the DS per-plugin breakdown
nsys stats --report nvtx_sum --format csv ${OUT}.nsys-rep | head -20

# Memcpy totals
nsys stats --report cuda_gpu_mem_time_sum --format csv ${OUT}.nsys-rep

# GPU metrics (SM activity, DRAM throughput) — requires --gpu-metrics-devices
nsys stats --report gpu_metric_gpu_util_sum --format csv ${OUT}.nsys-rep

完整命令参考:references/nsys-cli-recipes.md。

报告(Markdown,输出到 stdout——不使用外部 UI):

## Profile summary

**Hardware**: <name>, <mem_total> GB, SM x<sm>, NVDEC x<nvdec>, PCIe Gen<g> x<w>
**Ceilings**: decode <X> fps, compute ~<Y> TOPS @ INT8, memory <Z> GB/s

**Inference plateau**: batch=<B>, peak=<F> fps per batch → <F × B> fps aggregate

**E2E measured**: <actual> fps  (=<pct>% of inference plateau)

### Per-plugin time (from NVTX) — only for plugins emitting NVTX in this build

| Plugin          | Share of wall time | GPU / CPU | Notes |
|-----------------|--------------------|-----------|-------|
| nvinfer         | <pct>%             | GPU       | (always emitted; if absent, NVTX injection is broken) |
| nvdsosd         | <pct>%             | GPU       | (when in pipeline) |
| ...             | ...                | ...       | (other plugins as the verification probe shows) |

(Numbers above are illustrative — fill in from `nsys stats --report nvtx_sum`. Plugins
that don't emit NVTX in your DS / image combo simply don't appear; that's not a bug, it's
the limit of what NVTX captures here. See `references/nvtx-coverage.md`.)

### Applied configs (sample shape; values come from R1–R6 + Stage 3 measurements)

- `nvstreammux.batch-size = <plateau_batch>`
- `nvinfer.network-mode = 1 (INT8)` if calibration available, else `2 (FP16)`
- decoder `num-extra-surfaces = min(plateau_batch, 5)`
- queue between source and pgie, `max-size-buffers = plateau_batch × 4`
- ... (full list per the user's pipeline shape)

### Uninstrumented (skipped re-tune)

List the elements that didn't emit NVTX in this build (typically the closed-source binary
plugins — see `references/nvtx-coverage.md`) plus plain GStreamer-core helpers. Report
them so the user knows what wasn't directly measurable.

摘要应简洁。原始 nsys stats CSV 写入临时文件,不要放在回复中。

参考文档

文档适用场景
references/nvtx-coverage.md阶段 1——将每个流水线元素分类为 COVERED 或 UNINSTRUMENTED。
references/hw-ceiling-formulas.md阶段 2——将 nvidia-smi 输出转换为解码/计算/内存上限。
references/config-derivation-rules.md阶段 4——按 (plateau_batch, HW, N_streams, source_res, source_fps) 索引的逐参数公式。
references/nsys-cli-recipes.md阶段 3 和 5——精确的 nsys profile/nsys stats 调用命令。

非目标(此版本)

  • 不使用 Nsight Lens/GUI。 仅使用终端。
  • 不为未插桩的插件自动注入 NVTX。 MVP 会跳过这些插件的参数。后续版本再处理。
  • 没有迭代式的调优—测量—调优循环。 阶段 4 根据闭式规则一次性推导配置;阶段 5 进行测量并报告结果。如果用户想继续调优,可以使用更新后的输入重新调用该技能。

相关技能

  • deepstream-generate-pipeline——上游流水线生成。此技能假设流水线已存在或即将生成。
  • deepstream-byovm——HF → TensorRT 引擎构建。如果用户带来了新模型,请先运行此技能,再运行本技能。

备注

  • 按照仓库 CLAUDE.md 中的约定,此技能与其他 DS 技能一起位于 skills/deepstream-profile-pipeline/。
  • 要获取任何插件属性(类型、默认值、范围)和 Pad caps 的真实信息,请在 DS 容器内查询已加载的二进制文件:
    gst-inspect-1.0 nvinfer
    gst-inspect-1.0 nvstreammux
    gst-inspect-1.0 nvurisrcbin   # works on closed-source binary plugins too
    gst-inspect-1.0 | grep ^nv    # list every NVIDIA-specific element this build ships
    
    插件命名约定:任何以 nv* 为前缀的元素都是 NVIDIA DeepStream 专用元素(支持 NVMM,可能会发出 NVTX);其他所有元素都是上游 GStreamer-core(不支持 NVMM,绝不会发出 DS NVTX)。在排查陌生流水线时,将此前缀作为初步分类依据。
  • 插件代码的开源子集位于 /opt/nvidia/deepstream/deepstream/sources/gst-plugins/ 下;如需阅读实现,可查看此处(只有部分插件开源;对于闭源插件,必须通过 gst-inspect-1.0 检查,并在运行时观察其行为)。

评论

支持 Markdown