
サーバーレスAI APIでバッチ処理を最適化する
キュー駆動でべき等なサーバーレスAIパイプラインを、適切なバッチサイズ・並列上限・チェックポイント・リトライで構築し、スループット向上とコスト削減を実現します。
AIジョブが即時の回答を必要としないなら、バッチ処理の方が良い選択になることが多いです。 私ならこれを使ってAPIコストを約**50%**削減し、バックグラウンド処理をライブトラフィックから切り離し、大量のテキスト・画像・音声・動画のワークロードを、すべてを1つのサーバーレス関数に詰め込むことなく処理します。
要点はこうです。
-
私なら1つの長時間実行関数の代わりに、キュー、ステートレスワーカー、オブジェクトストレージを使います。
-
多くのLLMジョブではバッチあたり100〜500アイテムから始め、メディア中心の処理ではバッチサイズを縮小します。
-
関数内の並列度をワーカーあたり約5〜10リクエストに制限し、リクエスト数だけでなく毎分トークン数を監視します。
-
10〜50アイテムごとのチェックポイント、3〜5回のリトライ、指数バックオフ、そしてデッドレターキューを追加します。
-
各アイテムを
job_id:item_idのような安定したキーでべき等にし、決定論的な出力パスを使います。 -
**毎分アイテム数、バッチ時間、リトライ率、エラー率、バッチあたりコスト(USD)**を追跡します。
-
新しいジョブは、スケールする前に10〜50アイテムのパイロットでテストします。
主なアイデアはシンプルです。バッチAIパイプラインは、まず制限を軸に設計したときに最もうまく機能します。サーバーレスのタイムアウト、メモリ上限、ペイロード制限、プロバイダーのスロットリングはすべて、バッチサイズ、ファンアウト、リトライ、ストレージパターンを左右します。
マルチモデルのワークフローでは、私はAPIレイヤーもシンプルに保ちます。APIMartのような統一サービスは、1つのパイプラインがテキスト・画像・動画タスクのために500以上のモデルへルーティングする必要があり、各ワーカーにベンダーごとのロジックを持たせたくない場合に役立ちます。
最も重要なのは生の速度ではありません。それはスループット、リトライの安全性、そして実行ごとのコスト管理です。
サーバーレスAI推論:スケーラブルでコスト効率の高いモデルサービングを解説 | Uplatz

スケーラブルなサーバーレスバッチパイプラインの設計方法
これらの制限は、キュー駆動のセットアップへとあなたを導きます。
コアパイプラインのコンポーネントとデータフロー
スケーラブルなバッチパイプラインには4つの要素があります。プロデューサー、耐久性のあるメッセージキュー、ワーカープール、そして結果ストアです。
基本的なフローはこうです。プロデューサーが大きなペイロードをオブジェクトストレージにアップロードし、軽量なジョブをキューに置きます。ワーカーはそのジョブを取り出し、ペイロードを取得し、AI APIを呼び出し、結果を保存してから、初めてメッセージを確認応答(ack)します。この最後のステップが重要です。ワーカーがジョブの途中でクラッシュした場合、確認応答されていないメッセージが再び現れるので、別のワーカーがリトライできます [6][7]。
ジョブが大きすぎて関数のタイムアウト内に完了できない場合は、データセットをより小さなバッチに分割し、長時間稼働するオーケストレーターを通じて並列ワーカーへ作業をファンアウトします。
このベースフローが機能したら、次のステップはモダリティとランタイムでジョブをルーティングすることです。
モダリティごとにワークフローを分割すべきとき
ペイロードサイズや処理時間が意味のある形で変化する場合は、別々のキューを使います。すべてのAIタスクが同じワーカープールに存在すべきではありません。テキスト分類はアイテムあたり数秒かもしれません。重いメディアジョブは数分かかることもあります。両方を1つのプールに入れると、タイムアウトの挙動がすぐに厄介になります [4][7]。
より良いアプローチは、ファイルタイプだけでなく、ランタイムとペイロードサイズでキューを分割することです。イベントタイプでジョブをルーティングします。たとえば、PDF、画像、音声、動画を、イベントフィルターを使って別々のキューとワーカープールに送ります。これによりリトライが分離され、あるワークロードが別のワークロードを詰まらせるのを防ぎます [8]。
統一AI APIレイヤーとしてのAPIMartの活用

1つのパイプラインがテキスト・画像・動画タスクを処理する場合、別々のベンダー統合をやりくりすることは、メンテナンスの頭痛の種になりかねません [2][6]。APIMartは、GPT-5やClaudeのような言語モデル、画像モデル、そしてSoraやKling V3のような動画モデルを含む、500以上のAIモデルに対して1つのAPIを提供します。
つまり、ワーカー関数は異なるジョブタイプ間でステートレスかつ一貫した状態を保てます。認証、レート制限、リトライロジックのすべてが1つの統合ポイントの背後に置かれるため、パイプラインの各段階で異なるモデルが必要な場合にも役立ちます。
| コンポーネント | パイプラインでの役割 |
|---|---|
| 入力キュー | ジョブをバッファリングし、取り込みと処理を分離する |
| 統一APIレイヤー | 単一の認証とマルチモデルオーケストレーションのポイント |
| ワーカー | ステートレスで水平スケール可能なAI API呼び出し元 |
| 結果ストア | 出力を永続化し、べき等性チェックを可能にする |
| デッドレターキュー | 最大リトライ後に失敗したジョブを手動レビュー用に捕捉する |
適切なバッチサイズと並列モデルの選び方

パイプラインアーキテクチャが決まったら、次の判断は理論上はシンプルですが、実際には失敗しやすいものです。各ワーカーは一度にどれだけの作業を扱うべきか、そして何個のリクエストを並列で実行すべきか?
バッチが小さすぎると、オーバーヘッドに計算リソースを浪費します。大きすぎると、リトライが遅れて多くの作業をやり直すため、失敗のコストが高くつきます。最適点はたいてい、ランタイム、メモリ使用量、リトライコストのバランスから生まれます。
バッチサイズをランタイム・メモリ・リトライとバランスさせる
ほとんどのLLMワークロードでは、バッチあたり100〜500アイテムが堅実な開始レンジです。オーケストレーションのオーバーヘッドをより多くの作業に分散できるほど大きく、それでいて失敗しても巨大なチャンクをやり直さずに済むほど小さいサイズです。
リトライを考えるとイメージしやすくなります。ワーカーが巨大なバッチの終盤近くでクラッシュすると、その作業をすべてやり直す羽目になるかもしれません。だからこそ、10〜50件の完了ごとにチェックポイントを取り、クラッシュしてもごく一部の作業だけをやり直せるようにするのが有効です [2][11]。
メディア中心のジョブは、各レスポンスが大きいため、通常テキストのみのジョブよりも小さなバッチが必要です [1]。
不均一なワークロードには動的バッチングを使う
固定バッチサイズは紙の上ではきれいに見えます。本番環境では、しばしば破綻します。
トラフィックは変化します。夜間の一括実行は毎分数千アイテムを押し込むかもしれませんが、日中のトラフィックはゆっくりと来るかもしれません。1つの固定バッチサイズでは、両方のケースにうまく対応できません。
動的バッチングは、次のいずれかが起きたときにバッチを送信することでこれに対処します。
-
バッチが設定サイズに達する
-
設定した待機ウィンドウが期限切れになる
一般的なセットアップは、最大バッチサイズに加えて、5秒のような最大待機時間を組み合わせるものです [9][1]。混雑した時間帯には、サイズ上限が何度も繰り返しヒットし、スループットが高く保たれます。閑散とした時間帯には、タイマーが発動し、アイテムがキューに滞留したままにならないようにします。
複数のアイテムを1つのプロンプトに詰め込み、システムプロンプトのオーバーヘッドをより多くの作業に分散させることもできます [10]。
各関数内でAPI呼び出しを並列に実行する
バッチサイズが決まったら、次のステップは各関数内での並列呼び出しを制御することです。
遅延のほとんどは通常、ローカルの計算ではなく、ネットワークレスポンスの待機から生じます。そのため、非同期の並列処理がしばしば適切です。複数のリクエストを一度に送信し、待機はイベントループに任せます。
重要なのは上限です。セマフォを使って関数内の並列度を制限します。5〜10の同時リクエストのプールが妥当な出発点です [9][11]。これより大幅に上げると、プロバイダーのレート制限に引っかかるかもしれません。
LLM APIでは、主な制限はしばしば生のリクエスト数ではなく毎分トークン数です。したがって、ローリングする60秒ウィンドウでトークン使用量を追跡し、プロバイダーが先にやる前に自分でスロットリングします [10]。このガードレールが重要なのは、そうしないと1つのワーカーがメモリを食い尽くしたり、パイプライン全体のスロットリングを引き起こしたりしかねないからです。
リトライコストを膨らませずにスループット目標を達成できる、最もシンプルなセットアップを使いましょう。
| 戦略 | スループット | 信頼性 | レイテンシ | リトライコスト |
|---|---|---|---|---|
| 小さなバッチ(1〜10アイテム) | 低 | 高 | 低 | 低 |
| 中程度のバッチ(100〜500アイテム) | 高 | 中 | 中 | 中 |
| 大きなバッチ(1,000以上のアイテム) | 非常に高 | 低 | 高 | 高 |
| マネージドバッチAPI | 最大 | 高 | 非常に高(24h) | 低(マネージド) |
バッチワークフローを大規模でも信頼性が高く観測可能に保つ方法
バッチサイズと並列度を正しく設定することは、仕事の半分に過ぎません。ボリュームが増えるにつれ、より難しいのは、問題が発生したときにジョブを安全に保ち、問題を素早く見つけ出すことです。
すべてを再処理せずに部分的な失敗を扱う
1つの不良レコードがバッチ全体を潰すようなことは決してあってはなりません。 1つの入力が不正だったり、1つのリクエストがタイムアウトしたりしても、その失敗は封じ込められたままであるべきです。
実際には、各アイテムの処理ロジックには独自のエラーハンドリングが必要です。各チャンクの後にアトミックなチェックポイントを書き込み、最初からやり直すのではなく最後のチェックポイントから再開します。アイテムが3〜5回のリトライの後でもまだ失敗する場合は、永遠にリトライし続ける代わりに、手動レビュー用のデッドレターキュー(DLQ)に送ります。各リトライの前に指数バックオフを使います。たとえば、1秒待ち、次に2秒、次に4秒と待って、レート制限のかかったAPIエンドポイントを叩き続けないようにします [12][1][13]。
リカバリが安全になったら、それがどのくらいの頻度で起き、どれだけコストがかかるかを追跡します。
すべてのバッチジョブをべき等にする
リトライが安全なのは、繰り返し実行しても同じ結果が得られる場合だけです。
これはサーバーレスプラットフォームではさらに重要です。そこでは一時的なエラーがしばしば自動リトライを引き起こします。べき等性がなければ、それらのリトライは重複書き込みやその他の繰り返される副作用につながりかねません。
修正はシンプルです。ランタイムのタイムスタンプを使う代わりに、job_id:item_idのような安定したべき等キーを構築します [14][15]。次にアップサートを使い、アイテムを再処理すると2つ目のレコードを作るのではなく既存のレコードを置き換えるようにします。S3のようなファイルベースのストレージでは、作業アイテムのパラメータに結び付けた決定論的な出力パスを使い、再実行が重複を作るのではなく同じ出力を上書きするようにします [2][13]。
また、キューの可視性タイムアウトを、想定されるp99処理時間の少なくとも3倍に設定すべきです。これにより、2つ目のワーカーが1つ目のワーカーでまだ実行中のジョブを掴んでしまうのを防ぎます [2][13]。
バッチあたりのスループット・レイテンシ・コストを追跡する
負荷がかかっても依然としてバッチングが理にかなっているかを示すメトリクスが必要です。バッチレベルでは、次を追跡します。
成功率が**95%**を下回ったらアラートを設定します [1]。
失敗したアイテムのみをリトライします。スキップ&ログは、重要でないエンリッチメントジョブにのみ使います。
本番ワークロードのコスト削減とパフォーマンス改善の方法
主なコストドライバーを特定する
コストを削減する前に、お金がどこに行っているのかを見る必要があります。
サーバーレスAIバッチパイプラインでは、AI APIのトークン使用量が通常最大の出費です。バッチモードは2つの面で役立ちます。トークン支出を削減し、リクエストのオーバーヘッドを下げます。実際には、バッチAPIは同期呼び出しに比べて約50%低いトークンコストを提供します [5][18]。
トークンの次に、サーバーレスの計算時間がしばしば次の大きなドライバーになります。特にGPUランタイムで課金される動画や画像のジョブでそうです [17]。ストレージとデータ転送も、あなたに忍び寄ってくることがあります。大きなファイルをリージョンをまたいで移動していると、その料金はすぐに積み上がります。そして、リスクの高いワークフローでは、確信度の低い出力に対する人間によるレビューが、それだけで主要なコストセンターになりかねません [16]。
コストパターンはモダリティによっても変わります。テキストワークロードはトークンベースなので、通常は予測しやすいです。動画生成は仕組みが異なります。出力の秒単位で課金されるため、クリップの長さが支出に直接影響します。10秒のクリップは、単純に5秒のものよりコストがかかります。だからこそ、ここでは実行のチューニングが非常に重要になります。
メモリ・タイムアウト・パッケージサイズ・書き込みパターンをチューニングする
最良の節約の多くは、派手なトリックではなく、素朴な実行チューニングから生まれます。
クライアントのタイムアウトを60秒以上に設定します。大きなバッチを一度にメモリに読み込む代わりに、JSONLの入力と出力をストリーミングします。この1つの変更だけで、メモリ圧迫を減らし、バッチジョブを壊れにくくできます。量子化はVRAMがボトルネックのときにのみ使います [5][18]。
これらは小さな調整ですが、ジョブ自体を変えることなく無駄を削れます。
メモリ使用量とI/Oがまずまずの状態になったら、次の大きなレバーはモデル選択です。
モデル選択とバッチ戦略をビジネス目標に合わせる
最大のコストレバーは、ジョブに適したモデルを選ぶことです。
GPT-5やClaude Opusのようなフロンティアモデルは、複雑な推論には理にかなっています。しかし、分類や抽出では、それらはオーバースペックになりかねません。より軽量なモデルで十分なことが多いです。多くのパイプラインでは、約80%のタスクに軽量モデルを使い、残りの**20%に重量級モデルを取っておくことで、平均コストを70%から90%**削減できます [18][19]。
シンプルな分割がしばしばうまく機能します。
-
抽出と分類には軽量モデルを使う
-
重量級モデルは推論のために取っておく
-
タスクの複雑さに応じてバッチサイズをスケールする
異なるジョブタイプを異なるモデルにルーティングする必要がある場合、APIMartは500以上のモデルにわたる単一のAPIを提供します。
スケールする前に、10〜50アイテムのパイロットを実行してアイテムあたりのコストを測定します。これにより、ボリュームが急増する前に、各ジョブにどのくらいのコストがかかりそうかをきれいに読み取れます。
結論:バッチAIワークフローを改善する最もシンプルな方法
パイプライン、バッチサイズ、信頼性チェック、コストガードレールが決まれば、スケールするのはずっとシンプルになります。ファンアウト並列処理、適切なサイズのバッチ、そして厳格なリトライ処理が、遅い逐次ジョブを本番で実行できるものへと変える主なレバーです。
失敗を封じ込めましょう。リトライをべき等にしましょう。期待される結果を実際の出力と照合しましょう。それこそが、何かが壊れたときにシステムが横道に逸れるのを防ぐ部分です。その後は、通常コストが次の限界になります。
支出をバッチ実行あたりのUSDで追跡し、コストを各ジョブに結び付けて、高コストな外れ値を見つけられるようにします [2]。新しいワークロードは10〜50アイテムのパイロットから始め、アイテムあたりのコストを検証し、計算が合ってからスケールします [1][3]。
ほとんどのタスクでは、より小さなモデルが重い負担を担うべきです。より大きなモデルは、より複雑な生成作業のために取っておきましょう。そして、1つのバッチパイプラインが複数のモダリティとモデルタイプにまたがって実行される場合、APIMartのような単一レイヤーが、1つのAPIを通じてルーティングをシンプルに保てます。その組み合わせこそが、本番規模でバッチAIワークフローをより予測可能にするものです。
FAQ
リアルタイムのAI呼び出しの代わりに、いつバッチ処理を使うべきですか?
ユーザーのクリティカルパス上になく、数分から数時間まで待てる作業にはバッチ処理を使います。
次のようなオフラインジョブに適しています。
-
大規模なデータエンリッチメント
-
ドキュメント分析
-
ベクトルインデックスの作成
-
スケジュールされたレポート作成
リアルタイムエンドポイントは、インタラクティブなチャットやライブQ&Aのように、誰かが反対側で実際に待っているときにのみ使います。
自分のワークロードに適したバッチサイズはどう選べばよいですか?
アプリケーションレベルのバッチングでは、50〜100アイテムから始めます。多くの場合、最適点は100〜500の間に落ち着きます。プロバイダーネイティブのバッチAPIを使っているなら、はるかに大きくできます。1つのバッチで最大50,000リクエストになることもあります。
目標は、効率と失敗の分離との間で良いトレードオフを与えるバッチサイズを見つけることです。リトライが高くつきすぎない程度に小さく、それでいてオーケストレーションのオーバーヘッドを削れる程度に大きくしたいのです。
動的推論では、VRAMの制限とレイテンシ目標に基づいてバッチサイズをチューニングします。
リトライ中の重複処理を防ぐにはどうすればよいですか?
パイプラインをべき等にして、同じアイテムを再度処理しても毎回同じ結果になるようにします。
安定した不変のべき等キーを使います。作業を実行する前に、そのキーがすでに要求済みまたは処理済みかどうかを確認します。次にアップサートとユニーク制約を使って、重複書き込みを防ぎます。
処理済みのドキュメントIDのレジストリを保持しておくのも役立ちます。それにより、リトライや再開実行の際に、すでに完了したアイテムをスキップするシンプルな方法が得られます。
モデルマーケットで使いたいモデルを選ぶ
APIMart のモデルマーケットでチャット、画像、動画モデルを試し、統一 API でモデルの能力をすばやく体験できます。