影片結構化 AI 推理流程
「影片結構化」是一種 AI 落地的工程化實現,目的是把 AI 模型推理流程能夠一般化。它輸入影片,輸出結構化數據,將結果給到業務系統去形成某些行業的解決方案。
換個角度,如果你想用攝影機來實現某些智慧化監控、預警等,那麼「影片結構化」可能就是你要用到的技術方案。
不過,也不一定需要自己去實現,因為各個晶片廠商可能都提供了類似的流程框架:
以上個人沒用過,簡單看了下,都受限於只能用廠商自家的晶片。個人經驗來說,一般硬體還是需要多家可選的,自己實現一套「影片結構化」還是有必要的。
本文將介紹「影片結構化」的實現思路、技術架構,以及衍生的一些工作。
實現思路
有一個 AI 模型與一段影片,如何進行推理呢?
- 影片流:OpenCV 打開影片流,獲取影像幀
- 前處理:影像 Resize 成模型輸入的 Shape
- 模型推理:AI 框架進行模型推理,得到輸出
- 後處理:將輸出處理成期望的資訊
- 例如,目標檢測:解析框的位置和類別,再 NMS 篩選
以上是最基礎的推理流程,完成得不錯👏
簡單任務,這樣滿足要求就行。但實際任務,可能:
- 輸入
- 任務接收
- 影片流
- 相機選型
- 影片來源: 錄製影片、RTSP 實時流
- 幀率控制: 一般 5 fps,減少計算
- 多路並發: 多路影片,並行分析
- 硬體解碼
- 推理
- 前處理
- 輸入調整: 縮放、轉置
- Batch 合併
- 硬體加速
- 模型推理
- 硬體選型: Nvidia、華為昇騰、或其他
- 模型處理: 裁剪、轉換、量化
- 模型編排: 多任務多模型,有先後關係
- 後處理
- 輸出解析: 推理結果,變為結構化數據
- 硬體加速
- 前處理
- 輸出
- 結果推送
- 其他
- 影片存儲,License
- 鏈路追蹤,耗時分析
以上流程一般稱為「影片結構化」:輸入多路影片,進行實時分析,最後輸出結構化數據,給到業務系統。
該流程,這裡把它分為了輸入、推理、輸出,都是一個個任務節點,整體採用 Pipeline 方式來編排 AI 推理任務。輸入輸出時,一般會用 RPC 或消息隊列來與業務系統通訊。
整體架構
「影片結構化」整體架構,如下:
管道節點
管道 Pipeline 這塊是主要部分,其實現都是一個個節點:
- IN
- 任務接收;影片流解碼;幀率控制
- 推理
- 推理引擎做模型推理,結果進結構化數據;依編排往後繼續
- 追蹤
- 追蹤依賴推理出的特徵;業務不需要,就不編排
- OUT
- 結果推送;要預覽播放的話,進行影片流編碼
節點就是個生產消費者,用個阻塞隊列很快就能實現。節點間組成一個樹,也就是任務編排的結果。節點會有輸入輸出差異,要約定清楚或分幾個類型。
節點流程:消息隊列有任務,取出執行,結果進結構化數據,最後發給下一節點的消息隊列。
節點的執行緒數、隊列上限,都可做配置。依據耗時分析,可以優化調整。
GStreamer 的 pipeline + plugin 的技術架構值得學習。個人沒深入了解,所以不好具體評價,倒見過在輸入做插件化解碼。NVIDIA DeepStream 直接就基於 GStreamer 開發的。
結構數據
結構化數據,在整個 Pipeline 里是不斷追加完善的過程,最後輸出時一般 JSON 化推送。
它的內容約定,是最主要的。會有:
- 基礎資訊: task, frame 等資訊
- 推理結果: 會以任務分類進行標籤
它會用作節點的輸入,例如獲取人臉特徵,依賴前一目標檢測節點的人臉 boxes 資訊。
基礎模組
- 全局配置
- 通用配置、節點配置與編排;可視化編排,實際就是編輯它
- 一般 JSON 格式,結構化數據最後也 JSON 化
- 進程保活
- Supervisor 不錯,可以把終端日誌配置進文件
- 消息通訊
- 與外部系統,用 RPC 或 Redis,也可能推送 Kafka
- 內部用自己的消息隊列
- 記憶體共享
- 用在影像幀,以免拷貝,幀 ID 標識
- 顯示記憶體也預申請,隊列分配,減少 Host & Device 拷貝
技術選型
「影片結構化」用 C++ 實現,主要以下幾點:
- FFmpeg 編解碼(CPU)
- OpenCV 前後處理(CPU)
- 晶片生態庫,硬體加速:編解碼與前後處理
- 如 Nvidia: video codec, npp, nvjpeg; 昇騰 dvpp 等
- 基礎庫,選擇主流的就好,如:
- Log:gabime/spdlog, google/glog
- JSON: nlohmann/json
- RPC: grpc/grpc, apache/incubator-brpc
更詳細的技術棧,可見該分享://zhuanlan.zhihu.com/p/362711954 ,思維導圖很詳細。
「影片結構化」實現有些要看自己的權衡:
- 一個項目怎麼支援多個硬體?
- 編譯自動區分環境,編譯不同程式碼,最終會產生多套部署
- 需要抽象推理、前後處理等硬體相關功能
- 也可以考慮插件實現,管理好插件配置
- 編譯自動區分環境,編譯不同程式碼,最終會產生多套部署
- 影片流要不要用流媒體框架?
- 簡單點直接 FFmpeg,不引入 GStreamer
- 影像與結果怎麼優化同步?
- 只是影像顯示,存儲提供鏈接進結果(注意 IO 瓶頸)
- 本身影片顯示,直接繪製結果進影像,編碼進流
- 或預覽端自己實現,流數據包攜帶結果
衍生工作
「影片結構化」會有一些衍生的工作:庫、工具或系統。
首先,模型一般自定義格式,一是保護,二是方便自己使用。所以,會把原模型及其配置封裝進自定義格式,還會標明推理方式、前後處理選擇等。
這裡會有如下兩個部分:
- 模型轉換工具鏈: 不同硬體模型轉換後,再封裝進自己格式
- 模型推理引擎: 模型解封裝,再依配置進行推理,出結果
模型可能還要裁剪、量化,也是工作的一部分。
其次,任務情況、JSON 配置、日誌等,成熟一點,還會提供管理後台方便使用。
此外,還可能有:
- License: 生成、校驗相關工具,及管理記錄
- 除了有效期,還可以考慮限制路數、任務等
- 實時監控: 硬體狀態監控、預警
結語
「影片結構化」只是 AI 落地的一部分,實際做方案一是對接演算法模型、二是對接業務系統,還可能要去適配新的攝影機或硬體平台。
也就是會有兩種支援列表:硬體列表、模型列表。這就是積累的成果了。
「影片結構化」會部署成中心伺服器,或邊緣計算。不過,只是簡單任務,現在可能智慧攝影機就夠了,都帶邊緣計算識別人臉什麼的。
GoCoding 個人實踐的經驗分享,可關注公眾號!