1、前言
推薦領域演算法模型的線上推理是一個對高併發、高實時有較強要求的場景。演算法最初是基於Wide & Deep相對簡單的網路結構進行建模,容易滿足高實時、高併發的推理效能要求。但隨著廣告模型效果最佳化進入深水區,基於Transformer使用者行為序列和Attention的建模逐漸成為主流,這個階段模型的特點是引數的體量、網路結構複雜度呈指數級增長,演算法建模的創新工作往往由於吞吐和耗時的效能算力問題,導致無法落地於線上推理獲得效果收益。傳統透過擴容資源的方式,其邊際效應也在減弱,算力最佳化存在諸多挑戰:
1、高算力需求下的資源成本邊際效應問題:叢集資源擴容是提升算力的一種傳統方案,但算力需求的增加往往需要成倍數的資源增長才能抹平,帶來了極強的邊際遞減效應。
2、複雜演算法模型的線上推理算力擴充套件問題:推理引擎要求低延遲和高吞吐,而隨著模型演算法複雜度提升,突破計算資源算力上限(儲存、計算),推理耗時顯著增加,無法滿足實時推薦系統的效能要求。
針對上述挑戰和問題,廣告演算法架構在迭代演變的過程中,構建了一系列的最佳化體系,主要集中在兩個方面:
1、架構層面:設計分散式分圖異構計算框架,透過模型分圖,分散式推理實現算力的向外擴充套件;CPU&GPU異構硬體差異化部署,演算法結構與計算硬體資源相得益彰,最大化硬體適配性,實現算力的指數級增長。算力擴充套件的架構使得後續垂向最佳化成為可能,可以針對特定業務需求進行深度定製和調整。
2、高算力推理引擎層面:從底層架構出發,GPU運算元排程和計算邏輯精細化最佳化,深入挖掘GPU專用計算裝置的潛力,實現對推理效能的顯著提升。
2、分散式分圖異構計算框架
分散式分圖異構計算框架是我們針對算力擴充套件問題提出的解決方案,透過模型結構化拆分,分散式分圖計算,CPU&GPU異構硬體差異化部署,使演算法結構與計算硬體資源高度適配,充分發揮各自優勢。基於CPU計算叢集構建大規模稀疏模型建模,利用記憶體資源易擴充套件等優勢,支撐千億規模引數的高效能推理。基於GPU計算叢集構建稠密模型建模,利用高算力優勢,支撐超長使用者行為序列建模,為演算法建模的創新提供了堅實的架構基礎。我們基於該框架進一步研發並落地了京東零售首個Online Learning建模場景,使得模型可以感知人、貨、場的實時變化。同時GPU服務叢集作為獨立於整體服務體系的組成部分,便於針對GPU推理引擎進行專項最佳化,從而便捷地進行效能提升措施的實施。
圖1 分散式分圖異構計算框架
3、高算力推理引擎
為了打造高算力推理引擎,開始深入調研基於GPU推理引擎最佳化推理效能的可行性,GPU作為一種高度並行的多核處理器,具備極強的平行計算能力,由於GPU高度並行化的結構,先天適合以稠密矩陣計算為主的NLP、CV領域。但直接應用於推薦領域會存在TP99耗時上漲,資源利用率不高等問題。這主要與推薦領域模型的自身特點相關:
1、建模過程複雜:為建模使用者與商品關係,推薦領域模型建模不僅包含DNN等稠密計算部分,還存在大量針對稀疏特徵的Embedding建模方式以及特徵預處理等模組,集合了IO密集與計算密集兩大特性,造成計算過程與GPU親和性不高,難以充分發揮GPU的硬體優勢。
2、模型規模大:推薦領域模型以稀疏引數為主,百G規模引數無法完全載入至GPU視訊記憶體,稀疏引數交換導致頻寬需求高,造成GPU無法充分利用。
3、模型結構複雜:使用者行為序列建模成為模型建模的主流方法,而使用者特徵的多樣性(瀏覽行為、購買行為、加購行為)需要單獨建模以提升模型對使用者的感知能力,因此造成模型分支結構多,結構複雜。TensorFlow推理框架雖然提供了運算元級別的建模方案,透過堆疊細粒度運算元完成各種複雜的模型建模,靈活的支撐了多種行為序列建模方式。但也因此造成了運算元粒度過細,單運算元計算量小,不易於GPU充分排程的問題,尤其是對於線上推理本身計算量就相對較小的場景問題更為致命。
得益於分散式分圖異構計算框架,有效解決了上述1,2問題,並且可以讓我們針對GPU運算元排程和計算邏輯精細化最佳化,深入挖掘GPU專用計算裝置的潛力,實現對推理效能的顯著提升。具體工作體現在以下三個方面:a)TensorBatch:透過聚合計算請求提升GPU計算吞吐;b)深度學習編譯器:透過自動化的運算元融合、圖最佳化等方式最佳化模型推理效能;c)多流計算:透過打造GPU多計算通道,構建真正的平行計算推理引擎。
3.1、TensorBatch
廣告精排模型推理主要表現是單個請求耗時較短(毫秒級),同時每個請求中gpu kernel呼叫次數較多,每次gpu kernel的排程都會伴隨相應的kernel launch,瑣碎繁多的kernel launch會嚴重製約GPU模型的吞吐能力,同時會導致模型系統耗時較高,透過Nsight效能分析效能資料如下。
圖2 大批次KernelLaunch操作
kernel launch 本質上是從host端核函式呼叫到GPU開始計算之間的這段時間,主要包括準備計算需要資料的傳輸和執行需要warp執行緒束的獲取,無論是資料的傳輸還是選取執行所需要的warp執行緒束,多個請求之間是可以實現共享的,因此我們核心解決問題的思路是將多個模型推理請求合併成一個請求,完成模型推理後在對結果再進行合理的分割,減少請求級別 kernel launch 的數量,極大的提升kernel launch的效率,從而進一步提升GPU模型的吞吐能力,架構方案如 圖3, 例如 1個模型請求經過tensorflow推理需要進行 1000 次 kernel launch,3個請求需要3000次kernel launch,如果將3個請求合併成1個請求,那麼kernel launch數量會從3000 降至1000。
圖3 Tensor Batch架構圖
請求級別運算元融合在廣告精排模型進行全量上線,在GPU利用率不變的情況下,GPU模型吞吐能力提升2倍。請求級別融合本質是最佳化GPU kernel launch 效率,但是最佳化GPU kernel launch 效率方案不止一種,下面詳細介紹一下基於"深度學習編譯器"的運算元融合。
3.2、深度學習編譯器
KernelLaunch效率問題最佳化方面,我們首先採用了TensorBatch方案,在廣告演算法場景,除錯聚合數量在5-8左右較為合適(聚合後廣告數200-1000)。雖然對請求進行了聚合,但運算元執行的TimeLine仍較稀疏,如圖5所示,該現象解釋了GPU無法得到充分利用的原因。針對這一現象,我們進一步研發了基於深度學習編譯器的運算元融合方案,透過運算元融合n次 KernelLaunch至1次,大大降低整體KernelLaunch耗時,同時透過圖最佳化等策略進一步提升模型的推理效能。
圖4 GPU Kernel計算稀疏
3.2.1 深度學習編譯器分桶預編譯技術
XLA(Accelerated Linear Algebra)是google開源的深度學習編譯器,將高階別的模型描述轉換成高效的可執行程式碼,自動化的解決運算元融合、記憶體管理、資料佈局轉換等問題。該框架已融合進Tensorflow開源框架中,並提供較友好的程式設計介面。但原生深度學習編譯器在推薦領域模型應用方面存在一系列問題:
a)同一個XLA Graph針對不同的Tensor輸入屬性(數量、維度、型別)會觸發不同的編譯流程,形成多個XLA Runtime(編譯結果),導致開源方案只適用於CV領域,定長輸入(影像維度不變)的場景。推薦領域模型變長特徵(使用者行為序列)的存在使得在推理過程構建萬級別數量的XLA Runtime(編譯結果),在視訊記憶體消耗上不可接受。
b)Tensorflow-XLA為執行時編譯(JIT),編譯過程緩慢,通常完成一個XLA Runtime的編譯耗時長達1秒,且對CPU、GPU資源佔用較大,在廣告高實時場景下,耗時不可接受。
針對上述問題,我們研發了深度學習編譯器分桶預編譯技術。為避免不同特徵維度導致的多次編譯問題,首先對演算法結構進行XLA子圖劃分,形成多個XLA子圖。其次針對XLA子圖的輸入特徵變長情況,實現分桶Padding能力,降低XLA Runtime編譯數量,解決了編譯中遇到的視訊記憶體問題。最後透過模型XLA子圖分桶標記演算法,在模型載入階段進行預編譯,解決執行時編譯耗時問題。
在深度學習編譯器技術加持下,我們將廣告推薦精排模型的運算元排程次數從553次最佳化至190次,XLA子圖模組的運算元執行的TimeLine得到極大改善,單次推理耗時從14ms最佳化至9ms。
圖5 XLA Runtime
3.2.2 深度學習編譯器非同步編譯技術
透過深度學習編譯器分桶預編譯技術,我們解決了99.9%的問題,但仍有異常流量導致特徵維度超出預設的分桶範圍,導致觸發執行時編譯的可能。作為一個高穩定的線上系統,我們進一步實現了非同步編譯技術,解決異常流量帶來的耗時問題:
a)模型構圖方面,同時保留XLA子圖與模型原圖。
b)推理過程動態選擇,命中分桶情況則選擇XLA Runtime執行,未命中則選擇原圖執行,同時服務後臺觸發非同步XLA編譯,供下次請求使用。
圖6 深度學習編譯器非同步編譯
3.3、多流計算
圖7 GPU多流計算背景
Tensorflow深度學習框架雖然提供了GPU計算能力,但其CPU到GPU的互動通道僅為單通道模式。線上併發推理的場景下,存在運算元排程互斥、運算元計算阻塞排隊等問題。針對上述痛點我們設計了GPU多通道模式-多流計算架構,真正實現了GPU的併發計算能力。
我們對Tensorflow框架中的底層GPU通道的建立和分配機制進行了深入的改造與升級,賦予了其在面對同一模型時,針對不同的線上請求,動態選擇GPU通道進行運算的能力。每個GPU通道獨立持有一份CUDA Stream和CUDA Context,既消除了運算元併發排程導致的GPU資源爭搶問題,也使得不同請求擁有獨立的計算通道,提升GPU並行粒度。
圖8 多GPU通道
多GPU通道(多CudaStream + 多CudaContext)解決了KernelLaunch排程問題,運算元排程可以並行執行,減少了執行的GAP。但在GPU硬體層面,CudaContext採用分時複用原則,即此某一時刻只有一個CudaContext被排程執行,沒有完全達到運算元計算間的並行。
圖9 GPU Kernel交錯計算
MPS + 多流計算框架實現真正意義的平行計算
MPS侷限性:MPS(Multi-Process Service)是英偉達為充分利用GPU資源的一種解決方案。MPS多程序服務,每個程序有自己的上下文管理機制,MPS使用合併共享的並行模式,即將多個任務合併成一個上下文,因此可以同時跑多個任務,是真正意義上的並行。但MPS方案需要多程序服務的場景下才能生效,這種情況下單卡視訊記憶體無法承載多程序任務,視訊記憶體成為瓶頸,MPS機制失效,無法充分利用GPU算力。
圖10 Multi-Process Service侷限性
因此,我們升級了多流計算架構,將MPS與自研的多CudaStream + 多CudaContext的多流計算架構相結合,解決了視訊記憶體瓶頸的問題,最終透過單程序模型部署實現真正的平行計算。
圖11 GPU Kernel平行計算
綜上,我們實現了完整的GPU多流計算框架:建立多組通訊渠道打通軟體和硬體通道,融合排程Context實現真正的計算並行化。
圖12 GPU多流計算架構圖
4、總結
綜上,透過設計高效能的計算方案,打造新一代演算法架構推理體系,在架構層面透過分散式分圖異構方案很好的解決了高算力需求下的資源成本邊際效應問題,在高算力推理引擎層面,透過一系列的專項最佳化,讓GPU的算力得到充分的釋放,實現複雜演算法模型算力的擴充套件。目前新一代的高效能運算方案已經在廣告多個業務線進行了落地實踐,推薦首頁CTR模型、推薦通用資訊CTR模型、推薦商詳CTR的規模擴充套件至千億,助力推薦、搜尋等核心業務取得顯著的效果收益。
高效能演算法推理系統是演算法架構體系的重要組成部分,為演算法建模的創新提供了算力基礎,算力最佳化是一個極富挑戰性的領域,它需要我們在技術層面上不斷進行探索、學習和創新。目前,我們正在著手規劃下一代推理演算法架構體系,其最顯著的特點將是演算法、計算能力和架構的深度融合,以及線上和離線一體化的設計方案。
感謝廣告架構師小組的架構師們和演算法方向的專家們在演算法架構體系建設方面提供的寶貴指導建議。同時我們誠摯地邀請對此領域感興趣的同事們加入我們的討論。相信透過大家的共同努力和協作,一定能夠在這個前沿領域取得突破,為未來的推理演算法架構體系開闢新的可能性和機遇。