AI

バッチ推論とは?ジョブ分割・並列度と再実行設計を実装目線で解説

Amazon SageMaker のバッチ変換ジョブは、1回の呼び出しに載せるペイロードを既定6MB・上限100MBに制限し、並列度を明示するときは(並列度 × ペイロード上限)が100MBを超えられません(AWS「CreateTransformJob」APIリファレンス・2026年8月時点)。Azure Machine Learning のバッチデプロイでは、1回の run() に渡すファイル数が既定10、ミニバッチ1回のタイムアウトが既定30秒です。バッチ推論の実装で足を取られる箇所は、モデルの精度ではなくこの種の分割単位と打ち切り値の噛み合わせにあります。この記事では、バッチ推論の定義と入出力の組み方から、ジョブ分割と並列度の逆算、部分失敗のしきい値、再実行の冪等性、特徴量の時点整合、そしてバッチ推論を見送る条件までを実装目線でまとめます。

まとめ:バッチ推論の適用条件と、ジョブ設計で先に決める3つの値

バッチ推論とは、蓄積済みのデータをまとめて読み込み、ジョブとして予測を実行し、結果をストレージやテーブルへ書き出す提供方式です。オフライン推論とも呼ばれます。推論用のサーバーを常駐させないため、課金はジョブの実行時間だけ。1日1回しか使わない予測を24時間ぶんのインスタンス料金で回す構図を避けられます。

設計で先に決める値は3つ。1回のモデル呼び出しに渡すレコード数(分割単位)、同時に走らせる呼び出し数(並列度)、そして途中で切るまでの時間と許容する失敗件数(打ち切り)です。この3つはコードより先にジョブ定義のパラメータとして表に出てくるうえ、既定値のまま本番へ出すと必ずどこかで詰まります。SageMaker の並列度は未指定なら1、Azure Machine Learning のインスタンスあたり同時実行も既定1。ここを触らないかぎり、インスタンスを増やしても直列に近い速度しか出ません。

バッチ推論を選ぶかどうかの判断そのもの、つまりオンライン推論・非同期推論との比較はオンライン推論とは?バッチ推論との違いと遅延・コスト設計を実装目線で解説で扱っています。本記事は方式を選んだ後、ジョブをどう組むかに限定します。

バッチ推論の定義と、入力の分割・出力の書き戻しまでの実行経路

バッチ推論の実行経路は、入力の読み出し、モデル呼び出し、出力の書き出しという3区間に分かれます。どこを分割単位にするかで、後段の再実行のしやすさまで決まってしまう構造です。

定義:エンドポイントを常駐させず、蓄積データをジョブ単位で処理する方式

Vertex AI では BatchPredictionJob という非同期リクエストとして扱われ、モデルをエンドポイントへデプロイする手順そのものが不要です。オンライン推論がモデルを載せたサーバーを立て続けるのに対し、バッチ推論はジョブの起動時に計算資源を確保し、処理が終われば解放する。この違いが課金にも運用にも効いてきます。

規模による呼び分けがある点にも注意が必要です。Oracle のドキュメントは、単一のVMで完結する通常のバッチ推論、タスクを小さく割って短時間で回すミニバッチ推論、水平スケールが要る分散バッチ推論の3つに整理しています。数万件なら1台、数億件なら分散という切り分けで、境目はデータ量ではなく「1台で許容時間内に終わるか」に置きます。

入力の置き方:JSONL・CSV・BigQueryとファイル分割・レコード分割の指定

Vertex AI が受け付ける入力形式は jsonl・csv・bigquery・tf-record・tf-record-gzip・file-list の6種類で、出力は BigQuery テーブルか Cloud Storage の JSONL を選びます。BigQuery を入出力に置けば、下流の集計クエリから直接参照できるぶん連携が短くなる。

SageMaker では分割の指定が2段構えです。SplitType を Line・RecordIO・TFRecord のいずれかに設定してはじめて BatchStrategy が効き、SingleRecord なら1レコードずつHTTPで呼び出し、MultiRecord ならペイロード上限に収まるだけ詰め込みます。Azure Machine Learning は scoring script の run() が受け取る mini_batch がファイルパスのリストで、分割単位はファイルです。

選び分けの基準は1レコードの大きさに置きます。画像やPDFのように1件が数MBある入力はファイル単位、行が小さい表形式データは MultiRecord で詰めるほうが、モデル呼び出しの回数そのものが減ってジョブ時間が短くなります。

出力の書き戻し:入力レコードと予測結果を突き合わせるフィルタ指定

バッチ推論でいちばん後悔しやすいのが出力設計です。素の状態では予測値だけが並んだファイルが出てくるため、何行目がどの顧客IDだったのかを後段で当て直す作業が発生します。

SageMaker には DataProcessing があり、InputFilter で推論に不要な列を落とし、JoinSource で入力レコードを結果に結合し、OutputFilter で書き出す列を絞れます。顧客IDを推論には渡さず出力にだけ残す、という指定がここで完結する。Azure Machine Learning 側は output_action の既定が append_row で、出力ファイル名の既定は predictions.csv。scoring script 側でファイルを書くなら summary_only に切り替えます。

出力には主キー・推論を実行した時点・モデルのバージョンの3つを必ず載せます。後から精度を検証するとき、どのモデルがいつ出した予測かを追えないと、原因の切り分けが推測になってしまうためです。

ジョブ分割と並列度の決め方、SageMaker・Azure MLの既定値と上限

既定値のまま出して遅い、という相談の大半はこの節の数字で説明がつきます。3サービスとも並列度の既定が保守的に置かれているためです。

SageMakerの6MB既定と、並列度×ペイロードが100MBを超えない制約

MaxPayloadInMB の既定は6MB、上限は100MB。MaxConcurrentTransforms を0にするか未設定のままにすると execution-parameters を参照し、それが有効でなければ既定1が適用されます。つまり明示しないかぎり、1インスタンスへの並列リクエストは1本です。

制約はここから。MaxConcurrentTransforms を指定する場合、(MaxConcurrentTransforms × MaxPayloadInMB)が100MBを超えられません。並列度16を狙うならペイロード上限は6MBまで、ペイロードを20MBに上げるなら並列度は5が天井。この積の制約を知らずに両方を大きくすると、ジョブ作成の時点で弾かれます。任意サイズをHTTPのチャンク転送で送る場合は MaxPayloadInMB を0にしますが、組み込みアルゴリズムはチャンク転送に対応していません。

Azure MLのmini_batch_size 10とtimeout 30秒の既定値

Azure Machine Learning のバッチデプロイは、既定値が細かく効いてきます。mini_batch_size が10、retry_settings.timeout が30秒、retry_settings.max_retries が3、max_concurrency_per_instance が1、resources.instance_count が1。

ここで噛み合わないのが最初の2つです。timeout の30秒は「ミニバッチ1回ぶん」、つまり既定ではファイル10件をまとめて処理する時間を指します。1ファイルあたり5秒かかるモデルなら10件で50秒となり、既定のままでは毎回打ち切られる。公式のサンプルにも timeout を300へ引き上げた構成が載っています。対処は mini_batch_size を下げるか timeout を上げるかの二択で、メモリに余裕がないなら前者を選びます。

並列度・処理単位・タイムアウト・再試行で見る3サービスの既定値

実装に直接効く既定値だけを横並びにすると、触るべきパラメータが絞れます。

項目 SageMaker Batch Transform Azure ML バッチデプロイ Vertex AI バッチ推論
並列度の既定 1(未指定時) 1(インスタンスあたり) ジョブ側で確保
1回に渡す単位 ペイロード6MB既定 ファイル10件既定 入力ファイル単位
呼び出しの制限 600秒・最大3,600秒 30秒・値で変更 ジョブ時間に依存
再試行の既定 3回(範囲0〜3) 3回 ジョブ再実行
失敗の許容 ジョブ全体で停止 error_threshold -1 ジョブ単位

触る順序は、並列度、分割単位、タイムアウトの順です。並列度を上げないまま分割単位だけ大きくすると、1回の呼び出しが長くなってタイムアウトに当たるだけで終わります。

並列度を上げる前に測る1レコードの処理時間とインスタンス数の逆算

ここは断言します。1レコードあたりの処理時間を測らずにインスタンス数を増やす作業は、ほぼ無駄になります。

逆算の手順は単純です。まず1レコードの処理時間を実測し、総件数を掛けて単一プロセスでの総処理時間を出す。それを業務が許す完了までの時間で割った値が、必要な同時処理数になります。100万件で1件あたり20ミリ秒なら総処理時間は約5.6時間、2時間で終えたいなら同時処理数は3。ここに並列度とインスタンス数を割り当てます。

測らずに増やすとどうなるか。バッチ推論はジョブ起動のたびにコンテナを立ててモデルの重みを展開するため、その準備時間をインスタンスの数だけ払う構造です。実処理が数十秒しかないジョブを10台へ分散すれば、準備時間の比率が上がって総時間はむしろ伸びる。分散を検討する前に、1台でのジョブ時間の内訳を準備・処理・書き出しに分けてログへ落とします。

部分失敗を許容するしきい値の決め方と、二重書き込みを防ぐ再実行設計

バッチ推論の失敗は、オンライン推論のように呼び出し元のエラーとして表に出ません。気づかないまま欠けた予測が下流へ流れる事故が起きやすく、しきい値と再実行の設計が効いてきます。

error_threshold -1が招く、欠落に気づかないまま完了するジョブ

Azure Machine Learning の error_threshold は既定が -1 で、省略時はファイル失敗が何件あってもジョブを止めません。しかもこの値は入力全体に対する累計で、ミニバッチ単位ではない。100万件のうち3万件が落ちても、ジョブのステータスは成功として返ります。

決め方は業務が飲める欠落率からの逆算です。解約予測の架電リストのように多少の欠けを許せる用途なら0.1%相当の件数、与信や請求のように1件も落とせない用途なら0。ただし0は再実行のコストが高いジョブでは厳しく、入力データの汚れ1件でジョブ全体が止まります。入力の検証を前段のジョブへ切り出したうえで、しきい値を小さく置く構成が現実的です。

再試行の既定値3回とタイムアウト600秒・30秒の食い違いの調整

SageMaker の ModelClientConfig は InvocationsMaxRetries が既定3(範囲0〜3)、InvocationsTimeoutInSeconds が既定600秒(範囲1〜3600)。この2つを掛け合わせると、1回の呼び出しが最大で30分以上ぶら下がる計算になります。ジョブ全体の時間予算が2時間なら、この既定は明らかに過大。

調整の順序は、まずタイムアウトを実測のp99から決め、その後に再試行回数を絞る形です。p99が40秒のモデルなら、タイムアウトは60〜90秒。再試行は一過性のエラーを拾うためのもので、モデル側の恒常的な失敗は回数を増やしても通りません。Azure Machine Learning 側は max_retries が3、timeout が30秒なので、こちらはタイムアウトを引き上げる方向の調整になります。

冪等性の確保:ジョブ実行IDで出力先を分ける書き込み単位の設計

再実行して結果が二重になる構成は、バッチ推論でよく踏む失敗です。append_row のまま同じ出力ファイルへ追記し続ければ、ジョブを流し直すたびに同じ主キーの行が増えます。

回避策は出力先をジョブ実行IDで分けることです。実行ごとに専用のディレクトリへ書き、完了を確認してから下流が読む確定パスへ切り替える。下流がテーブルなら、主キーと推論時点をキーにした更新挿入で受けます。この形にしておけば、途中で落ちたジョブを何度流し直しても下流の状態は変わりません。部分再実行が要るなら、入力のファイル分割と出力のディレクトリ分割を同じ粒度で揃えておくと、失敗したぶんだけを選んで流し直せます。

特徴量の時点整合と、業務の締め時刻から逆算する実行スケジュール

ジョブが動くようになった後に残る問題は、精度が学習時どおりに出ないという症状です。原因の多くはモデルではなく、入力を組み立てるSQL側にあります。

学習時と推論時で特徴量がずれない集計窓の切り方と突き合わせ手順

学習時に「注文日から過去30日の購入回数」を使ったなら、推論時も基準日は各レコードの注文日でなければなりません。バッチ推論ではここが崩れやすい。入力をジョブ実行日で一括に切ると、過去の行にも実行日基準の集計が乗り、学習時には見えなかった未来のデータが混ざります。精度は落ちるのにエラーは出ないため、気づくまでに時間がかかります。

検証は突き合わせで行います。学習用データセットを同じパイプラインで再生成し、推論側の入力と主キー単位で列を比較する。数件のサンプルで目視するのではなく、全列の分布と欠損率を並べて差分を見ます。学習と推論で同じ定義の特徴量を配る仕組みそのものは特徴量ストアとは?オンライン・オフライン二層構成と導入判断を実装目線で解説で扱っています。

業務の締め時刻から逆算する起動時刻と、遅延したときの再実行の猶予幅

起動時刻はジョブの都合ではなく、結果を使う業務の締め時刻から逆算します。朝8時に架電リストが要るなら、下流の整形と配信に30分、ジョブ本体に1時間、そして失敗時に1回は流し直せる猶予として1時間。合計で朝5時半には起動している必要があります。

猶予幅を取らない設計は、1回の失敗がそのまま業務の遅延になる。前段のデータ連携が遅れたときにジョブを待たせるのか、欠けたまま走らせるのかも先に決めておきます。複数のジョブが依存し合う構成なら、依存関係と再試行をワークフロー側へ寄せた方が扱いやすく、AWS Step Functionsとは?ステートマシンの仕組み・料金と2種のワークフロー・採用判断を実装者目線で解説のようなステートマシンで待ち合わせと分岐を表現できます。

バッチ推論を見送る3条件と、オンライン・非同期推論へ寄せる分岐点

バッチ推論は安く済む方式ですが、当てはまらない処理へ入れると鮮度のクレームとジョブの再実行を両方抱えます。ここは条件を切って言い切ります。

見送り条件:鮮度が分単位・入力が到着即時・再計算が常駐費用を超える

1つ目は、予測結果の鮮度が分単位で要るとき。不正検知や在庫の引き当てのように直前の行動が効く領域へ、1日1回のジョブを当てても業務は回りません。

2つ目は、入力が到着した時点で処理を始める必要があるとき。データが届くたびに予測が要るなら、ジョブの起動間隔を短くする方向ではなく、オンライン推論か非同期推論へ切り替えます。起動間隔を5分に詰めたバッチは、準備時間の比率が上がるだけで常駐と変わらない費用になる。

3つ目は、再計算のコストが常駐費用を超えるとき。毎時すべての行を作り直すジョブは、差分だけを常駐サーバーで処理する構成より高くつく場合があります。全件再計算をやめられないなら、それはバッチの問題ではなく特徴量の設計の問題です。

コスト逆転の分岐点:稼働率で見るジョブ課金と常駐課金の損益境界

分岐点は稼働率で測ります。1日あたりの実処理時間、つまり件数×1件あたりの処理時間を24時間で割った値。これが数%に留まるならバッチ推論かサーバーレス推論、20%を超えていて、なおかつ結果を待っている人がいるならオンライン推論の常駐が見合います。

GPUを積む構成では判断がさらに単純です。GPUインスタンスは待機中も同じ単価で課金されるため、1日数十分しか計算しない用途を常駐させる理由はありません。ジョブ課金へ倒し、必要なときだけ確保する。判断の前提となる方式ごとの費用構造はオンライン推論とは?バッチ推論との違いと遅延・コスト設計を実装目線で解説にまとめてあります。特徴量の設計からジョブの運用、既存の業務システムへの組み込みまでを外部と進める場合は、機械学習モデル開発で対応しています。

よくある質問

バッチ推論の設計で問い合わせの多い論点を5つ挙げます。

バッチ推論とオフライン推論は同じ意味ですか?

実務ではほぼ同義で使われます。どちらも、蓄積したデータをまとめて処理し、結果を保存先へ書き出す提供方式を指す言葉です。細かく言えば、バッチは処理の単位(まとめて実行する)、オフラインは応答の性質(呼び出し元へ即時に返さない)を指しています。クラウド各社の呼称も分かれており、AWS はバッチ変換、Vertex AI はバッチ推論、Azure Machine Learning はバッチエンドポイントという名前で同じ構造を提供しています。

バッチ推論のジョブはどのくらいの頻度で回せばよいですか?

結果を使う業務の締め時刻から逆算して決めます。翌朝までに揃えばよい用途なら1日1回、日中の意思決定に使うなら数時間おき。頻度を上げるほどジョブの準備時間が占める比率が上がるため、起動間隔が10分を切るあたりから常駐との費用差が消えます。そこまで短い間隔が要るなら、頻度を詰めるのではなく方式そのものを見直す段階です。

並列度を上げてもジョブ時間が短くならないのはなぜですか?

原因は3つに絞られます。SageMaker なら(並列度 × ペイロード上限)が100MBを超えられない制約に当たっている場合、Azure Machine Learning ならインスタンスあたりの同時実行が既定1のままの場合、そしてジョブ時間の大半がモデルの計算ではなく起動準備やデータの読み書きで占められている場合です。まず1ジョブの内訳を準備・処理・書き出しで計測し、処理区間が支配的だと確認できてから並列度へ手を入れます。

バッチ推論の結果をAPIで即時に返すことはできますか?

できます。予測をあらかじめ計算してキーバリューストアやテーブルへ書き出しておき、APIは検索して返すだけにする構成です。推薦やスコアリングのように候補が有限で、入力がリクエストの内容に依存しない用途では、この形が遅延と費用の両面で有利になります。ただし入力の組み合わせが多すぎて事前計算しきれない場合や、直前の行動を反映する必要がある場合は成立しません。

モデルを差し替えたときにバッチ推論側で必要な作業は?

次回のジョブが指すモデルのバージョンを切り替えるだけで済みます。常駐エンドポイントのように無停止で入れ替える手順が要らない点が、バッチ推論の運用上の利点です。作業として残るのは出力側で、予測にモデルのバージョンを載せておき、旧モデルの出力と新モデルの出力を突き合わせられるようにしておきます。切り戻しは前のバージョンを指して流し直すだけです。

関連記事

資料請求

RELATED POSTS 関連記事