習(xí)路線:從后端到推理部署的全景指南)
1. 從零搭建AI Infra知識全景一個(gè)后端老兵的學(xué)習(xí)路線復(fù)盤這兩年AI應(yīng)用層卷得飛起但真正把模型跑起來、跑穩(wěn)、跑便宜的那批人反而越來越稀缺。我自己是從傳統(tǒng)后端轉(zhuǎn)過來的剛開始以為“不就是調(diào)個(gè)API嘛”結(jié)果第一次自己部署推理服務(wù)就被顯存、并發(fā)、量化、調(diào)度這些概念按在地上摩擦。后來花了小半年時(shí)間把AI Infra這條線上的知識點(diǎn)從頭到尾捋了一遍形成了一套自己的學(xué)習(xí)筆記。這篇文章就是把這套筆記重新整理出來講清楚AI Infra到底包含哪些模塊、每個(gè)模塊的核心技術(shù)點(diǎn)是什么、學(xué)習(xí)順序應(yīng)該怎么安排、以及我在實(shí)操中踩過的那些坑。如果你是有后端基礎(chǔ)想轉(zhuǎn)AI Infra的開發(fā)者或者已經(jīng)在做算法但想把工程側(cè)補(bǔ)齊的工程師再或者是對“模型怎么從訓(xùn)練到上線”這件事好奇的技術(shù)管理者這篇內(nèi)容應(yīng)該都能給你一個(gè)相對完整的知識地圖。我不會只列概念每個(gè)模塊都會說清楚它解決什么問題、關(guān)鍵參數(shù)怎么算、實(shí)操時(shí)注意什么。全文比較長建議先收藏按章節(jié)順序看。2. AI Infra知識全景的整體框架拆解2.1 為什么需要一張“全景圖”而不是零散學(xué)我一開始學(xué)的時(shí)候是典型的“哪疼醫(yī)哪”服務(wù)OOM了去查顯存優(yōu)化延遲高了去看批處理成本超了才想起來量化。這種學(xué)法的問題是你永遠(yuǎn)在救火而且每次救完不知道下一個(gè)火在哪。AI Infra本質(zhì)上是一個(gè)系統(tǒng)工程從硬件選型、集群調(diào)度、模型壓縮、推理引擎、服務(wù)框架到監(jiān)控運(yùn)維每一層都跟上下層強(qiáng)耦合。比如你選了INT8量化推理引擎得支持服務(wù)框架的batch策略也得跟著調(diào)不然精度掉了你還以為是模型問題。所以我的建議是先建立一張全景圖知道每個(gè)模塊在整條鏈路里的位置和職責(zé)然后再逐個(gè)深入。這樣你在遇到問題時(shí)能快速定位是哪個(gè)層出了問題而不是盲目試錯。2.2 六層架構(gòu)從硬件到業(yè)務(wù)的全鏈路我把AI Infra拆成六個(gè)層次從下往上依次是硬件層GPU/CPU/NPU、顯存帶寬、互聯(lián)技術(shù)NVLink、PCIe、存儲IO。這一層決定了你的算力上限和成本基線。集群與調(diào)度層K8s、Slurm、Ray、Volcano等負(fù)責(zé)資源分配、任務(wù)編排、多租戶隔離。核心問題是“怎么讓有限的卡跑更多的任務(wù)”。訓(xùn)練框架層PyTorch、TensorFlow、JAX以及分布式訓(xùn)練策略DDP、FSDP、Megatron、DeepSpeed。這一層關(guān)注的是“怎么把大模型訓(xùn)起來”。模型壓縮與轉(zhuǎn)換層量化PTQ/QAT、剪枝、蒸餾、ONNX導(dǎo)出、TensorRT編譯。核心目標(biāo)是“讓模型更小更快”。推理引擎與服務(wù)層vLLM、TensorRT-LLM、TGI、Triton、SGLang以及服務(wù)框架的批處理、緩存、路由策略。這一層直接決定線上延遲和吞吐。監(jiān)控與運(yùn)維層Prometheus、Grafana、DCGM、日志采集、告警、成本核算。沒有這一層前面所有優(yōu)化都是盲人摸象。這六層不是孤立的比如你在推理層做continuous batching底層調(diào)度層就得支持彈性擴(kuò)縮容監(jiān)控層得能采集到batch size和queue length。理解層與層之間的接口和約束比單獨(dú)學(xué)某一層更重要。2.3 學(xué)習(xí)順序?yàn)槭裁次医ㄗh“自頂向下”而不是“自底向上”很多人建議先學(xué)CUDA、再學(xué)分布式、再學(xué)推理我覺得對轉(zhuǎn)行者來說這個(gè)順序容易勸退。我的實(shí)際路徑是反過來的先從推理服務(wù)入手把模型跑起來遇到性能問題再往下挖。具體來說先學(xué)推理引擎的基本用法比如用vLLM起一個(gè)服務(wù)然后觀察它的瓶頸在哪——是顯存不夠、還是batch調(diào)度不合理、還是KV Cache管理有問題。帶著這些問題再去學(xué)量化、學(xué)調(diào)度、學(xué)顯存優(yōu)化學(xué)習(xí)動力和效果完全不一樣。自底向上適合科班做系統(tǒng)研究的人自頂向下適合工程背景想快速上手的人。3. 核心模塊深度解析與關(guān)鍵技術(shù)點(diǎn)3.1 推理引擎vLLM、TensorRT-LLM、TGI怎么選推理引擎是AI Infra里最直接影響線上表現(xiàn)的一層。我實(shí)際用過的三個(gè)主流方案各有適用場景。vLLM最大的賣點(diǎn)是PagedAttention把KV Cache按頁管理顯存利用率能提升到90%以上。它的continuous batching也是標(biāo)配適合請求長度差異大的場景。缺點(diǎn)是自定義算子不如TensorRT靈活極端性能場景下略遜。TensorRT-LLM是NVIDIA親兒子編譯后性能最強(qiáng)尤其在小batch低延遲場景。但它對模型結(jié)構(gòu)有要求編譯過程復(fù)雜換模型要重新編譯迭代速度慢。適合模型穩(wěn)定、追求極致性能的生產(chǎn)環(huán)境。TGIText Generation Inference是HuggingFace出的生態(tài)好、上手快支持動態(tài)批處理和流式輸出。性能介于前兩者之間適合快速驗(yàn)證和中小規(guī)模部署。選型時(shí)我會問三個(gè)問題模型會不會頻繁換延遲要求是P99還是平均團(tuán)隊(duì)有沒有精力維護(hù)編譯流程答案不同選擇就不同。下面這張表是我自己的經(jīng)驗(yàn)總結(jié)維度vLLMTensorRT-LLMTGI上手難度低高低極致性能中高高中模型兼容性好中好迭代速度快慢快適合場景通用生產(chǎn)穩(wěn)定高性能快速驗(yàn)證3.2 顯存優(yōu)化KV Cache到底吃多少顯存這是我最開始完全沒概念的地方。KV Cache的大小可以粗略估算KV Cache顯存 ≈ 2 × 層數(shù) × 注意力頭數(shù) × 頭維度 × 序列長度 × batch_size × 數(shù)據(jù)類型字節(jié)數(shù)舉個(gè)例子一個(gè)7B模型32層32個(gè)頭頭維度128FP162字節(jié)序列長度2048batch_size為1時(shí)2 × 32 × 32 × 128 × 2048 × 1 × 2 ≈ 1.07 GB看起來不大但batch_size到32就是34GB直接爆掉一張24G的卡。所以線上服務(wù)必須做KV Cache管理要么用PagedAttention分頁要么限制最大序列長度要么做量化。我實(shí)測下來把KV Cache量化到INT8顯存能省將近一半精度損失在可接受范圍內(nèi)。3.3 量化PTQ和QAT的取舍量化是降本最直接的手段。PTQ訓(xùn)練后量化不需要重新訓(xùn)練拿現(xiàn)成模型校準(zhǔn)一下就行適合快速上線。QAT量化感知訓(xùn)練要在訓(xùn)練時(shí)模擬量化誤差精度更好但成本高。我一般先用PTQ試如果精度掉得厲害比如超過2個(gè)點(diǎn)再考慮QAT。校準(zhǔn)集的選擇很關(guān)鍵不能用訓(xùn)練集要用真實(shí)分布的驗(yàn)證集否則量化參數(shù)會偏。另外注意不是所有層都適合量化attention的softmax前后、layer norm這些對精度敏感的地方通常保留FP16。3.4 分布式訓(xùn)練DDP、FSDP、張量并行的適用邊界訓(xùn)練側(cè)的知識點(diǎn)也很多但作為Infra工程師至少要理解三種并行策略數(shù)據(jù)并行DDP每張卡一份完整模型數(shù)據(jù)切分。適合模型能放進(jìn)單卡的情況。全分片數(shù)據(jù)并行FSDP/ZeRO模型參數(shù)、梯度、優(yōu)化器狀態(tài)分片到各卡。適合中等規(guī)模模型通信開銷可控。張量并行流水并行把單層切開或按層切分。適合超大模型但通信復(fù)雜調(diào)試難度高。選擇依據(jù)很簡單模型能不能放進(jìn)單卡能就用DDP不能但能放進(jìn)單節(jié)點(diǎn)多卡用FSDP再大就得上張量并行。我踩過的坑是FSDP的sharding策略配錯了導(dǎo)致通信量翻倍訓(xùn)練速度反而比DDP慢。后來發(fā)現(xiàn)是reshard_after_forward參數(shù)沒設(shè)對這個(gè)細(xì)節(jié)文檔里寫得很隱蔽。4. 實(shí)操過程從模型到線上服務(wù)的完整鏈路4.1 環(huán)境準(zhǔn)備與依賴管理我習(xí)慣用容器化環(huán)境避免依賴沖突?;A(chǔ)鏡像選CUDA runtime版本注意驅(qū)動版本要匹配。Python依賴用conda或uv管理推理引擎單獨(dú)建環(huán)境。這里有個(gè)細(xì)節(jié)vLLM和TensorRT-LLM對CUDA版本要求不同別裝在一個(gè)環(huán)境里。# 以vLLM為例的環(huán)境準(zhǔn)備 conda create -n vllm python3.10 conda activate vllm pip install vllm # 驗(yàn)證 python -c import vllm; print(vllm.__version__)4.2 模型量化與轉(zhuǎn)換實(shí)操以PTQ為例用GPTQ或AWQ做4bit量化。我一般用AWQ因?yàn)樗谛∧P蜕暇缺3指?。校?zhǔn)集準(zhǔn)備128到512條真實(shí)樣本太多沒必要太少會偏。# AWQ量化示意基于常見實(shí)踐 from awq import AutoAWQForCausalLM from transformers import AutoTokenizer model_path your-model-path quant_path your-quant-path quant_config {zero_point: True, q_group_size: 128, w_bit: 4, version: GEMM} model AutoAWQForCausalLM.from_pretrained(model_path) tokenizer AutoTokenizer.from_pretrained(model_path) model.quantize(tokenizer, quant_configquant_config) model.save_quantized(quant_path)量化后一定要做精度對比用同樣的測試集跑一遍看輸出差異。我遇到過量化后模型開始重復(fù)輸出的問題后來發(fā)現(xiàn)是校準(zhǔn)集里長文本太少調(diào)整后就好了。4.3 推理服務(wù)部署與參數(shù)調(diào)優(yōu)用vLLM起服務(wù)關(guān)鍵參數(shù)有幾個(gè)--max-model-len最大序列長度直接影響KV Cache顯存。--gpu-memory-utilization顯存利用率默認(rèn)0.9我一般設(shè)0.85留余量。--max-num-seqs最大并發(fā)序列數(shù)跟batch策略相關(guān)。--tensor-parallel-size張量并行度多卡時(shí)設(shè)置。python -m vllm.entrypoints.openai.api_server \ --model your-quant-path \ --max-model-len 4096 \ --gpu-memory-utilization 0.85 \ --max-num-seqs 64 \ --tensor-parallel-size 1啟動后先用小流量壓測觀察顯存和延遲。我習(xí)慣用locust或wrk做壓測重點(diǎn)看P99延遲和吞吐量隨并發(fā)的變化曲線。如果P99突然飆升通常是batch排滿了需要調(diào)max-num-seqs或加卡。4.4 監(jiān)控指標(biāo)與告警配置線上服務(wù)必須監(jiān)控這幾個(gè)指標(biāo)GPU利用率、顯存占用、請求隊(duì)列長度、P99延遲、每秒token數(shù)。用DCGM exporter采集GPU指標(biāo)Prometheus存儲Grafana展示。告警閾值我一般設(shè)顯存超過90%告警、P99延遲超過基線1.5倍告警、隊(duì)列長度持續(xù)大于閾值告警。這里有個(gè)經(jīng)驗(yàn)不要只看平均值要看分位數(shù)。平均延遲可能很好看但P99已經(jīng)炸了用戶體驗(yàn)照樣差。5. 常見問題與排查技巧實(shí)錄5.1 顯存OOM的排查思路OOM是最常見的問題。我的排查順序是先看是不是KV Cache太大調(diào)小max-model-len或max-num-seqs再看是不是模型本身太大量化或換更小模型最后看是不是有內(nèi)存泄漏長時(shí)間運(yùn)行后顯存持續(xù)增長。有個(gè)隱蔽的坑PyTorch的緩存分配器會保留已釋放的顯存導(dǎo)致nvidia-smi看到的占用比實(shí)際高??梢杂胻orch.cuda.empty_cache()手動清理但線上不建議頻繁調(diào)用會影響性能。5.2 推理延遲突然升高的定位方法延遲升高通常有三個(gè)原因請求量突增、batch調(diào)度不合理、某個(gè)請求卡住了。我會先看隊(duì)列長度如果隊(duì)列長但GPU利用率低說明調(diào)度有問題如果GPU利用率高但延遲高說明計(jì)算量到了瓶頸。還有一個(gè)容易忽略的點(diǎn)網(wǎng)絡(luò)IO。如果模型權(quán)重放在遠(yuǎn)程存儲加載時(shí)會拖慢首次推理。建議把權(quán)重預(yù)加載到本地或內(nèi)存。5.3 量化后精度下降的補(bǔ)救措施精度下降先別急著放棄量化??梢試L試換校準(zhǔn)集、調(diào)整量化粒度per-channel比per-tensor好、對敏感層保留FP16、用QAT替代PTQ。我遇到過4bit量化后精度掉3個(gè)點(diǎn)的情況把校準(zhǔn)集從128條增加到512條后降到1個(gè)點(diǎn)以內(nèi)。5.4 多卡并行時(shí)的通信瓶頸多卡推理時(shí)張量并行的通信開銷可能成為瓶頸。如果發(fā)現(xiàn)加卡后吞吐沒提升甚至下降先檢查NVLink是否啟用、通信是否走了PCIe。另外tensor-parallel-size不是越大越好一般不超過單節(jié)點(diǎn)卡數(shù)跨節(jié)點(diǎn)通信延遲太高。下面這張表是我整理的高頻問題速查問題現(xiàn)象可能原因排查動作顯存OOMKV Cache過大/模型過大調(diào)小序列長度/量化P99延遲高batch排滿/調(diào)度問題調(diào)max-num-seqs/看隊(duì)列吞吐上不去通信瓶頸/GPU利用率低檢查NVLink/調(diào)并行度精度下降量化誤差/校準(zhǔn)集偏差換校準(zhǔn)集/保留敏感層服務(wù)不穩(wěn)定內(nèi)存泄漏/資源競爭長跑監(jiān)控/隔離資源6. 學(xué)習(xí)資源與進(jìn)階路徑建議6.1 我實(shí)際用過的學(xué)習(xí)材料類型我不太推薦一上來就看論文容易陷進(jìn)去出不來。我的路徑是先看官方文檔和quickstart把服務(wù)跑起來然后看源碼里的關(guān)鍵模塊比如vLLM的scheduler和block manager最后再回頭看論文理解設(shè)計(jì)動機(jī)。這樣看論文時(shí)能對應(yīng)到具體代碼理解更深。6.2 從單機(jī)到集群的能力躍遷單機(jī)跑通只是第一步。集群環(huán)境下要考慮資源隔離、任務(wù)優(yōu)先級、故障恢復(fù)、多租戶計(jì)費(fèi)。我建議先在單機(jī)上把推理服務(wù)調(diào)優(yōu)到極限再上K8s做編排。上集群后重點(diǎn)學(xué)Volcano或Ray的調(diào)度策略以及怎么做彈性擴(kuò)縮容。6.3 成本核算每百萬token的真實(shí)成本怎么算這是很多團(tuán)隊(duì)忽略的。成本包括GPU租用或折舊、電力、運(yùn)維人力。粗略估算一張A100按每小時(shí)10元算吞吐1000 token/s那每百萬token成本約2.8元。量化到INT8后吞吐翻倍成本降到1.4元。這個(gè)賬算清楚了才知道優(yōu)化方向在哪。我個(gè)人在實(shí)際操作中的體會是AI Infra的學(xué)習(xí)沒有捷徑但有一條相對高效的路徑先跑通再調(diào)優(yōu)再深入原理。每遇到一個(gè)問題就把它當(dāng)成一個(gè)學(xué)習(xí)入口挖到底。半年下來你會發(fā)現(xiàn)那些曾經(jīng)陌生的概念已經(jīng)變成你排查問題時(shí)的直覺了。最后分享一個(gè)小技巧養(yǎng)成記錄的習(xí)慣每次調(diào)參、每次踩坑都記下來三個(gè)月后回看進(jìn)步速度會超出你想象。