
相信很多做大模型應用的朋友都有這種感覺模型在短文本下推理很快一旦把上下文拉長到幾十萬 token首字延遲就變得非常難以接受。用戶敲下問題后服務端要等好幾秒才吐第一個字這在生產環境里幾乎是致命的體驗問題。而這背后的主要瓶頸往往不是模型本身而是 LLM 推理過程中的 Prefill 階段。本文圍繞長上下文 LLM 推理中的 Prefill 優化展開完整梳理 Prefill 階段為什么慢、主流的加速思路是什么、如何通過 SGLang 與 vLLM 對接生產部署并給出可復制的啟動腳本、關鍵參數說明和常見問題排查方案。無論你是在做 RAG 應用、Agent 系統還是基于大模型的內部服務這篇文章都適合參考。1. Prefill 階段為什么是長上下文推理的瓶頸1.1 一次 LLM 推理的完整過程Prefill Decode要理解 Prefill 優化先要把 LLM 推理的完整流程拆開看。一次自回歸生成可以分成兩個階段Prefill預填充階段把用戶輸入的提示詞Prompt一次性喂給模型并行計算出所有輸入 token 的 Key/Value 狀態并生成第一個輸出 token。Decode解碼階段逐 token 生成后續輸出每一步只計算一個新的 token并把當前 token 的 K/V 追加到已有的狀態中。用一句話概括Prefill 是“一次算完輸入”Decode 是“一個一個往后蹦”。在短文本場景下Prefill 占用的時間很短大家主要關心 Decode 的速度。但當輸入上下文達到幾萬甚至幾十萬 token 時Prefill 的計算量會急劇膨脹成為延遲和吞吐的重要瓶頸。1.2 Prefill 階段的計算特征為什么 Prefill 會慢從計算特征來看原因非常直觀。第一它可以并行但計算量巨大。Prefill 階段需要對輸入序列中的所有 token 同時計算注意力計算復雜度與序列長度的平方成正比。一個 10 萬 token 的輸入注意力矩陣的規模是 10 萬乘以 10 萬顯存和算力消耗都相當驚人。第二它受限于顯存帶寬。除了計算注意力Prefill 還要把模型參數和輸入激活值反復搬運到計算單元。長序列下中間激活值占用大量顯存很容易觸發顯存溢出或者被迫降低 batch size從而拉低吞吐。第三它與 Decode 的優化手段并不完全兼容。Decode 重視的是低延遲和 K/V 緩存復用而 Prefill 更依賴高并行度和算子融合。如果在同一個服務里用同一套參數處理這兩個階段往往沒辦法同時做到最優。1.3 為什么說 TTFT 是用戶體感第一步TTFTTime To First Token指的是從用戶發起請求到收到第一個輸出 token 的時間。很多剛接觸大模型推理優化的同學會困惑TTFT 到底包含 Prefill 還是“Prefill 加一次 Decode”從工程角度看通常所說的 TTFT 包含一次完整的 Prefill 計算以及首次 Decode 生成首個 token 的時間。因為服務端必須完成 Prefill 才能拿到第一個輸出 token所以 Prefill 的耗時基本決定了 TTFT 的下限。這也是為什么長上下文場景下必須優先優化 Prefill否則無論 Decode 多快用戶的第一印象都會很糟糕。2. 加速 Prefill 的主流技術路線2.1 注意力計算優化注意力計算是 Prefill 階段最核心的耗時部分。常見的優化思路包括FlashAttention 系列通過分塊計算注意力避免把完整的 N×N 注意力矩陣寫入顯存顯著降低顯存占用并提升計算效率。FlashInfer一個面向大模型推理的算子庫提供更高效的注意力模板被 SGLang 等框架作為后端集成。稀疏注意力/線性注意力針對超長序列設計但在通用場景下仍然需要謹慎評估精度損失。在實際部署中優先使用支持 FlashAttention 或 FlashInfer 的推理框架是性價比最高的優化手段。2.2 算子融合與并行Prefill 階段包含大量小算子例如矩陣乘法、Softmax、LayerNorm 等。如果每個算子都單獨啟動 kernelGPU 的利用率會很低。算子融合的核心思路是把多個連續操作合并成一個 kernel減少顯存訪問和 kernel 啟動開銷。在并行層面還可以通過以下方式提速Tensor Parallel張量并行把模型權重切分到多張 GPU 上適合單機多卡場景。Pipeline Parallel流水線并行把模型層切分到多張 GPU 上適合模型較大或跨機場景。數據并行與請求并行多路請求同時處理提升整體吞吐。SGLang 和 vLLM 都對張量并行和部分算子融合提供了內置支持使用時只需要通過啟動參數配置即可。2.3 顯存管理與 Chunked Prefill長上下文輸入最容易碰到顯存溢出。一個很實用的優化方案是 Chunked Prefill分塊預填充把超長的輸入切分成多個 chunk 逐塊處理。這樣可以避免一次性申請超大顯存同時還能讓 Prefill 與 Decode 請求交錯執行提高 GPU 利用率。vLLM 中通過--max-num-batched-tokens等參數控制單次 batch 的最大 token 數實際上就能起到類似 Chunked Prefill 的效果。SGLang 也支持類似的調度策略對長上下文場景非常友好。2.4 緩存復用RadixAttention 與 Prefix Cache在多輪對話、Agent 工具調用、RAG 檢索場景中不同請求之間往往共享相同的前綴內容。如果能把這些前綴的 K/V 緩存復用起來就能大幅減少重復的 Prefill 計算。vLLM 的 Prefix Cache基于 PagedAttention 的頁級緩存復用當請求前綴與已有緩存一致時直接復用 K/V 頁。SGLang 的 RadixAttention將 K/V 緩存組織成 Radix Tree基數樹結構自動識別并復用公共前綴甚至支持更細粒度的緩存命中。這也是 SGLang 在長上下文、多輪對話和高并發場景下表現突出的重要原因。對于“47 倍速”之類的加速效果雖然不同硬件和場景下數據會有差異但緩存命中帶來的收益在實測中確實非常可觀。3. 環境準備與部署框架選型3.1 硬件與軟件環境Prefill 優化和具體的硬件環境強相關。以下是一套參考環境版本需根據你的實際項目情況調整本文重點演示配置思路項目推薦配置操作系統Ubuntu 20.04 / 22.04GPUNVIDIA A100 / H100或昇騰 910B 等國產加速卡顯存單卡 40GB 以上長上下文建議多卡CUDACUDA 11.8 / 12.1 及以上Python3.10 或 3.11推理框架SGLang、vLLM 二選一或對比使用容器方案Docker 或裸機 conda 環境均可如果你使用的是昇騰 910B 等非 NVIDIA 硬件需要特別注意框架對國產加速卡的適配情況。部分版本對昇騰的支持還不完善尤其是 embedding 模型和 reranker 模型的啟動方式可能與 GPU 環境不同建議先閱讀框架官方文檔確認。3.2 SGLang 與 vLLM 怎么選這兩個框架是目前大模型推理部署中討論度最高的兩個選擇SGLang主打高性能和靈活的運行時調度RadixAttention 是它的核心亮點。適合多輪對話、長上下文、復雜 Agent 調用等場景Prefill 優化的可調參數比較多。vLLM生態成熟兼容性好社區用戶量大。它基于 PagedAttention對顯存管理和 Decode 階段優化做得非常出色同樣支持 Chunked Prefill。在實際項目中如果團隊更看重穩定性和生態兼容性可以優先考慮 vLLM如果追求極限的長上下文性能和緩存復用率SGLang 非常值得嘗試。兩者都在快速迭代中建議在生產選型前做一次同模型同硬件的對比測試。4. 實戰用 SGLang 部署并優化長上下文推理4.1 安裝 SGLang推薦使用 Docker 方式部署這樣環境隔離更干凈也方便后續升級。# 拉取 SGLang 鏡像 docker pull lmsysorg/sglang:latest # 創建容器并掛載模型目錄 docker run -it --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v /data/models:/models \ lmsysorg/sglang:latest \ bash如果你希望使用 conda 環境也可以先用 conda 創建 Python 3.10 環境然后通過 pip 安裝pip install --upgrade pip pip install sglang[all]安裝完成后可以用python -c import sglang; print(sglang.__version__)驗證。4.2 啟動服務下面以 Qwen 系列 32B 模型為例演示一個適合長上下文 Prefill 優化的啟動腳本。python -m sglang.launch_server \ --model-path /models/Qwen2.5-32B-Instruct \ --host 0.0.0.0 \ --port 30000 \ --tp-size 4 \ --mem-fraction-static 0.8 \ --context-length 131072 \ --chunked-prefill-size 8192 \ --attention-backend flashinfer \ --enable-prefix-caching4.3 關鍵參數說明--tp-size 4表示使用 4 張 GPU 做張量并行。模型較大或上下文很長時這個參數能顯著加快 Prefill 計算。--context-length 131072設置最大上下文長度。需要根據模型實際能力和顯存調整不是越大越好。--chunked-prefill-size 8192單次 Prefill 的最大 token 數。長上下文場景建議設置成 4096 到 8192 之間的值避免一次性申請過多顯存。--attention-backend flashinfer使用 FlashInfer 作為注意力后端通常在長序列下能獲得更好的性能。--enable-prefix-caching開啟前綴緩存配合 RadixAttention 使用多輪對話和 Agent 場景提升明顯。--mem-fraction-static 0.8指定用于緩存和運行時的顯存比例需要根據顯存大小實測調整。啟動后服務會監聽 30000 端口??梢杂孟旅娴?Python 腳本快速測試import requests resp requests.post( http://localhost:30000/generate, json{ text: 請用三句話說明什么是 Prefill 階段。, sampling_params: { max_new_tokens: 256, temperature: 0.7 } } ) print(resp.json())5. 實戰用 vLLM 部署并優化 Prefill5.1 安裝 vLLMvLLM 同樣支持 Docker 和 pip 安裝。建議先用官方鏡像驗證環境再根據業務需求定制依賴。docker pull vllm/vllm-openai:latest docker run -it --gpus all \ --shm-size 32g \ -p 8000:8000 \ -v /data/models:/models \ vllm/vllm-openai:latest \ bash5.2 啟動服務python -m vllm.entrypoints.openai.api_server \ --model /models/Qwen2.5-32B-Instruct \ --host 0.0.0.0 \ --port 8000 \ --tensor-parallel-size 4 \ --max-model-len 131072 \ --max-num-batched-tokens 8192 \ --enable-prefix-caching \ --gpu-memory-utilization 0.85.3 與 SGLang 的差異說明--enforce-eager參數在 vLLM 中如果加上這個參數會關閉 CUDA Graph直接走 eager 模式。這個模式可以降低顯存占用但通常會犧牲部分性能。生產環境長上下文場景下建議先測試不要因為顯存緊張而盲目開啟必要時優先縮小 batch size 或 max-model-len。--tensor-parallel-size等同于 SGLang 的--tp-size。--enable-prefix-cachingvLLM 的前綴緩存開關適合多輪對話和 RAG 場景。vLLM 默認提供 OpenAI 兼容接口部署完成后可以直接用 curl 測試curl http://localhost:8000/v1/chat/completions \ -H Content-Type: application/json \ -d { model: /models/Qwen2.5-32B-Instruct, messages: [{role: user, content: 你好請介紹 Prefill 優化。}], max_tokens: 256 }6. 精度選擇與量化部署6.1 FP16、BF16 與 FP32 如何選擇精度選擇對 Prefill 階段的速度和顯存占用影響非常大。簡單說明三者的差別精度特點適用場景FP32數值范圍廣精度最高但顯存占用大、速度慢小模型調試FP16顯存占用減半速度較快但小數值容易出現精度溢出NVIDIA GPU 推理主流選擇BF16動態范圍與 FP32 接近訓練和推理都更穩定推薦用于大模型推理INT8/INT4顯存占用進一步降低速度提升但可能帶來精度損失資源受限或長上下文場景在長上下文 Prefill 場景下顯存是剛性約束。如果模型允許建議優先用 BF16如果還是放不下再考慮 AWQ、GPTQ 或 INT8 量化方案。需要注意的是量化模型的 Prefill 計算可能依賴反量化算子不同框架的實現差異較大部署前要做精度對比驗證。6.2 量化模型的啟動示例以 Qwen3.5-122B-A10B-GPTQ-INT4 這類模型為例無論使用 SGLang 還是 vLLM核心思路都是指定量化模型目錄路徑并配合多卡張量并行啟動。SGLang 示例python -m sglang.launch_server \ --model-path /models/Qwen3.5-122B-A10B-GPTQ-INT4 \ --tp-size 8 \ --context-length 65536 \ --chunked-prefill-size 4096量化模型部署后建議用一組標準業務問題分別比較量化模型和原模型的輸出質量再決定是否上線。7. 效果驗證與性能對比7.1 如何測量 TTFT測量 TTFT 最直接的方法是在客戶端記錄請求發出時間和第一個 token 返回時間。下面是一個簡單的 Python 腳本思路import time import requests url http://localhost:30000/generate long_prompt 這是一段很長的輸入... * 1000 start time.time() resp requests.post(url, json{ text: long_prompt, sampling_params: {max_new_tokens: 1} }, streamTrue) first_token_time time.time() - start print(fTTFT: {first_token_time:.3f} s)需要注意的是max_new_tokens1時模型只需要做 Prefill 和一次 Decode能更準確地反映 Prefill 階段的耗時。如果服務端有緩存命中首次請求和后續請求的 TTFT 會有明顯差異這種差異本身就是 Prefix Cache 效果的一種驗證。7.2 對比維度建議做性能對比時建議至少記錄以下指標TTFT首 token 延遲Prefill 耗時Decode 吞吐token/s顯存占用峰值同批次并發請求數盡量做到同一個模型、同一個輸入文本、同一個硬件環境下對比才具有參考價值。8. 常見問題與排查思路問題現象常見原因解決思路長上下文啟動時顯存溢出context-length 設置過大或顯存比例設置過高調小 context-length或降低 mem-fraction-static / gpu-memory-utilization使用 --enforce-eager 后性能下降關閉了 CUDA Graph執行效率降低盡量保留 CUDA Graph優先通過減小 batch size 來緩解顯存多卡并行時負載不均tensor 并行配置不合理或模型切分不均檢查 tp-size必要時結合 pipeline parallel前綴緩存命中率低輸入前綴動態變化或未開啟 prefix caching在 SGLang 開啟 --enable-prefix-cachingvLLM 開啟 --enable-prefix-caching昇騰 910B 上 vLLM 無法啟動 embedding 模型框架對國產加速卡的模型類型支持有限查看框架官方適配文檔必要時改用其他框架或單獨部署 embedding 服務量化模型輸出質量明顯下降量化精度選擇不合適對比 FP16/BF16 輸出考慮改用 AWQ 或調整量化參數遇到問題時建議按以下順序排查確認框架版本和模型版本匹配。查看服務端日志定位是顯存問題還是算子兼容問題。把參數逐步降到最小可運行狀態例如先關閉 prefix caching調小 context-length。確認是 Prefill 慢還是 Decode 慢可以通過max_new_tokens1的請求分開測。對比不同 attention 后端例如 flashinfer 與 flash-attention。9. 最佳實踐與工程建議9.1 參數配置要按場景實測Prefill 優化沒有“萬能參數”。長文檔問答、Agent 多輪調用、RAG 檢索等場景對 Prefill 的要求完全不同。建議把參數配置做成環境變量或配置文件方便在測試環境快速切換。9.2 優先復用再談壓縮在長上下文場景中緩存復用帶來的收益往往比單純壓縮模型更明顯。如果業務中有大量重復前綴應該優先開啟 Prefix Cache 或 RadixAttention再考慮是否通過量化降低顯存。9.3 注意生產環境變更流程調整 Prefill 相關參數或升級框架版本前一定要在上線前做充分驗證。特別是涉及--context-length、--tp-size這些直接影響顯存分配和計算效率的參數時建議先在測試環境用壓測腳本模擬線上流量。記錄優化前后的 TTFT、吞吐、顯存指標。保留可回滾的部署配置。逐步灰度發布不要一次性全量切換。9.4 日志與監控生產環境建議至少監控以下指標平均 TTFT 和 P95 TTFTPrefill 和 Decode 階段耗時拆分GPU 利用率和顯存占用前綴緩存命中率請求排隊時間和超時率有了這些數據才能判斷 Prefill 優化是否真正解決了業務瓶頸而不是只靠啟動參數“感覺變快了”。10. 總結Prefill 階段是長上下文 LLM 推理中不可回避的性能瓶頸。本文從 Prefill 的原理出發梳理了注意力算子優化、Chunked Prefill、張量并行、前綴緩存復用等主流加速手段并給出了 SGLang 和 vLLM 的完整部署示例與關鍵參數解釋。在實際項目中Prefill 優化的收益非常依賴具體場景RAG 應用中公共前綴越多緩存復用帶來的提升越明顯超長上下文中 Chunked Prefill 能顯著降低顯存壓力提高服務穩定性。如果你正在部署長上下文服務建議先用同一份測試數據對比 SGLang 和 vLLM 在你當前硬件上的表現再決定把哪一套方案放進生產環境。下一步可以繼續深入學習 FlashInfer 后端實現、K/V 緩存調度策略以及量化模型在長上下文場景中的精度表現。把這些內容研究透大模型推理優化的功底就算真正扎實了。