對應原題(Common ‧ Inference, Serving and GPU Performance)

  • When would you choose vLLM vs SGLang vs TensorRT-LLM vs a custom stack? — Asked at: NVIDIA, Together AI
  • How would you cut LLM serving cost by 10x? Enumerate every lever and rank them.
    — Asked at: Microsoft, Amazon, NVIDIA, Cursor
  • Your p99 latency doubled after a deploy with no model change. Walk through the diagnosis.
    — Asked at: OpenAI, Amazon, Databricks, Perplexity
  • What is chunked prefill, and why does it improve tail latency under mixed traffic?
  • Explain disaggregated prefill/decode serving and when it pays for itself. — Asked at: Moonshot AI, Groq

🎯 什麼情境該想到我

當你「要選推論框架、要砍成本、或線上延遲突然壞掉」的時候。這一頁是 B 區所有機制的應用層。

⚙️ 怎麼用

一、框架選型

框架設計重心選它的理由不選它的理由
vLLMPagedAttention 的發源地,通用高吞吐生態最廣、新模型支援最快、上手最簡單、社群最大極致單卡效能不如編譯式方案
SGLangRadixAttention(以基數樹管理 KV,跨請求自動共享前綴)+ 結構化輸出多輪對話、agent、共享前綴極多的場景;約束解碼快生態較新
TensorRT-LLMNVIDIA 官方,編譯式(先 build engine)NVIDIA 硬體上的極致效能,尤其配 Triton;FP8/FP4 支援最完整要 build engine(改配置就重 build)、模型支援較慢、運維重
TGIHuggingFace 生態整合只剩既有部署維運已進入維護模式、repo 已封存(README 只收小修,官方改推薦 vLLM/SGLang;查證 2026-10-15),新專案不要選
llama.cpp / OllamaCPU / Apple Silicon / 單機本地開發、邊緣部署、Mac不是為多租戶高吞吐服務設計
自建特殊硬體或極端規模只有兩種情況:(1) 非 NVIDIA 的自研硬體(Groq、TPU)(2) 規模大到 1% 的改善值一個團隊其他所有情況都是造輪子

(表中各框架的強弱定位是截至 2026-10 的判斷,非 benchmark 結論;TGI 狀態查證 2026-10-15。)

選型的務實順序:先 vLLM 跑起來 → 量出瓶頸 → 再決定要不要換。
「哪個最快」的 benchmark 隨版本變動極快(而且各家自己測自己贏),不要拿別人的數字做決策。

二、★ 降本十倍:槓桿排序

按投報率排,不是按技術含量排:

#槓桿量級說明
1不要呼叫 LLM∞精確快取(同問題同答案)、規則能解的就別用模型、用分類器擋掉不需要生成的請求。最高的槓桿永遠是「不做」
2模型路由 / 換小模型5–20×絕大多數流量不需要最強的模型。用小模型處理 + 信心低時升級。這通常是單一最大的一筆
3前綴快取快取命中的 input 便宜 10×(部分新模型 20×)長 system prompt / few-shot / agent 迴圈。改個排序就生效。見 前綴快取 Prompt Caching。OpenAI/Anthropic 快取命中價多為原 input 的 0.1×,部分新模型 0.05×(查證 2026-10-15)
4量化2–6×不只省一半權重,省下的顯存變成併發。見 GPU 記憶體估算 的 6× 那張表
5連續批次 + 調大 batch2–20×若還在用靜態批次,這是免費的倍數。見 連續批次 Continuous Batching
6縮短 prompt 與輸出2–5×output token 比 input 貴約 5 倍(OpenAI、Anthropic 現行模型價目皆為 5×,查證 2026-10-15)——「請簡潔回答」是有現金價值的。壓縮 few-shot、去掉冗餘上下文
7蒸餾出專用小模型5–10×有穩定任務與足夠流量時最划算。見 知識蒸餾
8批次 API / 離線化~2×非即時的工作丟批次端點(OpenAI、Anthropic 的 Batch API 皆為 input/output 五折,查證 2026-10-15)。先問「這真的需要同步嗎」
9硬體與採購1.5–3×預留執行個體、spot、選對卡(decode 重頻寬、prefill 重算力)
10推測解碼延遲 2–3×⚠️ 這是延遲優化,不是成本優化——高 batch 下反而更貴。見 推測解碼 Speculative Decoding

(「量級」欄:#3、#6、#8 的價格比例已對 OpenAI/Anthropic 官方價目查證 2026-10-15;其餘倍數為經驗值,未查證。)

面試答法:「10× 不會來自單一技術。典型組合是 模型路由 5× × 量化 2× × 前綴快取 + 批次 ——而且我會先量清楚成本的組成(input/output token 比例、併發、快取命中率),再決定動哪個。盲目優化推論 kernel 是最常見的走錯方向。」

三、Chunked Prefill

問題:連續批次讓 prefill 和 decode 混在同一個 batch 裡。一個 8K token 的 prefill 要算幾十毫秒,這段時間所有正在 decode 的使用者全部卡住——他們看到文字突然停頓。

沒有 chunked prefill
step: │ D D D │  P(8K,一次算完,60 ms)  │ D D D │
                 └─ 所有 decode 使用者卡 60 ms ─┘   ← p99 ITL 爆掉

有 chunked prefill(每步 token 預算 = 2048)
step: │ D D D +P₁ │ D D D +P₂ │ D D D +P₃ │ D D D +P₄ │
        每步都混入一小塊 prefill,decode 幾乎不受影響

機制:設定每步的 token 預算(vLLM 的 max_num_batched_tokens),先塞滿 decode 的 token,剩餘額度拿來做 prefill 的一部分。

效果
✅ p99 ITL 大幅改善,decode 變平順
✅ 每步 token 數穩定 → GPU 利用率穩定
❌ 那個長 prefill 自己的 TTFT 變差(被切成好幾步)

一句話:拿長請求的 TTFT,換所有人的 ITL 穩定。 混合流量(長短 prompt 並存)下幾乎一定該開。

四、PD 分離(Disaggregated Prefill/Decode)

動機:prefill 和 decode 是兩種完全不同的工作負載(見 Prefill 與 Decode),硬塞在同一個池子裡,任何批次策略都是妥協。

        ┌──────────────┐   KV cache 傳輸   ┌──────────────┐
請求 ──▶│  Prefill 池   │ ═══════════════▶ │  Decode 池    │──▶ 串流輸出
        │ compute-bound │  (RDMA/NVLink)   │ memory-bound  │
        │ 大算力的卡     │                  │ 大頻寬的卡     │
        │ 小 batch      │                  │ 超大 batch     │
        └──────────────┘                  └──────────────┘

好處:

  • 徹底消除互相干擾——TTFT 和 TPOT 可以獨立最佳化到極致
  • 各自用最適合的批次策略(prefill 不需要大 batch,decode 需要)
  • 可以獨立擴縮——長 prompt 流量多就加 P 節點
  • 可以用不同硬體——這正是 Groq / Moonshot 會問這題的原因

代價:

  • KV cache 要跨節點搬。一條 4K 的 Llama-70B 序列是 1.25 GiB——沒有 RDMA / NVLink 等級的互連就是災難
  • 架構複雜度、故障模式變多
  • 小規模是淨虧

什麼時候值得:(1) 規模夠大,P 和 D 都能各自吃滿卡 (2) prompt 長度變異大 (3) SLO 對 TTFT 和 TPOT 都嚴格 (4) 有高速互連。
少於幾十張卡基本不值得 —— 用 chunked prefill 就好。

五、★ p99 診斷手冊:「沒改模型,p99 卻變兩倍」

這題考的是系統性排查,不是猜。順序很重要:

Step 1:先拆是 TTFT 還是 TPOT

p99 E2E ↑
 ├─ TTFT ↑  →  排隊?prefill 變長?→ 往 Step 2、3
 └─ TPOT ↑  →  batch 變大?KV 變長?preemption?→ 往 Step 4

沒有分開量這兩個,後面全是瞎猜。

Step 2:★ 輸入/輸出長度分布變了嗎(最常見的真兇)

「沒改模型」≠「沒改 prompt」。檢查:

  • prompt 模板是不是加了東西(多塞了幾段檢索結果、多了一個工具定義)
  • 輸出長度分布(改了 max_tokens?改了指示讓模型變囉嗦?)
  • 上游的 RAG 是不是多召回了幾段

prefill 的 attention 是 ——prompt 長 2 倍,TTFT 可能是 4 倍。

Step 3:★ 前綴快取命中率掉了嗎(第二常見)

改一個字的 system prompt,快取命中率就歸零。

  • 看 cache_read_input_tokens 的比例有沒有斷崖
  • 有沒有人在 prompt 前面加了時間戳 / request ID(見 前綴快取 Prompt Caching 的經典坑)
  • 工具定義是不是變成動態生成了(改工具定義會打掉整個快取)

Step 4:排程與顯存壓力

  • preemption 率 —— 看 log 裡的 preempted 計數。被搶佔又 recompute 的請求就是 p99 的長尾
  • KV cache 利用率 —— 接近 100% 代表已經在邊緣
  • 等待佇列長度 —— TTFT 裡的排隊成分
  • max_num_seqs / max_num_batched_tokens 有沒有被改

Step 5:部署本身

  • 框架 / kernel 版本變了嗎(升級可能換了 attention 後端)
  • TP/PP 配置變了嗎(TP 不小心跨節點 → 見 平行化策略)
  • 副本數變少了嗎(HPA 設定、節點被驅逐)
  • warmup 做了嗎(新 pod 的前幾個請求含 CUDA graph 捕捉與 JIT,特別慢)

Step 6:硬體與鄰居

  • GPU 降頻(溫度、功率上限)、ECC 錯誤
  • 共置的其他工作負載搶 PCIe / 網路
  • 換了不同型號的卡(同一個 node group 裡混了 A100 和 H100)

Step 7:上游放大

  • 重試風暴 —— 延遲一上升,客戶端 timeout → 重試 → 負載更高 → 更慢。這會把小問題放大成事故
  • 有沒有人新接了一個高流量 client

答題框架:「先分層(TTFT/TPOT)→ 再看輸入分布 → 再看快取命中 → 再看排程壓力 → 最後才懷疑硬體。
我的經驗是九成的『沒改模型卻變慢』最後都是prompt 變長了或快取失效了。」

⚠️ 注意 / 什麼時候不適用

  • 框架 benchmark 半年就過時。上面寫的是設計重心,不是效能排名。要選就自己用真實流量測。
  • 降本槓桿會互相衝突:大 batch 省錢但傷延遲;推測解碼降延遲但高 batch 下加成本。先定 SLO,再談成本。
  • 別在沒有 per-request 的 token 計數與成本歸因前談降本。沒有歸因就是瞎調。
  • chunked prefill 的 token 預算要調。太小會讓長 prefill 的 TTFT 難看,太大就失去效果。
  • PD 分離不要在小規模上做,複雜度成本遠大於收益。
  • p99 診斷不要跳步。直接去 profile kernel 是最浪費時間的起手式。

🧪 我實際套用的紀錄

  • 2026-09-20:從面試題庫展開。待辦:把 p99 診斷的 Step 1–7 做成 runbook。

🔗 相關