上線影片推理服務 使AI應用更高效

愛奇藝技術產品團隊發表於2020-07-15

寫在前面

在愛奇藝影片影像增強專案中上線影片推理服務,透過最佳化將處理速率提升了10倍,GPU利用率穩定在90%以上。本文透過分享影片推理服務解決方案,幫助為解決利用率低的問題相關從業者提供一些思路。


背 景

和業內專家交流過程中,我們發現影片推理是一個共同的熱點需求和難點需求,普遍反應是深度模型推廣速度快,最佳化工作跟不上模型上線的要求,表現出來是叢集的整體利用率不盡如人意。在愛奇藝AI推理服務中,影像類業務佔了最大的比例,影像的主要來源是影片。業務的服務形式表現為:對影片流資料進行模型推理(後文簡稱影片推理)。
影片推理服務中影片分類業務這一大類最為廣泛應用,通常是採用多個分類模型進行推理,得到一些分類的機率數值或者特徵數值表示。這類服務典型業務有:影片稽核,版權檢查,人臉識別等等。
而影片推理服務中的另一大類服務,則是影片變換服務。簡單來講,就是輸入一個影片,再輸出一個經過變形的影片。這類演算法常常帶有更多的主觀性。影像增強,超解析度的轉換,是目前行業中的代表性業務。
影片變換服務與對比分類服務,有兩個特點:
第一,是計算需求量常常比分類服務高一個或幾個數量級。分類服務通常只需要對影片中的一小部分有代表性資訊進行處理,幀率可以縮減,輸入影像解析度可以降低。影片變換服務則需要針對影片的每一幀影像進行處理,影像解析度常常保持不變,甚至會增大。
第二,是多數演算法需要手動整合。影片變換演算法通常包含比較複雜的前後處理操作,既包含深度模型,又有傳統CV操作。不同影片變換演算法差異性較大,更不容易抽象成統一服務。
 這兩個特點在上線影片推理服務時,我們常常遇到兩個麻煩。第一,效能最佳化不足。如果演算法全量上線,需要的計算資源成本太高;第二,推理功能需要和編解碼功能在一起整合,針對每個模型都要進行手動調整測試。上線週期基本上由平臺工程師的個數決定。
本文重點將放在影片變換服務上,同時會簡單分享在短影片推理服務的最佳化工作。


已有方案

對於影片變換服務,出現在大多數工程師腦中的第一個方案,通常是先將影片拆成影像,然後呼叫原有的影像推理服務,最後將推理結果彙總處理,返回彙總結果。這個彙總結果可能是一系列圖片,也可能是編碼後的影片。

在影片影像增強專案中,編碼團隊改造了ffmpeg,完成解碼→推理轉換→編碼整個過程。其中推理轉換過程,採用了一個自定義的filter,用於前後處理和模型推理。速度比寫硬碟方案快了不少,資源消耗也少了很多。

實際執行過程中,發現GPU利用率較低。主要原因是,CPU編碼速度比GPU推理速度要慢。於是採用GPU硬體編碼器,速度大大提升,GPU利用率有所提升,但是距離GPU計算極限還有較大差距。

這裡需要指出一個普遍存在對GPU利用率(GPU utilization)的誤解。手冊中,GPU utilization含義是:

 “Percent of time over the past sample period during which one or more kernels was executing on the GPU.”

也就是說,計算時間佔總時間的比例。簡單來講,也就是GPU在幹活時間中的比例。至於GPU幹得累不累,需要用另一個指標(Occupancy)來衡量。可惜的是這個指標不是那麼容易拿到。

那麼要怎麼讓GPU工作更加飽滿呢?有一個直接辦法,就是加大計算任務規模。原來一次處理一張圖片,現在一次處理16張圖片。通常把一次處理樣本的數量叫做batch size。對於多數影像模型來說,batch size大於16之後,處理速度不會有顯著增加。調大batch size之後,吞吐量可能增加2-4倍,單張圖片的處理延遲略有增加。

回到影片影像增強專案上,ffmpeg filter API一次只允許處理一張圖片。所以,要另外想辦法。在解釋具體最佳化工作之前,先來分析一些整個任務執行路徑。



一個典型的推理過程如下:

上線影片推理服務 使AI應用更高效

解碼 → NV12轉RGB → 前處理 → 模型推理 → 後處理 → RGB轉NV12 → 編碼



如果編解碼在CPU上完成,推理在GPU完成,還會多出在記憶體和視訊記憶體之間搬移資料的環節。1080p一幀圖片RGB原資料大小為5.93MB。按兩倍影片速率計算,一秒鐘需要在記憶體和視訊記憶體之間傳輸的資料量為:2x24x5.93x2=569.28MB。按照3GB/s的傳輸速度(Pageable Data Transform),大約需要190ms。也就是說大約20%時間,會花費在資料傳輸上。

為了解決資料搬移造成計算斷流的問題,Nvidia提供了一個影片推理解決方案:DeepStream。
DeepStream採用TensorRT(TRT)作為推理引擎,支援多路影片輸入,採用GPU硬編解碼單元進行,影片到影像再到影片的轉換。在整個轉換過程中,所有資料都可以保留在GPU視訊記憶體中,沒有額外換進換出開銷。調優過的DeepStream的任務,速度快,吞吐量接近硬體計算理論峰值。
於是我們做實驗,實驗中TensorRT對不同解析度模型多次執行最佳化過程,模型轉換時間長。不同batch size也需要使用不同的最佳化後模型。如果模型中有不支援的操作,需要編寫對應的外掛。此外,有特殊的前後處理的業務邏輯在DeepStream上整合起來比較困難。
DeepStream在顏色空間轉換時,會發生取整誤差,對色彩比較敏感的模型,結果會出現較大差異。DeepStream使用的影像縮放演算法,也與實際訓練抽幀演算法有差異,造成模型結果不一致。
基於上述原因,我們在影片影像增強專案上,沒有選用DeepStream。


最佳化方案介紹

    最終我們方案如下圖所示:

上線影片推理服務 使AI應用更高效


一個典型的請求流程如下:

  1. 請求方傳送任務請求到服務入口;

  2. 服務入口程式將任務資訊,如影片來源地址/目標地址、回撥地址等資訊記錄到資料庫中;

  3. 工作程式(worker)讀取任務資料庫,執行推理邏輯,最後將處理結果上傳到雲端儲存,併傳送處理結果到回撥地址。

其中,工作程式的推理環節是我們最佳化的重點和難點。


這個方案有三個特點:
  1. 所有操作都在GPU完成,並且支援批次推理;

  2. 前後處理及推理過程都透過python指令碼完成;

  3. 完整方案包括影片下載,處理,上傳流水線並行服務。

第一個特點與DeepStream類似,效能引數也和DeepStream相當,就不贅述。
細節見下圖:
上線影片推理服務 使AI應用更高效

本方案的第二特點是最獨特的亮點,解決DeepStream內部黑盒操作方式,最大化使用自由度。我們採用使用者自定義python指令碼,來載入模型和執行推理,大大增加了業務適配和驗證工作的速度。本方案提供的python環境預裝了Tensorflow,PyTorch,cupy,opencv等常見的演算法庫,覆蓋了大多數基本功能。同時也支援自定義CUDA kernel呼叫,解決長尾和效能需求。

一些模型還有複雜的前後處理要求。開始部署時,對資源的需求量比較少,透過指令碼快速開發,將一些基礎操作組合起來,實現業務快速落地,儘早評估模型效果,加快迭代速度。如果反饋結果比較好,業務擴大服務規模,資源需求變得龐大。這時我們可以針對計算瓶頸,使用CUDA API編寫計算kernel,提高計算效率,節省大量成本。

我們最終的期望是,演算法工程師可以自行使用SDK來除錯推理功能,確認結果,以減少平臺工程師介入。同時,SDK還提供了操作計時功能,可用於分析效能瓶頸。

常見使用場景是,一個服務通常會使用多個模型進行推理,然後使用boosting演算法取得更加可靠的結果。本方案可以輕鬆支援多模型推理,只要視訊記憶體容量滿足需求,甚至可以同時對Tensorflow和PyTorch的模型進行推理。

在不同計算框架間,進行資料交換,是這個方案面臨的重要問題。深度學習開發社群提出了DLPack協議,來解決這個問題。因為DLPack沒有做資料搬移,效能損失可以忽略。這個協議一推出就得到PyTorch,mxnet,cupy等框架的支援。但是在專案開發時,Tensorflow還沒有不支援DLPack功能。Google工程師建議,將視訊記憶體資料搬移到記憶體中,生成一個numpy物件後,再傳送到Tensorflow Session。這樣一來,把資料保持在視訊記憶體的設計就被打破了。我們透過編寫了特殊的Tensorflow OP,解決了這個問題。這個OP將視訊記憶體中的資料複製到指定變數中,推理時使用指定變數作為輸入。但在使用這個特殊OP時,呼叫者需要保證傳遞的資料不能超過目標變數的空間。

值得慶幸的是,社群開發了tfdlpack-gpu來完成這個目標。這個特殊OP也完成了它的歷史使命。


僅僅“算得快”還不能滿足業務實際需求。我們將整個計算過程封裝成一個統一服務:從開發除錯,模型部署,到執行監控,形成了完整功能閉環。為了更好的提供開箱即用體驗,我們提供了任務管理、監控、日誌等API。演算法工程師只需要提交模型和推理指令碼,就可以在雲端部署服務。排程系統可以根據待執行任務的多寡進行動態的擴縮容,也可以按照預先設定完成定時擴縮容。

在推廣該方案中,我們遇到的一個最常見的問題是:推理時預處理結果和訓練的樣本不一致。影片解碼完之後,拿到的結果通常是NV12編碼,透過自定義的CUDA kernel轉換成RGB編碼。但是,因為不同運算單元的計算方式和取整誤差的影響,CUDA kernel得到RGB編碼與ffmepg拿到的結果存在1%-2%的誤差。雖然人眼看過去沒有太大區別,但是對模型結果卻有不同程度的影響。此外,不同的影像縮放演算法也給結果帶來不小的影響。

解決預處理結果不一致問題,最直接的辦法是使用影片推理服務對訓練素材進行處理,用同一個預處理結果進行訓練。這樣方式,保證了訓練和推理時的輸入一致性。


短影片推理服務

在解決長影片變換問題之後,我們嘗試將這個服務擴充套件到短影片推理業務上。短影片推理服務多用於稽核、打標籤等業務中,使用場景多為同步線上服務。這就對整個請求延遲要一定的要求。業務願意用更多的資源來換取更低的請求延遲,所以這類服務線上上的GPU利用率比長影片服務更低。

要達到低延遲的目標,常見的辦法是降低處理資料量。其中一個典型的方法是,只對短影片的關鍵幀做處理。一兩分鐘的影片,關鍵幀的數量為10到20個。這方式可以透過一次推理就能取得結果。

但是為長影片構建的流水線,在短影片上表現得並不好。因為在開始解碼前,我們需要對硬體解碼器做初始化,通常會花費大約110ms。推理的耗時大概也在100ms左右,實際端到端延遲是純推理耗時的大約兩倍。經過仔細閱讀手冊,我們發現一個解決辦法:對硬體編碼器進行重新配置,而不是重新初始化。拿到第一幀資料的時間從110ms縮短到15ms。最終得到的結果是,推理時間佔比大於85%。


總 結


經過愛奇藝技術產品團隊的細緻調優後,影片影像增強專案最終吞吐速率比ffmpeg方案提升了10倍,相同的任務使用的資源量只有原來的10%。這樣因為資源使用量減少了,所以影片影像增強專案中,運營同學就可以把節約的資源更多的用於擴大影片增強的覆蓋範圍。

上線影片推理服務 使AI應用更高效
值得注意的是,V100實際吞吐量是T4的2.57倍。但是,T4標稱的fp16處理能力是V100的一半。猜測可能原因是,T4的記憶體頻寬是V100的1/3。綜合考慮,我們最終還是使用了V100來處理影片。使得實際執行過程中,影片影像增強服務GPU利用率始終保持在90%以上。
上線影片推理服務 使AI應用更高效
隨著深度學習模型不斷快速迭代發展、應用範圍不斷擴充、業務模式不斷的更新變化,單一種服務方式已經不能滿足全部需求。本專案針對影片推理服務,透過將由GPU執行推理服務全流程,支援自定義推理指令碼,將推理和資料傳輸並行等方式,達到了良好計算效率與最佳化工作量的平衡,實現了影片推理類模型的快速落地,同時節省了大量成本。我們希望透過平臺化標準化影片推理服務,解決模型上線難和影片推理上線利用率低的問題,讓演算法工程師從繁瑣的工程實踐中得到解放

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69945252/viewspace-2704704/,如需轉載,請註明出處,否則將追究法律責任。

相關文章