📝

ローカルLLMをllama.cpp + GGUFで動かしてみる

に公開

背景

LLM(大規模言語モデル)が SaaS として広く提供されるようになりましたが、

  • 呼び出すたびに従量課金が発生 する
  • 企業データがクラウドに渡る リスクがある
  • オフライン環境では利用できない といった課題があります。

一方、CPU/GPU の性能向上と量子化技術の進歩により、ローカル端末や小型 IoT 機器でも LLM を動かせる時代 になりました。本記事ではローカル推論の選択肢と、最もメジャーな llama.cpp を例に導入手順を紹介します。


LLM をローカルで実行する方法

代表的な 4 つのアプローチ

方法 特徴 長所 短所 典型的ハードウェア
llama.cpp C/C++ 製・シングルバイナリ。GGUF を直接ロード 軽量・ビルド容易・CPU/GPU/Metal/Vulkan 対応・量子化(Q2〜Q8) 大規模モデルは量子化必須、FP16 未対応 x86_64, Apple Silicon, Raspberry Pi 5
PyTorch + Transformers Python 製。Hugging Face の公式手順 拡張性・エコシステムが豊富 メモリ/GPU 要件大、起動遅い A100, T4 など GPU サーバ
TensorRT‑LLM NVIDIA TensorRT で最適化 GPU 推論が高速・省メモリ NVIDIA GPU 限定、セットアップ複雑 L4, A100
Ollama llama.cpp をラップしたワンコマンド CLI モデル取得〜実行が簡単 パラメータ調整が限定的、モデル種類がコミュニティ依存 Apple Silicon, x86_64

なぜ llama.cpp なのか?

  • バイナリ < 20 MB・依存ほぼゼロで配布容易
  • Q4_0 量子化なら 7B モデルを RAM 6 GB で推論
  • Metal / CUDA / OpenCL / Vulkan のバックエンドで幅広い GPU を活用

llama.cpp で扱えるモデル形式

形式 拡張子 概要 llama.cpp での扱い
Unsloth チェックポイント ディレクトリ構成 & adapter_model.bin LoRA 学習後の差分ウェイト 要変換
Hugging Face 標準 pytorch_model.bin / *.safetensors FP32/FP16 ウェイト 要変換
GGUF *.gguf llama.cpp ネイティブ量子化形式 そのままロード可

非 GPU 環境向けのヒント

  • Q4_0 / Q5_0 量子化 + --threads $(nproc) が定石
  • Raspberry Pi 5 (ARM64, 8 GB RAM) なら 4 GB 前後の 3B モデルが実用域
  • メモリ不足時は --ctx-size 1024 などでコンテキスト長を削減

Unsloth 形式を GGUF 形式へ変換する手順

Hugging Face で公開される LoRA 学習済みモデルや、自己学習したモデルは Unsloth 形式 になっている場合が多々あります。llama.cpp で推論するには 2 段階 の変換が必要です。

  1. Unsloth → Hugging Face 形式 への変換

    pip install unsloth
    python convert_unsloth_to_hf.py \
        --input_dir ./unsloth_model \
        --output_dir ./hf_model
    
  2. Hugging Face → GGUF への変換

    git clone https://github.com/ggerganov/llama.cpp
    python llama.cpp/convert_hf_to_gguf.py \
        ./hf_model \
        --outfile llama3-q4_0.gguf \
        --outtype q4_0      # Q2_K, Q4_0, Q5_1, Q8_0 など選択可
    

convert_hf_to_gguf.pyで実装されている変換サイズ(2025/04/28時点)

出力タイプ 量子化ビット/パラメータ (bpw) 7Bモデルの 目安サイズ 特徴・用途
f32 32 bit (=4 byte) ≈ 26 GB 重量級・完全に損失なし。学習や再量子化の中間形式には便利だが、推論は非常に遅く RAM を大量消費する。
f16 16 bit ≈ 13 GB Hugging Face で一般的な half precision。品質低下は無視できるが、GPU/CPU メモリを圧迫しやすい。​
bf16 16 bit (bfloat16) ≈ 13 GB f16 と同容量。bfloat16 対応ハードウェアでは積和演算が速い。品質は f16 同等。
q8_0 8 bit ≈ 6.7 GB 1 byte 量子化。ほぼ f16 と同じ精度で、CPU 推論でも速度・メモリ効率がよい。GPU では I/O 待ちがボトルネックに。​
tq2_0 ≈ 2.7 bit (true 2-bit “ternary-plus” 量子化) ≈ 2.4 GB 4 bit 未満で Q4 系よりさらに小型。重要重みは 3 値化 ±1/0、残りはスケール係数で補正。品質は Q4_K_M に近く、RAM を大きく節約できる。
tq1_0 1.69 bit ≈ 1.5 GB 最小クラスの「3-値」量子化。メモリ/ストレージ節約効果は極大だが、パープレキシティ増加が大きく長文生成では破綻しやすい。研究・実験用途向け。​
auto 入力モデルの dtype をそのまま踏襲 既存 GGUF を再生成する際や、量子化せずメタデータのみ更新したいときに使う。​

ローカル LLM の実践

1. 変換ログ(抜粋)

INFO:hf-to-gguf:Exporting model...
token_embd.weight, torch.float16 --> Q4_0, shape = {4096, 32000}
...
✅  Finished. Saved as llama3-q4_0.gguf (size: 4.1 GB)

2. llama.cpp で実行

./main -m ./llama3-q4_0.gguf \
       -p "日本で最も高い山は?" \
       --n-predict 32 \
       --threads 8 \
       --gpu-layers 35   # Metal GPU 全乗せ

実行結果例

Q: 日本で最も高い山は?
A: 日本アルプスの一角である富士山(標高 3,776 m)です。
  • 推論速度: Apple M2 Pro で 35 token/s
  • メモリ使用量: 約 5.8 GB (Q4_0, ctx=2048)

3. 効率化 Tips

項目 低リソース CPU GPU あり
量子化 Q4_0 / Q5_0 Q5_1 / Q8_0
スレッド数 $(nproc) GPU layers で CPU 負荷削減
ビルドオプション make LLAMA_OPENBLAS=1 make LLAMA_METAL=1

まとめ

  • llama.cpp + GGUF軽量・高速・マルチプラットフォーム なローカル推論の有力候補
  • Unsloth 形式モデルは 2 ステップ で簡単に変換可能
  • オフライン環境や PoC にも、7B クラスなら数 GB で運用可能
DXC Lab

Discussion