tiny-llm:在 Apple Silicon 上從零實作 Qwen3 推論與排程
learn LLM inference system on Apple Silicon for systems engineers: build a tiny vLLM + Qwen
秒懂
- 它是什麼?
- skyzh/tiny-llm 是一門寫給系統工程師的實作課程,用 MLX 陣列從矩陣乘法一路做到 paged KV cache 與 continuous batching,最後接上一個有界、可驗證的 coding agent 迴圈。它的價值在於把 vLLM 的關鍵機制拆成可讀完的 Python 與 Metal 實作,代價是它是一份教材而非可直接上線的服務框架。
- 適合誰用?
- tiny-llm 適合已經寫過系統程式、想親手把 KV cache、paged attention 與 continuous batching 做一遍的工程師,也適合需要在不依賴 CUDA 叢集的情況下理解 serving 內部運作的團隊;不適合只想找一個能直接部署的推論伺服器、或期待有社群支援與版本保證的人。動手前先確認三件事:你的機器是否為 Apple Silicon 且能跑 MLX,Qwen3-4B 的 4-bit 權重是否放得進你的統一記憶體,以及 Week 4 的 agent 迴圈是否只在一次性 workspace 中執行。
- 可以商用嗎?
- 可以。Apache-2.0 是寬鬆授權:你可以使用、修改並販售以它為基礎的軟體,只需保留著作權與授權聲明。
- 還在維護嗎?
- 有在維護。儲存庫在最近一天內有新的提交。
- 用什麼語言寫的?
- 主要是 Python(依據 GitHub 的語言統計)。
以上回答依據專案的 GitHub 資料(最近同步於 2026年9月15日)與我們的分析,不構成法律意見。
開源專案深度解析
它想解決的是理解斷層,不是推論速度
多數工程師對 LLM serving 的認識停在兩層:上層是 vLLM 這類框架的 API,下層是推論引擎內部的 kernel 與排程器。中間那段「token 怎麼變成 logits、KV cache 怎麼長大、排程器為什麼要分頁」往往只能靠讀論文或讀大型專案的原始碼拼湊。tiny-llm 針對的就是這段斷層。README 把它定位成 CMU Needle 的 LLM serving 對應版本:Needle 讓學生從零寫出一個自動微分框架,tiny-llm 則讓學生從零寫出一條把 Qwen3 載入、產生 logits、輸出文字的完整路徑。目標讀者寫得很明確,是 systems engineers,不是想學 prompt engineering 或模型微調的人。課程的四週安排也反映了這個取向:第一週做 attention、RoPE、GQA、RMSNorm、MLP、sampling 與自迴歸迴圈,第二週才加入 KV cache 與基準測試,第三週處理 continuous batching、chunked prefill 與 paged KV,第四週把模型接進一個受控的 agent 迴圈。前半是數值與記憶體,後半是排程與系統邊界,兩者共用同一份程式碼。
MLX 當正解,學生自己寫算子
這門課最關鍵的設計決定,是它建立在 MLX arrays 與 MLX extension runtime 之上,但不使用高階神經網路層。當某一章要教一個算子,學生的解法必須用 Python、C++ 或 Metal 自己實作,而不是呼叫 MLX 對應的最佳化版本。MLX 在這裡扮演兩個角色:正確性驗證的 oracle,以及效能比較的 baseline。這個安排讓「我的實作對不對」與「我的實作快不快」都有客觀參照,而不是靠講師主觀描述。選擇 Apple Silicon 的理由 README 講得直接:統一記憶體空間加上對 Metal kernel 的直接存取,學生可以在單機上檢視完整路徑,不必依賴昂貴的 CUDA GPU 環境。模型選擇同樣是取捨後的結果。Qwen3-4B 大到足以暴露真實的權重頻寬、attention 與 cache 成本,又小到可以在本機反覆迭代;它的 grouped-query attention、QK normalization、BF16 啟動值與 4-bit 權重,也讓練習貼近當前 serving 實務。第二週的路線是量化 decode matvec、融合模型 kernel、tiled prefill,再到 split-K,每一步都由配對過的基準測試決定是否採用。這個「先量測再優化」的順序,比直接給出最佳解更接近真實工作。
從 dense history 到 paged KV 的排程轉折
第三週是整門課的結構轉折點。前兩週的模型仍然假設每次 decode 都能看到完整的歷史,KV cache 只是一塊持續增長的緩衝區。第三週引入 continuous batching 與 chunked admission 之後,paged KV 成為 serving 的標準佈局,decode attention 與 FlashAttention 必須學會直接讀取分頁,排程器才不需要在每一步重建稠密的歷史。這是 vLLM 的核心機制之一,tiny-llm 把它拆成 3.3 到 3.5 三章,讓學生依序實作分頁配置、直接分頁 attention、以及分頁版 FlashAttention。課程另外提供兩個選修章節:MoE 與 speculative decoding。它們被標為 optional,說明主線不依賴它們,但想理解現代模型架構或推論加速技巧的人可以延伸。Week 4 則是完全不同的題目。它從一個有界、可驗證的 agent 迴圈開始,接上一個小型 workspace,README 說課程一次只發布一個經過審查的檢查點,目前 Days 1 到 9 涵蓋 workspace 檢視、經核准的編輯、單一驗證指令、效果收據、檢查點與恢復邊界、以收據為基礎的上下文壓縮、暫停後檢視與引導、可觀察結果的確定性評估、兩個隔離分支的 tokenizer 與 KV 前綴重用,以及超出提示大小的工具結果如何以有界的身分、摘要與頭尾觀察呈現並支援範圍檢索。這一段與前三週的推論主線關聯較弱,比較像是把 serving 機制放進 agent 情境的應用練習。
安裝與驗證的實際指令
README 給的起點是書本網站 skyzh.github.io/tiny-llm,環境設定另外有一頁 setup.html。若已經有 checkout,驗證方式是這三行:pdm install -v、pdm run check-installation、pdm run test-refsol -- -- -k week_1。套件分工在 README 中寫得清楚:tiny_llm 是學生實作練習的地方,tiny_llm_ref 則是測試與 benchmark 附錄使用的參考解答。章節順序列在 book/src/SUMMARY.md。這幾行指令同時透露了工具鏈的假設:套件與虛擬環境由 pdm 管理,測試以 pytest 風格的 -k 選擇器過濾,week_1 只是其中一個過濾條件。check-installation 這個任務名稱暗示它會驗證 MLX 與 Metal 環境是否可用,但 README 沒有列出它實際檢查的項目,實際輸出需要自己跑過才知道。Week 4 的執行前提與前三週不同,README 特別警告 Day 3 可以把檔案內容送進模型、在核准後修改檔案、並執行一個精確配置的指令,因此必須使用不含機密的一次性 workspace,並在跑迴圈之前先讀 book/src/week4-overview.md。這是整份文件中少數帶有安全語氣的段落,值得照做。
教材定位帶來的三個限制
第一個限制是平台綁定。課程建立在 MLX 與 Metal 之上,README 選擇 Apple Silicon 的理由是統一記憶體與本機可檢視性,這個選擇同時排除了沒有 Apple 硬體的讀者。想在 Linux 或 CUDA 環境複製這條路徑的人,會發現大部分章節的程式碼無法直接搬移,因為它依賴 MLX extension runtime 而不是通用的 kernel 介面。第二個限制是它不會變成產品。README 沒有提供任何推論伺服器、部署流程或 API 相容層,tiny_llm 是學生填寫練習的位置,tiny_llm_ref 是參考解答。想找一個能承接線上流量、有多租戶隔離或可觀測性整合的服務框架,這個專案並不提供,也不打算提供。第三個限制是進度本身。Roadmap 表格把每個章節的 Code、Test、Doc 與 Audit 四欄分開追蹤,Week 1 全部完成,Week 2 之後的 Audit 欄仍是進行中的狀態,Week 4 更是一次只發布一個經過審查的 Day,目前到 Day 9。README 說明 Audit 是作者 Chi 對學習者可見內容的個人編輯審查,與程式碼、測試、文件是否就緒無關。這意味著後半段的教材品質與前半段不在同一個完成度上,跟著目錄走會遇到尚未審查的章節。另外 README 結尾提到還有其他未涵蓋的主題,但文字在此截斷,無法確認清單內容。
與直接讀 vLLM 原始碼的差異
最直接的替代方案是讀 vLLM 的原始碼。兩者處理的是同一批機制:paged KV cache、continuous batching、chunked prefill、FlashAttention 的變體。差別在於閱讀順序與回饋迴路。vLLM 是一個生產系統,它的程式碼必須同時處理多種硬體後端、多種量化格式、分散式執行與向後相容,讀者很難判斷某段程式碼是核心機制還是歷史包袱。tiny-llm 把這些機制抽出來,用一個 4B 模型與單機環境重新實作,每一章只增加一個概念,並且用 MLX 當作正確性與效能的參照。代價是簡化。tiny-llm 不會教你怎麼處理多 GPU 的張量平行、怎麼做 prefix caching 的跨請求共享、怎麼在生產環境中處理模型熱更新,這些在 vLLM 裡都是真實存在的複雜度。另一個替代是 CMU Needle,README 自己就把 tiny-llm 定位成 Needle 在 LLM serving 方向的對應版本。Needle 的目標是自動微分與訓練框架的內部運作,tiny-llm 的目標是推論與排程,兩者互補而非替代。如果你的問題是「模型怎麼訓練出來的」,Needle 更合適;如果問題是「一個請求進來之後,token 經過哪些排程與記憶體決策才變成回應」,tiny-llm 的第三週是少見的完整拆解。
授權、維護與升級成本
專案採用 Apache-2.0,這個授權允許商業使用、修改與再散布,並包含專利授權條款,同時要求保留著作權聲明與變更說明。把 tiny_llm_ref 的參考解答直接放進自家產品之前,仍應自行確認衍生作品的標示方式,這裡不構成法律意見。維護成本要從教材的角度看,而不是從函式庫的角度看。README 沒有列出任何 release,也就是說沒有版本號可供鎖定,升級等同於跟著 main 分支移動。Roadmap 顯示 Week 4 仍在逐日發布,任何依賴該週內容的程式碼都可能在下一次推送時改變行為。相對地,Week 1 的章節在 Code、Test、Doc、Audit 四欄都已標記完成,是整份教材中最穩定的部分。最後更新時間為 2026 年 9 月 9 日,專案未封存,仍在活躍發布。若你的用途是內部教學或技術評估,這種不穩定是可以接受的;若你的用途是把某一段實作搬進需要長期支援的程式庫,就必須把相關程式碼複製出來自行維護,並預期上游不會為你的相容性負責。
編輯結論
tiny-llm 適合已經寫過系統程式、想親手把 KV cache、paged attention 與 continuous batching 做一遍的工程師,也適合需要在不依賴 CUDA 叢集的情況下理解 serving 內部運作的團隊;不適合只想找一個能直接部署的推論伺服器、或期待有社群支援與版本保證的人。動手前先確認三件事:你的機器是否為 Apple Silicon 且能跑 MLX,Qwen3-4B 的 4-bit 權重是否放得進你的統一記憶體,以及 Week 4 的 agent 迴圈是否只在一次性 workspace 中執行。README 明確要求 Week 4 使用不含機密的可丟棄 workspace,這是採用前必須先讀完 book/src/week4-overview.md 的原因。
社群筆記