BANG:B站影片影像分析與處理引擎

陶然陶然發表於2022-11-09

   前言

  為了給使用者提供更好的影片觀看體驗,B站已研發出很多先進的影片影像分析與處理演算法。在影片轉碼任務中,這些演算法既可以改善影片畫質,也可以促進轉碼效率的提升,從而實現更高畫質、更流暢的影片效果。研發的演算法種類繁多,用途各異,同時B站不同業務對於演算法的要求也各不相同。為了能夠對各種基本演算法進行高效部署和管理,同時向各個業務方提供簡單靈活且統一的呼叫介面,B站研發了一套功能強大的影片影像分析與處理引擎——BANG(Bilibili video/image Analyzing and processiNg enGine)。  

B站影片影像分析與處理引擎

  BANG 向下包羅各種影片影像分析與處理演算法,向上提供即插即用的呼叫介面,從而為直播和點播轉碼等業務提供服務。目前, BANG 已應用到多項影片雲轉碼業務中。比如,在質量可控的點播最佳化轉碼系統中,負責感興趣區域(ROI)檢測、傳統影片前處理,以及機器學習視覺無損前處理演算法的部署;在 S12、TI11 賽事直播轉碼業務中,負責 深度學習超分和增強演算法的部署。

  針對直播和點播轉碼業務的特點,BANG對於演算法部署執行的效率有極高的要求。BANG 引擎內部採用了高效的多級流水線架構,同時引入了幀內分塊並行、多幀並行等多種並行機制,使整個轉碼流程可以獲取儘可能大的吞吐量。此外,為了充分利用 GPU 資源,BANG提供了基於 CUDA 的核心運算元,同時還封裝了 TensorRT、TensorFlow 等深度學習模型推理庫,從而讓核心演算法工作在高效率。

  對於業務方,BANG 提供了一套統一且簡潔的呼叫介面,可以方便快捷地整合到各種直播、點播的轉碼系統中,有效避免了重複開發。轉碼系統呼叫演算法時,只需傳入配置影片影像分析與處理邏輯的字串。BANG 可以自動管理基本演算法,生成符合業務需求的影片處理流水線。比如,在 S12 超分演算法中,為了避免對三次元人臉過度處理而產生失真,業務方只需透過配置,呼叫 ROI 檢測和人臉區域旁路處理,即可達到人臉保護的效果。下面我們對 BANG 進行更詳細的介紹。

   01 高效的多級流水線架構

  一種典型的影片處理和轉碼系統是採用單執行緒,對每一幀依次進行解碼、分析、處理和編碼操作。雖然這樣實現起來很簡單,但由於每一幀的處理週期是所有操作的時間之和,因此係統的吞吐量非常低。為了提高系統的吞吐量,我們採用了多級流水線架構。下圖中的模型展示了多級流水線提高吞吐量的原理。  

BANG 的多級流水線架構可以顯著提高吞吐量

  如圖所示,BANG 為解碼、分析和處理階段分配了獨立的緩衝佇列,同時為分析和處理單獨分配了執行緒。因此,分析、處理可以與編、解碼並行執行。在該流水線架構下,影片轉碼系統按照如下步驟對每一幀進行處理:

  解碼器對碼流進行解碼。解出一幀放入解碼佇列後,繼續解碼下一幀。

  影片分析執行緒從解碼佇列中讀取解碼幀,然後對影片內容進行分析,獲取 ROI、影片質量等資訊。分析之後將影片幀和結果送入分析佇列。

  影片處理執行緒從分析佇列中讀取影片幀及其內容分析結果,然後按照配置對影片影像進行處理。處理之後的影像放入處理佇列。

  編碼器讀取處理佇列中的影片幀,進行編碼輸出。

  上述 4 個操作分別由 4 個執行緒並行執行。每個執行緒各司其職,整個流水線在同一時間對多幀進行處理。因此,系統可以充分利用計算資源,顯著提高轉碼系統的吞吐量。

  由於輸入、輸出以及內部處理的緩衝佇列由BANG維護,因此呼叫 BANG 的方法非常簡單。業務方只需提供一個返回處理結果的回撥函式,並將解碼影像一幀一幀送給 BANG 即可。BANG 在收到解碼影像後,會對影片幀進行非同步處理。處理結果會透過回撥函式返回給轉碼系統。

  基於高效的多級流水線結構, BANG 既可以被方便快捷地整合,同時也能取得到非常高的吞吐量。比如,在 S12 4k 超分專案中,超分模型本身的推理速度為 75fps;而採用 BANG 的超分轉碼系統,端到端也能達到同樣的速度。換句話說,在轉碼業務中,BANG 幾乎可以讓處理演算法發揮出百分之百的效率。

   02 基本演算法的加速和部署

  從上面的示意圖可以發現,整個轉碼系統的吞吐量取決於解碼、分析、處理和編碼中最耗時的模組。因此,為了進一步提高吞吐量,需要對比較耗時的分析和處理演算法進行加速最佳化。在 BANG 中,影片影像分析和處理演算法大致分為兩類——基於傳統方法的演算法和基於深度學習的演算法。我們對這兩類演算法採用了不同的加速策略。

  基於深度學習的演算法一般是以一個網路模型的形式存在。透過標準的卷積、歸一化等操作,此類演算法對影像進行端到端的處理。演算法邏輯由模型結構和模型引數隱式定義。對於基於深度學習的演算法,BANG藉助 TensorRT 深度學習推理庫進行部署。TensorRT 是 Nvidia 推出的加速深度學習推理的工具集,主要包含模型最佳化工具和執行時推理庫。在 Nvidia 系列顯示卡上,TensorRT可以有效加速模型的推理速度。  

Nvidia 關於 TensorRT 的介紹

  我們首先利用 TensorRT對各種深度學習模型進行離線最佳化,將模型轉換成 32 位和 16 位混合精度的模型。然後, BANG 呼叫 TensorRT 推理介面,載入模型檔案後,即可進行推理,對影像進行分析和處理操作。實踐表明,與TensorFlow 推理庫相比,使用 TensorRT 最佳化和部署模型可以取得約 100% 的加速。不過,TensorRT 還在發展過程中,有一些個性化的操作還不支援。因此,BANG中仍加入了 TensorFlow 推理庫,以部署包含特殊操作的深度神經網路。最近,隨著 TensorFlow 逐漸式微,PyTorch 不斷完善,BANG後續還將加入 PyTorch 推理庫,以獲得更大的相容性。此外,考慮到模型推理前後往往涉及資料的基本預處理和後處理,比如畫素複製、影像縮放、影像塊融合等,BANG也利用 CUDA 對這些通用的基本操作進行了 GPU 加速。

  雖然深度學習方法具有優異的效能,但其依賴於 GPU 資源,計算量非常大。因此這類方法主要適用於少數熱門直播房間的轉碼業務。對於B站每天需要處理的數十萬點播轉碼任務,目前還無法替代傳統演算法。傳統演算法一般由C/C++ 實現後執行在 CPU 上。  

SIMD 模式可以在一個指令週期內同時處理多個資料,可以顯著加速密集的畫素運算

  對於傳統演算法,BANG 採用 SSE、AVX 等系列指令集進行基本操作的SIMD (Single Instruction Multiple Data)加速 。這些基本操作包括畫素複製、向量元素型別轉換、矩陣加法等。加速最佳化後的基本運算元可以顯著提高傳統演算法的執行效率.。

  對基礎核心演算法進行加速,可以減少影片分析和處理的執行時間,提高整個轉碼系統的吞吐量。

   03 幀內分塊並行和多幀並行機制

  影片影像的資料量非常巨大。因此,對於需要處理所有畫素的去噪、增強、超分等操作而言,計算壓力極大。有時即使對演算法進行 GPU、SIMD 加速之後,單執行緒處理整張圖依然會耗費很多時間,從而影響系統的吞吐量。因此,對於最佳化後速度低於 60fps的演算法,僅僅使用多級流水線架構仍無法滿足 1080p 增強或 4k 60fps 超分直播這類任務的實時要求。

  為了進一步提高轉碼系統的吞吐量,我們還需要繼續提高影像處理環節的執行速度。在多級流水線架構基礎之上,我們引入了子執行緒機制。在處理執行緒中開闢多個子執行緒,讓子執行緒對單幀進行分塊並行處理,或者對多幀並行處理。下圖展示了兩種並行機制進一步提高系統吞吐量的原理。  

在多級流水線架構中引入多執行緒機制可以進一步提高系統吞吐量

  上圖展示了兩種不同的對影片影像處理環節進行多執行緒加速的方案。第一種是將影像分成多個子塊,為每個影像塊分配一個處理執行緒。影像塊之間可以並行處理。這種並行機制適合去噪、增強等不需要全域性語義資訊的畫素級處理,可以分塊處理後再拼接影像。該方案能進一步降低系統延遲,適用於直播場景。

  另一種並行機制是同時並行處理多幀。雖然是由單個執行緒處理整張影像,但同一時間處理多幀也能提高吞吐量。這種機制適合所有處理演算法,尤其是需要影像全域性資訊的演算法,比如影像填補修復等。不過相比於單幀分塊機制,這種機制的延遲會稍大一些,更加適用於點播場景。使用並行策略之後,影片影像處理的時間可以成倍減少,從而能顯著提高系統的吞吐量。分塊並行和多幀並行的特點可以總結為下表。  

兩種並行機制的吞吐量一樣,但是系統延遲和適用範圍有所不用

  當演算法需要使用 GPU 時,我們會在每個處理子執行緒內都例項化一個推理引擎。BANG 支援為每個子執行緒繫結特定的 GPU 裝置,以便業務方在多卡機器上靈活地部署。

  當然,在計算資源充足的條件下,上述兩種並行機制可以同時啟用。此時, BANG 可以同時處理多幀,每一幀內還並行處理多個分塊。該模式可以進一步降低處理階段的執行時間,使系統達到最大的吞吐量。

  大幅提高處理階段的執行效率後,影片影像分析模組往往會成為效能瓶頸。與處理演算法不同,影片影像分析演算法一般對影像的區域性資訊並不敏感。因此,可以將原圖降取樣後再送入分析演算法。這樣可以顯著降低分析的複雜度,但仍能得到與直接使用原圖相近的結果。在分析模組中,我們也引入了多幀並行機制,以進一步提升系統吞吐量。

  透過引入多執行緒機制,BANG 可以充分利用計算資源,使整個轉碼系統的吞吐量成倍增長。比如,在使用深度學習增強演算法的 KPL 賽事直播中,沒有開啟多執行緒機制時,系統只能使用一張 GPU 顯示卡,吞吐量只有 45fps 左右。達不到 60fps 的實時要求。而當啟動分塊並行機制後,可以配置對每張圖使用兩張顯示卡分塊並行處理。此時,單幀處理時間會減少一半,整個轉碼系統的吞吐量能翻倍達到90fps,遠遠超過 60fps 的實時要求。

   04 透過字串配置處理流水線

  BANG 中包含很多影片影像分析與處理演算法,而不同轉碼任務的業務需求各不相同,為了應對多變的應用需求,BANG 設計了一種基於字串的流水線配置方法。所有云轉碼業務都可以整合同一個 BANG 引擎專案,不同的轉碼業務只需要傳入一個字串即可自定義滿足各自需求的影片影像分析與處理流程。

  為了實現這個功能,我們採用工廠設計模式,將所有分析演算法與處理演算法放入到工廠類中進行管理。在收到配置資訊之後,對流水線配置資訊進行解析,然後例項化需要執行的基本演算法,再裝配到一個流水線類中,即可初始化一套具有特定功能的分析與處理流水線。下面來看幾個具體的案例。

  4.1 S12、TI11 賽事直播:

  4k 超分 + ROI 人臉保護 + 硬體編碼

  在這個直播轉碼任務中,系統需要對 1080p 60fps 的源影片進行超分,得到 4k 格式影片,再經過硬體編碼器壓縮後輸出碼流。那麼轉碼系統就可以透過傳入下面的引數配置字串,來呼叫 BANG 實現上述超分功能。

  BANG="process='dnn_sr S12':scale=2x2:output_cuda_device='0'"

  上述配置中 "process='dnn_sr S12'" 表示對解碼影像使用深度學習超分演算法[3],採用代號為 "S12" 的模型檔案。由於該處理會將 1920x1080 的影像變換成 3840x2160 的影像,這個可以透過 "scale=2x2" 進行配置。最後透過 output_cuda_device='0' 設定 GPU 處理後的資料繼續保留在 0 號顯示卡內,直接供後續硬體編碼器讀取。這樣可以避免處理後畫素從 GPU 傳回 CPU,再從 CPU 上傳到 GPU 中進行硬編。此時就可以實現實時超分轉碼的功能,而對於 TI 11 比賽,可以直接修改模型名稱,使用專門針對 DOTA2 畫面最佳化的超分模型即可。

  但是使用上述配置進行超分時,會發現處理後畫面中人臉的區域可能會被過度增強,出現失真現象。這是由於這些模型是專門針對遊戲畫面進行最佳化的,對於非自然的遊戲畫面內容效果很好,但是對自然場景下的三次元內容效果欠佳。那麼此時可以修改 BANG 的配置引數,使用 ROI 檢測和畫質保護功能。

  BANG="analyze=roi:process='dnn_sr S12|-face bicubic':scale=2x2:output_cuda_device='0'"

  上述配置中首先使用 "analyze=roi" 在 BANG 中新增一條功能為 ROI 區域檢測的影像分析流水線。那麼在 BANG 對每一幀進行處理時就會呼叫檢測演算法,檢測出影片中的人體、人臉、文字等人眼比較感興趣的內容。"process='dnn_sr S12|-face bicubic'" 表示對整張圖進行深度學習超分處理,同時對人臉區域進行簡單的放大處理,最後將自然放大的人臉影像塊融合回超分影像上,就可以達到對人臉區域的保護效果。下圖展示了配置 ROI 人臉保護後,三次元人臉更加自然,同時遊戲內容依然清晰。  

深度學習超分和 ROI 保護配合使用

  4.2 點播最佳化轉碼前處理:

  傳統/深度學習前處理 + 多幀並行

  我們在對熱門的點播影片進行最佳化轉碼[1]的時候,會投入額外的算力,引入一些前處理演算法,去除影片畫面中的視覺冗餘資訊,提高整個轉碼系統的編碼效能。這些演算法包括傳統方法和深度學習演算法[2]兩大類。和直播轉碼系統一樣,這些演算法也可以透過 BANG 整合到點播轉碼系統中。使用時只需要修改配置引數即可,比如使用 CPU 資源進行傳統方法前處理,引數可以配置成:

  BANG="process='vod_code_process':frame_threads=8"

  該配置表示使用點播轉碼前處理方法對影片進行消除冗餘的處理,同時透過 "frame_threads=8" 配置 8 個幀處理執行緒,對解碼幀進行幀並行處理。在要使用深度學習方法時,也只需要修改配置字串即可。

  此外,BANG 還可以單獨工作在分析模式,此時只對影片影像進行分析,輸出分析結果,而不進行影像處理。比如在上述質量可控的點播最佳化轉碼系統中[1],我們使用 BANG 對影片原始檔進行 ROI 檢測,並儲存 ROI 區域資訊,以供後續多次編碼重複使用(同一個檔案,不同解析度和幀率的編碼過程可以使用同一個 ROI 資訊檔案,因此只需要進行一次 ROI 檢測)。使用下面的配置就可以對影片進行 ROI 檢測,同時儲存 ROI 資訊到 'roi.json' 檔案中。

  BANG="analyze=roi:analyze_file='roi.json'"

  4.3 KPL 賽事直播:

  1080p 增強 + 幀內分塊並行

  對於 KPL 比賽的增強,我們採用了一個更大規模的神經網路,該網路在單張 GPU 下的速度只有 45fps,為了達到 60fps 的實時轉碼速度,可以配置使用多執行緒,如下。

  BANG="analyze=roi:process='dnn_enhance KPL|-face bicubic':block_threads=2:gpu_list='1,2'"

  對於 KPL 比賽影片的增強,我們同樣開啟了 ROI 保護,防止對人臉過度處理。處理演算法呼叫的是深度學習增強方法,模型使用的是專門針對 KPL 最佳化的模型檔案。同時我們透過 "block_threads=2" 配置 BANG 分配兩個處理執行緒,對每幀進行分塊並行處理,透過 "gpu_list" 指定系統編號為 "1" 的顯示卡處理上半部分,編號為 "2" 的顯示卡處理下半部分。

  在使用這樣的配置之後,KPL 增強直播轉碼即可穩定達到 60fps,為使用者提供清晰且流暢的觀賽體驗。

  這種基於字串的配置方法,可以讓多個業務方十分方便和靈活地呼叫 BANG, 為各自的轉碼系統提供個性化的影片影像分析和處理的功能,有效避免了重複開發,顯著提高了業務迭代效率。

   05 總結

  為了高效部署和管理大量的影片影像分析和處理演算法,同時為直播和點播轉碼業務方提供簡單、一致且靈活的呼叫介面,我們開發了一套功能強大的影片影像分析與處理引擎——BANG(Bilibili video/image Analyzing and processiNg enGine)。直播和點播轉碼系統可以很方便地整合 BANG,然後透過基於字串的配置方法,靈活地定製符合各自業務需求的影像分析與處理流程。透過採用多級流水線架構、分塊並行、多幀並行、基礎演算法加速等技術,BANG極大最佳化了系統的吞吐量,滿足了業務中苛刻的速度要求。未來,我們還將繼續完善 BANG,加入更豐富的基本演算法,同時對演算法進行更深入的最佳化,將 BANG 打造成更加強大的影片影像分析與處理引擎,為影片業務提供更大的幫助。

來自 “ 嗶哩嗶哩技術 ”, 原文作者:蔡春磊&葉天曉;原文連結:http://server.it168.com/a2022/1109/6773/000006773623.shtml,如有侵權,請聯絡管理員刪除。

相關文章