地圖:從算力硬件到推理服務(wù)的全鏈路解析)
做 AI 訓(xùn)練和部署這大半年我最大的一個(gè)感受是能把模型的 loss 訓(xùn)下去的人很多但能把一張訓(xùn)練卡的算力用好、把幾千張卡組織成一個(gè)不空轉(zhuǎn)的整體、把推理服務(wù)的延遲壓進(jìn) SLA 的人是另一種稀缺。這個(gè)領(lǐng)域有一個(gè)很寬泛的名字叫 AI Infra。我最初以為它只是“搭環(huán)境、裝驅(qū)動(dòng)、調(diào)框架”真正深入以后才發(fā)現(xiàn)它是一整條從芯片到業(yè)務(wù)的鏈路算力硬件、集群網(wǎng)絡(luò)、資源調(diào)度、分布式訓(xùn)練、推理引擎、存儲(chǔ)訪問(wèn)、性能剖析……每一環(huán)都是獨(dú)立的深水區(qū)。這篇 AI Infra 知識(shí)全景學(xué)習(xí)筆記就是我把這條鏈路里繞不開的知識(shí)點(diǎn)整理成的一份地圖式提綱從底層到上層逐層拆解同時(shí)把我實(shí)際踩過(guò)的坑和算過(guò)的賬一并寫出來(lái)。無(wú)論你是剛要從算法轉(zhuǎn)向工程還是已經(jīng)在維護(hù)訓(xùn)練集群這份筆記都能幫你快速建立起全局坐標(biāo)系。1. AI Infra 全景認(rèn)知先給這個(gè)領(lǐng)域畫張地圖1.1 AI Infra 不是什么而是什么很多人有一個(gè)慣性思維覺(jué)得做 AI 最核心的是模型結(jié)構(gòu)。在大模型出現(xiàn)之前這個(gè)想法問(wèn)題不大單卡訓(xùn)練、單機(jī)推理瓶頸主要在算法本身。但到了大模型階段問(wèn)題徹底變了模型參數(shù)動(dòng)輒幾十 B、上百 B單卡放不下就要切切了就要通信通信就要組網(wǎng)組網(wǎng)就要調(diào)度調(diào)度就要考慮資源隔離和利用率跑起來(lái)還要監(jiān)控、評(píng)測(cè)、優(yōu)化。這一整條鏈路就是 AI Infra。舉一個(gè)很直觀的例子你向大模型問(wèn)一個(gè)問(wèn)題表面上只是輸入一句文本收到一段回答但背后實(shí)際發(fā)生了至少四段工作請(qǐng)求進(jìn)入網(wǎng)關(guān)被調(diào)度到某個(gè)實(shí)例實(shí)例從存儲(chǔ)里讀取模型權(quán)重和數(shù)據(jù)GPU 完成數(shù)千次矩陣運(yùn)算中間還要通過(guò)網(wǎng)絡(luò)同步多個(gè)設(shè)備的計(jì)算結(jié)果。任何一個(gè)環(huán)節(jié)慢用戶感受到的就是“轉(zhuǎn)圈圈”。所以 AI Infra 不是某一臺(tái)機(jī)器或某一個(gè)軟件而是讓“輸入-計(jì)算-輸出”這條鏈條高效運(yùn)轉(zhuǎn)的全部工程手段。這也是我把它稱為“知識(shí)全景”的原因。它不像某個(gè)算法可以用一個(gè)公式講清楚而是一個(gè)橫跨硬件、網(wǎng)絡(luò)、系統(tǒng)軟件、并行計(jì)算、服務(wù)架構(gòu)的交叉學(xué)科。要理解它必須先有一張地圖。1.2 七個(gè)層次的知識(shí)框架我按自己的理解把 AI Infra 從上到下拆成七個(gè)層級(jí)。這個(gè)分層不一定是標(biāo)準(zhǔn)定義但用來(lái)建立知識(shí)體系非常順手層級(jí)解決的核心問(wèn)題典型概念與工具算力硬件層提供計(jì)算和顯存資源GPU/NPU、HBM 顯存、高速互聯(lián)總線集群網(wǎng)絡(luò)層讓多卡高效交換數(shù)據(jù)RDMA、擁塞控制、集合通信資源管理層把算力按需分配給多個(gè)任務(wù)Kubernetes、GPU 虛擬化、調(diào)度策略分布式訓(xùn)練層把大模型拆到多卡上訓(xùn)練數(shù)據(jù)并行、張量并行、流水線并行、ZeRO推理服務(wù)層把訓(xùn)練好的模型變成可用服務(wù)連續(xù)批處理、KV Cache、推理引擎存儲(chǔ)與數(shù)據(jù)層讓數(shù)據(jù)/檢查點(diǎn)讀寫不拖后腿分布式文件系統(tǒng)、緩存、預(yù)取可觀測(cè)與性能層定位瓶頸、優(yōu)化成本Profiling、利用率監(jiān)控、成本模型這張表的順序就是知識(shí)依賴的方向。底層決定上層的可能性上層則反過(guò)來(lái)影響底層的選型。比如你推理引擎的批處理策略直接決定了你要買多少卡你的調(diào)度策略又決定了訓(xùn)練任務(wù)的利用率。我在學(xué)習(xí)時(shí)的一個(gè)心得是不要一上來(lái)就扎進(jìn)分布式訓(xùn)練的源碼里而是先按這七個(gè)層級(jí)各看三篇有分量的文章腦海里有了“哪一環(huán)對(duì)應(yīng)什么問(wèn)題”的索引再往后學(xué)效率會(huì)高出很多。接下來(lái)我會(huì)按從底層到上層的順序把每一層的關(guān)鍵知識(shí)點(diǎn)展開講。2. 算力與集群網(wǎng)絡(luò)AI Infra 的地基2.1 為什么算力瓶頸不是“算”而是“搬”很多剛接觸 AI Infra 的人會(huì)以為GPU 越快訓(xùn)練越快。這句話只對(duì)了一半。真正決定大模型訓(xùn)練和推理上限的往往不是計(jì)算峰值而是數(shù)據(jù)搬運(yùn)速度。大模型的兩個(gè)核心階段能很清楚地說(shuō)明這個(gè)問(wèn)題。訓(xùn)練階段每一輪迭代都要把權(quán)重和梯度在顯存里來(lái)回讀寫推理階段自回歸生成是逐 token 解碼的前一個(gè) token 的結(jié)果必須參與后一個(gè) token 的計(jì)算本質(zhì)上是串行的訪存密集操作算力的利用率天然受限。我常用一個(gè)“食堂打飯”的類比來(lái)理解這件事算力就是廚師的炒菜速度顯存帶寬就是窗口遞菜的速度。如果廚師一分鐘能炒十盤菜但窗口一分鐘只能遞出三盤整個(gè)食堂的效率就是三盤/分鐘。你換一個(gè)廚師更強(qiáng)的算力效率依然不變。AI Infra 大量?jī)?yōu)化的本質(zhì)都是讓“遞菜速度”追上“炒菜速度”。實(shí)測(cè)來(lái)看目前主流訓(xùn)練加速卡的顯存帶寬通常在 2TB/s 到 3TB/s 之間而計(jì)算峰值已經(jīng)到每秒幾百甚至上千 TFLOPS。大模型的核心算子基本都是訪存密集型很多時(shí)候顯存帶寬直接決定了你的訓(xùn)練吞吐上限。2.2 顯存與 I/OHBM 與緩存的作用顯存帶寬之所以能做到這么高靠的是 HBM高帶寬內(nèi)存技術(shù)。HBM 的邏輯和傳統(tǒng) GDDR 顯存不一樣它通過(guò) 3D 堆疊的方式把多個(gè) DRAM 層疊在一起用硅通孔連接從而獲得遠(yuǎn)超平面布線的數(shù)據(jù)通道寬度。簡(jiǎn)單說(shuō)通道更寬一次能并行搬的數(shù)據(jù)就更多。但 HBM 容量相對(duì)有限單卡主流是 80GB 左右。這就是矛盾所在一個(gè) 7B 參數(shù)的模型光權(quán)重用 BF16 存儲(chǔ)就要 14GB再加上梯度和 Adam 優(yōu)化器狀態(tài)單卡根本裝不下。所以必須把模型切到多張卡上切了之后就要通信這就引出了集群網(wǎng)絡(luò)。在實(shí)際調(diào)優(yōu)時(shí)還要注意算子庫(kù)的選擇和緩存利用。一個(gè)卷積或者矩陣乘法會(huì)被拆成很多 tile 放到片上緩存里計(jì)算如果 tile 切得不夠合理緩存命中率低算力就會(huì)被白白浪費(fèi)。這也是為什么同樣的模型有人能跑到高利用率、有人只能跑到一半的原因。我通常在排查一個(gè)算子慢的問(wèn)題時(shí)會(huì)先去確認(rèn)是不是顯存訪問(wèn)模式問(wèn)題而不是急著懷疑硬件壞了。2.3 集群網(wǎng)絡(luò)高速互聯(lián)、RDMA 與集合通信單機(jī)多卡之間目前主流方案是高速 NVLink 全互聯(lián)或類似的高帶寬總線帶寬能到數(shù)百 GB/s延遲極低??绻?jié)點(diǎn)之間則要用 RDMA 網(wǎng)絡(luò)如 InfiniBand 或 RoCE帶寬通常在 200Gbps 到 400Gbps 級(jí)別。注意單位差異節(jié)點(diǎn)內(nèi)是 GB/s跨節(jié)點(diǎn)是 Gbps兩者有 8 倍的單位換算關(guān)系算峰值時(shí)很多人會(huì)在這一點(diǎn)上被繞暈。有了網(wǎng)絡(luò)之后就要考慮怎么組織通信。分布式訓(xùn)練中最常見(jiàn)的通信原語(yǔ)是 AllReduce也就是把所有卡的梯度做一個(gè)求和再?gòu)V播給所有卡。業(yè)界最常用的集合通信庫(kù) NCCL 對(duì)這個(gè)操作做了大量?jī)?yōu)化包括分塊傳輸、流水線重疊、拓?fù)涓兄饶軌虬淹ㄐ帕繅旱浇咏碚撋舷?。但網(wǎng)絡(luò)擁塞會(huì)成為隱形的殺手。我遇到過(guò)一種情況4 機(jī) 8 卡訓(xùn)練時(shí)明明單卡之間的通信測(cè)試帶寬都正常整個(gè)訓(xùn)練吞吐卻只有預(yù)期的 60%。排查到最后發(fā)現(xiàn)是網(wǎng)絡(luò)交換機(jī)上的擁塞控制策略沒(méi)有開啟多卡并發(fā)傳輸時(shí)大量數(shù)據(jù)包排隊(duì)丟棄觸發(fā)重傳通信效率被拉低了一個(gè)量級(jí)。這個(gè)坑告訴我AI Infra 的學(xué)習(xí)不能只停留在代碼層交換機(jī)配置、網(wǎng)卡參數(shù)這些“硬件晦澀區(qū)”同樣是性能的重要組成部分。3. 資源管理與調(diào)度把算力當(dāng)成稀缺資源對(duì)待3.1 從單機(jī)到集群為什么 Kubernetes 管理 GPU 這么重要當(dāng)集群里有幾十臺(tái)機(jī)器、每臺(tái)機(jī)器多張卡問(wèn)題就變成了誰(shuí)來(lái)決定一個(gè)訓(xùn)練任務(wù)跑到哪張卡上如果只靠人工分配不僅效率低而且容易造成嚴(yán)重的資源碎片。所以絕大多數(shù) AI 集群都會(huì)引入 Kubernetes 這類容器編排平臺(tái)把底層的異構(gòu)機(jī)器抽象成統(tǒng)一的資源池。但 Kubernetes 對(duì) GPU 的管理邏輯很特別。CPU 是用完即釋放的而 GPU 一旦被容器獨(dú)占除非任務(wù)結(jié)束否則就會(huì)一直占用顯存和計(jì)算資源。所以 GPU 調(diào)度不能只看“有沒(méi)有空閑卡”還要看顯存余量、算力配額、是否支持在卡間做緊耦合通信。這就催生了 GPU 虛擬化和分時(shí)復(fù)用技術(shù)比如對(duì)物理 GPU 做硬件切分或者在時(shí)間片上把一張卡分給多個(gè)推理任務(wù)從而提升整體利用率。我在實(shí)際維護(hù)集群時(shí)的一個(gè)體會(huì)是調(diào)度的根本目標(biāo)不是“把任務(wù)塞進(jìn)機(jī)器”而是“把任務(wù)放到能完成它且讓整體利用率最高的位置”。比如兩個(gè)訓(xùn)練任務(wù)分別需要 60GB 和 20GB 顯存物理卡是 80GB如果調(diào)度器把它們錯(cuò)開放到同一張卡就能省下另一張卡去跑別人如果調(diào)度器沒(méi)有碎片感知能力就會(huì)各占一張卡白白浪費(fèi) 20GB 空間。3.2 調(diào)度策略組合優(yōu)化與權(quán)衡資源調(diào)度本質(zhì)上是一個(gè)組合優(yōu)化問(wèn)題最簡(jiǎn)單的兩類策略是“裝箱”Binpack和“打散”Spread。Binpack把任務(wù)盡量集中到少數(shù)節(jié)點(diǎn)上空出整塊節(jié)點(diǎn)。好處是省電壞處是單點(diǎn)故障影響面大并且把多個(gè)大型訓(xùn)練任務(wù)放在同一機(jī)架可能造成網(wǎng)絡(luò)擁塞。Spread把任務(wù)均勻打散到各個(gè)節(jié)點(diǎn)。好處是容錯(cuò)性好壞處是容易產(chǎn)生碎片并且訓(xùn)練任務(wù)之間的通信可能因?yàn)槲恢梅稚⒍兟?。在大?guī)模訓(xùn)練場(chǎng)景通常還要考慮拓?fù)?。同一個(gè)訓(xùn)練任務(wù)里的多張卡最好落在同一個(gè)交換機(jī)下最好是一個(gè)物理機(jī)箱內(nèi)因?yàn)?NVLink 帶寬比跨節(jié)點(diǎn)網(wǎng)絡(luò)高一個(gè)量級(jí)。很多調(diào)度器會(huì)做拓?fù)溆H和性計(jì)算就像訂機(jī)票時(shí)優(yōu)先安排同航站樓轉(zhuǎn)機(jī)一樣需要為“通信密集”的任務(wù)預(yù)留“同一機(jī)架”的位置。我踩過(guò)一個(gè)很典型的坑某團(tuán)隊(duì) A 同學(xué)反饋 GPU 利用率只有 30%我看了一下任務(wù)分布發(fā)現(xiàn)調(diào)度器為了“均勻”把一個(gè) 8 卡訓(xùn)練任務(wù)拆到 8 個(gè)不同節(jié)點(diǎn)上每張卡之間都通過(guò)網(wǎng)絡(luò)通信。結(jié)果模型的張量并行頻繁跨節(jié)點(diǎn)同步通信開銷把計(jì)算時(shí)間完全吃掉。后來(lái)改成把 8 卡全部調(diào)度到同一臺(tái)多卡機(jī)器上利用率直接回到 85% 以上。這充分說(shuō)明調(diào)度策略不是拍腦袋決定的必須結(jié)合任務(wù)的通信模式。3.3 層級(jí)調(diào)度與排隊(duì)別讓大任務(wù)餓死小任務(wù)除了位置選擇調(diào)度還要處理優(yōu)先級(jí)和排隊(duì)。一個(gè)動(dòng)輒占用上百?gòu)埧ǖ拇笮陀?xùn)練任務(wù)如果和小型推理任務(wù)混跑可能會(huì)長(zhǎng)期占據(jù)共享資源。比較成熟的調(diào)度器會(huì)設(shè)計(jì)兩級(jí)結(jié)構(gòu)先按優(yōu)先級(jí)和高層策略決定哪一類任務(wù)可以進(jìn)入再在內(nèi)部做具體的放置。訓(xùn)練任務(wù)往往長(zhǎng)期霸占推理任務(wù)則偏向延遲敏感兩者混部實(shí)際上是另一個(gè)大的研究課題。學(xué)習(xí)這一層知識(shí)我的建議是先把 Kubernetes 的資源模型Requests/Limits和調(diào)度器擴(kuò)展機(jī)制看懂再去看主流的 AI 調(diào)度器是怎么做 GPU 分配和隊(duì)列管理的。這里很多經(jīng)驗(yàn)都無(wú)法從文檔里學(xué)到只能靠真實(shí)集群的“性價(jià)比”來(lái)感知。4. 分布式訓(xùn)練的核心邏輯并行策略與顯存優(yōu)化4.1 單卡裝不下四種并行怎么選分布式訓(xùn)練就是解決“模型太大”和“數(shù)據(jù)太多”兩個(gè)問(wèn)題業(yè)界形成了四種基本并行策略策略切什么顯存收益通信開銷適用場(chǎng)景數(shù)據(jù)并行DP復(fù)制模型切數(shù)據(jù)無(wú)每卡都要完整模型每步同步梯度通信量與模型大小成正比單卡能裝下模型時(shí)張量并行TP切分矩陣運(yùn)算的維度每卡只存一部分權(quán)重每層多次集合通信極高單卡裝不下、且節(jié)點(diǎn)內(nèi)高帶寬場(chǎng)景流水線并行PP按層切分網(wǎng)絡(luò)每卡只存部分層通信量小但產(chǎn)生流水線氣泡超深網(wǎng)絡(luò)、跨節(jié)點(diǎn)場(chǎng)景序列并行SP切分序列長(zhǎng)度維度減少激活值顯存依賴注意力機(jī)制的重計(jì)算長(zhǎng)序列場(chǎng)景常與 TP 組合數(shù)據(jù)并行的邏輯最好理解每張卡復(fù)制一份完整模型喂不同的數(shù)據(jù)算完梯度后在卡間做 AllReduce 求平均再同步更新。它的顯存開銷最大但通信結(jié)構(gòu)最簡(jiǎn)單是工程上最容易被框架封裝好的選擇。張量并行則直接把一個(gè)矩陣乘法拆開到多張卡上做比如把權(quán)重矩陣按行切給卡 A、按列切給卡 B每張卡只持有模型的一部分。通信頻率很高因?yàn)樗饔糜谀P蛢?nèi)部每一層的計(jì)算每處理一個(gè)層就要做數(shù)據(jù)同步。所以張量并行幾乎只在高帶寬的節(jié)點(diǎn)內(nèi)使用跨節(jié)點(diǎn)用張量并行基本是災(zāi)難。流水線并行是另一個(gè)極端它把幾十層網(wǎng)絡(luò)切成多段每張卡負(fù)責(zé)一段輸入數(shù)據(jù)像流水線一樣經(jīng)過(guò)所有段。通信量小但會(huì)產(chǎn)生氣泡——即某些卡在等上游輸出時(shí)是空閑的。這兩種策略之間的選擇本質(zhì)上是在“通信成本”和“空閑成本”之間做權(quán)衡。4.2 一個(gè)必須算的賬ZeRO 到底省了什么在真正上多機(jī)多卡之前建議先把 ZeRO 這套優(yōu)化思路搞懂。它解決的問(wèn)題是即使單卡裝不下模型也不一定非要切模型可以把模型狀態(tài)“分片并行”地放在多張卡上。先算一筆賬7B 模型用 BF16 存儲(chǔ)是 14GB訓(xùn)練通常需要 FP32 主權(quán)重、一階動(dòng)量、二階動(dòng)量三者加起來(lái)每參數(shù) 12 字節(jié)也就是說(shuō)優(yōu)化器狀態(tài)就要 84GB再加上梯度和權(quán)重總量超過(guò) 110GB。單卡 80GB 根本放不下。ZeRO 的解決思路是分階段把狀態(tài)切到各卡上ZeRO-1只把優(yōu)化器狀態(tài)切分到各卡每卡顯存從 110GB 降至約 40GBZeRO-2把優(yōu)化器狀態(tài)和梯度都切分每卡約 25GBZeRO-3把參數(shù)、梯度、優(yōu)化器狀態(tài)全部分片每卡約 14GB。代價(jià)是通信量上升。ZeRO-3 每一步都需要從別的卡拉取參數(shù)通信量大約是數(shù)據(jù)并行的 1.5 到 2 倍。所以 ZeRO 不是無(wú)腦最優(yōu)而是用一部分通信開銷換取顯存空間。配置時(shí)常用的經(jīng)驗(yàn)值是先看單卡能不能放下 FP16 權(quán)重和梯度放得下就用 ZeRO-2放不下才升到 ZeRO-3。4.3 流水線氣泡與微批次調(diào)優(yōu)如果用流水線并行就要立刻面對(duì)“氣泡”這個(gè)概念。假設(shè)把模型切成 8 段8 個(gè) stage一次只喂一個(gè) micro-batch那么整條流水線只有第一個(gè) batch 進(jìn)入時(shí)是滿負(fù)荷后面每個(gè) stage 都是串行執(zhí)行大量時(shí)間在等待上游——這就是氣泡。解決辦法是引入多個(gè) micro-batch微批次讓流水線里的每個(gè) stage 同時(shí)都在干活。氣泡比例近似等于 (stage 數(shù) - 1) / (micro-batch 數(shù) stage 數(shù) - 1)。stage 越深需要越多 micro-batch 才能填滿流水線。我實(shí)際調(diào)參時(shí)會(huì)先按這個(gè)公式算再結(jié)合顯存余量決定 micro-batch 數(shù)量通常調(diào)到氣泡占比低于 10% 才會(huì)認(rèn)為參數(shù)合理。還有一個(gè)容易忽略的點(diǎn)micro-batch 數(shù)量增大每張卡上的激活值顯存也會(huì)增加。所以微批次調(diào)優(yōu)本質(zhì)上是在“氣泡”和“激活顯存”之間找平衡。遇到峰值顯存 OOM優(yōu)先減小 micro-batch而不是盲目換并行策略這是成本最低的調(diào)整方式。4.4 一個(gè)真實(shí)的選型場(chǎng)景模擬項(xiàng)目 X給一個(gè)具體的決策示例。模擬項(xiàng)目 X 要訓(xùn)練一個(gè) 30B 參數(shù)的模型集群是 4 臺(tái)機(jī)器、每臺(tái) 8 張 80GB 卡共 32 卡。BF16 權(quán)重 60GB單卡裝不下ZeRO-2 可以把優(yōu)化器狀態(tài)分片每卡權(quán)重 60GB 梯度 60GB 優(yōu)化器狀態(tài)約 30GB合計(jì)約 150GB算出來(lái)其實(shí)仍超單卡。這時(shí)正確的組合是把模型切成 4 份張量并行并用 ZeRO-2 處理優(yōu)化器狀態(tài)。每個(gè) TP 組內(nèi)用高帶寬互聯(lián)通信組間再通過(guò)數(shù)據(jù)并行同步梯度是典型的“TP ZeRO DP”組合。這種決策樹的推導(dǎo)邏輯是先看單卡能否容納權(quán)重和梯度 → 不能則選擇 TP 切分 → 再看優(yōu)化器狀態(tài)是否超過(guò)單卡剩余顯存 → 仍超則加 ZeRO-2 → 如果模型層數(shù)很深可進(jìn)一步加入 PP用跨節(jié)點(diǎn)連接。整個(gè)過(guò)程中每一步都涉及顯存賬和通信賬只有把兩張賬都算清楚才能得到可靠的配置。5. 推理服務(wù)層讓模型真正跑起來(lái)5.1 訓(xùn)練和推理的思路為什么完全不同訓(xùn)練追求的是“吞吐”單位時(shí)間處理多少 token、梯度更新多快推理追求的首要是“延遲”用戶發(fā)出請(qǐng)求到收到第一個(gè) token 要多久。這導(dǎo)致技術(shù)選型完全不同。大模型推理可以拆成兩個(gè)階段prefill預(yù)填充處理用戶輸入的整段 prompt屬于計(jì)算密集型GPU 算力利用率很高decode解碼階段逐 token 生成答案屬于訪存密集型每生成一個(gè) token 都要把當(dāng)前所有緩存權(quán)重讀一遍算力利用率通常很低。很多人第一次看到推理卡的 GPU 利用率只有 20% 到 30%就是這個(gè)原因不是卡不行而是 decode 階段天然受帶寬限制。這帶來(lái)一個(gè)關(guān)鍵結(jié)論推理性能優(yōu)化的重點(diǎn)是盡量減少 decode 階段的訪存量而不是盲目堆算力。5.2 連續(xù)批處理與 KV Cache 管理最早期的推理服務(wù)采用靜態(tài)批處理一批請(qǐng)求同時(shí)到達(dá)、同時(shí)算完、同時(shí)離開。這種模式的問(wèn)題在于decode 階段批內(nèi)的每個(gè)請(qǐng)求長(zhǎng)度不同短的請(qǐng)求會(huì)等長(zhǎng)的請(qǐng)求大量算力白白浪費(fèi)。于是出現(xiàn)了連續(xù)批處理每個(gè) step 動(dòng)態(tài)地從隊(duì)列里撈入新請(qǐng)求同時(shí)把已經(jīng)結(jié)束的請(qǐng)求移出批次。因?yàn)?decode 階段每個(gè)請(qǐng)求只是順序讀取自己的緩存新舊請(qǐng)求可以互相穿插而不干擾所以吞吐能提升數(shù)倍。這是目前主流推理引擎的標(biāo)準(zhǔn)做法。還有一個(gè)繞不開的概念是 KV Cache。自回歸生成時(shí)模型需要把之前所有 token 的 Key 和 Value 緩存下來(lái)避免每步重新計(jì)算。KV Cache 的大小非常驚人以 7B 模型為例每個(gè) token 約產(chǎn)生 0.5MB 緩存4096 token 長(zhǎng)度就是 2GB。如果顯存只有 80GB留給權(quán)重約 14GBKV Cache 能容納的并發(fā)請(qǐng)求數(shù)非常有限。主流引擎采用分頁(yè)管理的方式優(yōu)化 KV Cache 的顯存利用率核心思想是顯存按頁(yè)分配像操作系統(tǒng)虛擬內(nèi)存一樣減少碎片和浪費(fèi)。這也是我在配置推理服務(wù)時(shí)最喜歡調(diào)的一項(xiàng)它直接決定了并發(fā)能力和延遲表現(xiàn)。如果你觀察到服務(wù)排隊(duì)嚴(yán)重先別急著加卡看看 KV Cache 的使用率和顯存碎片率。5.3 推理引擎的量化與硬件選型有感推理場(chǎng)景還有一個(gè)和訓(xùn)練截然不同的點(diǎn)量化技術(shù)對(duì)性能影響極大。把權(quán)重從 FP16 降到 INT8KV Cache 也做量化顯存和帶寬需求幾乎減半decode 吞吐能翻倍。所以推理服務(wù)的性能優(yōu)化往往是從“省內(nèi)存”入手的。在硬件選型上我學(xué)到一個(gè)重要指標(biāo)“算力與帶寬比”。如果一款卡算力極高但帶寬一般它跑 decode 任務(wù)時(shí)算力會(huì)被嚴(yán)重浪費(fèi)反之如果帶寬高但算力一般反而能在實(shí)際推理中表現(xiàn)更好。這個(gè)比值可以作為判斷推理場(chǎng)景卡型適配度的第一參考就像選車型時(shí)不只看馬力還要看變速箱匹配。具體的卡型選擇我不過(guò)多展開因?yàn)闀?huì)牽涉到成本模型建議結(jié)合自己的 token 吞吐目標(biāo)來(lái)算。6. 存儲(chǔ)、數(shù)據(jù)與可觀測(cè)性容易被忽視的隱形成本6.1 檢查點(diǎn)與數(shù)據(jù)讀取訓(xùn)練被“餓死”的現(xiàn)象很多團(tuán)隊(duì)把精力全放在并行配置上結(jié)果 GPU 利用率還是上不去最后發(fā)現(xiàn)是磁盤讀取慢導(dǎo)致數(shù)據(jù)供不上。訓(xùn)練任務(wù)可以類比成一條生產(chǎn)線GPU 是終端裝配工數(shù)據(jù)加載環(huán)節(jié)就是原料輸送帶。輸送帶一旦斷料再快的裝配工也只能等。大模型的檢查點(diǎn)checkpoint保存非??膳乱粋€(gè)百億級(jí)模型的全量權(quán)重和優(yōu)化器狀態(tài)可能有數(shù)百 GB全靠訓(xùn)練結(jié)束一次性寫出寫盤期間整批 GPU 都要停下來(lái)等。常用方案是異步 checkpoint把寫盤交給后臺(tái)線程讓訓(xùn)練迭代替換繼續(xù)進(jìn)行同時(shí)用內(nèi)存緩存或高性能分布式文件系統(tǒng)避免每次讀卡前訪問(wèn)慢速磁盤。我測(cè)試過(guò)的一個(gè)案例里開啟異步保存后訓(xùn)練吞吐從每分鐘 12 個(gè) step 提升到 19 個(gè) step提升接近 60%只是簡(jiǎn)單地把同步寫盤改為后臺(tái)異步完成。這說(shuō)明存儲(chǔ)層的優(yōu)化是性價(jià)比極高的投資學(xué)習(xí) AI Infra 時(shí)千萬(wàn)別只看“計(jì)算”。6.2 性能剖析與慢任務(wù)定位當(dāng)訓(xùn)練或推理性能不達(dá)標(biāo)時(shí)第一件事不是改超參而是定位瓶頸在哪一層。我歸納了一個(gè)排查順序表每次按表執(zhí)行就能很快縮小范圍現(xiàn)象優(yōu)先排查對(duì)象可能原因GPU 利用率低且波動(dòng)大數(shù)據(jù)加載鏈路磁盤讀慢、預(yù)處理沒(méi)做、隊(duì)列太小GPU 利用率低但 CPU 忙數(shù)據(jù)預(yù)處理訓(xùn)練線程在等數(shù)據(jù)轉(zhuǎn)換完成多卡通信時(shí)吞吐驟降網(wǎng)絡(luò)層擁塞控制未開、交換機(jī)降速、網(wǎng)卡拓?fù)洳粚?duì)單個(gè)節(jié)點(diǎn)明顯比同集群慢硬件層GPU 降頻、HBM 出現(xiàn)錯(cuò)誤、散熱問(wèn)題顯存頻繁 OOM并行/緩存配置激活值過(guò)大、KV Cache 碎片、micro-batch 過(guò)大在實(shí)際觀測(cè)中我會(huì)同時(shí)關(guān)注 GPU 利用率、顯存帶寬利用率、網(wǎng)絡(luò)吞吐三個(gè)指標(biāo)。如果 GPU 利用率 90% 但顯存帶寬跑滿說(shuō)明是該卡的訪存極限加卡不一定有用如果網(wǎng)絡(luò)吞吐打到線速則是通信瓶頸又要回頭調(diào)整并行策略。這種綜合分析能力是 AI Infra 學(xué)習(xí)者最核心的一項(xiàng)修煉。7. 學(xué)習(xí)路線與常見(jiàn)坑寫給后來(lái)者的實(shí)踐建議7.1 我推薦的學(xué)習(xí)順序如果從零開始建議按“單卡訓(xùn)練 → 多機(jī)多卡 → 集群調(diào)度 → 推理部署 → 性能剖析”的順序走每個(gè)階段都動(dòng)手做一個(gè)小實(shí)驗(yàn)而不是只讀文檔。第一步先把一個(gè)開源對(duì)話模型的微調(diào)跑通觀察顯存占用和單卡利用率。第二步到兩臺(tái)機(jī)器上做數(shù)據(jù)并行看看梯度同步帶來(lái)的性能損耗。第三步嘗試把模型切成張量并行或流水線并行體驗(yàn)通信開銷的巨大差異。第四步部署推理服務(wù)調(diào)整批處理和 KV Cache 配置觀察并發(fā)和延遲變化。這個(gè)過(guò)程走下來(lái)你會(huì)對(duì)每個(gè)概念的“手感”非常清晰。遇到問(wèn)題時(shí)不至于在概念之間打轉(zhuǎn)。我認(rèn)識(shí)的不少人都會(huì)跳步一上來(lái)就學(xué)多機(jī)多卡結(jié)果連單卡的顯存賬都不會(huì)算最后還是得回頭補(bǔ)基礎(chǔ)。7.2 高頻問(wèn)題速查把幾個(gè)經(jīng)常遇到的問(wèn)題整理成速查表方便直接對(duì)照模型訓(xùn)練時(shí) loss 一直是 NaN先查學(xué)習(xí)率和混合精度配置再看數(shù)據(jù)里有沒(méi)有異常值最后查梯度累計(jì)和 loss scaling。多卡訓(xùn)練時(shí)某張卡“掉隊(duì)”導(dǎo)致整體等待。這類問(wèn)題多半是慢節(jié)點(diǎn)需要檢查該卡的時(shí)鐘頻率、散熱和 HBM 錯(cuò)誤。推理服務(wù)響應(yīng)慢但 GPU 利用率不高優(yōu)先級(jí)最高的是檢查 KV Cache 命中率和批處理是否生效很多情況下是并發(fā)隊(duì)列配置不對(duì)。集群利用率統(tǒng)計(jì)虛高注意有的監(jiān)控把“已分配但空閑”也算成被使用看真實(shí)利用率一定要看算力采樣數(shù)據(jù)而不是分配比例。7.3 一點(diǎn)個(gè)人體會(huì)說(shuō)到最后我想分享一個(gè)這段時(shí)間學(xué) AI Infra 最深的感觸它不是一個(gè)靠“多看幾篇論文”就能掌握的知識(shí)而是一門靠“算賬”和“試錯(cuò)”積累的手藝。顯存賬、帶寬賬、延遲賬、成本賬每一步都在做權(quán)衡而真正的優(yōu)化往往發(fā)生在交叉地帶。我在實(shí)際維護(hù)集群時(shí)發(fā)現(xiàn)最花時(shí)間的不是把任務(wù)跑起來(lái)而是讓任務(wù)跑得快且穩(wěn)。每一次利用率提升的背后可能只是一行調(diào)度配置的改動(dòng)或者一次網(wǎng)絡(luò)參數(shù)的調(diào)優(yōu)但它需要你對(duì)整條鏈路都有清晰的認(rèn)知。這也是我整理這份 AI Infra 知識(shí)全景學(xué)習(xí)筆記的原因把地圖先畫好后面的路才不容易走偏。如果讓我再給一條具體建議那就是把“成本模型”刻在腦子里。無(wú)論是選并行策略、買卡、調(diào)顯存還是配網(wǎng)絡(luò)都先估算單位 token 或單位樣本的成本再?zèng)Q定優(yōu)化方向。這個(gè)習(xí)慣一旦養(yǎng)成你會(huì)發(fā)現(xiàn)所有技術(shù)的選擇都變得清晰起來(lái)。