OpenAI API で 409 エラーが返される場合、リクエストの内容がサーバー上のリソースの現在の状態と競合しています。通常、既に進行中の操作や重複したリソースが原因となります。

よくある原因

Fine-tuningジョブの重複実行

同じトレーニングデータやモデルに対して、既に実行中のFine-tuningジョブがあるのに、さらに同じ設定で新しいジョブを作成しようとするとこのエラーが発生します。OpenAI API はアカウント内で同時に実行できるFine-tuningジョブの数に制限があり、また同一のトレーニングデータセットに対して並行実行できないためです。

ファイルのアップロード競合

Files API を使用してトレーニングファイルをアップロードする際に、既にアップロード中や処理中のファイルIDに対して再度アップロードリクエストを送信すると競合が発生します。同じファイルIDに複数のアップロード操作が並行実行されようとするとき、この409エラーが返されます。

モデルカスタマイズの状態競合

Fine-tuning済みモデルに対して、訓練完了前にさらに別のFine-tuningジョブを開始しようとした場合、リソースの状態競合として扱われることがあります。

解決手順

ステップ1:実行中のFine-tuningジョブを確認する

まず現在実行中のジョブを一覧表示して、重複するジョブがないか確認します。

# 実行中のFine-tuningジョブを一覧表示
curl https://api.openai.com/v1/fine_tuning/jobs \
  -H "Authorization: Bearer $OPENAI_API_KEY"

レスポンスを確認して、対象のトレーニングデータと同じ設定のジョブが既に running または queued 状態で存在していないか確認します。

ステップ2:完了済みジョブの確認とクリーンアップ

既に完了したジョブが大量に残っていないか確認し、必要に応じて確認します。

# 特定のジョブの詳細情報を確認
curl https://api.openai.com/v1/fine_tuning/jobs/<job-id> \
  -H "Authorization: Bearer $OPENAI_API_KEY"

ステータスが succeededfailed であれば、新しいジョブは作成できます。running の場合は完了まで待機する必要があります。

ステップ3:ファイルのアップロード状態を確認する

Files API でアップロード済みファイルの状態を確認します。

# アップロード済みファイル一覧を取得
curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY"
# 特定のファイル情報を確認
curl https://api.openai.com/v1/files/<file-id> \
  -H "Authorization: Bearer $OPENAI_API_KEY"

ファイルのステータスが processed になっていることを確認してから、Fine-tuningジョブを再度作成します。

ステップ4:新しいFine-tuningジョブを作成する

競合するジョブがないことを確認した後、新しいジョブを作成します。

curl https://api.openai.com/v1/fine_tuning/jobs \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o-mini-2024-07-18",
    "training_file": "<file-id>",
    "validation_file": "<validation-file-id>",
    "hyperparameters": {
      "epochs": 3
    }
  }'

それでも解決しない場合

レート制限に達している可能性があります。OpenAI API ダッシュボード(https://platform.openai.com/account/billing/limits)でアカウントの利用状況と制限内容を確認してください。

また、複数の環境やスクリプトから同時にAPIリクエストを送信していないか確認します。特にCIパイプラインやバッチ処理では、リトライロジックを実装する際に遅延(exponential backoff)を追加してください。

# Pythonでのリトライ例
import time
import openai

max_retries = 5
for attempt in range(max_retries):
    try:
        response = openai.FineTuning.create(
            model="gpt-4o-mini-2024-07-18",
            training_file="<file-id>"
        )
        break
    except openai.error.APIError as e:
        if e.http_status == 409:
            wait_time = 2 ** attempt  # 指数バックオフ
            print(f"競合エラー。{wait_time}秒後に再試行します")
            time.sleep(wait_time)
        else:
            raise

さらに問題が解決しない場合は、OpenAI サポート(https://help.openai.com)に具体的なジョブIDを含めて問い合わせてください。


免責事項:本記事の内容は、執筆時点の公開情報をもとに作成したものです。ソフトウェアの仕様は予告なく変更されることがあります。最新の情報は各ツールの公式サポートページをご確認ください。本記事の情報を利用した結果生じたいかなる損害についても、著者および運営者は責任を負いかねます。