
llama.cpp 在 iOS 上的應用:Swift 整合指南
將 llama.cpp 整合到 iOS 應用程式的分步指南。專案設定、Metal GPU 加速、模型載入、token 串流和記憶體管理,適用於正式環境部署。
llama.cpp 是在 Apple 硬體上運行 GGUF 語言模型的推論引擎。它使用 Metal 進行 GPU 加速,支援從 A14(iPhone 12)起的所有 iPhone 機型,並根據模型大小和裝置,以每秒 20-50 個 token 的速度生成。
本指南涵蓋從專案設定到正式環境部署的完整整合流程。
整合選項
選項 1:Swift Package(推薦)
llama.cpp 儲存庫包含一個 Swift Package,您可以直接新增到 Xcode 專案中:
- 在 Xcode 中,前往 File,Add Package Dependencies
- 輸入 llama.cpp 儲存庫 URL
- 選擇您想要的版本或分支
- 在 Swift 文件中匯入
llama模組
這是最簡單的整合路徑。該套件會在建構時編譯 llama.cpp,並將 C API 暴露給 Swift。
選項 2:預建置框架
將 llama.cpp 建構為 XCFramework 並作為二進位相依性包含。這可避免在專案中編譯 C++ 原始碼:
# 建構框架
mkdir build-ios && cd build-ios
cmake .. -G Xcode \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_OSX_DEPLOYMENT_TARGET=15.0 \
-DLLAMA_METAL=ON \
-DBUILD_SHARED_LIBS=OFF
cmake --build . --config Release
選項 3:llama.swift 封裝器
社群維護的 Swift 封裝器在 C 繫結之上提供更符合 Swift 風格的 API。這些封裝器處理橋接樣板程式碼並公開更簡潔的介面。
專案設定
最低需求
- iOS 15.0+(用於 Metal 計算著色器)
- Xcode 15+
- 實體裝置進行測試(模擬器不支援 Metal 計算)
建構設定
將 Metal 框架新增到您的專案:
- 連結
Metal.framework和MetalKit.framework - 如需要,設定
METAL_COMPILER_FLAGS用於自訂著色器
權限
不需要特殊權限。llama.cpp 在應用程式的正常沙箱中運行。記憶體使用是主要關注點(下方討論)。
載入模型
import llama
class LlamaEngine {
private var model: OpaquePointer?
private var context: OpaquePointer?
func loadModel(at path: String) throws {
// 模型參數
var modelParams = llama_model_default_params()
modelParams.n_gpu_layers = 99 // 將所有層卸載到 Metal
// 載入 GGUF 文件
model = llama_load_model_from_file(path, modelParams)
guard model != nil else {
throw LlamaError.modelLoadFailed
}
// 建立推論上下文
var ctxParams = llama_context_default_params()
ctxParams.n_ctx = 2048 // 上下文視窗大小
ctxParams.n_threads = 4 // CPU 執行緒(用於非 Metal 運算)
ctxParams.n_batch = 512 // 提示處理的批次大小
context = llama_new_context_with_model(model, ctxParams)
guard context != nil else {
throw LlamaError.contextCreationFailed
}
}
func unload() {
if let ctx = context {
llama_free(ctx)
context = nil
}
if let mdl = model {
llama_free_model(mdl)
model = nil
}
}
deinit {
unload()
}
}
關鍵參數
n_gpu_layers: 設為 99(或模型的實際層數)以將所有計算卸載到 Metal。這是最重要的效能設定。
n_ctx: 以 token 計的上下文視窗大小。較大的視窗使用更多記憶體。2048 對大多數行動使用場景來說是實用的。如需更長的對話則用 4096。
n_threads: 用於 CPU 運算的 CPU 執行緒數。設為裝置的效能核心數(iPhone 通常為 2-4)。
n_batch: 提示評估期間每批處理的 token 數。較高的值加速提示處理但使用更多記憶體。512 是良好的預設值。
生成文字
分詞和提示處理
extension LlamaEngine {
func generate(
prompt: String,
maxTokens: Int = 256,
temperature: Float = 0.7,
onToken: @escaping (String) -> Void
) -> String {
guard let ctx = context, let mdl = model else { return "" }
// 對提示進行分詞
let promptTokens = tokenize(prompt)
// 建立用於提示處理的批次
var batch = llama_batch_init(Int32(promptTokens.count), 0, 1)
for (i, token) in promptTokens.enumerated() {
llama_batch_add(&batch, token, Int32(i), [0], i == promptTokens.count - 1)
}
// 處理提示
llama_decode(ctx, batch)
llama_batch_free(batch)
// 生成 token
var output = ""
for _ in 0..<maxTokens {
let logits = llama_get_logits(ctx)
// 取樣下一個 token
let token = sampleToken(logits: logits!, temperature: temperature)
// 檢查是否為序列結尾
if llama_token_is_eog(mdl, token) { break }
// 將 token 解碼為字串
let piece = decodeToken(token)
output += piece
onToken(piece)
// 準備下一個批次
var nextBatch = llama_batch_init(1, 0, 1)
llama_batch_add(&nextBatch, token, Int32(promptTokens.count + output.count), [0], true)
llama_decode(ctx, nextBatch)
llama_batch_free(nextBatch)
}
return output
}
private func tokenize(_ text: String) -> [llama_token] {
let maxTokens = Int32(text.utf8.count + 16)
var tokens = [llama_token](repeating: 0, count: Int(maxTokens))
let count = llama_tokenize(model, text, Int32(text.utf8.count),
&tokens, maxTokens, true, false)
return Array(tokens.prefix(Int(count)))
}
private func decodeToken(_ token: llama_token) -> String {
var buf = [CChar](repeating: 0, count: 64)
let len = llama_token_to_piece(model, token, &buf, 64, 0, false)
return String(cString: Array(buf.prefix(Int(len))) + [0])
}
}
Metal GPU 加速
當設定了 n_gpu_layers 時,Metal 加速會自動啟用。llama.cpp 在首次載入時編譯 Metal 著色器(需 1-2 秒,之後會快取)。
效能影響
| 組態 | iPhone 15 Pro,3B Q4 | iPhone 14,3B Q4 |
|---|---|---|
| 僅 CPU(n_gpu_layers = 0) | 8-12 tok/s | 6-10 tok/s |
| Metal(n_gpu_layers = 99) | 18-25 tok/s | 14-18 tok/s |
Metal 平均提供 2 倍加速。正式環境務必啟用。
Metal 著色器快取
llama.cpp 首次在裝置上運行時會編譯 Metal 著色器。這為首次模型載入增加 1-2 秒。後續載入是即時的(著色器由 iOS 快取)。
記憶體管理
記憶體預算
iOS 在觸發 jetsam(強制終止)之前,會給應用程式約 50-70% 的裝置總 RAM:
| 裝置 | 總 RAM | 應用程式預算 | 可用於模型 |
|---|---|---|---|
| iPhone 12(4GB) | 4GB | 約 2.5GB | 約 1.5GB |
| iPhone 14(6GB) | 6GB | 約 3.5GB | 約 2.5GB |
| iPhone 15 Pro(8GB) | 8GB | 約 5GB | 約 3.5GB |
3B Q4 模型在 RAM 中使用約 2.2GB。在 6GB 裝置上,這為您的應用程式、iOS 和其他程序留下約 1.3GB。緊湊但可行。
最佳實踐
// 載入前檢查可用記憶體
func canLoadModel(sizeBytes: Int) -> Bool {
let available = os_proc_available_memory()
// 為應用程式和作業系統保留 500MB 餘量
return available > sizeBytes + 500_000_000
}
// 處理記憶體警告
func didReceiveMemoryWarning() {
engine.unload()
// 顯示「模型已卸載」訊息,提供重新載入選項
}
- 載入前始終檢查可用記憶體
- AI 功能不活躍時卸載模型
- 處理
didReceiveMemoryWarning時卸載模型 - 應用程式在背景時切勿保持模型載入狀態
模型交付
捆綁
將 GGUF 文件作為資源新增到 Xcode 專案。透過 Bundle.main 存取:
let modelPath = Bundle.main.path(forResource: "model", ofType: "gguf")!
對於超過 200MB 的模型,考慮使用 On Demand Resources 以避免膨脹初始下載大小。
下載
安裝後下載模型並存儲在應用程式的 Documents 目錄中:
let documentsURL = FileManager.default
.urls(for: .documentDirectory, in: .userDomainMask)[0]
let modelURL = documentsURL.appendingPathComponent("model.gguf")
使用 URLSession 背景下載處理大型文件。支援中斷後恢復。
正式環境檢查清單
- 模型在目標裝置上載入不會當機(在最低 RAM 目標裝置上測試)
- Metal 加速已啟用(透過效能日誌驗證)
- 記憶體警告處理程式優雅地卸載模型
- 下載後驗證模型文件完整性(SHA256)
- 串流 token 在 UI 中平滑顯示
- 使用者可以取消生成(中斷生成迴圈)
- 轉入背景時卸載模型
- 模型未載入時應用程式正常運作(優雅降級)
微調後的 GGUF 模型是關鍵要素。基礎模型生成通用回應。在您的領域資料上微調的模型(透過 Ertas 等平台)生成與應用程式目的和風格相符的回應。llama.cpp 整合方式無論使用哪個模型都是相同的。
Ship AI that runs on your users' devices.
Early bird pricing starts at $14.50/mo — locked in for life. Plans for builders and agencies.
Keep reading

AI in iOS Apps: CoreML, Cloud APIs, and On-Device LLMs Compared
Three paths to AI in your iOS app. CoreML for Apple's ecosystem, cloud APIs for capability, and on-device LLMs via llama.cpp for cost and privacy. A practical comparison for Swift developers.

Can LLMs Actually Run on iPhones? Benchmarks and Real-World Performance
Real benchmark data for running LLMs on iPhones via llama.cpp. Token generation speeds, memory usage, and thermal behavior across iPhone models from the iPhone 12 to iPhone 16 Pro.

llama.cpp on Android: A Kotlin Integration Guide
Step-by-step guide to integrating llama.cpp into an Android app with Kotlin. JNI bindings, Vulkan GPU acceleration, model loading, and memory management across the Android device spectrum.