影片結構化 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 個人實踐的經驗分享,可關注公眾號!

Tags: