【OpenAI API】Vision対応LLMの画像トークン消費量計算法 2025年最新版
こんにちは!
OpenAIのVision対応(つまり画像も入力できるLLM)モデルは、画像をトークンに変換する際に2つの異なる計算方式を採用しています。
最新のGPT-5系列やGPT-4.1系列では、従来のタイル方式とは異なるパッチベース方式が導入されました。この変更により、画像処理の効率性が大幅に向上し、より細かな制御が可能になっています。
2つの計算方式の違い
OpenAIは現在、パッチベース方式とタイルベース方式という2つの計算方法を並行して運用しています。
パッチベース方式は、GPT-4.1-mini、GPT-4.1-nano、GPT-5-mini、GPT-5-nano、o4-miniといった新世代モデルで採用されています。この方式では画像を32×32ピクセルという非常に小さなパッチに分割します。従来のタイル方式が512×512ピクセルだったことを考えると、約256分の1のサイズで処理することになり、より精密な画像理解が可能になりました。
一方、GPT-4o、GPT-4.1、GPT-5、o1、o3などの主力モデルは引き続きタイルベース方式を採用しています。こちらは512×512ピクセルのタイルに分割し、処理前に画像を適切にリサイズすることで効率的な処理を実現しています。
モデル別トークン計算表
パッチベース方式(32×32ピクセル)
| モデル | 乗数 | 最大パッチ数 | 1024×1024画像のトークン数 |
|---|---|---|---|
| GPT-5-mini | 1.62 | 1536 | 1,659 |
| GPT-5-nano | 2.46 | 1536 | 2,519 |
| GPT-4.1-mini | 1.62 | 1536 | 1,659 |
| GPT-4.1-nano | 2.46 | 1536 | 2,519 |
| o4-mini | 1.72 | 1536 | 1,761 |
タイルベース方式(512×512ピクセル)
| モデル | ベーストークン | タイルあたりトークン | 低解像度トークン | 1024×1024画像のトークン数(高解像度) |
|---|---|---|---|---|
| GPT-5 | 70 | 140 | 70 | 630 |
| GPT-4o | 85 | 170 | 85 | 765 |
| GPT-4.1 | 85 | 170 | 85 | 765 |
| GPT-4.5 | 85 | 170 | 85 | 765 |
| GPT-4o-mini | 2,833 | 5,667 | 2,833 | 25,501 |
| o1 | 75 | 150 | 75 | 675 |
| o1-pro | 75 | 150 | 75 | 675 |
| o3 | 75 | 150 | 75 | 675 |
| computer-use-preview | 65 | 129 | 65 | 581 |
| GPT Image 1 | 65 | 129 | 65 | 323 + 追加トークン* |
*GPT Image 1の高忠実度モードでは、正方形画像に4,160トークン、縦長/横長画像に6,240トークンが追加されます。
パッチベース方式の詳細
パッチベース方式では、まず画像を32×32ピクセルのパッチでカバーするのに必要な数を計算します。例えば、1024×1024の画像であれば、32×32のパッチが1024個必要になります。
ただし、パッチ数には1536という上限が設定されています。これを超える大きな画像の場合、自動的にスケールダウンが行われます。スケーリング係数は画像全体が1536パッチ以内に収まるように計算され、アスペクト比を保ちながら縮小されます。
最終的なトークン数は、パッチ数にモデル固有の乗数を掛けて算出されます。GPT-5-miniやGPT-4.1-miniは1.62倍、GPT-5-nanoやGPT-4.1-nanoは2.46倍、o4-miniは1.72倍という乗数が適用されます。この乗数の違いは、各モデルの内部アーキテクチャの違いを反映しています。
パッチベース計算の実装例
import math
def calculate_patch_tokens(width, height, model="gpt-4.1-mini"):
"""パッチベース方式のトークン計算"""
multipliers = {
"gpt-5-mini": 1.62,
"gpt-5-nano": 2.46,
"gpt-4.1-mini": 1.62,
"gpt-4.1-nano": 2.46,
"o4-mini": 1.72
}
# 必要なパッチ数を計算(32×32ピクセル単位)
raw_patches = math.ceil(width / 32) * math.ceil(height / 32)
# 1536パッチを超える場合はリサイズ
if raw_patches > 1536:
# スケーリング係数を計算
r = math.sqrt(32 * 32 * 1536 / (width * height))
# パッチ境界に合わせて調整
width_scale = math.floor(width * r / 32) / (width * r / 32)
height_scale = math.floor(height * r / 32) / (height * r / 32)
r = r * min(width_scale, height_scale)
resized_width = width * r
resized_height = height * r
# リサイズ後のパッチ数
final_patches = math.ceil(resized_width / 32) * math.ceil(resized_height / 32)
else:
final_patches = raw_patches
# 最大1536パッチに制限し、モデル固有の乗数を適用
final_patches = min(final_patches, 1536)
return int(final_patches * multipliers.get(model, 1.62))
タイルベース方式の詳細
タイルベース方式は、より複雑な多段階処理を行います。
高解像度モード(detail="high")では、まず画像を2048×2048ピクセルの正方形に収まるようにリサイズします。次に、画像の短辺が768ピクセル(GPT Image 1の場合は512ピクセル)になるように再度リサイズを行います。この2段階のリサイズにより、様々なアスペクト比の画像を効率的に処理できるようになっています。
リサイズ後の画像は512×512ピクセルのタイルに分割され、必要なタイル数が計算されます。最終的なトークン数は、ベーストークンとタイル数×タイルあたりのトークン数の合計となります。
低解像度モード(detail="low")を選択した場合、リサイズやタイル分割は行われず、モデルごとに定められた固定のトークン数が使用されます。GPT-4oなら85トークン、GPT-4o-miniなら2833トークンといった具合です。
タイルベース計算の実装例
import math
def calculate_tile_tokens(width, height, detail="high", model="gpt-4o"):
"""タイルベース方式のトークン計算"""
model_config = {
"gpt-5": {"base": 70, "tile": 140, "min_side": 768},
"gpt-4o": {"base": 85, "tile": 170, "min_side": 768},
"gpt-4o-mini": {"base": 2833, "tile": 5667, "min_side": 768},
"o1": {"base": 75, "tile": 150, "min_side": 768},
"gpt-image-1": {"base": 65, "tile": 129, "min_side": 512}
}
config = model_config.get(model, model_config["gpt-4o"])
# 低解像度モードは固定値
if detail == "low":
return config["base"]
# ステップ1: 2048×2048に収める
if max(width, height) > 2048:
scale = 2048 / max(width, height)
width = int(width * scale)
height = int(height * scale)
# ステップ2: 短辺を目標サイズに調整
scale = config["min_side"] / min(width, height)
width = int(width * scale)
height = int(height * scale)
# ステップ3: 512×512タイルの数を計算
tiles = math.ceil(width / 512) * math.ceil(height / 512)
# 総トークン数 = ベース + (タイル数 × タイルあたりトークン)
return config["base"] + (tiles * config["tile"])
画像サイズ最適化でコストを削減
巨大な画像をそのまま送信すると、トークン消費量が急増してコストがかかります。特に問題となるのが、パディングによる無駄なトークン消費です。例えば、513×513ピクセルの画像は、タイルベース方式では2×2の4タイルとして処理されますが、実際には各タイルの大部分が空白となり、非効率的です。
パッチベース方式では32の倍数、タイルベース方式では512の倍数に近いサイズに調整することで、パディングを最小限に抑えることができます。また、画像の内容に応じて適切な解像度を選択することも重要です。文字認識が不要な画像なら、思い切って小さくリサイズしても問題ない場合が多いのです。
効率的なサイズへの最適化コード
from PIL import Image
def optimize_image_size(image_path, model_type="tile", max_dimension=2048):
"""
画像をパディングが最小になる効率的なサイズに最適化
Parameters:
- image_path: 画像ファイルのパス
- model_type: "patch" (32の倍数) または "tile" (512の倍数)
- max_dimension: 最大サイズ制限
"""
img = Image.open(image_path)
width, height = img.size
# モデルタイプに応じた基本単位
unit = 32 if model_type == "patch" else 512
# 現在のサイズが最大値を超える場合は先に縮小
if max(width, height) > max_dimension:
scale = max_dimension / max(width, height)
width = int(width * scale)
height = int(height * scale)
# 最適なサイズを計算(パディングを最小化)
def find_optimal_size(size, unit):
# 現在のサイズに最も近い単位の倍数を見つける
lower = (size // unit) * unit
upper = lower + unit
# パディングが少ない方を選択
if size - lower < upper - size:
return lower if lower > 0 else upper
else:
return upper
optimal_width = find_optimal_size(width, unit)
optimal_height = find_optimal_size(height, unit)
# リサイズ実行
optimized_img = img.resize((optimal_width, optimal_height), Image.LANCZOS)
# トークン数を計算して表示
if model_type == "patch":
patches = (optimal_width // 32) * (optimal_height // 32)
estimated_tokens = int(patches * 1.62) # GPT-4.1-miniの場合
print(f"最適化後: {optimal_width}x{optimal_height} ({patches}パッチ, 約{estimated_tokens}トークン)")
else:
tiles = (optimal_width // 512) * (optimal_height // 512)
estimated_tokens = 85 + tiles * 170 # GPT-4oの場合
print(f"最適化後: {optimal_width}x{optimal_height} ({tiles}タイル, 約{estimated_tokens}トークン)")
return optimized_img
# 使用例
# optimized = optimize_image_size("large_photo.jpg", model_type="tile")
# optimized.save("optimized_photo.jpg")
様々なサイズでの計算例
| 画像サイズ | GPT-4o (タイル) | GPT-4.1-mini (パッチ) | GPT-5 (タイル) | o4-mini (パッチ) |
|---|---|---|---|---|
| 512×512 | 255トークン | 413トークン | 210トークン | 439トークン |
| 768×768 | 425トークン | 930トークン | 350トークン | 989トークン |
| 1024×1024 | 765トークン | 1,659トークン | 630トークン | 1,761トークン |
| 2048×2048 | 1,445トークン | 2,490トークン* | 1,190トークン | 2,635トークン* |
| 4096×4096 | 1,445トークン | 2,490トークン* | 1,190トークン | 2,635トークン* |
*1536パッチの上限によりリサイズされた後の値
最適化のポイント
モデル選択は用途によって使い分けることが重要です。OCRやテキスト認識にはGPT-4.1、高速な分析にはGPT-4o-mini、詳細な画像理解にはGPT-5、コスト重視ならGPT-4.1-nanoといった具合です。
画像サイズの最適化は特に重要です。例えば、3000×4000ピクセルの写真を処理する場合、そのまま送信するとタイルベースでは約2500トークン消費しますが、2048×1536にリサイズすれば1445トークンで済みます。さらに1536×1024にすれば935トークンまで削減できます。多くの用途では、この程度のリサイズは品質にほとんど影響しません。
また、最初は低解像度モードで処理し、必要に応じて高解像度で再処理するという段階的アプローチも有効です。これにより、多くの場合でコストを大幅に削減できます。
コスト効率の良い画像サイズの目安
タイルベース方式を使う場合、以下のサイズが効率的です。512×512(1タイル)、1024×512(2タイル)、1024×1024(4タイル)、1536×1024(6タイル)といった具合に、512の倍数に合わせることで無駄なパディングを避けられます。
パッチベース方式では、32の倍数が効率的です。例えば、960×960、1280×960、1920×1080といったサイズは、パッチ境界にぴったり収まるため、無駄がありません。特に1920×1080は一般的な画像サイズでもあり、そのまま処理できるメリットがあります。
制限事項と注意点
APIには以下の制限があります。ファイルサイズは最大50MB、1リクエストあたり最大500枚の画像、対応フォーマットはPNG、JPEG、WEBP、非アニメーションGIFです。
モデルには苦手な分野もあります。医療画像の解釈、非ラテン文字のテキスト認識、小さすぎる文字の読み取り、回転した画像の理解、精密な空間認識などは精度が低下する可能性があります。
まとめ
OpenAIのVision APIを効率的に利用するには、モデルの特性を理解し、適切な画像サイズに最適化することが不可欠です。パッチベース方式では32の倍数、タイルベース方式では512の倍数にサイズを調整することで、パディングによる無駄を最小限に抑えられます。
巨大な画像をそのまま送信するのではなく、用途に応じた適切なサイズにリサイズすることで、コストを大幅に削減できます。多くの場合、元画像の50-70%程度のサイズでも十分な品質を保てることを覚えておきましょう。
それでは次回またお会いしましょう!
