ggml 簡介

ggml 是一個以 C 與 C++ 編寫的低階機器學習(ML)函式庫,專為 Transformer 推論設計。它作為多個流行的裝置端大型語言模型(LLM)專案的底層引擎,包括 llama.cpp、whisper.cpp、ollama、Jan、LM Studio 與 GPT4All。

ggml 的核心優勢

ggml 以極簡與高效為設計目標,特別適合在資源受限的硬體上部署。其主要優點包括:

  • Minimal Footprint: 核心函式庫僅包含不到五個檔案,編譯後的二進位大小低於 1MB。
  • Simplified Compilation: 僅需 GCC 或 Clang 即可完成基本編譯,且不需要 GPU 支援,避免使用複雜的建置工具。
  • Broad Hardware Compatibility: 支援 x86_64、ARM、Apple Silicon、CUDA 以及其他硬體架構。
  • Memory Efficiency: 函式庫最小化張量儲存與計算的開銷,並支援量化張量以降低記憶體使用量,且可能提升效能。

技術取捨

作為仍在積極開發中的低階函式庫,ggml 具有以下限制:

  • Backend Variance: 並非所有張量操作在所有後端皆受支援(例如,某些操作在 CPU 上可執行,但在 CUDA 上不可用)。
  • Development Complexity: 使用 ggml 需要深入的低階程式設計知識。
  • Stability: 由於仍在積極開發中,預期會有破壞性變更。

關鍵術語與概念

了解 ggml 需要熟悉多種低階抽象,這些抽象提供了對效能的細粒度控制:

  • ggml_context: 張量、圖形與可選資料的容器。
  • ggml_cgraph: 表示由後端執行之操作順序的計算圖。
  • ggml_backend: 執行計算圖的介面,實作包括 CPU(預設)、CUDA、Metal、Vulkan 與 RPC。
  • ggml_backend_buffer_type: 與特定後端相連的記憶體配置器(例如,配置 GPU 記憶體)。
  • ggml_backend_buffer: 由 buffer_type 分配的緩衝區,可容納多個張量的資料。
  • ggml_gallocr: 用於在計算圖中有效管理張量的圖形記憶體配置器。
  • ggml_backend_sched: 將計算分配至多個後端的排程器(例如,將工作在 CPU 與 GPU 之間分割),並自動將不支援的操作指派給 CPU。

實作工作流程

基本計算

對於簡單的操作,例如矩陣乘法,ggml 的工作流程包括:

  1. 為張量資料分配一個 ggml_context
  2. 建立張量並指派資料。
  3. 為操作定義一個 ggml_cgraph(例如 ggml_mul_mat)。
  4. 透過 ggml_graph_compute_with_ctx 執行計算。
  5. 取得結果並釋放記憶體。

後端驅動計算

當使用特定硬體後端(如 CUDA)時,流程更為詳細,以確保裝置記憶體的有效管理:

  1. 初始化 ggml_backend
  2. 僅為張量中繼資料分配 ggml_context
  3. 建立張量中繼資料(形狀與類型)。
  4. 分配 ggml_backend_buffer 以在裝置上儲存張量。
  5. 將張量資料從 RAM 複製至後端緩衝區。
  6. 建立 ggml_cgraphggml_gallocr 以進行圖形分配。
  7. 透過 ggml_backend_graph_compute 執行計算。
  8. 將結果張量從裝置緩衝區複製回 RAM。

除錯計算圖

開發者可以檢查 ggml_cgraph 以驗證操作順序。函式庫提供 ggml_graph_print 以將圖形輸出至主控台,並提供 ggml_graph_dump_dot 以 Graphviz dot 格式匯出圖形供視覺化呈現。

Sources