ローカルLLMの導入では、モデルファイルを入手できても、読み込みエラー、メモリ不足、CPUだけでの実行、期待と違う回答など、別の層で問題が起こります。これらを一つの「動かない」にまとめると、確認箇所を絞れません。
この記事では、重みと一緒に必要な構成、SafetensorsとGGUFで異なる同梱範囲、推論中のメモリ、実行確認の順序を整理します。最後に、小型GGUFモデルとllama.cppを使い、読み込み・生成・計算環境を分けて確かめます。
対応するショート「ローカルLLMは、重みファイル1個だけでは動かない」では、必要な構成と確認段階を3投稿で短く整理しました。この記事は、形式の比較、メモリの内訳、実行例まで広げて説明します。
まず全体像
重みはモデルの数値であり、実行方法そのものではない
重みは、学習で得た数値を多次元に並べたデータ(テンソル)です。そのテンソルをどの層のどの場所へ割り当てるかは、層数、次元、Attention方式などの設定が決めます。重みだけでは、層をつなぐ計算の流れを組み立てられません。
入力側には、文字列をモデル固有のID列へ変えるトークナイザーが必要です。異なる語彙表や分割規則を使えば、同じ文章でもモデルへ入るID列が変わります。
チャット用モデルでは、会話を所定の順序と特殊トークンへ整形するチャットテンプレートも確認します。
入力形式が違えば、制御トークンがそのまま出たり、会話が続かなかったりします。
これらを実際に計算するのが推論エンジンです。ファイル形式だけでなく、モデルのアーキテクチャと使用するCPU・GPUバックエンドに対応している必要があります。
生成時のtemperature、top-p、最大生成長などは、次のトークンを選ぶ方法を調整します。設定ファイルに既定値が含まれる場合もありますが、モデルの重みやトークナイザーとは役割が違います。
参考:Models — Hugging Face Transformers、Chat templates — Hugging Face Transformers
Safetensors一式とGGUF一ファイルは、同梱範囲が違う
SafetensorsとGGUFは、どちらも重みを扱えますが、同じ単位で配布する形式ではありません。
| 配布の形 | 主に含むもの | 別に確認するもの |
|---|---|---|
| Hugging FaceのリポジトリとSafetensors | Safetensorsはテンソルを安全に保存する。リポジトリには通常、config.json、トークナイザー関連ファイルなども置く |
対応するライブラリ、必要なカスタムコード、チャットテンプレート、生成設定の有無 |
| GGUF | テンソルと、モデル構造やトークナイザーなど推論に必要なメタデータを一ファイルへまとめられる | そのアーキテクチャ、量子化方式、メタデータを解釈できる推論エンジン |
Safetensorsはテンソルの保存形式です。Hugging Face Transformersでは、重みに加えて設定とトークナイザーを同じモデル一式として扱います。
generation_config.jsonのような生成設定が置かれることもありますが、すべてのモデルで必須とは限りません。
GGUFは、単一ファイルでの配布と推論を意識した形式です。ただし、ファイルにメタデータが入っていることと、任意の推論エンジンがそのモデルを実行できることは同じではありません。エンジン側の対応状況を確認します。
参考:Safetensors、GGUF specification、Using Transformers at Hugging Face
量子化しても、必要メモリは重みだけではない
量子化は、主に重みを低いビット数で表し、ファイル容量や重みのメモリ使用量を減らします。しかし、推論中のメモリは次の合計で考えます。
推論中のメモリ = 重み + KVキャッシュ + 計算用バッファなど
KVキャッシュは、自己回帰型Transformerが処理済みトークンのKeyとValueを各層で再利用するための領域です。一般的な動的キャッシュでは、文脈が長くなるほど保持量が増えます。
増え方は、モデルの層構造、キャッシュのデータ型、参照範囲を制限するSliding Window Attentionのような方式、推論エンジンの実装によって変わります。
計算用バッファは、演算の途中結果などを保持します。必要量はエンジン、バックエンド、バッチサイズ、処理条件で変わるため、重みファイルの容量だけから一意に決められません。
CPUへ置く層とGPUへ置く層を分ければ、RAMとVRAMの配分も変わります。VRAMだけを減らせても、RAM使用量やCPU・GPU間の転送が増える場合があるため、配置と速度を一緒に確認します。
参考:KV cache strategies — Hugging Face Transformers、llama.cpp
「動いた」を4段階へ分ける
サーバーの起動や一度の文章生成だけでは、すべての層を確認できません。次の順で分けると、どこまで通ったかを記録できます。
| 段階 | 見るもの | その段階だけでは分からないこと |
|---|---|---|
| 1. 読み込み | 形式とアーキテクチャが認識され、初期化が完了したログ | 入力形式の正しさ、出力品質 |
| 2. 生成 | 固定入力に対し、停止条件まで期待した形式の文字列が返る | 意図したGPUを使ったか、用途に十分な品質か |
| 3. 計算環境 | バックエンド、デバイス名、層の配置、メモリ内訳のログ | 要約やコード生成などの品質 |
| 4. 用途別品質 | 用途を代表する固定入力と、形式・内容・再現性の確認項目 | 別用途や未評価条件での品質 |
たとえば、制御トークンがそのまま出る場合は、モデル能力を疑う前にトークナイザー、チャットテンプレート、停止条件を確認します。
GPUで動かすつもりなのに遅い場合は、デバイス名とオフロード結果をログで確認します。
品質確認では、要約なら残すべき要点と出力形式、コード生成なら実行結果というように、用途ごとの判定条件を用意します。「自然な文章が一度出た」ことを、用途全体の品質保証にはしません。
小型GGUFで最小確認する
実際に、llama.cppのllama-cliと、ggml-orgが公開しているgemma-3-1b-it-GGUFのQ4_K_M量子化を使いました。確認日は2026年8月11日です。
環境はllama.cpp build b8123、コンテキスト長512、モデルの全層をGPUへ配置する指定です。
llama-cli.exeがあるフォルダで、次のコマンドを実行しました。
.\llama-cli.exe `
-hf "ggml-org/gemma-3-1b-it-GGUF:Q4_K_M" `
-st `
-p "Reply with exactly: READY" `
-n 16 `
--temp 0 `
-c 512 `
-ngl all `
--no-display-prompt `
--simple-io
出力は次の一行でした。
READY
起動ログでは、指定したGGUFとモデル構造の読み込みが完了し、VulkanバックエンドのGPU名が表示されました。メモリも、モデル、コンテキスト、計算用の領域に分けて報告されました。
この環境と設定でファイルを読み、短い固定入力へ出力できました。ログ上では、GPUで計算する仕組みであるVulkanバックエンドも使われています。
-ngl allはモデルの全層をGPUへ配置する指定です。指定値だけで判断せず、実際の配置をログで確認します。
この例では-pへ直接文字列を渡したため、チャットテンプレートは確認していません。READYの出力も、読み込みと最小生成の確認に限られます。
日本語対話、要約、コード生成などの品質は、別の固定入力と判定条件で確認します。
モデルとコマンドの詳細は、ggml-org/gemma-3-1b-it-GGUFとllama.cpp CLIを参照してください。
問題を層ごとに切り分ける
症状から断定はできませんが、最初に見る層を決める手掛かりにはなります。
| 症状 | 最初に確認する層 |
|---|---|
| 形式やアーキテクチャが不明という読み込みエラー | ファイルの完全性、モデル構造、エンジンの対応版 |
| 制御トークンが出る、会話の役割が崩れる | トークナイザー、チャットテンプレート、停止条件 |
| 生成はできるが想定より遅い、VRAMを使っていない | CPU・GPUバックエンド、オフロード結果、メモリ配置 |
| 文章は返るが用途の要件を満たさない | 用途別の固定入力、生成設定、モデル選択 |
| APIは応答するがアプリの処理が進まない | APIの入出力、その上のアプリやエージェントの制御 |
モデルは重みと構造を持ち、推論エンジンは計算を実行します。APIは呼び出すための窓口で、エージェントは入力、出力、ツール呼び出しの流れを組み立てます。
上の層が起動しても、下の層の品質まで自動的に保証されません。どの層の成功を確認したのかを分けて記録すると、モデル交換や設定変更の前後も比較できます。
まとめ
ローカルLLMを実行するには、重み、モデル構造の設定、対応するトークナイザーと入力形式、それらを解釈できる推論エンジンが必要です。SafetensorsとGGUFでは同梱範囲が違います。
ファイル数ではなく、必要な構成がそろっているかを確認します。
量子化後も、推論中には重み、KVキャッシュ、計算用バッファがメモリを使います。必要量は、コンテキスト長、キャッシュ方式、バッチサイズ、CPU・GPUへの配置と一緒に見ます。
実行確認は、読み込み、生成、計算環境、用途別品質の順に分けます。どこまで確認したかを明示すれば、「起動した」「文字が返った」「目的に使える」を混同せずに判断できます。