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

この記事で作るもの

  • Gemma 4 31B (GGUF版) をローカル環境で動かし、対話精度を最大化させるPythonスクリプト
  • 前提知識:Pythonの基本的な文法、ターミナルでのコマンド操作
  • 必要なもの:16GB以上のVRAMを持つGPU(RTX 3090/4090推奨)、または大容量RAMを積んだMac/PC

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

ASUS RTX 4090

Gemma 4 31Bを高速かつ1枚のGPUで余裕を持って動作させるための必須装備です

Amazonで見る 楽天で見る

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

なぜこの方法を選ぶのか

ローカルLLMの世界では、モデルの「賢さ」と同じくらい「チャットテンプレートの正確さ」が重要です。 先日公開されたGemma 4系のGGUFファイルでは、このテンプレートに不備があり、モデルが本来の性能を発揮できず、返答が途中でループしたり、不自然な終了タグが出力される問題がありました。 Redditの r/LocalLLaMA でも話題になった通り、bartowski氏らによってこのテンプレート問題が修正された最新版GGUFが公開されています。

他にもOllamaなどで手軽に動かす方法はありますが、あえて llama-cpp-python を使うのは、実務でのシステム組み込みや、細かい推論パラメータ(GPUレイヤーの割り当て、コンテキスト長の設定など)を直接制御できるためです。 私の経験上、PoCから本番環境への移行を考えるなら、抽象度の高すぎるツールより、こうした低レイヤーを叩けるライブラリに慣れておく方が、最終的なトラブルシューティング時間を50%以上削減できます。

Step 1: 環境を整える

まずは最新の llama-cpp-python をインストールします。 CUDA環境(NVIDIA GPU)を使っている場合は、必ずGPU支援を有効にするコンパイルオプションを付けてください。

# CUDA環境の場合(RTX 4090等)
CMAKE_ARGS="-DGGML_CUDA=on" pip install llama-cpp-python huggingface_hub

# Mac (Apple Silicon) の場合
CMAKE_ARGS="-DGGML_METAL=on" pip install llama-cpp-python huggingface_hub

llama-cpp-python は頻繁にアップデートされますが、Gemma 4のような新しいモデルのメタデータを正しく読み込むには、執筆時点での最新版(0.3.2以上推奨)が必要です。 huggingface_hub は、ブラウザを使わずにコマンドラインからモデルを高速にダウンロードするために使用します。

⚠️ 落とし穴: 単に pip install llama-cpp-python とすると、GPUが認識されずCPU推論になり、1トークンの生成に数秒かかる地獄を味わうことになります。 インストールのログに CUDA_LIBnvcc のパスが表示されているか、必ず確認してください。

Step 2: 修正版モデルのダウンロード

次に、bartowski氏が公開している修正済みのGGUFファイルをダウンロードします。 今回はバランスの良い「Q4_K_M」クオンタイズ(量子化)版を使用します。

from huggingface_hub import hf_hub_download

# 修正済みGGUFモデルをダウンロード
model_path = hf_hub_download(
    repo_id="bartowski/google_gemma-4-31B-it-GGUF",
    filename="google_gemma-4-31B-it-Q4_K_M.gguf",
    local_dir="./models"
)

print(f"Model downloaded to: {model_path}")

このリポジトリを選ぶ理由は明確です。 公式の初期変換では欠落していた chat_template メタデータが正しく埋め込まれており、Python側で手動でタグ(<start_of_turn> 等)を管理する手間が省けるからです。 31BモデルをQ4_K_Mで運用する場合、VRAMは約18GB〜20GB程度消費します。RTX 3090/4090なら1枚で完結します。

Step 3: 動かしてみる

いよいよ推論コードを書きます。 ここで重要なのは、chat_handler を使わずに、最新の llama-cpp-python が持つ自動テンプレート適用機能を活用することです。

import os
from llama_cpp import Llama

# モデルの初期化
llm = Llama(
    model_path="./models/google_gemma-4-31B-it-Q4_K_M.gguf",
    n_gpu_layers=-1, # すべてのレイヤーをGPUにオフロード(4090使用時)
    n_ctx=4096,      # コンテキスト長(用途に合わせて調整)
    verbose=False
)

# チャット形式での推論
response = llm.create_chat_completion(
    messages=[
        {"role": "system", "content": "あなたは優秀なエンジニアです。"},
        {"role": "user", "content": "Pythonで高速な非同期処理を書くコツを3つ教えて。"}
    ],
    temperature=0.7,
    max_tokens=500
)

print(response["choices"][0]["message"]["content"])

期待される出力

1. asyncioのイベントループをブロックしないこと。
2. aiohttpなどの非同期ライブラリを適切に活用すること。
3. CPU負荷の高い処理はrun_in_executorで別プロセスに逃がすこと。
...

n_gpu_layers=-1 を指定することで、VRAMの許す限り全ての計算をGPUで行います。 これにより、RTX 4090環境であれば、31Bモデルでも秒間40〜50トークン程度の爆速レスポンスが得られるはずです。

Step 4: 実用レベルにする

実務で使う場合、ストリーミング出力(一文字ずつ表示される形式)は必須です。 また、例外処理を加えて、GPUのメモリ不足(OOM)などでプロセスが死なないようにガードを固めます。

def ask_gemma(prompt: str):
    try:
        stream = llm.create_chat_completion(
            messages=[{"role": "user", "content": prompt}],
            stream=True
        )

        full_response = ""
        for chunk in stream:
            if "content" in chunk["choices"][0]["delta"]:
                token = chunk["choices"][0]["delta"]["content"]
                print(token, end="", flush=True)
                full_response += token

        return full_response

    except MemoryError:
        print("GPU VRAM不足です。コンテキスト長を短くするか、量子化率を上げてください。")
    except Exception as e:
        print(f"予期せぬエラー: {e}")

# 実戦投入
ask_gemma("複雑なSQLクエリを最適化するためのチェックリストを作って。")

このようにストリーミングにすることで、ユーザーの体感待ち時間をほぼゼロにできます。 私はこの構成をローカルのナレッジベース検索(RAG)の回答生成エンジンとして活用していますが、Gemma 4 31Bの論理的思考能力は、以前の27Bモデルと比較しても明らかに向上していると感じます。

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

エラー内容原因解決策
NoneType object is not subscriptableテンプレートが不正で終了タグが認識されていない本記事で紹介した bartowski 版の最新GGUFに差し替える
llama_model_load: error loading modelllama-cpp-pythonのバージョンが古いpip install -U llama-cpp-python で更新する
推論が極端に遅いGPUにレイヤーが載っていないn_gpu_layers を1以上に設定し、ログで CUDA が使われているか確認

次のステップ

この記事で「正しく動くGemma 4」を手に入れた後は、このモデルをAPI化して既存のワークフローに組み込むことを検討してください。 例えば、fastapi を使って簡易的なエンドポイントを作成すれば、社内の他のツールからローカルLLMを呼び出せるようになります。

また、31BというサイズはRAG(検索拡張生成)において非常に強力な力を発揮します。 LangChainやLlamaIndexと組み合わせて、自分のPCにある大量のPDFやMarkdownドキュメントを読み込ませ、この「修正済みGemma 4」に質問してみてください。 テンプレートが修正されたことで、引用元の明示や情報の構造化が格段に安定していることに気づくはずです。 自宅サーバーに4090を2枚挿している私としては、このモデルを2枚のGPUに分割してロードし、コンテキスト長を32kまで伸ばして運用するのが最近のブームです。

よくある質問

Q1: 31Bモデルを動かすのに32GBのRAMしかありませんが大丈夫ですか?

システムRAMが32GBあれば、Q4_K_M量子化ならCPU推論で動かすことは可能です。ただし、生成速度は1秒間に1〜2トークン程度になるため、実用性を求めるなら最低でもVRAM 24GBのGPUを用意するか、Macのユニファイドメモリを活用することをお勧めします。

Q2: 古いGGUFファイルを使っているのですが、テンプレートだけ後付けで直せますか?

技術的には可能ですが、推奨しません。llama-cpp-pythonchat_format 引数でJinja2テンプレートを直接指定できますが、モデルファイル(GGUF)自体のメタデータを最新に更新した方が、将来的な互換性やコードの可搬性が高まります。

Q3: 以前のGemma 2と比べて、Gemma 4は何が違いますか?

私の実体験ベースでは、特に「指示への忠実度」と「日本語の自然さ」が改善されています。以前は英語が混じったり、システムプロンプトを無視することが稀にありましたが、今回の修正済みモデルではその頻度が激減しています。実務でのタスク実行には31Bが最適なバランスです。


あわせて読みたい