從 Nano‑vLLM 拆解 LLM 推論引擎:架構、排程與關鍵效能思維

本篇文章更新時間:2026/02/03
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣新台幣 贊助支持。


從 Nano‑vLLM 看見 LLM 推論引擎的底層運作機制

讀後筆記:架構、排程與從 Prompt 到 Token 的旅程

編輯前言:市面上人人都在談模型大小、訓練技巧,但真正決定「推論效率」的,其實是推論引擎本身。這篇文章出自 Understanding LLM Inference Engines: Inside Nano-vLLM (Part 1) - Neutree Blog,以極小卻可跑產線的 Nano‑vLLM 為案例,重新拆解 vLLM 在生產環境中高效能的底層設計。我在閱讀後深刻感受到:理解推論引擎,是真正理解 LLM 系統架構的關鍵基礎。

核心觀點 (Key Takeaways)

  • 推論引擎的效能不是魔法,而是來自「排程(scheduler)+記憶體管理(block manager)+高度最佳化的模型執行」三者的協作。
  • Prefill 與 Decode 兩階段本質差異巨大,因此必須用不同的批次處理與資源策略。
  • vLLM 的核心創新:以固定大小 block 管理 KV cache 並搭配 prefix caching,大幅減少重複計算,是高吞吐量的關鍵理由。

深入解析

這篇文章不是教你如何呼叫 API,而是揭開每一次 generate() 的過程,背後到底發生了什麼事。

文中一句話我認為非常到位:「While most developers interact with LLMs through high-level APIs, understanding what happens beneath the surface can significantly impact system design decisions.」

換句話說,懂推論,才能真正設計高效能的 LLM 產品。

從 Prompt 到 Sequence:資料如何變成可處理的單位

文章第一步談到 tokenizer──這看似普通,卻是推論架構的起點。每個 prompt 被切成 tokens,並以 sequence 結構進入系統。這些 sequences 就是 Scheduler 操作的基本單位。

我特別喜歡作者把這部分講得很務實:不同模型的 tokenizer 完全不一樣,所以同一句話的 token 數量也不同。這意味著「推論成本」並不能僅看字數,必須看 tokenizer 的切分方式。

Producer-Consumer:LLM 推論其實就是一個排程系統

Nano‑vLLM 裡,新增請求(add_request)與實際運算是分開的:

  • add_request:把 sequence 放進 Waiting queue
  • step loop:拉出要運算的 sequences,組成 batch

這種架構最大的好處就是「可控的批次處理」。你要吞吐(throughput)還是延遲(latency),全靠 batch size 調整。

文章點得非常清楚:

  • 大 batch = 高吞吐、但每個請求要等最慢那個
  • 小 batch = 低延遲、但 GPU 利用率下降

在產品端,我常看到團隊亂調參數導致效能暴死,其實就是不理解這個基本 trade‑off。

Prefill vs Decode:兩個完全不同的工作負載

Prefill 一次處理整段 prompt,decode 則一次只跑一個 token。

所以排程時必須區分兩種情境:

  • Prefill:大量 tokens、計算密集、適合大批次
  • Decode:一 token 一步、小但頻繁,需要大量最佳化(例如 CUDA Graph)

這也是為什麼 vLLM 的效能遠高於 naive 實作,因為它不把這兩者混在一起處理。

Scheduler:誰先跑?誰等資源?

Scheduler 管理兩個 queue:

  • Waiting queue:還沒開始跑的 sequences
  • Running queue:正在 prefill 或 decode 的 sequences

核心邏輯:

  • 新請求先進 Waiting,等待 Block Manager 分配 KV cache
  • 分配完成後進 Running queue
  • 若 KV cache 不夠,會被 preempt 回 Waiting,等資源釋放後再繼續

這裡可以看到推論引擎其實像是「現代作業系統 scheduler」的縮影,帶有 preemption 與資源管理。

Block Manager:vLLM 靈魂角色

文章在這段給了最重要的 insight:把 KV cache 切成固定大小 block,並透過 hash 做 prefix caching。

  • Sequence 長短不一,但 block 固定(例如 256 tokens)
  • 長序列跨多 block,但不同序列不會共享 block
  • 若相同 prefix 已出現,直接增加 reference count,而不重算該段 KV cache

這種做法超聰明:在聊天場景,大家幾乎共享同一個 system prompt,因此能節省大量計算。

而且 Block Manager 僅在 CPU 管理 metadata,真正的 KV cache 存在 GPU,相當於「控制平面(CPU)+資料平面(GPU)」分離,降低 overhead。

Model Runner:多 GPU 的協作邏輯

Nano‑vLLM 採 leader‑worker 架構執行 tensor parallel:

  • Rank 0:負責統一指令與協調
  • 其他 GPU:讀 shared memory,做自己的部分

由於都是單機多卡,採 shared memory 避免網路 overhead,非常務實。

此外,decode 步驟因為非常細碎,Nano‑vLLM 使用 CUDA Graphs 預先捕捉常用 batch size,以降低 kernel launch overhead,這點也直接對吞吐造成巨大影響。

筆者心得與啟發

讀完 Part 1,我最大的感觸是:

推論引擎的效能不是靠某一個技巧,而是靠整套架構思維:排程、記憶體分配、批次策略、GPU 最佳化,共同作用才能撐起「產線級 LLM 服務」。

如果你正在做:

  • LLM API 服務
  • 多租戶推論平台
  • 自架本地模型,提高吞吐量
  • 或想理解為何 vLLM 這麼快

這系列文章真的值得從頭讀到尾。

從 Prefill-Decode 的結構拆解,到 Block Manager 的 prefix caching,再到 CUDA Graph 的 decode 最佳化,這些概念都是 LLM 推論工程師的必備基礎。對我來說,這篇文章最有價值的一點,是讓我重新意識到:推論效能不是 CPU 跑快或 GPU 大就能解決,而是系統設計能力的展現。

期待 Part 2 深入 attention 與 KV cache 的真正結構,那會是理解推論效能的另一個關鍵拼圖。


Share:

作者: Chun

資訊愛好人士。主張「人人都該為了偷懶而進步」。期許自己成為斜槓到變進度條 100% 的年輕人。[///////////____36%_________]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *


文章
Filter
Apply Filters
Mastodon