百度搜索萬億規模特徵計算系統實踐

本文主要介紹百度搜索在全網萬億級規模內容做內容理解的工程實踐,涉及機器學習工程化、資源調度、存儲優化等多個 Topic。

業務背景

百度收錄了互聯網海量內容,要索引這些內容,需要先對內容做深度理解,提取包括內容語義、內容質量、內容安全等多維度信息,從而進一步支持內容篩選過濾、語義建庫等需求。對全網海量內容做深度理解,挑戰是非常大的,主要是體現在成本和效率上。

在成本上,計算量非常大,除了因全網內容數據量大(萬億規模)、特徵數多外,有兩個趨勢也加劇了計算壓力,一方面是互聯網內容圖文化、視頻化比例持續大幅增長,圖片 / 視頻的計算量遠大於文本,另一方面,深度學習技術大規模應用,特別近期大模型的興起,對算力需求也隨之劇增。在效率上,怎麼讓系統更易用,儘可能地提升業務迭代效率,是所有工程系統的核心目標之一。

關鍵思路

(1)成本優化:要滿足如此龐大的算力需求,需要極致地『開源節流』。

1.『開源』:儘可能擴大計算資源池,通過採購來滿足 ROI 低,挖潛現有資源是關鍵。從公司整體看,資源使用並不充分,在線資源存在波峯波谷,庫存空閒資源也不少,而我們大多爲離線計算,對資源穩定性要求不高,可以結合兩者,建設一套彈性計算調度系統來解決資源問題。

2.『節流』:儘可能優化服務性能,降低單位計算成本,模型推理計算量大,但本身有較大的優化空間,結合模型結構和 GPU 硬件特點進行優化,可以大幅提升模型服務單卡吞吐。此外,優化 CPU 處理、使用百度自研崑崙芯片等多種方式也能降低單位成本。

(2)效率優化:如圖所示,整體業務流程包括實時和離線計算兩部分,新增特徵需對存量數據離線刷一遍,而對 Spider 新收錄的數據,會篩選高時效性的數據實時計算,其餘的也離線計算,計算大頭在離線部分。效率問題主要爲:怎麼支持模型快速工程化?怎麼提升離線計算效率?

1. 模型服務框架 & 平臺:模型工程化是通過統一的模型服務框架和配套的模型服務平臺來實現,模型服務框架和平臺支持並涵蓋從構建、測試、上線等模型服務全生命週期的各個環節。

2. 特徵批量計算平臺:爲了離線特徵計算效率問題,建設了統一的批量計算平臺,分析並深度優化從離線任務開發到計算過程中各環節的效率和性能瓶頸,儘可能地提升效率。

技術方案

**3.1 **整體架構

整體架構如下圖所示,最核心的是模型服務平臺、批量計算平臺、計算調度系統、模型服務框架這幾部分。

1. 模型服務框架:算法同學使用統一的模型服務框架進行服務封裝,基於研發效率考慮,選擇 Python 作爲框架語言,但 Python 性能問題也很明顯,因此需要做很多針對性優化。此外,我們也在框架持續集成多種推理優化手段,儘可能地降低服務單位計算成本 。

2. 模型服務平臺:模型服務平臺支持模型服務 DevOps 和能力輸出,平臺以『算子』作爲管理粒度,『算子』代表一種完整功能,如視頻分類等,它通常需要多個模型服務組合使用。算法同學在平臺註冊算子,提供服務拓撲等元信息,也通過自動性能調參、自動化壓測等生成性能報告,服務拓撲和性能報告是後續調度的重要輸入。平臺也提供算子檢索、調研試用等功能,以中臺化方式支持其他業務需求。

3. 計算調度系統:計算調度系統做流量和資源的統一調度,所有對模型服務的請求都會經過計算調度系統的網關,執行流控和路由等流量策略,計算調度系統也會調度百度多個 PaaS 的多種空閒異構資源,自動化部署合適的算子,給離線計算提供更大吞吐。

4. 批量計算平臺:批量計算平臺支持離線作業的任務生成、任務調度、DevOps 等功能,建設基於 HTAP 的存儲方案,解決 Scan 吞吐瓶頸問題,並聯動計算調度系統,支持大規模離線計算。

**3.2 **技術關鍵點

本章節主要闡述系統技術關鍵點,包括遇到的技術難點、思考和權衡折衷,一些共性問題也期望讀者能和我們多多交流。

3.2.1 模型服務框架

在實際業務場景,模型服務框架有幾個關鍵問題需要解決:業務編程模型、Python 服務性能優化、以及推理性能優化,下面介紹。

3.2.1.1 業務編程模型

實現某個功能往往需要組合使用多個模型和多種數據處理邏輯,爲了抽象表達處理流,實現通用邏輯複用,採用方案如下:

3.2.1.2 Python 服務性能優化

選擇 Python 降低了開發成本,但也引入了 Python GIL(全局解釋器鎖)問題,導致不能充分利用 CPU 多核,極大限制了服務吞吐,解決方案如下:

主要有推理調度、推理優化、模型量化、模型壓縮等優化手段,經過優化,服務單卡吞吐相比原生實現通常有數倍提升。

1. 推理調度:動態批量處理(DynamicBatching)和多 Stream 執行。GPU 批量計算效率更高,由於服務也接受實時單條請求,沒法請求時拼 Batch,因此採用服務內緩存拼 Batch,犧牲時延換吞吐。Stream 可看做 GPU 任務隊列,默認全局單條,任務串行執行,會出現 GPU IO 操作(內存顯存互拷)時,計算單元閒置,通過創建多 Stream,不同推理請求走不同 Stream 讓 IO 和計算能充分並行。

2. 推理優化:業界主流方案是使用 TensorRT,但是實際應用會有動態圖靜態化失敗、TensorRT Op 覆蓋不全等問題。爲解決這些問題,團隊自研 Poros(開源版本:https://github.com/PaddlePaddle/FastDeploy/tree/develop/poros),結合 TorchScript、圖優化、TensorRT、vLLM 等技術,實現無需複雜模型轉化,添加幾行代碼即可大幅提升推理性能,效率和性能雙贏,同時 Poros 也支持崑崙等異構硬件。

3. 模型量化:GPU、崑崙等硬件對低精度都有更強的算力,量化雖有少量效果損失,但帶來大幅吞吐提升,因此,上線都會採用 FP16 乃至 INT8/INT4 量化,這部分也是通過 Poros 支持。

4. 模型壓縮:通過模型蒸餾、模型裁剪等方法精簡模型參數,減少計算量,但是需要訓練,且效果有損,通常和算法同學一起合作優化。

3.2.2 計算調度系統

計算調度系統的運行架構圖如下,所有請求流量都通過統一的網關(FeatureGateway),網關支持流控、路由等多種流量策略。離線作業也通過網關提交計算需求,網關會將需求轉發給調度器(SmartScheduler)進行調度。調度器對接了百度內多個 PaaS,不斷檢測空閒資源,根據需求、多種指標、空閒異構資源分佈等,自動化調度部署合適的算子,算子元信息從服務平臺獲取,調度完成後,調度器會調整網關的流控和路由等。

系統比較關鍵的兩個問題:怎麼實現算子(複合服務,含複雜服務拓撲)自動化部署?怎麼在流量分佈不穩定、多異構資源等複雜條件下進行調度?

3.2.2.1 自動化部署

爲簡化調度器開發複雜度,採用聲明式編程,實際是基於 k8s controller 機制開發。算子自動化部署實現方案如下:

1.CRD 擴展:利用 K8S CRD 來自定義 ServiceBundle(算子部署包)等對象,通過 controller 機制讓在 PaaS 等外部系統執行部署等操作。ServiceBundle 包含了算子需要的所有子服務部署信息,以及其拓撲關係。調度創建算子服務時,會從最底層開始逐層創建子服務,上層子服務可以通過通信託管機制獲得下游子服務地址。

2. 通信託管:通信託管機制是基於配置中心和模型服務框架實現,服務啓動命令會帶有遠程配置地址和 AppID,通過加載遠程配置可以實現下游服務地址啓動時變更。其實更理想方案是使用 ServiceMesh 等技術將架構能力和業務策略解耦,但考慮我們要在多 PaaS 部署,而在各個 PaaS 都部署 ServiceMesh SideCar 等組件成本較高,集成到框架又過於重,因此,先建設基於配置中心的方案,後續時機成熟再考慮遷移。

3.2.2.2 調度設計

調度是個非常複雜的問題,在我們場景,其複雜性主要體現在以下幾方面:

1. 算子調度:算子(複合服務)可承載流量取決於其最短板的子服務容量,調度時需要整體考慮,避免長板服務資源浪費。

2. 流量分佈變化:部分算子的性能會受輸入數據分佈影響,如視頻 OCR 會受視頻時長、畫面文字比例影響,調度時需要自適應調整。

3. 多異構硬件:算子有些能支持多種異構硬件(崑崙 / GPU/CPU 等),有些只能綁定一種,怎麼分配才能保證全局資源最有效利用。

4. 其他因素:作業優先級、資源優先級、資源波動等因素也都會影響調度,實際調度要考慮的因素非常多元化。

基於以上因素考慮,我們的調度設計方案如下:

1. 兩階段調度:分流量調度和資源調度兩階段,各自獨立調度。流量調度負責對當前算子服務容量分配到各個作業,並結果同步到網關,調整流量策略;資源調度負責根據資源空閒情況和算子容量缺口等進行調度,最終對算子服務實例進行擴縮容。

2. 流量調度:流量調度 Adjust 階段會根據任務運行指標等調整歸一化係數,再用係數將任務所需 Qps 映射成 NormalizedQps,NormalizedQps 是後續所有調度的依據,從而解決流量分佈變化影響問題。在 Sort 階段會根據作業優先級等排序,在 Assign 階段會根據 Sort 結果,按優先級將現有算子容量分配到各個作業。Bind 階段會將結果執行,同步路由等到網關。

3. 資源調度:資源調度 Prepare 階段會先將作業的容量缺口轉換成對應服務實例數缺口;接着進行 HardwareFit,將要擴容的服務分配到合適的硬件資源隊列,並根據資源稀缺性、計算性價比等進行 Sort;然後進行 PreAssign,對各子服務進行資源預分配,最後 GroupAssign 階段考慮複合服務的各子服務調度滿足度,對複合服務的各子服務容量進行細調,避免資源浪費。

3.2.3 批量計算平臺

批量計算平臺要解決的問題:彈性資源比較充裕時(如夜間),對 Table(分佈式表格系統)的 Scan 吞吐瓶頸,以及怎麼儘可能地優化離線任務效率,下面介紹具體解決方案。

3.2.3.1 HTAP 存儲設計

先分析對 Table Scan 慢的原因,主要如下:

1. 讀寫混合:OLTP(抓取更新等)和 OLAP(特徵批量計算等)需求都訪問 Table,多種讀寫方式混合,而底層採用 HDD 存儲,大量讀寫混合使磁盤 IO 吞吐嚴重下滑

2.Scan 放大:Table 採用寬表結構存儲,不同任務 Scan 時通常只需要其中的某幾列,但 Table Scan 時需要讀取整行數據再過濾,IO 放大嚴重。

3. 擴容成本高:由於 OLTP 和 OLAP 混合讀寫,要爲 Scan 單獨擴容成本高,同時因讀寫比例難以固定,也很難預估擴容資源。

通過上述分析可知,關鍵問題還是 OLTP/OLAP 混合使用 Table。參考業界實踐,採用單一存儲引擎難以同時滿足 OLTP 和 OLAP 場景,但爲了存儲系統易用性,又希望一套存儲系統同時支持兩種場景。因此,我們結合業務場景和業界經驗,實現一個 HTAP 存儲方案,具體方案如下:

1.OLAP/OLTP 存儲分離:針對批量計算等 OLAP 場景建設高效 OLAP 存儲,減少因 OLAP/OLTP 混合使用 Table 帶來的讀寫混合問題,也可根據需求單獨擴容。

2. 高效 OLAP 存儲設計:自研 OLAP 存儲基於 Rocksdb、AFS(百度類 HDFS)構建,採用增量同步、行數據分區、列數據動態合併存儲的設計,將 Table 全量數據劃分成 N 個數據物理分區,利用 Table 的增量 Snapshot 定期高效同步更新 OLAP 存儲數據(由於 Table 底層採用 LSM 存儲,增量 Snapshot 效率遠高於全量 Scan)。列存儲根據字段訪問熱點重新組織,將熱點列在物理層一起存儲,降低 IO 放大,也支持動態調整。方案會存在數據同步延時問題,但在我們場景,時效性要求不高,問題可以忽略。

3.HTAP SDK:提供統一的 SDK 同時支持對 Table 和 OLAP 存儲訪問,用戶基於 SDK 可以同時執行自己的 OLAP 和 OLTP 任務。

3.2.3.2 任務生成與調度

爲了簡化批量計算任務的開發,平臺目前提供了三種任務開發模式:配置化、KQL、離線框架,開發自由度 / 成本由低到高,易用性由高到低:

Function classify = {
def classify(cbytes, ids):
    unique_ids=set(ids)
    classify=int.from_bytes(cbytes, byteorder='little', signed=False)
    while classify != 0:
        tmp = classify & 0xFF
        if tmp in unique_ids:
            return True
        classify = classify >> 8
    return False
}
declare ids = [2, 8];
select * from my_table
convert by json outlet by row filter by function@classify(@cf0:types, @ids);

除了以下幾種方式,平臺也在嘗試結合大模型實現基於自然語言的任務生成。實際上,無論採用哪種方式,最後生成的離線任務都是基於離線框架,只是根據更具體的場景提供了更高度的封裝而已。

任務生成後,會將任務調度到 MapReduce 或者 FaaS 平臺執行,不同任務生成方式在調度前的預處理有所不同,比如 KQL 任務需要先做 KQL 解析再生成實際任務做調度,而業務通過框架開發的任務比較容易出現各種非預期問題,所以走自動化准入等 DevOps 流程。任務執行時,會先向計算調度系統提交需要的算子以及期望吞吐,之後不斷向網關獲取要可用 Quota,並結合當前任務實例數、失敗率等,自適應調整請求投遞速度。

總結

當前系統支持搜索出圖、視頻搜索、圖片搜索等十多個業務方向,支持數百個算子的研發和上線,天級數百億的計算調用,支持全網萬億規模內容特徵的例行更新。隨着 AI 大模型時代的到來,帶來很多新的場景和挑戰,有很多點值得重新思考,後續我們將結合大模型進行更多的探索。

作者:Jay

來源:百度 Geek 說

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ccv_ffA-_otrYpjBFE7Ikw