ベスト プラクティス: GPU を使用した Cloud Run ジョブ

このページでは、GPU と Cloud Run ジョブを使用して、大規模言語モデル(LLM)のトレーニング、ファインチューニング、LLM でのバッチ推論やオフライン推論などの AI ワークロードを実行する際のパフォーマンスを最適化するためのベスト プラクティスについて説明します。コンピューティング負荷の高いタスクやバッチ処理をリアルタイムで実行できる Cloud Run ジョブを作成するには、次の操作を行います。
  • 読み込みが高速で、GPU に対応する構造への変換が最小限で済むモデルを使用し、その読み込み方法を最適化します。
  • 同時実行を効率的で最大限に活用できる構成を使用し、コストを抑えながら、1 秒あたりのターゲット リクエストの処理に必要な GPU の数を減らします。

Cloud Run に大規模な ML モデルを読み込む際のおすすめの方法

ML モデルは、コンテナ イメージ内に保存するか、Cloud Storage からの読み込みを最適化することをおすすめします。

ML モデルの保存と読み込みのトレードオフ

比較する項目は次のとおりです。

モデルの位置 デプロイ時間 開発環境 コンテナの起動時間 ストレージ費用
コンテナ イメージ 低速。規模の大きいモデルを含むイメージを Cloud Run にインポートするには、より長い時間が必要になります。 コンテナ イメージを変更すると再デプロイが必要になります。大規模なイメージの場合、再デプロイに時間がかかることがあります。 モデルのサイズによって変わります。非常に大きなモデルの場合、Cloud Storage を使用すると予測可能なパフォーマンスを実現できますが、パフォーマンスは低下します。 Artifact Registry に複数のコピーが存在する可能性があります。
Cloud Storage FUSE ボリューム マウントを使用して読み込まれる Cloud Storage 高速。モデルはコンテナの起動時にダウンロードされます。 設定が難しくなく、Docker イメージの変更も必要ありません。 ネットワークの最適化を使用すると高速になります。ダウンロードを並列処理しません。 Cloud Storage に 1 つのコピー。
Cloud Storagetransfer manager の同時ダウンロードのコードサンプルに示すように、Google Cloud CLI コマンド gcloud storage cp または Cloud Storage API を使用して同時にダウンロードされます。 高速。モデルはコンテナの起動時にダウンロードされます。 イメージに Google Cloud CLI をインストールするか、Cloud Storage API を使用するようにコードを更新する必要があります。設定が少し難しくなります。 ネットワークの最適化を使用すると高速になります。Google Cloud CLI はモデルファイルを並列でダウンロードするため、FUSE マウントよりも高速です。 Cloud Storage に 1 つのコピー。
インターネット 高速。モデルはコンテナの起動時にダウンロードされます。 通常はシンプルです(多くのフレームワークでは中央リポジトリからモデルがダウンロードされます)。 通常は不安定で予測不能です。
  • フレームワークが初期化中にモデル変換を適用する場合があります(これはビルド時に行う必要があります)。
  • モデルホストとモデルのダウンロード用のライブラリが効率的でない場合があります。
  • インターネットからのダウンロードには、信頼性に関するリスクがあります。ダウンロード ターゲットが停止している場合、ジョブが開始されない可能性があります。また、ダウンロードされた基盤となるモデルが変更され、品質が低下する可能性があります。独自の Cloud Storage バケットにホストすることをおすすめします。
モデル ホスティング プロバイダによって異なります。

コンテナ イメージにモデルを保存する

Cloud Run にデプロイされたコンテナ イメージに ML モデルを保存した場合、Cloud Run の組み込みコンテナ イメージ ストリーミングの最適化が利用されます。これにより、ネットワーク最適化を別途行うことなく、ファイルの読み込み時間を最大にすることができます。

ML モデルを含むコンテナのビルドには時間がかかることがあります。Cloud Build を使用している場合は、ビルドを高速化するためにサイズの大きいマシンを使用するように Cloud Build を構成できます。これを行うには、次の手順でビルド構成ファイルを使用して、イメージをビルドします。

steps:
- name: 'gcr.io/cloud-builders/docker'
  args: ['build', '-t', 'IMAGE', '.']
- name: 'gcr.io/cloud-builders/docker'
  args: ['push', 'IMAGE']
images:
- IMAGE
options:
 machineType: 'E2_HIGHCPU_32'
 diskSizeGb: '500'
 

モデルを含むレイヤがイメージ間で異なる場合(ハッシュが異なる場合)は、イメージごとに 1 つのモデルコピーを作成できます。モデルレイヤが各イメージで固有の場合、イメージごとにモデルのコピーが 1 つ存在する可能性があるため、Artifact Registry の費用が増加する可能性があります。

Cloud Storage にモデルを保存する

Cloud Storage から ML モデルを読み込む際に ML モデルの読み込みを最適化するには、Cloud Storage ボリュームのマウントを使用するか、Cloud Storage API またはコマンドラインを直接使用して、下り(外向き)設定が all-traffic に設定されたダイレクト VPCプライベート Google アクセスを使用する必要があります。

インターネットからモデルを読み込む

インターネットからの ML モデルの読み込みを最適化するには、下り(外向き)設定値を all-traffic に設定してすべてのトラフィックを VPC ネットワーク経由でルーティングし、高帯域幅で公共のインターネットに到達するように Cloud NAT を設定します。

ビルド、デプロイ、ランタイム、システム設計に関する考慮事項

以降のセクションでは、ビルド、デプロイ、ランタイム、システム設計に関する考慮事項について説明します。

ビルド時

ビルドを計画する際に考慮すべき事項は次のとおりです。

  • 適切なベースイメージを選択します。まず、使用する ML フレームワークの Deep Learning Containers または NVIDIA コンテナ レジストリのイメージから始めます。これらのイメージには、パフォーマンス関連の最新のパッケージがインストールされています。カスタム イメージの作成はおすすめしません。
  • 結果の品質に影響することを証明できる場合を除き、4 ビットの量子化モデルを選択して同時実行を最大化します。量子化により、より小さい高速なモデルが生成され、モデルのサービングに必要な GPU メモリの量が削減されます。また、実行時の並列処理を増やすこともできます。理想的には、モデルはターゲット ビット深度に量子化されるのではなく、ターゲット ビット深度でトレーニングする必要があります。
  • コンテナの起動時間を最短にするために、読み込み時間が短いモデル形式(GGUF など)を選択します。これらの形式はターゲット量子化タイプをより正確に反映し、GPU への読み込みの際に必要な変換が少なくなります。セキュリティ上の理由から、pickle 形式のチェックポイントは使用しないでください。
  • ビルド時に LLM キャッシュを作成してウォームアップします。Docker イメージをビルドするときに、ビルドマシンで LLM を開始します。プロンプト キャッシュを有効にして、一般的なプロンプトやサンプル プロンプトをフィードし、実際に使用できるようにキャッシュをウォームアップします。生成された出力を保存して、実行時に読み込みます。
  • ビルド時に生成した独自の推論モデルを保存します。効率の悪いモデルを読み込み、コンテナ起動時に量子化などの変換を適用する場合と比べると、大幅に時間を節約できます。

デプロイ時

ビルドを計画する際に考慮すべき事項は次のとおりです。

  • ジョブ実行のタスク タイムアウトを 1 時間以下に設定します。
  • ジョブ実行で並列タスクを実行する場合は、並列処理を、プロジェクトに割り当てた該当する割り当て上限の最小値より小さい値に設定します。デフォルトでは、並列実行されるタスクの GPU ジョブ インスタンスの割り当ては 5 に設定されています。割り当ての増加をリクエストするには、割り当てを増やす方法をご覧ください。GPU タスクは可能な限り迅速に開始され、最大数に達します。最大数は、プロジェクトに割り当てた GPU 割り当ての量と選択したリージョンによって異なります。並列処理を GPU 割り当て上限よりも大きく設定すると、デプロイは失敗します。

実行時

  • サポートされているコンテキストの長さを事前に管理します。サポートするコンテキスト ウィンドウが小さいほど、並列で実行可能なクエリの数が増えます。具体的な方法はフレームワークによって異なります。
  • ビルド時に生成した LLM キャッシュを使用します。プロンプトとプレフィックス キャッシュを生成したときに使用した同じフラグを指定します。
  • 作成した保存済みモデルから読み込みます。モデルの読み込み方法の比較については、モデルの保存と読み込みのトレードオフをご覧ください。
  • フレームワークでサポートされている場合は、量子化された Key-Value キャッシュの使用を検討してください。これにより、クエリあたりのメモリ要件を削減し、より多くの並列処理を構成できます。ただし、品質に影響することもあります。
  • モデルの重み、アクティベーション、Key-Value キャッシュに予約する GPU メモリの量を調整します。メモリ不足エラーが発生しない範囲で、できるだけ高い値に設定します。
  • モデル読み込みの並列化の使用など、コンテナの起動パフォーマンスを改善するオプションがフレームワークにあるかどうかを確認します。

システム設計レベル

  • 必要に応じてセマンティック キャッシュを追加します。クエリとレスポンスをすべてキャッシュに保存すると、一般的なクエリの費用を抑えることができます。
  • プリアンブルのばらつきを制御します。プロンプト キャッシュは、プロンプトが順番に格納される場合にのみ有用です。キャッシュは事実上プレフィックス キャッシュです。シーケンス内での挿入や編集は、キャッシュに保存されていないか、一部しか存在しないことを意味します。