Aikの技術日記

技術的な進捗とか成果とかを細々と投稿するブログです。時々雑記も。

OpenAI APIのGPT-4oで画像入力リクエストを試してみた

はじめに

こんにちは、筆者です。

つい先日、界隈で話題沸騰の「GPT-4o」を触ってみるべく…まずは環境構築方法からまとめました: aik0aaat.hatenadiary.jp

そして今回は、いよいよ本題の「API経由のGPT-4oモデルの使い方」をまとめていこうかと!

執筆当時だと、ChatGPT経由のGPT-4oは無料ユーザーはもちろん、有料ユーザー(Plus)でさえもレート制限が掛かっていますが…。
以前APIを調べてみた感想としては、API経由の方がずっとお安く使えるなという印象でしたので。

技術力あって少しでも安く使いたいとお考えの場合、API経由で使うのはいい選択肢の様に思えます。
(というか筆者自身、そう考えてAPI経由にしようと思いましたので…)

また、余談にも記載しましたが…。
API経由で画像を入力すれば、学習データにも使われない様ですしね。
学習データに使われるのを忌避したい時にも使えるでしょう…。

前置きが長くなりましたが…本題へいきましょう٩( ‘ω’ )و
※各情報は執筆当時(2024/05)のものとなります。

GPT4-oを使う条件

まずはGPT4-oを使う条件から。
GPT4-oをAPI経由で使う場合、有料ユーザーへ加入する必要はありませんが…。
代わりにOpenAI APIで$5以上の支払いをしないと使用できない様になっています。

5 ドル以上の支払い(使用レベル 1)が完了すると、OpenAI API を介してGPT-4、GPT-4 Turbo、および GPT-4oモデルにアクセスできるようになります。
https://help.openai.com/en/articles/7102672-how-can-i-access-gpt-4-gpt-4-turbo-and-gpt-4o

なので、前回の記事で紹介した支払い方法の登録から、「Add to credit balance」で$5を課金しましょう。
課金してしまえば、この金額を使い切らずともGPT4-oを使えます。

課金後、APIキーを$OPENAI_API_KEYの部分に入れ、ターミナルから以下を叩いて:

curl https://api.openai.com/v1/models \
  -H "Authorization: Bearer $OPENAI_API_KEY"

レスポンス内部に以下の様にgpt-4oが入っていればOKです。

{
    "id": "gpt-4o",
    "object": "model",
    "created": 1715367049,
    "owned_by": "system"
}

GPT4-oの使い方

ここからは「GPT4-oの使い方」を掘り下げて見ていこうと思います。
APIで言うと「Chat」をクローズアップする形ですね。

  • エンドポイント: https://api.openai.com/v1/chat/completions
  • HTTPメソッド: POST

全てのAPIリクエストオブジェクト/レスポンスオブジェクトについては、
TypeScriptのInterfaceとしてまとめた形で以下Gistで貼っておきます…が:

長いので折り畳み

…折角なので「マルチモーダルで会話してみる」というユースケースを元に、
具体的なリクエスト方法をまとめていこうかと。

※GPT4-oモデルは「マルチモーダル」を謳っていますが、
執筆当時現在は、公式Docsには画像を送付する方法しか記載ありません。
このため、当記事では「画像をリクエストする」という点のみにフォーカスします。

画像と一緒にGPT4-oを使ってみる

画像を送付するには、messagesプロパティを以下の様に指定すればOKです:

"messages": [
  {
    "role": "user",
    "content": [
      {
        "type": "text",
        "text": "What'\''s in this image?"
      },
      {
        "type": "image_url",
        "image_url": {
          "url": "[画像URL]"
        }
      },
    ]
  }
],

※参考公式記事

送付可能な画像の拡張子はpng, jpg, gif, webpで、
画像送付の方法は「URL形式」のみです。
urlへ、WikipediaやX等に投稿された画像を指定して送付する形ですね。

なお、urlBase64エンコードして画像をData URI化しても送付可能です。
ネット上に上がってない画像を送付したいなら、こちらでやっても良いでしょう。
※以下の記事を参考にさせていただきました: qiita.com

※なお筆者が同一プロンプト&同一画像で検証してみた所、
「URL指定時」と、「Base64エンコードのData URI化指定時」どちらでも、消費されるトークンはほぼ変わりありませんでした。

画質の指定

以下の様にdetailを指定する事で、GPT-4oに渡す画像の解像度を指定可能です。

{
  "type": "image_url",
  "image_url": {
    "url": "https://example.com/image.png",
    "detail": "low"
  }
},

指定できる値は以下の通り:

  • low: 画像の低解像度(512px x 512px)verを受け取り、85トークンで画像を認識
    • トークン量節約 & API応答の高速化が見込める
  • high: 最初にモデルが低解像度の画像を確認し、入力画像のサイズに基づいて入力画像の詳細な切り抜きを作成して検証
  • auto: デフォルト

highについては公式Docsを引用したのですが、正直よく意味がわからなかったので…。
highモードとlowモードで、画像認識の精度を確かめてみました。

  • 入力メッセージ(system): あなたは一般的な感性を持つ人間です。
  • 入力メッセージ(user):
添付する画像にはどの様なものが描写されているのかを述べてください。
また、画像を見た時の第一印象を教えてください。
直感的な感想の方が好ましいです。
  • 入力画像(自作オリキャライラストです、縦736px × 横597px - 182KB):

"自作のオリジナルキャライラスト"

  • high:(使用トークン数:1002(入力:844/出力:158))
この画像には、アニメ風のキャラクターが描かれています。
キャラクターは短い銀髪で、黒いヘアバンドを着けており、ヘアバンドには花の飾りが付いています。
キャラクターは青い服を着ており、手には花を持っています。背景は抽象的で、黒と白のコントラストが強調されています。

第一印象としては、キャラクターの表情が少し寂しげで、全体的に落ち着いた雰囲気が感じられます。
色使いや背景のデザインが独特で、アート的な印象を受けます。
  • low:(使用トークン数:338(入力:164/出力:174))
この画像には、アニメ風のキャラクターが描かれています。
キャラクターは短い白髪で、頭に花の飾りをつけています。手には花を持っており、背景は抽象的で、黒と白のコントラストが強調されています。
キャラクターの表情は穏やかで、少し物憂げな雰囲気を感じさせます。

第一印象としては、非常に美しいアートスタイルで、キャラクターの繊細さと優雅さが強く伝わってきます。
背景のコントラストがキャラクターを際立たせ、全体的に幻想的で夢幻的な雰囲気を醸し出しています。

highだと使用トークン量が爆増(164→844)していることが分かります…。
出力される内容の精度は上がってそうですが、このためにトークンを数倍跳ね上げるかと言われると微妙な様な…。
もう少し画像サイズを変えれば違った結果が得れるかもしれませんがね。

ともあれ、トークン量を極力削減したいならlowを指定してみるのは良さそうですね。
(元々の画像が512px以下なら不要ですが)

GPT4-oのレート制限について

ここまでGPt4-oの使い方を見てきましたが、ここからはGPT4-oの利用制限について見ていきましょう。
執筆当時だと、ChatGPT経由のGPT-4oは以下の様な制約がある様ですが…(公式記事):

  • 無料ユーザー: 制限あり
    • 筆者が試した際は、画像添付のメッセージ含め10回(画像あり:3回)程度で制限かかりました
  • 有料(Plus)ユーザー: 最大80件メッセージ/3h
    • ピーク時間帯だと下がる可能性あり
    • チームワークスペースユーザーだと更に向上
    • ※料金: $20
  • 有料(Enterprise)ユーザー: 無制限
    • ※料金: $25/1人、2人以上の加入必須

API経由では、OpenAI APIへ課金してきた金額に応じて「Tier」と言うものが付与され…。
Tierによって、使用可能なレート制限が変わってきます。
※高Tier(=たくさん課金している)であるほどレート制限は緩いです。

Tier表とその条件について以下表に:

Tier 条件 Usase Limits
Tier1 $5課金 $100/月
Tier2 $50課金 かつ 最初の支払いから7日経過 $500/月
Tier3 $100課金 かつ 最初の支払いから7日経過 $1,000/月
Tier4 $250課金 かつ 最初の支払いから14日経過 $5,000/月
Tier5 $1000課金 かつ 最初の支払いから30日経過 $15,000/月

GPT4-oのレート制限について、表にまとめてみました:

Tier RPM RPD TPM TPD IPM Batchキュー制限
Tier1 500 - 30000 - - 90000
Tier2 5000 - 450000 - - 1350000
Tier3 5000 - 600000 - - 40000000
Tier4 10000 - 800000 - - 80000000
Tier5 10000 - 10000000 - - 1500000000

※用語の解説:

  • Usase Limits:
    • OpenAI APIへ毎月幾らまで課金できるかを示します
  • RPM, RPD…について:
    • RPM: 1あたりのリクエス
    • RPD: 1あたりのリクエス
    • TPM: 1あたりのトーク
    • TPD: 1あたりのトーク
    • IPM: 1あたりの画像
    • Batchキュー制限: Batch APIを使用した際にキューへ詰めれる上限量

※上記制限は、1ユーザーではなく「1組織」に掛かります。Tierもユーザー単位でなく、組織単位で掛かります。

全体的に、やはりChatGPTよりAPIの方がレート制限は低い様に思えます。
大体は「1分あたり」の制限量ですからね…。
ChatGPTだと15分待たないといけなかったりしますが、APIではその辺のストレスはグッと低くなりそうです。

個人的にはIPMの値が気になりますが…公式記事にはまだ記載がない様です。

ちなみに、後どれくらいでレート制限に引っ掛かるかはOpenAIのLimitsページでも見れますが…。
以下のHTTPヘッダーを参照する事でも確認可能です:

  • x-ratelimit-limit-requests: 数値型
    • 残りリクエスト最大数
  • x-ratelimit-limit-tokens: 数値型
  • x-ratelimit-remaining-requests: 数値型
  • x-ratelimit-remaining-tokens: 数値型
  • x-ratelimit-reset-requests: 文字列型、例:1s
    • リクエスト数のレート制限がリセットされるまでの時間
  • x-ratelimit-reset-tokens: 文字列型、例:6m0s
    • トークン数のレート制限がリセットされるまでの時間

※注意:
レート制限については日々細かく調整が入っています。
当記事では執筆当時(2024/05)現在の情報を記載しますので、最新の情報を知りたい場合は公式記事を参照ください。

おわりに

今回はOpenAI APIの中でも「GPT4-o」の使い方にフォーカスし、詳細な使い方やリクエスト/レスポンス値、レート制限についてまとめてみました。

全体的な感想として、ChatGPTよりはAPI経由の方がリーズナブルに使えるなと言う印象です。
最低でも$5支払えば、GPT4-oにアクセス出来る様になる上…。
使った分だけしかお金は出ていかないので、毎月課金よりはかなりローコストになるんじゃないかと。

代償に、ある程度の技術力は要しますけどね…。
あと流石に毎回curlAPIを叩くのは利便性も悪いので、本格的に使いたいならシステム化は必須でしょう。

システム化等の労力をかけるか、ChatGPT経由で気軽に使える様にしたいかは人それぞれでしょうが…。
私は折角なので、前者を取ってみようかと思います。

もしシステム化したとして、そのサンプルコードは公開しないでしょうが…。
今回の記事、並びにGistが同じくシステム化を検討している方への参考になれば幸いです。

それでは|д゚*)

余談:API経由で渡した画像は学習データに使われる?

画像を生成AIに渡すとなると、「渡したデータは学習データに使われるんじゃないか?」と言うのが気になる人も多いと思います。
特に商用のイラストや、ラフ段階の未公開イラストなんかを投げるとしたら気をつけたい所でしょう…。

ただ、OpenAI側はAPI経由のデータは学習データに使わないと声明を出してくれています。

当社のプラットフォームの他の部分と同様に、OpenAI API に渡されるデータとファイルは、明示的にトレーニングにオプトインすることを選択しない限り、モデルのトレーニングに使用されることはありません。
当社のデータ保持とコンプライアンス基準の詳細については、こちらをご覧ください。
https://help.openai.com/en/articles/7102672-how-can-i-access-gpt-4-gpt-4-turbo-and-gpt-4o#h_746ed54009


OpenAI モデルのトレーニングにはどのようなデータソースが使用されますか?
OpenAI は、公開ソース、ライセンスを受けたサードパーティのデータ、人間のレビュー担当者が作成した情報など、さまざまな場所からのデータを使用します。
個人向けの ChatGPT および DALL·E のバージョンのデータも使用します。
ChatGPT チーム、ChatGPT Enterprise、および API プラットフォーム (2023年3月1日以降) からのデータは、モデルのトレーニングには使用されません。
https://openai.com/enterprise-privacy/

学習データに使われる事を回避するためにも、API経由で使うのはいい選択肢かもです。

あとよくよく記載を見ると、「Plusユーザーのものは使わない」とは記載してないので…。
有料ユーザーであっても、Plusの段階だと使われてしまう(はず)なのは要注意ですね。

余談:Batchで更にお得に使える

ちょくちょく当記事でも触れてましたが…。
GPT4-oを使う際、「Chat」API以外にも「Batch」APIを使う選択肢があります。

Batch APIのメリデメは以下の通り:

  • メリット👍:
    • 料金が50% OFF
    • 1分当たりのレート制限に縛られない
      • 代わりにBatchキュー制限がありますが、Chat APIよりも制限は大幅に緩いです
  • デメリット👎:
    • 非同期処理(リクエスト後直ぐに結果がわからない)
    • 実行完了まで最大24h掛かる

総じて「直ぐに結果が欲しい、やりながらベースでプロンプトを改善していく」には不向きですが…。
直ぐに結果が欲しいのではないなら、使ってみる余地はあるかと。

使い方は以下を参照に: https://platform.openai.com/docs/guides/batch/rate-limits

ざっくりとした処理の流れとしては以下になる様です:

  1. .jsonl形式で入力用のファイルを作成
  2. File APIで入力用ファイルアップロード、ファイルID取得
  3. ファイルIDを元にBatch APIでバッチ生成
  4. API経由でバッチステータスを確認し、完了しているかどうかチェック(ポーリング形式)
  5. 完了時のファイルIDを元に、File APIで出力ファイルをダウンロード

余談:File API経由でGPT4-oへ画像をアップロードできるか

今回GPT4-oへ画像をアップロードする際、こちらの公式記事を参考にしましたが…。
ここには、画像URLで指定する以外に「OpenAI FileAPI」を使って画像をアップロードする方法が示唆されてました:

"messages": [
  {
    "role": "user",
    "content": [
      {
        "type": "text",
        "text": "What'\''s in this image?"
      },
      // 「URL形式」
      {
        "type": "image_url",
        "image_url": {
          "url": "[画像URL]"
        }
      },
      // 「OpenAI FileAPI」
      {
          "type": "image_file",
          "image_file": {
            "file_id": "[File ID]"
          }
      },
    ]
  }
],

FileAPIで一度画像をアップロードしてから、返却値のidを指定して送付…という形式の様です。

アップロード対象のファイルは512MB以下、1組織(≒1ユーザー)全体でアップロード可能な容量は100GBと、制限はありますが…。
Base64エンコードが出来ない環境下なら、一考の余地はあるかな〜と思って検証してみましたが…。

執筆当時の環境だと、file_id形式でのアップロードは許可されてなかったですorz。
まぁ参考にした公式記事はAssistantsに関する記事でしたからね…そりゃそうですわな。

副産物として、FileAPIの詳細をまとめあげてしまったので…。
TypeScriptのInterfaceとしてまとめた形でGistに貼っておきます:

長いので折り畳み