作 者 | 黃潤鵬
出品 | 騰訊云開發者
隨著大模型技術的爆發,AI Infra 已成為基礎設施領域的核心戰場。過去1年多的時間,我們團隊落地了多個大模型應用,包括語音合成大模型、內容理解多模態大模型、生成式推薦大模型,跑通大模型訓練到推理的全鏈路。踩了很多坑,也積累了不少經驗。本文將分享傳統后臺工程師積累的技術棧和方法論,如何延續并遷移到 AI 系統,并系統性拆解 AI Infra 的硬件、軟件、訓練和推理挑戰。
硬件演進
經濟基礎決定上層建筑。軟件層面的架構設計,無法脫離硬件約束。了解現代 AI 硬件特性非常有必要。
(一臺高性能的GPU服務器可以換一套深圳房子)
1.1 從CPU為中心到GPU為中心
傳統基礎設施以 CPU 為核心,通過多線程和微服務構建分布式系統,處理高并發請求(如 Web 服務)。這些都有成熟的方法論了(如“海量服務之道”)。主要工作是邏輯事務的處理,瓶頸在網絡 I/O 和 CPU 核心數量。發展到今天,硬件已經很少是制約 CPU 系統設計的瓶頸。
而 AI Infra 以 GPU 為核心,其設計目標從邏輯事務處理轉向高吞吐浮點計算。此時CPU 多線程被 GPU 并行計算替代,內存被顯存替代。如下圖所示,H20單卡96GB顯存,可以提供44TFlops的單精度浮點運算,算力和訪存帶寬是主流CPU數十倍甚至數百倍。每臺機器安裝8卡=768GB顯存,另外還有 CPU 192核384線程 + 2.3TB 內存。
為什么 GPU 會成為核心?是因為 LLM 大模型每次生成一個 token,都需要讀取全量的模型參數。傳統的 CPU + 內存的算力和帶寬無法滿足如此恐怖的計算密度,計算和通信都必須轉移(offload)到 GPU 內完成。CPU 成為數據搬運工和“輔助處理器”。
為了更直觀地理解這個計算密度,我們做一個簡單的計算。不考慮計算的延時,LLM 大模型生成一個 token 的耗時公式計算為。
以 DeepSeek-R1-671B-A37B-FP8 模型為例,計算一個 token 耗時,H20 為 37B × 1byte ÷ 4000GB/s = 9ms,如果是 CPU 則為 37B × 1byte ÷ 64GB/s = 578ms 。
1.2 從“去IOE ” 到“AI大型機 ”
顯而易見,我們的現在身處新的一輪烈火烹油的硬件革命的歷史進程中,各種專用硬件、專用網絡層出不窮。DeepSeek-R1 和 QWen3-235B 千億級參數訓練需千卡 GPU 集群協同,通過專用網絡互聯構建“AI超算”,其設計邏輯與以前的 IBM 大型機驚人相似——以硬件集中化換取極致性能與可靠性。
(IBM大型機)
傳統 Infra 的分布式理念貌似在 AI 時代失效了。傳統 Infra 追求橫向擴展,而 AI Infra 呈現 “AI 大型機”特性,是因為傳統后臺服務的可以容忍毫秒級延遲,但 AI 集群不行,GPU 的算力是 CPU 的數百倍,微秒級的延時等待也會造成很大的算力損耗,需要硬件的高度集成。在可預見的1-3年的未來,這樣的專用硬件+網絡的集中式架構很難發生比較大的改變。
回顧歷史,我們總是在尋求科技平權。前人推動“去IOE”(IBM小型機、Oracle數據庫、EMC存儲),用分布式廉價x86 pc機替代集中式高端硬件,本質上是利用軟件創新重構一個高可用+低成本的互聯網基礎設施。"AI大型機"是技術發展必由之路,但不是終極形態。長期(5年)來看,必然會出現 "AI 去 NVIDIA 化",重演“去 IOE”的歷史。
軟件演進
說完硬件體系的革命,接下來再關注下軟件層面的變化。
相比傳統后臺應用的增刪查改,AI 應用的新范式是模型訓練和推理。模型訓練是指通過海量數據擬合出一個復雜的神經網絡模型,推理就是利用訓練好的神經網絡模型進行運算,輸入的新數據來獲得新的結論。
舉個例子,訓練就是根據 <年齡, 身高> 的分布使用最小二乘法擬合模型 y = ax + b,推理就是利用這個模型 y = ax + b,輸入一個新的年齡,預測身高。
2.1 深度學習框架
工欲善其事,必先利其器。傳統后臺應用依賴 tRPC 或 Spring 等微服務框架,幫助我們屏蔽負載均衡、網絡通信等底層細節,我們可以把精力放在業務實現上。
與之相似,AI 應用則依賴深度學習框架。如果沒有深度學習框架,我們就可能陷入在茫茫的數學深淵中,掙扎于痛苦的 GPU 編程泥潭里。有了深度學習框架,我們才可以把所有精力花在設計模型和創新本身上,而不用關注底層的實現細節,極大降低了 AI 應用的門檻。
大家可能聽說過不同的深度學習框架——Tensorflow,PyTorch。現在是2025年,不用糾結選哪個,因為 PyTorch 就是 AI 模型訓練、推理的深度學習框架的事實標準。開源模型和代碼都是 PyTorch 一邊倒。
得益于動態計算圖、自動微分和豐富的 Tensor 操作算子,PyTorch 能幫助我們快速實現模型設計。如下圖所示,只需要描述模型結構+待學習的網絡參數,不需要關心數學計算和 GPU 編程的細節。
2.2 GPU 編程
絕大部分的 AI 應用,的確不需要我們手寫數學計算的 GPU 代碼。但為了滿足模型創新的需求,有必要學習 GPU 編程。例如 Meta 發布的 HSTU 生成式推薦模型,核心的 hstu_attn 計算,如果直接用 PyTorch 框架算子組合實現,則時間復雜度為 O(M * N2) ,其中 M 和 N 是一個數量級,相當于O(N3) 。但是通過自定義內核,可以優化到 O(N2)。
在 GPU 核心上運行的代碼片段稱為內核(kernel)。編寫高性能的 CUDA 內核需要豐富的經驗,并且學習曲線陡峭。因為我們習慣于傳統 CPU 編程處理串行的計算任務,通過多線程提高并發度。而 GPU 采用 SIMT 架構,有大量計算單元(CUDA Cores)和數萬個線程,但是被分組后的線程同一時刻只能執行相同的指令。這與傳統CPU的串行思維、不同線程處理不同任務,存在根本性沖突,導致 GPU 編程學習難度大。
(現實生活中的SIMT架構)
現在推薦使用 Triton 編程語言完成 GPU kernel 的開發,它提供類似 Python 的語法,無需深入理解 GPU 硬件細節(如線程調度、共享內存管理),而且和 PyTorch 深度學習框架的生態結合更好。推薦這個 Triton-Puzzles-Lite 項目用作 Triton 的入門學習。
2.3 Python 編程
正如客戶端開發離不開Kotlin/Objective-C,AI Infra 的編程第一公民就是 Python。PyTorch 深度學習框架的設計哲學強調 Python 優先 。
以前大部分模型還可以輕松導出 ONNX、TorchScript 等用 C++ 部署,現在隨著對模型的細粒度優化和控制越來越多,比如 KV Cache、MoE/模型并行、復雜的if/for控制流、自定義 Triton 算子等,模型越來越難以脫離 Python 的控制部署。筆者也從“C++ Boy”變成“Python Boy”。
(筆者git提交的語言統計變化)
模型訓練的挑戰
我們一直追求更大的模型,DeepSeek-R1 有數千億參數,使用了數十萬億 token 的訓練數據,涉及算力、存儲、通信等多維度的工程挑戰。有了 PyTorch 深度學習框架,只是 AI 應用落地的萬里長征第一步。接下來我們將討論深度學習框架之上的模型訓練的挑戰。
3.1 存得下
DeepSeek-R1 模型大小=670GB,而一臺 GPU 服務器有8張H20卡,提供768GB顯存,足夠存下一個完整的 DeepSeek 模型。那整個行業為什么還投入大量的人力物力,頂著通信延時造成的算力損耗,也要建設分布式 GPU 集群?核心原因是單臺 GPU 服務器“存不下”。
3.1.1 顯存刺客:中間激活
如下圖所示的模型,x1/x2/x3/x4 這些中間變量就是"中間激活"。它們是神經網絡前向傳播(Forward)的“堆棧幀(Stack Frame)”——記錄每一層處理后的數據快照,確保反向傳播(Backward)可回溯梯度,根據預測誤差調整模型權重,最小化損失函數。
這些中間激活為什么會成為"顯存刺客"?是因為中間激活的空間復雜度是和輸入數據長度正相關的,特別的,對于 LLM 來說是O(N2)正比于輸入數據長度的平方,這是一個指數爆炸式增長的數字。類似函數遞歸不斷增長的“堆棧幀”導致的內存溢出,我們遇到了 AI Infra 的 OOM(Out of Memory)挑戰。
借助 PyTorch 的 profiler 工具,我們可以直觀地看到這個OOM。下圖是訓練過程中不同階段的顯存分配,包括模型參數(Parameter)、優化器狀態(Optimizer state)、中間激活(Activation)、梯度(Gradient)。在前向傳播結束后出現一個顯存占用(中間激活)的尖峰,遠大于模型參數本身。
3.1. 2 模型并行
傳統后臺服務使用分片(Sharding)策略解決單機存不下的問題。與之相似,AI Infra 提出“模型并行”,就是將單個大模型拆分為多個子模塊,并分布到不同 GPU 上協同工作,通過通信來共享數據。有不同的“拆分模型”策略,例如按模型模塊劃分,按張量(Tensor)劃分的,也可以將多種拆分方法結合起來一起使用。PyTorch 深度學習框架和開源方案 Megatron 都能幫助我們高效地實現模型并行。
(不同的模型并行策略)
3. 2 算得快
建設分布式 GPU 集群的原因,一個是因為“單機存不下”,另外一個是提升訓練速度。但簡單的機器堆疊,算力不一定有線性的增長。因為分布式訓練并不是簡單地把原來一個 GPU 做的事情分給多個 GPU 各自做。需要協調多個 GPU 機器計算任務分配,GPU 機器之間的數據傳輸會引入網絡IO和通信開銷,降低訓練速度。
3. 2.1 通信計算重疊
如下圖所示的常規訓練時序是串聯式的,存在許多網絡 IO,GPU 利用率低,訓練速度慢。我們希望 GPU 大部分時間都在計算,而不是花在數據傳輸或等待其他 GPU 的工作上。
傳統后臺服務我們通過多線程或異步 IO 避免阻塞 CPU 主線程,與之相似,AI Infra 提出通信計算重疊的方法論。GPU 編程模型中有流(stream)的概念,一個流表示一個 GPU 操作隊列,該隊列中的操作將以添加到流中的先后順序而依次執行。不同流之間可以并行執行。那么通過令計算和通信操作加入不同的流中,可以做到二者的執行在時間上重疊。例如 TorchRec 的 訓練流水線 能幫助我們實現高效的通信計算重疊。
模型推理的挑戰
AI 模型訓練成本很高,優秀如 DeepSeek 也要燒掉500萬美金,但再貴也只是一次性的。而模型推理的成本更高,因為用戶越多,AI 模型推理次數越多,總成本越高。模型推理面對的挑戰和傳統 Infra 非常相似,主要是2個挑戰:高吞吐(降本),低延時(增效)。
4.1 降低延時
現在的 AI 模型越來越多地直面終端用戶,需要和用戶進行實時的交互,例如文本對話和語音合成。模型推理耗時過高,會直接造成用戶體驗受損,用戶流失與轉化率下降。
傳統后臺服務我們使用鏈接復用、緩存、柔性等技術降低系統響應時間。AI Infra 也有相似的做法。
4.1.1 CUDA Graph
在 GPU 編程模型中,CPU 和 GPU 是異構的,CPU 通過 API(例如 CUDA API) 向 GPU 提交任務,然后異步等待 GPU 的計算結果返回。GPU 收到任務后,會執行內核啟動、內存拷貝、計算等操作。這個過程中,涉及到 CPU 與 GPU 之間的通信、驅動程序的處理以及 GPU 任務的調度等環節,會產生一定的延遲。模型推理需要執行大量重復的 GPU 操作,每個的 GPU 操作都要重復執行上訴環節,這些非核心的 GPU 開銷會成倍數地放大,影響最終響應時間。
(CPU 和 GPU 通信)
在傳統后臺服務,我們使用 Redis 的 Lua 腳本封裝多個 Redis 操作和計算邏輯,一次提交,減少網絡開銷。與之相似,AI Infra 利用 CUDA Graph 技術將多個 GPU 操作轉化為一個有向無環圖(DAG),然后一次性提交整個 DAG 提交到 GPU 執行,由GPU自身來管理這些操作的依賴關系和執行順序,從而減少 CPU 與 GPU 之間的交互開銷。
(多個 GPU 內核啟動轉化為 CUDA Graph)
4.1.2 KV Cache:空間換時間
LLM 大模型推理存在大量矩陣乘法運算,且高度依賴上下文信息。每次推理都需要將之前生成過的詞重新輸入模型進行計算。這種計算方式使得復雜度達到了 O(N2),其中必然存在大量的重復計算。
例如,給定“天氣”,模型會逐個預測剩下的字,假設接下來預測的兩個字為“真好”。
將“真”拼接到“天氣”的后面,即新的輸入為“天氣真”,再預測“好”。
4.1.3 流式響應
有時候模型推理延時實在避免不了,可以從工程交互上想辦法。傳統后臺服務的 RPC 通信是一問一答方式,這種方式不太適合語音合成或者文本對話的場景。因為大模型推理需要幾秒-幾十秒,如果等待模型推理結束才展示結果,用戶會等待較長的時間,體驗很差。
流式響應就是當模型推理計算得到第一個token或者第一個音頻幀的時候,立馬展示或者播放給用戶,同時后續的模型推理結果在已經建立的 TCP 流上繼續順序傳輸。工程上從關注模型推理的整體耗時,改為關注首token或首個音頻幀的耗時。幾乎所有的 LLM 推理框架都支持了流式響應。
4.2 提高吞吐量
提高吞吐量是程序員在傳統 Infra 領域孜孜不倦的追求,因為更高的吞吐量意味著更低的機器成本。實現 AI 應用的高吞吐本質上就是提高昂貴的 GPU 的利用率,讓 GPU 單位時間能完成更多的任務。
盡管模型推理需要執行萬億次浮點運算,但 GPU 有大量的計算單元(CUDA Cores),單個請求的模型推理很難令 GPU 利用率達到飽和。提高 GPU 利用率有2個方法:傳統批處理和連續批處理。這里的“傳統批處理”是相對于“連續批處理”這樣的新型批處理方式而言的。
4.2.1 傳統批處理
其實傳統后臺服務也大量使用了批處理,例如 Redis 的 MGet 命令,單次請求就完成所有 key 的獲取,將 N 次網絡往返(RTT)壓縮為1次。與之相似,模型推理的批處理就是將多個輸入樣本打包(batch),將原本串行的 N 次輕量的推理計算,合并為 1 次重量的計算,實現單位時間內處理更多的請求,提高了 GPU 利用率。
“打包輸入樣本”是一個共性需求,大部分推理框架都提供該功能,例如 Triton Inference Server 的 Batcher 。
(模型批量推理流程圖)
4.2.2 連續批處理
傳統批處理類似 “固定班次的公交車”:乘客(請求)必須等待發車時間(組建一個batch),發車后所有乘客同步前進。即使有乘客提前下車(短請求完成),車輛仍需等待所有乘客到達終點(長請求完成)才能返程接新乘客。傳統批處理存在著資源浪費:GPU 要等待長請求處理完,不能處理新的請求而空閑。
這個問題在 LLM 應用領域顯得特別突出,因為不同用戶請求 Prompt,模型的回答結果長度差異巨大,如果使用傳統批處理,GPU 空閑率很高。這個本質上是個任務調度問題,傳統后臺服務我們使用工作竊取算法(work stealing)解決線程空閑問題,與之相似,AI Infra 提出“連續批處理”解決這個問題。
連續批處理類似“隨時隨地拼車的順風車”,每輛車(GPU)在行程中可隨時上/下客。新乘客(請求)直接加入當前車輛的空位(空閑計算單元),已完成的乘客立即下車(釋放資源)。幾乎所有的 LLM 推理框架都支持了連續批處理能力,例如 vLLM 的 Continuous Batching。
(連續批推理流程圖)
結語
AI Infra 面對的工程挑戰,例如計算、存儲、通信,大部分是新時代的老問題,我們在傳統 Infra 領域都能找到對應的場景和解決思路。差異只在于戰場從 CPU 轉移到 GPU,傳統后臺工程師積累的方法論,依然可以無縫銜接到 AI Infra。
感謝你讀到這里,不如關注一下?
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.