在 AI 專案中,大多時候開發者的關注點都集中在如何進行訓練、如何調優模型、如何達到滿意的識別率上面。但對於一個完整專案來說,通常是需求推動專案,同時,專案也最終要落到實際業務中來滿足需求。
對於常用的 AI 訓練和機器學習工具如 TensorFlow,它本身也提供了 AI Serving 工具TensorFlow Serving。利用此工具,可以將訓練好的模型簡單儲存為模型檔案,然後透過的指令碼在 TensorFlow Serving 載入模型,輸入待推理資料,得到推理結果。
但與擁有較固定計算週期和執行時長的 AI 訓練不同,AI 推理的呼叫會隨著業務的漲落而漲落,經常出現類似白天高、夜間低的現象。且在大規模高併發的節點需求情況下,常規的部署方案,明顯無法滿足此類需求,此時需要使用更專業的 AI 推理模型和擴縮容、負載均衡等技術完成預測推理。
UAI-Inference 採用類似 Serverless 的架構,透過請求排程演算法、定製擴縮容策略,自動完成 AI 請求的負載均衡,實行節點動態擴容和回收,可提供數萬的 AI 線上推理服務節點。
AI 推理(Inference)的線上執行有兩大關鍵因素:一是透過 GPU/CPU 對資料進行快速決策,二是對訪問請求的實時響應。下圖為某一 AI 線上推理場景 24 小時內的資源使用情況,其中,橫軸為時間、縱軸為使用者資源請求量,橙色線現表示資源配置情況。
凌晨 00:00-8:00 點,使用者基本處於睡眠狀態,此刻的資源請求較少,閒置資源較多;8:00 以後,手機等裝置使用量增多,推理訪問請求逐漸上升;直至中午,裝置訪問達到高峰,請求量超過設定的資源量,系統紡問出現延遲;之後線上使用量降低,部分資源又將閒置……
可以看到,一天內不同的時間段,訪問量會隨著使用者作息規律而出現相應的起伏,若是將資源配置設定過小,則會導致計算資源不足,系統吞吐量變低,致使訪問延遲。但若投入過多的配置,又會產生大量的閒置資源,增加成本。
UAI-Inference 整體架構
為了應對線上推理對實時擴縮容以及大規模節點的需求,UAI-Inference 在每一臺虛擬機器上都部署一個 AI 線上服務計算節點,以類似 Serverless 的架構,透過 SDK 工具包和 AI 線上服務 PaaS 平臺,來載入訓練模型並處理推理(Inference)請求。整體架構如下:
SDK 工具包:主要負責模型載入。包含介面程式碼框架、程式碼和資料打包模板以及第三方依賴庫描述模板。使用者根據 SDK 工具包內的程式碼框架編寫介面程式碼,準備好相關程式碼和 AI 模型以及第三方庫列表,然後透過打包工具將訓練模型進行打包。
任務打包完畢後,系統自動將業務部署在 AI 線上推理 PaaS 平臺上處理推理請求。這裡,平臺每個計算節點都是同構的,節點具有相等的計算能力,以保證系統的負載均衡能力。此外,動態擴縮容、分散式容災等彈性可靠設計也是基於該平臺實現。
線上推理實現原理
在實現上,系統主要採用 CPU/GPU 計算節點來提供推理任務的基礎算力,透過 Docker 容器技術封裝訓練任務,內建 Django Server 來接受外部 HTTP 請求。下圖展現了處理請求的簡單原理與流程:
在初始化過程中(init),Django Server 會先根據 conf.json 載入 AI Inference 模組,然後呼叫該模組的 load_model 將 AI 模型載入到 Django HTTP 伺服器中;在處理推理請求時,Django 伺服器會接受外部的 HTTP 請求,然後再呼叫 execute 函式來執行推理任務並返回結果。
這裡,採用容器技術的好處是可以將執行環境完全隔離,不同任務之間不會產生軟體衝突,只要這些 AI 服務在平臺節點上執行滿足延時要求,就可進行 AI 線上推理服務部署。
功能特性
UAI-Inference 適用於常見的大規模 AI 線上服務場景,如影像識別、自然語言處理等等。整體而言,該系統具有以下功能特點:
面向 AI 開發:透過預製的 NVIDIA GPU 執行環境和容器映象,UAI-Inference 提供基於 Docker 的 HTTP 線上服務基礎映象,支援 TensorFlow、Keras、Caffe、MXNet 多種 AI 框架,能快速 AI 演算法的線上推理服務化。
海量計算資源:擁有十萬核級別計算資源池,可以充分保障計算資源需求。且系統按照實際計算資源消耗收費,無需擔心資源閒置浪費。
彈性伸縮、快速擴容:隨著業務的高峰和低峰,系統自動調整計算資源配比,對計算叢集進行橫向擴充套件和回縮。
服務高可用:計算節點叢集化,提供全系統容災保障,無需擔心單點錯誤。
使用者隔離:透過 Docker 容器技術,將多使用者儲存、網路、計算資源隔離,具有安全可靠的特性。
簡單易用:支援視覺化業務管理和監控,操作簡單。
因為推理請求是隨著訪問量的變化而變化的,因此,線上推理的可靠性設計,考慮以下幾點:1)充足資源池,保證在高併發情況下,系統擁有足夠的計算資源使請求訪問正常;2)負載均衡:將請求合理的分配到各節點當中;3)請求排程演算法:用於計算資源的實時排程;4)效能監控:檢視使用者訪問狀態,為系統擴縮容做參考;5)高可用部署:保證在單節點當機時,系統能夠正常執行。
負載均衡
UAI-Inference 為每個線上服務提供了自動負載均衡能力,當使用者提交同構、獨立的 AI 線上推理容器映象時,平臺會根據請求的負載建立多個計算節點,並使用負載均衡技術將請求轉發到計算叢集中。
如圖所示,負載均衡主要包括網路層和轉發層。網路層中,同一個交換機(IP)可以接多個後端節點,透過請求排程演算法將請求分配到各個計算節點當中。排程演算法可以採用Hashing、RR(Round Robin)、Shortest Expected Delay等,其中,Hashing 適用於長連結請求,Shortest Expected Delay 適用於短連結請求。目前,UAI-Inference 採用 RR 的方式在計算節點間排程請求。整個系統最底層是一個統一的資源池,用以保證充足的計算資源。
動態擴縮容
在實現擴容之前,需要透過監控瞭解各節點當前的線上推理狀態,這裡,主要是透過實時收集節點的負載(CPU、記憶體)、請求的 QPS 和延時資訊,來制定動態的擴容和縮容策略。
系統狀態實時監控
此外,UAI-Inference 系統將 HTTP 請求、延時和 HTTP 返回碼實時記錄成日誌,然後透過資料統計來在圖形介面展示 HTTP 請求量、延時、成功率等資訊。平臺會實時收集所有計算節點的 stdout 資料,並錄入日誌系統,使用者可以透過觀察線上執行日誌來了解線上執行狀態,並根據監控資訊自動選擇擴容和縮容。
高可用
除了基本的擴縮容和負載均衡,我們也透過將計算節點叢集化的方式,提供全系統容災保障。如下圖所示,系統會把整個服務切分成多個 set,部署在跨機房的某幾個機架或者區域裡面,當某一個機房或者 set 當機時,其他地區的線上推理處理還在進行。這種方式的好處是當出現單點故障時,其他區域的計算節點能夠保證整個線上推理請求的正常執行,避免因單節點故障導致的系統不可用。
本文透過對 UAI-Inference 的實現原理、架構設計以及彈性擴縮容、負載均衡、高可用等可靠策略的介紹,講解了大規模、高併發線上推理請求時,UCloud 的部分解決策略和方案。希望能夠拋磚引玉,為其他開發者做AI線上推理部署時帶來新的思路。
截止目前,UAI-Inference 提供了 CPU/GPU 數萬節點的線上推理服務。未來,我們會兼顧高效能線上服務和高價效比的線上服務兩個方向,同時提供針對 GPU 硬體和 CPU 硬體的最佳化技術,進一步提升線上服務的效率。同時也會著力於公有云和私有云的結合,後期將會推出私有云的線上推理服務。
宋翔,UCloud 高階研發工程師。負責 UCloud AI 產品的研發和運營工作,曾先後於系統領域頂級會議 Eurosys、Usinex ATC 等發表論文,在系統體系架構方面具有豐富的經驗。