AI業務活用 2026.05.03

ローカルLLM運用で失敗しない|VRAM・トークン数の計算式とPythonスクリプト

タグ:ローカルLLM / VRAM計算 / トークンカウント / GPU運用 / tips

モデルサイズ別の必要VRAM早見表

モデル規模fp16(16bit)int8(8bit)GGUF Q4(4bit)
7B~16GB~8GB~5GB
13B~28GB~14GB~9GB
34B~68GB~34GB~22GB
70B~140GB~70GB~45GB

※推論時のKVキャッシュ(コンテキスト4096)を含む概算値。バッチサイズ1の場合。

VRAM必要量の計算スクリプト

# vram_calculator.py

from dataclasses import dataclass

@dataclass
class ModelVRAMRequirement:
    model_name: str
    params_billions: float
    dtype: str  # "fp16", "int8", "q4"
    context_length: int = 4096
    batch_size: int = 1

BYTES_PER_PARAM = {
    "fp32": 4,
    "fp16": 2,
    "bf16": 2,
    "int8": 1,
    "q4": 0.5,  # 4-bit量子化(実際は4.5〜5bit/param)
    "q5": 0.625,
}

def calculate_vram_gb(req: ModelVRAMRequirement) -> dict:
    # モデルウェイトのサイズ
    params = req.params_billions * 1e9
    bytes_per_param = BYTES_PER_PARAM.get(req.dtype, 2)
    model_size_gb = (params * bytes_per_param) / (1024 ** 3)
    
    # KVキャッシュ(簡易計算:Llama-like アーキテクチャ)
    # 実際はlayers数・head数・head_dimによって変わる
    kv_cache_gb = (
        req.context_length * req.batch_size * 2 *  # K + V
        req.params_billions * 0.01  # 経験的係数
    ) / 1024
    
    # オーバーヘッド(CUDA管理・アクティベーション等)
    overhead_gb = model_size_gb * 0.2
    
    total_gb = model_size_gb + kv_cache_gb + overhead_gb
    
    return {
        "model_weights_gb": round(model_size_gb, 1),
        "kv_cache_gb": round(kv_cache_gb, 2),
        "overhead_gb": round(overhead_gb, 1),
        "total_required_gb": round(total_gb, 1),
        "fits_in": {
            "RTX 3060 (12GB)": total_gb <= 12,
            "RTX 3090 (24GB)": total_gb <= 24,
            "RTX 4090 (24GB)": total_gb <= 24,
            "A100 (40GB)": total_gb <= 40,
            "A100 (80GB)": total_gb <= 80,
        }
    }

# 使用例
models_to_check = [
    ModelVRAMRequirement("Llama-3-7B-fp16", 7, "fp16", context_length=8192),
    ModelVRAMRequirement("Llama-3-7B-Q4", 7, "q4", context_length=8192),
    ModelVRAMRequirement("Llama-3-70B-Q4", 70, "q4", context_length=4096),
]

for req in models_to_check:
    result = calculate_vram_gb(req)
    print(f"\n{req.model_name} (ctx={req.context_length})")
    print(f"  必要VRAM: {result['total_required_gb']} GB")
    print(f"  内訳: ウェイト {result['model_weights_gb']}GB + KVキャッシュ {result['kv_cache_gb']}GB + オーバーヘッド {result['overhead_gb']}GB")
    
    fits = [name for name, ok in result['fits_in'].items() if ok]
    print(f"  動作するGPU: {', '.join(fits) if fits else 'なし(マルチGPU必要)'}")

APIリクエスト前のトークン事前カウント

# token_counter.py
# pip install tiktoken anthropic

import tiktoken
import anthropic
import os

def count_tokens_openai(text: str, model: str = "gpt-4o") -> int:
    """OpenAI系モデルのトークン数を事前カウント"""
    enc = tiktoken.encoding_for_model(model)
    return len(enc.encode(text))

def count_tokens_claude(text: str) -> int:
    """Claudeのトークン数を正確にカウント(APIが必要)"""
    client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
    
    # count_tokens APIを使用(無料・リクエストが軽い)
    response = client.messages.count_tokens(
        model="claude-sonnet-4-5",
        messages=[{"role": "user", "content": text}]
    )
    return response.input_tokens

def safe_truncate(text: str, max_tokens: int, model: str = "gpt-4o") -> str:
    """コンテキスト上限を超えないようにテキストを切り詰める"""
    enc = tiktoken.encoding_for_model(model)
    tokens = enc.encode(text)
    
    if len(tokens) <= max_tokens:
        return text
    
    # 上限内に切り詰めて戻す
    truncated_tokens = tokens[:max_tokens]
    truncated_text = enc.decode(truncated_tokens)
    print(f"⚠️ テキストを {len(tokens)}{max_tokens} トークンに切り詰めました")
    return truncated_text

# 使用例
long_doc = "あいう" * 10000  # 長いテキスト

token_count = count_tokens_openai(long_doc)
print(f"推定トークン数: {token_count:,}")

# GPT-4oのコンテキスト上限(128K)に合わせて切り詰め
safe_text = safe_truncate(long_doc, max_tokens=100_000)

Ollamaでのローカル実行

# Ollamaのインストール(Mac)
brew install ollama

# 推論用にOllamaサービスを起動
ollama serve

# モデルをダウンロードして実行(別ターミナルで)
ollama pull llama3.2:7b      # 7B fp16 ~4.7GB (Q4量子化済み)
ollama pull llama3.2:70b-q4  # 70B Q4 ~40GB

# APIサーバーとして使う(OpenAI互換)
# curl http://localhost:11434/v1/chat/completions でアクセス可能
# ollama_api.py - OpenAI SDKでOllamaに接続
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:11434/v1",
    api_key="ollama"  # 任意の文字列でOK
)

def local_llm_chat(prompt: str, model: str = "llama3.2:7b") -> str:
    response = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        max_tokens=512,
    )
    return response.choices[0].message.content

# 実行
result = local_llm_chat("Pythonのリスト内包表記を説明してください")
print(result)

GPU別の現実的な選択肢(2026年)

VRAM 6〜8GB(RTX 3070/4060等):
  → 7Bモデル(Q4量子化)で基本的な用途
  → コンテキスト長: 4096が安全、8192は厳しい

VRAM 12GB(RTX 3060/4070等):
  → 7B fp16 or 13B Q4
  → ほぼ全ての7Bモデルがスムーズに動く

VRAM 24GB(RTX 3090/4090等):
  → 13B fp16 or 34B Q4
  → 開発・研究用途のゴールデンスタンダード

VRAM 48GB以上(A6000/Mac Pro等):
  → 70B Q4、または13B fp16 × バッチ処理
  → 本格的なローカル推論サーバー向け

あわせて読みたい

参考ソース