使用 Python pyservicemaker API 開發 NVIDIA DeepStream SDK。適用於建置影片分析管道(video analytics pipelines)、基於 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
- Platforms: Ubuntu 24.04 (x86_64 與 ARM64/Jetson)
典型管道流程 (Pipeline Flow)
Source → Stream Muxer → Inference → [Tracker] → OSD → Renderer
中括號 [ ] 內的元件為選填——僅在使用者明確要求時才加入。
| 階段 | 角色 | 關鍵元件 | 必要? |
|---|---|---|---|
| Source (來源) | 輸入來自檔案、RTSP、攝影機 | nvurisrcbin (首選), nvmultiurisrcbin, filesrc |
是 |
| Stream Muxer (串流組合器) | 批次處理串流以進行推論 | nvstreammux |
是 |
| Inference (推論) | 執行 TensorRT 模型 | nvinfer, nvinferserver |
是 |
| Tracker (追蹤器) | 跨畫格多物件追蹤 | nvtracker |
僅在要求的狀況下 |
| OSD (畫面標註) | 繪製邊界框 (Bounding Box)、標籤與覆蓋層 | nvosdbin |
是 (用於視覺化) |
| Renderer (算繪器/輸出) | 顯示或儲存輸出 | nveglglessink, nv3dsink, filesink |
是 |
記憶體模型
DeepStream 使用 NVIDIA 視訊記憶體管理器 (NVMM) 來實現 GPU 緩衝區的零複製 (Zero-copy) 傳輸。Caps 字串使用 memory:NVMM 來指示 GPU 記憶體 (例如 video/x-raw(memory:NVMM), format=NV12)。
關鍵規則
-
僅新增要求的元件:切勿新增使用者未要求的管道元件。
- 追蹤器 (
nvtracker):僅在使用者明確要求跨畫格追蹤或物件 ID 時新增 - 次要 GIE (Secondary GIE):僅在使用者要求分類或屬性擷取時新增
- 分析元件 (
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)
- 始終使用
-
元資料 (Metadata) 疊代:使用
.frame_items與.object_items(會傳回疊代器 Iterator,而非列表 List)- 切勿對這些物件使用
len()——請透過疊代來計數 - 疊代器只能被消耗一次
- 切勿對這些物件使用
-
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" -
緩衝區複製 (Buffer Cloning):進行非同步處理時,務必複製緩衝區
tensor = buffer.extract(0).clone() # 關鍵步驟 -
佇列 (Queue) 型態:
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:這對狀態過渡(State Transition)至關重要# 當使用 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,或是帶有動態批次/高度/寬度軸),你必須在 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。自訂 Parser 與
cluster-mode必須與實際輸出匹配:
| 模型世代 | 輸出 Tensor 形狀 | 欄位 | cluster-mode |
|---|---|---|---|
| v8 / v11 | [batch, 84, 8400] |
[features(4+80), anchors] — 未經 NMS 的原始 cx/cy/w/h + 類別分數 |
2 (NMS) |
| v10 / v26+ | [batch, 300, 6] |
[max_det, (x1,y1,x2,y2,conf,cls)] — 已完成 NMS,像素座標 |
4 (無) |
如何在執行階段識別:在自訂 Parser 中記錄 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 虛擬環境存取。當任務需要使用 venv 時(例如安裝模型下載/轉換的 pip 相依套件),務必在 venv 內部安裝pyservicemaker與pyyaml。產生的程式碼與 README 中的 venv 設定步驟必須包含:
若缺少此設定的症狀:在 venv 內部執行應用程式時出現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'。
關鍵路徑
- 模型路徑 (Models):
/opt/nvidia/deepstream/deepstream/samples/models/ - 主要偵測器 (Primary Detector):
/opt/nvidia/deepstream/deepstream/samples/models/Primary_Detector/resnet18_trafficcamnet_pruned.onnx - 追蹤器函式庫 (Tracker lib):
/opt/nvidia/deepstream/deepstream/lib/libnvds_nvmultiobjecttracker.so - Kafka 函式庫 (Kafka lib):
/opt/nvidia/deepstream/deepstream/lib/libnvds_kafka_proto.so - 範例設定檔 (Sample configs):
/opt/nvidia/deepstream/deepstream/samples/configs/deepstream-app/
參考文件
重要事項:請務必閱讀這些文件以取得完整細節。切勿憑記憶產生程式碼。
| 文件 | 使用時機 |
|---|---|
| references/gstreamer_plugins.md | 查詢外掛程式 (Plugin) 屬性,列出了所有屬性 |
| 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 | 設計模式、常見陷阱、反模式 (Anti-patterns) |
| 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 | 建立自訂協定轉接器 (Adapter):nvds_msgapi |
快速錯誤參考
| 錯誤 | 解決方案 |
|---|---|
iterator has no len() |
使用疊代進行計數,請勿使用 len() |
pad template not found |
使用 "sink_%u",勿用 "sink_0" |
| Queue 資料遺失 | 搭配 Process 時請使用 multiprocessing.Queue |
| 設定解析失敗 | 在 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 |
| RTSP 無資料/重複連線 | 使用 ffplay 測試 URL,並檢查憑證 |
RuntimeError: Probe failure |
measure_fps_probe 無法附加至 Sink 元件;請改用 nvinfer 或 nvosdbin |
setDimensions 負數維度 / Engine 建置失敗 |
為動態 ONNX 模型新增 infer-dims=C;H;W(例如 infer-dims=3;640;640) |
venv 中出現 No module named 'pyservicemaker' |
在 venv 內部執行 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. -->




