【OpenAI API】Vision対応LLMの画像トークン消費量計算法 2025年最新版

【OpenAI API】Vision対応LLMの画像トークン消費量計算法 2025年最新版
Photo by Clay Banks / Unsplash

こんにちは!

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%程度のサイズでも十分な品質を保てることを覚えておきましょう。

それでは次回またお会いしましょう!

関連情報

・Google Geminiシリーズの画像トークン消費量計算

Gemini 2.5 Pro/Flashにおけるマルチモーダルトークン(画像のトークン数、動画のトークン数など)計算ガイド
こんにちは! 本日は、Gemini 2.5 ProおよびGemini 2.5 Flashを使用する際、料金計算やコンテキストウィンドウの管理において、トークン数の正確な把握は非常に重要です。本記事では、画像、動画、音声といったマルチモーダルコンテンツのトークン計算方法について詳しく解説します。 基本概念:トークンとは Gemini 2.5シリーズにおいて、1トークンは約4文字に相当し、100トークンは約60-80語(英語)に相当します。すべての入力と出力はトークン単位で処理され、課金もトークン数に基づいて行われます。 Gemini 2.5シリーズのモデルと料金 利用可能なモデル * Gemini 2.5 Pro: 高度な推論能力を持つフラグシップモデル * Gemini 2.5 Flash: コスト効率に優れた高速モデル * Gemini 2.5 Flash Image: 画像生成専用モデル コンテキストウィンドウ 両モデルとも1,000,000トークンの大規模なコンテキストウィンドウを提供します。

・Anthropic Claudeシリーズの画像トークン消費量計算

Claude 4.5 APIにおける画像入力のトークン数計算と最適化ガイド
こんにちは! 今回は、Claude 4.5 sonnet/haiku、Claude 4.1 OpusをAPIからつかうときの画像のトークン数計算方法について詳しく解説します。 画像トークン数の計算方法 Claude 4.5 APIに送信する画像は、テキストと同様にトークンとしてカウントされ、料金計算の基礎となります。画像がAPIのサイズ制限内でリサイズ不要な場合、以下の簡単な計算式でトークン数を推定できます。 基本計算式 トークン数 = (横幅px × 縦幅px) ÷ 750 この計算式を使用することで、アップロード前にコストを予測し、必要に応じて画像を最適化することが可能になります。例えば、1000×1000ピクセルの画像は約1334トークンを消費し、Claude 4.5の料金体系では、画像1枚あたりのコストを事前に計算できます。1092×1092ピクセル(1.19メガピクセル)の画像であれば約1590トークンとなり、これを基準にバッチ処理のコストも見積もることが可能です。 画像サイズの制限と最適化 Claude 4.5 APIには画像サイズに関するいくつかの重要な

Read more

Python と JavaScript で絵文字の文字数が違う!サロゲートペアが引き起こす位置ずれバグの話

Python と JavaScript で絵文字の文字数が違う!サロゲートペアが引き起こす位置ずれバグの話

こんにちは! Qualitegプロダクト開発部です! PII(個人情報)検出のデモアプリを開発していて、検出したエンティティの位置をハイライト表示する機能を実装していました。 バックエンドは Python(FastAPI)、フロントエンドは JavaScript という構成です。 ある日、テストデータにこんなメール文面を使ったところ、ハイライトの位置が途中から微妙にずれるバグに遭遇しました。 鈴木一郎 様 いつもお世話になっております。 サンプル商事の佐藤でございます。 先日の件、確認が取れましたのでご連絡いたします。 お忙しいところ恐縮ですが、ご確認のほど宜しくお願い致します。 💻 #オンラインでのお打ち合わせ、お気軽に声がけください! ―――――――――――――――――――――――――――――― サンプル商事株式会社 営業部 第一課 山田 太郎 (Yamada Taro) 〒100-0001 東京都千代田区千代田1-1-1 サンプルビル 3F tel: 03-1234-5678 https://example.com/contact 検出結果をハイライト表示

By Qualiteg プロダクト開発部
大企業のAIセキュリティを支える基盤技術 - 今こそ理解するActive Directory 第5回 ブラウザ設定と認証

大企業のAIセキュリティを支える基盤技術 - 今こそ理解するActive Directory 第5回 ブラウザ設定と認証

こんにちは、今回はシリーズ第5回「ブラウザ設定と認証」について解説いたします! さて、前回(第4回)では、プロキシサーバーをドメインに参加させることで、ChatGPTやClaudeへのアクセスを「誰が」行ったかを確実に特定する仕組みを解説しました。「信頼の連鎖」の概念や、Windows版Squidなら1時間で構築できる環境、Negotiate/NTLM/Basicという3段階の認証フォールバック機構について理解いただけたかと思います。 しかし、せっかくサーバー側で完璧な統合Windows認証環境を構築しても、ブラウザ側の設定が適切でなければ、ユーザーには毎回パスワード入力ダイアログが表示されてしまいます。 「Edgeだと自動でログインできるのに、Chromeだとパスワードを聞かれる」 「同じサーバーなのにURLの書き方で動作が違う」 これらはヘルプデスクに寄せられる典型的な問い合わせです。(ただ、業務に好きなブラウザ使っていいよ、という企業はそんなに多くはないとおもいます) 今回は、統合Windows認証がブラウザでどのように動作するのか、その仕組みから各ブラウザ(Edge/

By Qualiteg AIセキュリティチーム, Qualiteg コンサルティング
スライドパズルを解くAIから学ぶ、「考える」の正体

スライドパズルを解くAIから学ぶ、「考える」の正体

こんにちは! 「このパズル、AIの教科書に載ってるらしいよ」 子供の頃に遊んだスライドパズル。いや、大人が遊んでも楽しいです。 数字のタイルをカチャカチャ動かして揃えるあれです。実はこのシンプルなパズルが、AI研究の出発点のひとつだったって知ってました? 今回は、このパズルを題材に「AIがどうやって考えているのか」を解き明かしていきます。しかも、ここで使われている手法は、Google Mapsの経路探索からChatGPTまで、現代の様々な技術のベースになっているんです。 まず遊んでみよう 理屈の前に、まずは感覚を思い出してみてください。 最初に shuffle をクリックすると、配置がシャッフルされゲームを開始できます。 ちなみに必ず解くことができるようになっていますが、慣れていないとそれなりに難しいかもしれません。 どうでしょう? 何手でクリアできましたか? クリアできなくても大丈夫です。記事後半で、実際にAIが解いてくれる機能つきゲームも掲載しています^^ 以下は動画です。本ブログで紹介するアルゴリズムで実際にパズルを解く様子をご覧いただけます

By Qualiteg 研究部
楽観的ロック vs 悲観的ロック:実際のトラブルから学ぶ排他制御

楽観的ロック vs 悲観的ロック:実際のトラブルから学ぶ排他制御

こんにちは! Qualitegプロダクト開発部です! 「楽観的ロックを実装したのに、まだ競合エラーが出るんですけど...」 これは私たちが実際に経験したことです。 本記事では、楽観的ロックと悲観的ロックの違いを、実際に発生したトラブルを通じて解説します。 抽象的な説明ではなく、 「なぜそれが必要なのか」「どんな問題を解決できるのか」 を実感できる内容を目指します。 目次 1. 問題の背景:並列処理で謎のエラー 2. ロックなしの世界:なぜ競合が起きるのか 3. 楽観的ロックの導入:期待と現実 4. 楽観的ロックの限界:解決できなかった問題 5. 悲観的ロックによる解決 6. 実装時のハマりポイント 7. どちらを選ぶべきか:判断基準 8. まとめ 1. 問題の背景:並列処理で謎のエラー 1.1 システムの概要 私たちが開発していたのは、 複数のワークスペースを切り替えて使用するAPIサーバー でした。 当社AI関係のプロダクトの一部だったのですが、結合テスト兼負荷テストを実行すると、まれに発生してしまっていました。 ユーザーは複数のワーキン

By Qualiteg プロダクト開発部