📝
ローカル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 段階 の変換が必要です。
-
Unsloth → Hugging Face 形式 への変換
pip install unsloth python convert_unsloth_to_hf.py \ --input_dir ./unsloth_model \ --output_dir ./hf_model
-
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 で運用可能
Discussion