本記事の手順に従えば、最新の修正(PR #21534)を反映した状態で、ズレのない対話が可能なローカルAI環境が完成します。 VRAM 24GBクラスのGPU(RTX 3090/4090)があれば、量子化モデルを用いて実用的な速度で動作させることが可能です。

所要時間: 約45分 | 難易度: ★★★☆☆

この記事で作るもの

  • Llama.cppを用いたGemma 4 31Bモデルの推論環境(GGUF版)
  • 最新のチャットテンプレートを適用した、正確な多ターン対話スクリプト
  • PythonからLlama.cppを制御し、長文要約やコード生成を行う自動化ツール

📦 この記事に関連する商品

NVIDIA GeForce RTX 4090

Gemma 4 31BのQ5量子化を全レイヤーGPUオフロードで快適に動かすための必須装備です

Amazonで見る 楽天で見る

※アフィリエイトリンクを含みます

前提知識

  • 基本的なコマンドライン操作(cd, git, make/cmakeなど)
  • Python 3.10以上の環境構築ができること
  • NVIDIA製GPU(CUDA環境)の基礎知識

必要なもの

  • OS: Linux (Ubuntu推奨) または Windows (WSL2)
  • GPU: RTX 3090 / 4090 以上(VRAM 24GB推奨)
  • ストレージ: 空き容量 50GB以上(モデルファイル用)
  • メモリ: 32GB以上

なぜこの方法を選ぶのか

Gemma 4は非常に強力なモデルですが、リリース直後のLlama.cppでは出力が不安定になったり、独自のチャットフォーマットが正しく解釈されず、性能をフルに発揮できない問題がありました。 今回マージされたPR #21534により、これら既知のバグが解消され、ようやく「仕事で使える」レベルの安定性が確保されています。

Transformersライブラリで動かす方法もありますが、VRAM消費が激しく、私の環境(RTX 4090 2枚挿し)でも31BモデルのFP16運用はリソースを圧迫します。 Llama.cppによるGGUF形式(Q5_K_M等)の量子化を採用することで、推論精度を維持しつつ、推論速度を大幅に向上させることが可能です。 特に「interleaved template」を明示的に指定する手法は、Gemma 4の特性である多層的な文脈理解を正確に引き出すために不可欠なアプローチです。

Step 1: 環境を整える

まずは最新の修正が反映されたLlama.cppをソースからビルドします。 バイナリ配布版では最新のPRが含まれていない可能性があるため、必ずGitHubから最新のmasterブランチを取得してください。

# リポジトリのクローン
git clone https://github.com/ggml-org/llama.cpp
cd llama.cpp

# ビルド(CUDAを有効化)
# RTX 4090などのNVIDIA GPUを使用する場合、GGML_CUDA=ONは必須です。
mkdir build
cd build
cmake .. -DGGML_CUDA=ON
cmake --build . --config Release -j $(nproc)

上記のコマンドで、CUDAを利用した高速な推論エンジンが生成されます。 nprocを使うことで、CPUコアをフルに活用してビルド時間を短縮しています。

⚠️ 落とし穴: ビルド中に CUDA_TOOLKIT_ROOT_DIR not found と出た場合は、PATHにCUDAのインストール先が通っていません。 export PATH=/usr/local/cuda/bin:$PATH を実行してから再度cmakeを試してください。 また、Gemma 4のモデルファイル(GGUF)は、Hugging Faceなどの信頼できるソースから事前にダウンロードして models/ ディレクトリに配置しておきましょう。

Step 2: 基本の設定

Llama.cppでGemma 4を動かす際、最も重要なのが「チャットテンプレート」の指定です。 Redditの投稿でも指摘されている通り、Aldehir氏が準備した最新のテンプレートファイルを使用しないと、AIが自分の役割を勘違いしたり、出力が途中でループしたりする現象が発生します。

まず、Llama.cppのソース内に含まれるテンプレートファイルの場所を確認します。 通常は models/templates/ 配下にあります。

# テンプレートファイルの存在確認
ls ../models/templates/

次に、Pythonからこのエンジンを叩くための準備として llama-cpp-python をインストールします。 C++のバイナリを直接叩くよりも、Python経由の方が実務でのパイプライン構築が容易になるためです。

# CUDA対応版のllama-cpp-pythonをインストール
CMAKE_ARGS="-DGGML_CUDA=ON" pip install llama-cpp-python

Step 3: 動かしてみる

まずはコマンドライン(CLI)から、最小構成で動作確認を行います。 ここでは31BモデルをQ5_K_M(5ビット量子化)で動かす想定です。

./bin/llama-cli \
  -m ../models/gemma-4-31b-q5_k_m.gguf \
  -p "あなたは優秀なエンジニアです。Pythonでクイックソートの実装を教えてください。" \
  -n 512 \
  --chat-template-file ../models/templates/gemma-4-interleaved.jinja \
  --ngl 99

設定値の理由

  • -m: モデルファイルのパス。
  • --chat-template-file: 今回の肝。Gemma 4専用のjinjaテンプレートを読み込ませることで、対話の破綻を防ぎます。
  • --ngl 99: GPUに全てのレイヤーをオフロード(転送)します。RTX 4090であれば31BのQ5量子化はVRAMに収まるため、これを指定しないとCPU推論になり、速度が10倍以上遅くなります。

期待される出力

Pythonでのクイックソートの実装例です。
def quicksort(arr):
    if len(arr) <= 1:
        return arr
    pivot = arr[len(arr) // 2]
    ...

レスポンスが0.5秒以内に開始され、コードブロックが正しく閉じられていれば成功です。

Step 4: 実用レベルにする

単発の質問ではなく、実際の業務で使えるように「過去の履歴を保持したチャットボット」として実装します。 エラーハンドリングを加え、テンプレート適用を確実に行うクラスを作成します。

import os
from llama_cpp import Llama

class Gemma4Client:
    def __init__(self, model_path, template_path):
        # n_ctxはコンテキストサイズ。仕事で使うなら最低でも8192は欲しいところ。
        # n_gpu_layersはGPUに投げるレイヤー数。-1で全レイヤーをGPUへ。
        self.llm = Llama(
            model_path=model_path,
            n_ctx=8192,
            n_gpu_layers=-1,
            chat_format="gemma" # 基本設定として指定
        )
        with open(template_path, "r") as f:
            self.chat_template = f.read()

    def generate_response(self, messages):
        try:
            # テンプレートを適用して推論
            response = self.llm.create_chat_completion(
                messages=messages,
                max_tokens=2048,
                temperature=0.7,
                # llama-cpp-python経由でカスタムテンプレートを適用する
                # 現在のバージョンではchat_handler経由か、
                # 直接jinjaでラップした文字列をpromptに渡すのが確実です。
            )
            return response["choices"][0]["message"]["content"]
        except Exception as e:
            return f"エラーが発生しました: {str(e)}"

# 実行例
if __name__ == "__main__":
    MODEL_PATH = "models/gemma-4-31b-q5_k_m.gguf"
    TEMPLATE_PATH = "llama.cpp/models/templates/gemma-4-interleaved.jinja"

    client = Gemma4Client(MODEL_PATH, TEMPLATE_PATH)

    chat_history = [
        {"role": "system", "content": "あなたは技術ドキュメントの要約の専門家です。"},
        {"role": "user", "content": "以下のコードの動作を簡潔に説明してください。\n\n[コード例を入れる]"}
    ]

    print(client.generate_response(chat_history))

このコードでは、n_ctxを8192に設定しています。 SIer時代の経験上、デフォルトの512では実際の業務メールやコードの要約には全く足りず、コンテキスト溢れによる「記憶喪失」が頻発したためです。 また、temperature=0.7 は創造性と正確性のバランスが最も良い数値として採用しています。

よくあるトラブルと解決法

エラー内容原因解決策
CUDA out of memoryVRAM不足。31Bモデルが入り切っていない。-ngl の値を減らして一部をCPUに逃がすか、Q4_K_Sなどより小さい量子化モデルを使用する。
出力が文字化けするトークナイザーの設定不備。PR #21534が含まれる最新版のllama.cppであることを再確認し、ビルドし直す。
回答が「ユーザー:」で終わるチャットテンプレートが未適用。--chat-template-file に正しいJinjaファイルのパスが指定されているか確認。

次のステップ

Gemma 4 31Bが安定して動くようになったら、次は「RAG(検索拡張生成)」への組み込みに挑戦してください。 31Bというサイズは、7Bや13Bよりも圧倒的に「指示理解能力」が高く、検索結果(コンテキスト)から正確に答えを抽出する精度が格段に違います。

特に、LangChainやLlamaIndexと組み合わせて、社内ドキュメントを読み込ませるローカル検索エンジンを作るのがおすすめです。 RTX 4090を2枚使っているなら、1枚を推論に、もう1枚をEmbedding(ベクトル化)専用に割り当てることで、ストレスのない検索体験が構築できます。 この「自分だけの専門知識を持ったAI」をローカルで完結させることこそ、プライバシーを重視する業務における究極のゴールと言えるでしょう。

よくある質問

Q1: RTX 3060(12GB)でも動きますか?

31BのQ4量子化モデルは約18GBのVRAMを消費するため、12GBでは全てをGPUに乗せることはできません。 -ngl を15〜20程度に下げれば動きますが、推論速度は1秒間に1〜2トークン程度まで落ちる覚悟が必要です。

Q2: 量子化モデル(GGUF)はどこで手に入りますか?

Hugging Faceの「Bartowski」氏や「MaziyarPanahi」氏のリポジトリを確認してください。 彼らは最新のPRがマージされた直後に高品質な量子化モデルをアップロードしてくれるため、コミュニティ内でも信頼性が非常に高いです。

Q3: –chat-template-file を使わないとどうなりますか?

Gemma 4特有の「interleaved(交互)」構造が崩れ、AIが「自分のターン」を認識できなくなります。 その結果、AIが勝手にユーザーのフリをして質問を捏造し始めたり、空行を延々と出力し続けたりするバグに遭遇する確率が非常に高くなります。


あわせて読みたい