HuggingFace Blog HuggingFace ★ 105 6 min

Transformers now runs llama.cpp quants

🔗 https://huggingface.co/blog/transformers-llama-cpp-quants

📌 【HuggingFace】Transformers 直接讀 GGUF,免轉檔跑本地模型

TL;DR:transformers 現在能原生載入 llama.cpp 的 GGUF 量化模型,效能貼近原生引擎。

過去想在筆電跑本地大型語言模型,開發者得在 llama.cpp、Ollama、MLX 這些各自獨立的生態圈裡選一邊站。現在 Hugging Face 把這道牆打通了:直接把 GGUF 檔丟進 from_pretrained,就能用熟悉的 transformers API 生成文字。

🤔 本地推論的痛點:格式各自為政

llama.cpp 的推論引擎撐起了 Ollama、LM Studio、Jan 等一票本地 AI 工具,加上 MLX,讓本地推論成為日常可用的選項。GGUF 正是由 llama.cpp 團隊開發的格式,官方在 Hub 上以 ggml-org 身分釋出量化 checkpoint,Unsloth、LM Studio Community、bartowski 等發布者也提供多種量化版本,GGUF 模型的下載量已達數百萬次。但這些模型過去主要活在 llama.cpp 生態內,難以直接接上 transformers 慣用的工作流。

🧩 怎麼接上的:重用 ggml kernels,而非重寫一套

為了讓相容性不只是「能跑」而是「跑得舒服」,HuggingFace 團隊透過 kernels 函式庫重用 llama.cpp 底層的 ggml kernels,並降低 generate 過程中的額外開銷,藉此讓效能貼近 llama.cpp 原生表現。目前的重點是 Apple Silicon 上的本地推論,並先支援 Qwen3.5 架構。

GGUF 檔案把模型權重與 metadata(包含 tokenizer 資訊與可選的 chat template)打包成單一檔案,並支援不同量化等級。以 Q4_K_M 為例,多數權重壓到 4-bit,同時保留敏感 tensor 在較高精度,藉此在檔案大小與精度之間取得平衡。以 Unsloth 的 Qwen3.5-4B 為例:

GGUF 版本檔案大小特性
BF168.42 GB未量化參考版本
Q6_K3.53 GB比小版本更高精度
Q5_K_M3.14 GB大小與精度的折衷
Q4_K_M2.74 GB本地推論的實用起點

官方建議從 Q4_K_M 開始嘗試,若記憶體充裕再往 Q5_K_M、Q6_K 調整;更激進的量化能讓更大模型塞進記憶體,但精度取捨因模型與任務而異,應該實際評估在你要跑的工作上。

🧩 三行程式碼開始生成

安裝需求包括 Apple Silicon Mac、相容的 PyTorch 版本,以及最新版 transformers(目前需裝 main 分支)與 kernels:

pip install -U "git+https://github.com/huggingface/transformers.git" kernels

載入時只需把 Hub 上的 model_id 與檔名以 gguf_file 參數傳入 from_pretrained,不需額外設定:

from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "unsloth/Qwen3.5-4B-GGUF"
filename = "Qwen3.5-4B-Q4_K_M.gguf"

tokenizer = AutoTokenizer.from_pretrained(model_id, gguf_file=filename)
model = AutoModelForCausalLM.from_pretrained(model_id, gguf_file=filename)

當權重能保持打包狀態留在 Metal 上時,transformers 會自動載入相容的 ggml/Metal layer kernels,並以 ggml-org/ggml-attn 作為 attention 實作;若該 kernel 抓不到,就會 fallback 到 sdpa 並跳出警告,開發者也可以直接傳入 attn_implementation="sdpa" 強制指定。若沒有相容的量化 kernel,loader 會退回 dequantize 模型,記憶體用量會增加。

除了直接呼叫 API,也能用 transformers serve 開出 OpenAI 相容介面:

transformers serve "unsloth/Qwen3.5-4B-GGUF:Qwen3.5-4B-Q4_K_M.gguf"

model 參數用 <model_id>:<filename>.gguf 格式指定要載入哪個量化版本,接著就能用 Jan、Pi 等支援 OpenAI 相容 API 的客戶端,設定 Base URL 為 http://localhost:8000/v1 直接連上。

📊 效能對比:跑分貼近 llama.cpp

官方以三款 GGUF checkpoint(小型 dense 模型、較大 dense 模型、mixture-of-experts 模型)做基準測試,對照組是 llama.cpp 的 llama-bench 工具(build 5f55650a7,release b10200,Metal backend),測試機為 MacBook Pro M2 Max、32 GB 統一記憶體、macOS 26.6、PyTorch 2.12.1、kernels 0.17.0。文章指出,在這三個 checkpoint 上,transformers 的生成速度都非常接近 llama.cpp。

⚠️ 目前限制

支援範圍還在起步階段:僅鎖定 Apple Silicon,架構上也只先覆蓋 Qwen3.5;缺少相容量化 kernel 時會退回 dequantize,記憶體用量隨之上升。

🎯 實務啟示

如果你已經在用 Unsloth、bartowski 等來源的 GGUF checkpoint,現在可以直接用 transformers 生態(generate、transformers serve)接手,不必在工具鏈之間切換;對已經熟悉 transformers API 的工程師來說,這是把本地推論納入既有 pipeline 的低成本路徑。

🔗 來源

#Transformers #GGUF #LlamaCpp #LocalInference #HuggingFace #Quantization #AppleSilicon #Qwen #OpenSource #MachineLearning

原始資料 HuggingFace Blog · 收集於 2026-09-22
來源原標題
Transformers now runs llama.cpp quants
機構
HuggingFace
原始連結
https://huggingface.co/blog/transformers-llama-cpp-quants

摘要原文

Back to Articles Transformers now runs llama.cpp quants Published September 22, 2026 Update on GitHub Upvote 32 +26 Marc Sun marcsun13 Follow Arthur Zucker ArthurZ Follow Lysandre lysandre Follow We're adding support for running GGUF models efficiently in transformers , so you can use checkpoints sized for your laptop's memory through the familiar transformers APIs. Pick a GGUF from the Hub, load it with from_pretrained , and start generating on your own machine. Running AI models on your laptop has become much easier, and llama.cpp has been a big part of that. Its inference engine powers local AI tools such as Ollama, LM Studio, and Jan. Alongside projects like MLX , it has helped make local inference a practical option for everyday use. A recent example of what local AI can feel like: This is where we are right now. And i’m not gonna lie it feels pretty magical 🧙‍♀️ Qwen3.6 27B running inside of Pi coding agent via Llama.cpp on the MacBook Pro For non-trivial tasks on the @huggingface codebases, this feels very, very close to hitting the latest Opus in Claude… pic.twitter.com/lsIxLoUneU — Julien Chaumond (@julien_c) April 24, 2026 GGUF , developed by the llama.cpp team, is a widely used format for local inference. The team also shares quantized checkpoints under ggml-org on the Hub . Publishers such as Unsloth , LM Studio Community , and bartowski also provide ready-to-use GGUF checkpoints in a range of quantizations, so users can pick the version that fits their machine. GGUF models have been downloaded millions of times. We want to make it easier to run these models locally with transformers, too. Compatibility is only useful if the model is pleasant to run. To bring performance close to llama.cpp, we're reusing its underlying ggml kernels through the kernels library, and reducing overhead in generate . Our initial focus is local inference on Apple Silicon, starting with the Qwen3.5 architecture. What is the GGUF file format? GGUF packages model weights and metadata, including tokenizer information and an optional chat template, in one file. It supports different quantization levels, letting you trade some precision for a smaller memory footprint. Variants such as Q4_K_M mix tensor precisions, using mostly 4-bit weights while keeping sensitive tensors at higher precision. Here's how quantization changes the file size of Unsloth's Qwen3.5-4B : GGUF variant File size Tradeoff BF16 8.42 GB Unquantized reference Q6_K 3.53 GB More precision than the smaller variants Q5_K_M 3.14 GB A middle ground between size and precision Q4_K_M 2.74 GB A practical starting point for local inference We suggest starting with Q4_K_M , then trying Q5_K_M or Q6_K if you have more memory available. More aggressive quantization can help larger models fit, but the quality tradeoff depends on the model and the task. Evaluate it on the work you actually want the model to do. The Hub's GGUF documentation describes the available quantization types. Load GGUF with transformers To get started, you need: An Apple Silicon Mac . A PyTorch version supported by the published ggml-quantization kernel builds , usually the two latest PyTorch releases. The latest version of transformers (main for now, until the next release) and a compatible version of kernels . pip install -U "git+https://github.com/huggingface/transformers.git" kernels To load a GGUF model, pass its Hub model_id and filename as gguf_file to from_pretrained . No extra configuration is needed: when the weights stay packed on Metal, transformers automatically loads the compatible ggml/Metal layer kernels and uses ggml-org/ggml-attn as the attention implementation. If that kernel cannot be fetched, the model falls back to "sdpa" with a warning, and you can always force "sdpa" by passing attn_implementation="sdpa" explicitly. See the GGUF documentation for more loading options. import torch from transformers import AutoModelForCausalLM, AutoTokenizer model_id = "unsloth/Qwen3.5-4B-GGUF" filename = "Qwen3.5-4B-Q4_K_M.gguf" tokenizer = AutoTokenizer.from_pretrained(model_id, gguf_file=filename) model = AutoModelForCausalLM.from_pretrained( model_id, gguf_file=filename ) That is the only GGUF-specific step. Everything after it is the standard transformers API: messages = [{ "role" : "user" , "content" : "Explain why the sky is blue in a few sentences." }] inputs = tokenizer.apply_chat_template( messages, tokenize= True , add_generation_prompt= True , return_dict= True , return_tensors= "pt" , ).to(model.device) with torch.inference_mode(): outputs = model.generate(**inputs, max_new_tokens= 256 ) print (tokenizer.decode(outputs[ 0 ], skip_special_tokens= True )) Without a compatible quantization kernel, the loader falls back to dequantizing the model and uses more memory. Serve GGUF with your preferred interface You can also use the same checkpoint with transformers serve , which exposes an OpenAI-compatible API: pip install -U "transformers[serving] @ git+https://github.com/huggingface/transformers.git" kernels transformers serve "unsloth/Qwen3.5-4B-GGUF:Qwen3.5-4B-Q4_K_M.gguf" The model argument uses <model_id>:<filename>.gguf : before the colon is the Hub repository ( unsloth/Qwen3.5-4B-GGUF ), and after it is the file to load ( Qwen3.5-4B-Q4_K_M.gguf ). This selects a specific quantization from a repository that may contain several. For models whose chat template supports thinking, add --reasoning off to skip it or --reasoning on to enable it. The default, --reasoning auto , follows the chat template’s default. See the reasoning options for details. You can connect a client such as Jan or Pi by adding a custom OpenAI-compatible provider with these settings: Setting Value Base URL http://localhost:8000/v1 Model ID unsloth/Qwen3.5-4B-GGUF:Qwen3.5-4B-Q4_K_M.gguf transformers runs the model on your Mac, while the client provides the conversation interface. The same endpoint can be used by other clients that support this API. Benchmarking against llama.cpp Our reference for local inference performance is llama.cpp. The comparison below focuses on three GGUF checkpoints: a small dense model, a larger dense model, and a mixture-of-experts model. The llama.cpp column comes from the llama-bench tool (build 5f55650a7 , release b10200, Metal backend from ggml 0.18.0), run as llama-bench -m <file> -p 0 -n 128 -r 3 , which reports tg128 : the token-generation rate over 128 decoded tokens, averaged across three repetitions, with prompt processing excluded. The transformers column is generate producing the same 128 tokens from a 12-token prompt, best of three warmed runs, and it includes prefill. Measured on a MacBook Pro M2 Max, 32 GB unified memory, macOS 26.6, PyTorch 2.12.1, kernels 0.17.0, plugged in. The benchmark script import time import torch from transformers import AutoModelForCausalLM, AutoTokenizer model_id, filename = "unsloth/Qwen3.5-4B-GGUF" , "Qwen3.5-4B-Q4_K_M.gguf" model = AutoModelForCausalLM.from_pretrained(model_id, gguf_file=filename) tokenizer = AutoTokenizer.from_pretrained(model_id, gguf_file=filename) inputs = tokenizer( "The capital of France is Paris. The capital of Germany is" , return_tensors= "pt" ) inputs = inputs.to(model.device) with torch.inference_mode(): model.generate(**inputs, max_new_tokens= 8 , min_new_tokens= 8 , do_sample= False ) # warm up torch.mps.synchronize() for _ in range ( 3 ): time.sleep( 90 ) # let the machine cool: back-to-back runs decay by 10% or more start = time.perf_counter() model.generate(**inputs, max_new_tokens= 128 , min_new_tokens= 128 , do_sample= False ) torch.mps.synchronize() print ( f" { 128 / (time.perf_counter() - start): .1 f} tok/s" ) For the other column: llama-bench -hf unsloth/Qwen3.5-4B-GGUF:Q4_K_M -p 0 -n 128 -r 3 Transformers is close to llama.cpp across all three checkpoints.

由 claude-code/sonnet 自動生成