会社情報

インデクシング 3.0 の背後にある設計の選択:統合、パッケージ化、実行、およびデプロイメント

ステュ・スチュワート、アブラハム・ジョー、SJ・キム、パリトシュ・モハン

Twelve Labsは、Indexing 3.0の背後にある具体的な設計上の決定事項について詳しく説明しています。これには、サービス境界の統合が拡張性を向上させた理由、単一コンテナパッケージングがさまざまなデプロイ環境で可能にすること、統合実行レイヤーとしてRay Serveを採用したことによる実際のコスト、そしてシステムが別々のコードベースに分裂することなく複数のデプロイターゲットをサポートする方法が含まれます。

Twelve Labsは、Indexing 3.0の背後にある具体的な設計上の決定事項について詳しく説明しています。これには、サービス境界の統合が拡張性を向上させた理由、単一コンテナパッケージングがさまざまなデプロイ環境で可能にすること、統合実行レイヤーとしてRay Serveを採用したことによる実際のコスト、そしてシステムが別々のコードベースに分裂することなく複数のデプロイターゲットをサポートする方法が含まれます。

この記事の内容

No headings found on page

ニュースレターに登録する

ニュースレターに登録する

ビデオ理解に関する最新の技術進歩、チュートリアル、業界の動向をお届けします

ビデオ理解に関する最新の技術進歩、チュートリアル、業界の動向をお届けします

AIを活用してビデオを検索、分析、探索します。

2026/03/25

13分

記事へのリンクをコピー

パート1では、これまでのインデックス作成プラットフォームが「機能して」いたにもかかわらず、なぜスケーリングの限界に達したのかを示しました。その制限要因は、生のモデルのスループットではなく、アプリケーションにインフラストラクチャの前提が組み込まれたマイクロサービス多用のシステムに伴う運用上および組織上のオーバーヘッドでした。チームとプロダクトの領域が拡大するにつれて、調整コスト、サービス間をまたぐデバッグ、デプロイメントの結合が日々のエンジニアリング速度を支配し始めました。核となった再考は、インデックス作成を一貫したポータブルなシステムとして扱うことでした。つまり、マイクロサービスのメッシュから、アプリケーションロジックの可読性を維持する効率化されたレイヤーへと移行し、実行レイヤーが分散処理を担当し、インフラストラクチャは定義的なものではなく交換可能なものにすることでした。このレイヤー化された視点により、コントロールプレーンの相互作用から動作を再導出することなく、ビデオ → 再利用可能な表現 → 下流の検索/生成というエンドツーエンドのパスをより容易に推論できるようになります。

パート2では、その再考を現実にした具体的な設計の選択肢を紐解いていきます。なぜ統合によって拡張性が低下するどころか向上したのか、「シングルコンテナ」がパッケージングの制約として何を意味するのか、統一された実行レイヤーに賭けることで何を得て(そして何を支払うのか)、プラットフォームを断片化することなく複数のデプロイ環境向けにどのように設計したのか、について説明します。


1 - イデオロギーではなく、実現要因としての統合

図1: 境界が減ることで、より迅速な推論が可能に

私たちはパート1で、Indexing 2.0における本当の代償は「コンピュートの不足」ではなく、境界の蓄積であったと主張しました。各ステージが独自のサービス契約、デプロイアーティファクト、および推論すべき障害モードになってしまいました。各ステップが個別のサービス境界になると、システムのデバッグ、パッケージング、および進化が難しくなりました。

Indexing 3.0では、その境界の表面積を削減するためのレバーとして統合を利用しています。これは「ただ単にモノリスを作る」ということではありません。重要なのは、システムが必要な部分ではモジュール性を維持しつつ、真の独立性が得られない場所での調整オーバーヘッドの支払いをやめることです。


境界を減らすことで柔軟性が制限されるどころか向上した理由

プロダクションのMLシステムにおける柔軟性は、最も多くの「箱」を持つことから生まれるわけではありません。フリートの半分を同期させることなく、動作を変更できることから生まれます。

統合は、以下のような方法で役立ちました:

  • 変更時に安定した状態を維持しなければならない、サービス間のデータ契約の数を削減する。

  • ランタイム、トレースシステム、およびデプロイパイプライン間の変換のためだけに存在する「接着コード」を崩壊させる。

  • エンドツーエンドのインデックス作成パスを1つの一貫したフローとしてより容易に推論できるようにする。


開発者体験を倍増させる手段としての統合

私たちはパート1で、言語とランタイムの境界(一部のインフラ用のGo、MLワークフロー用のPython)が摩擦を生み出したことを指摘しました。インターフェースが常にクリーンであるとは限らなかったためです。

統合こそが、その摩擦を解消する手段です。

実際には、以下の点が改善されます:

  • デバッグ:エラーがシリアライズされ、ラップされ、再試行され、コンテキストが失われる場所が減ります。

  • プロファイリング:サービスをまたいでログを繋ぎ合わせることなく、ステージ間のレイテンシと使用率を容易にトレースできます。

  • オンボーディング:エンジニアが1つのコードパスをたどり、メンタルモデルをより迅速に構築できます。


意図的に制限された狭い表面積

統合は、システムの目的が限定されている場合にのみ機能します。インデックス作成は「ビデオが入力され、再利用可能な表現が出力される」変換レイヤーです。そのスコープを明確に保つことで、コードベースを不要なものの寄せ集めにすることなく、統合によって付随的な複雑さを削減できます。


2 - パッケージングの再考:「シングルコンテナ」が実際に意味すること

図2: 各環境で自己完結型のユニットとして実行

パート1で主張したように、デプロイメントの柔軟性は、単なる「あれば良いもの」ではなく、最優先の制約として表れました。「完全なプラットフォーム」のように見える環境もあれば、「コンテナランタイムといくつかのノブ」のように見える環境もあります。Indexing 3.0は、その全領域にわたって動作する必要がありました。

「シングルコンテナ」とは、その制約を表すパッケージングの略称です。


「シングルコンテナ」とは、圧縮ではなく切り離しのこと

目的は、すべてのコンポーネントを1つの肥大化したイメージに詰め込むことではありません。目的は、インフラストラクチャ固有のコントロールプレーンプリミティブに依存することなく、インデックス作成システムを実行可能にすることです。

実用的な定義は以下の通りです:

  • システムを自己完結型のユニットとしてデプロイできること。

  • コアとなるオーケストレーションを実行するために、Kubernetes API(または同様のもの)を必要としないこと。

  • アーキテクチャの分岐なしに、最小限の環境で動作できること。

これは私たちの核となるフレームワークに沿っています。すなわち、デプロイメントはアプリケーションロジックに漏れ出す制約ではなく、最下層のプロパティになります。


オーケストレーションのアプリケーションへの移行

マイクロサービスのメッシュでは、オーケストレーションはアプリケーションの外部に存在する傾向があります。それはルーティング、コントローラー、プラットフォームの動作に分散されています。

パート1のレイヤー化されたモデルでは、オーケストレーションは内部に移動します:

  • インデックス作成アプリケーションが「何が起こるべきか」を定義します。

  • 実行レイヤーがそれを実行し、スケーリングします。

  • インフラストラクチャがその基盤となります。

この反転こそがポータビリティを可能にするものです。なぜなら、システムはもはや単一の動作環境に固定されないからです。


なぜこれが最初に思われた以上に重要だったのか

パッケージングは、どこで実行できるかということだけではありません。以下のようなことにも影響を与えます:

  • ローカル開発がどれほど簡単か。

  • 環境間で動作がどれほど一貫しているか。

  • 新しいデプロイメントがどれだけの運用表面積を引き継ぐか。

パッケージングがシンプルになると、ロールアウト、デバッグ、サポート、オンボーディングなど、下流にあるすべてのこともシンプルになります。


3 - 統一された実行レイヤーの選択:理想と現実

図3: ルーティング、スケーリング、信頼性を担う単一の基盤

パート1では、Indexing 3.0をマイクロサービスメッシュから効率的なレイヤーへと移行するものとして位置づけました。そこでは、アプリケーションロジックは一貫した状態を保ち、実行レイヤーが分散処理を担当し、インフラストラクチャレイヤーは交換可能になります。

このセクションは、そのストーリーの生々しい中間部分です。「私たちのインデックス作成ロジック」と「顧客が持っている任意のコンピュート」の間に位置する実行レイヤーを選択することが実際に何を意味するのか。私たちは、その統一レイヤーとしてRay Serve(Ray CoreおよびRay ServeのマネージドプロバイダーとしてAnyscaleを使用)を選択しました。この決定により実際に大きなメリットが得られましたが、直接言及するに値するコストも伴いました。


単一の抽象化がもたらす理想

統一された実行レイヤーの核となる約束はシンプルです。増大するサービス群全体でそれらのメカニズムを再構築するのではなく、並行処理、スケーリング、およびフォールトハンドリングを表現するための単一の場所を提供します。

Ray Serveのサービングモデルはその約束を具体化します:

  • リクエストはHTTP(またはgRPC)プロキシから入り、キューに入れられて利用可能なレプリカにルーティングされ、ユーザーコードを実行するレプリカアクターによって実行されます。

  • Serveは単一のイングレスポイントだけでなく、スケーラビリティと高可用性のために複数のプロキシをサポートしています。

  • モデルコンポジションのためにサービスがDeploymentHandlesを介して相互に呼び出す場合でも同じリクエストパスが適用されるため、内部コンポジションでルーティング挙動とバッチ処理挙動を共有できます。

インデックス作成プラットフォームを構築している場合、インデックス作成は単一のモデル呼び出しではないため、これは魅力的です。それはマルチステージのフローであり、各ステージには並行処理制御と失敗セマンティクスが必要です。統一された実行レイヤーは、「多くの場当たり的なスケジューラーでこれを繋ぎ合わせた」状況と「標準化できる単一のスケジューリング基盤がある」状況との分かれ目になります。

これは、パート1のパッケージングとデプロイメントの推進要因にも合致します。オーケストレーションロジックが、Kubernetesコントローラーやマイクロサービスの接着コードに分散されるのではなく、実行レイヤー内にある場合、アーキテクチャを書き換えることなくさまざまな環境で実行できるシステムに近づきます。


インデックス作成ワークロードの現実

過小評価されがちな部分は、実行レイヤーはただではないということです。それは独自のリクエストパス、独自のコントロールプレーン、そして独自のパフォーマンス特性をもたらします。Ray Serveの独自のドキュメントでも、最も一般的な問題はリクエストパスにおける高レイテンシと低スループットであり、監視すべき特定のルーターと処理レイテンシの指標を示しています。

ビデオのインデックス作成において、それは重要です。なぜなら、ワークロードの形状がオーバーヘッドを増幅させる傾向があるからです。


現実 #1: リクエスト・ルーティングのオーバーヘッドは本物であり、無視できない

Ray Serveのアーキテクチャは、リクエストをプロキシ経由でルーティングし、キューに入れ、実行前に利用可能なレプリカを選択します。これは一般的なサービングには合理的なデフォルトですが、コードが実行される前にもフレームワーク側の処理が発生していることを意味します。

アプリケーションがステージ間に多くの「小さなホップ」を抱えている場合、そのルーティングオーバーヘッドがエンドツーエンドのレイテンシの測定可能な部分になる可能性があります。抽象化は、システムを構築するのには役立ちますが、同時にコンポジションのコストについても考慮に入れておく必要があることを意味します。

これは仮定の話ではありません。Rayのパフォーマンス調整ガイダンスでは、リクエストパスのボトルネックの診断について明確に議論されており、問題のシグナルとしてルーターのスループットとキューイングのレイテンシを指し示しています。そして、Rayエコシステムは、要求の厳しいサービングワークロードにおけるレイテンシを削減するためのカスタムルーティングの新しいサポートなど、ファーストクラスのパフォーマンスレバーとしてリクエストルーティングへの投資を続けています。

インデックス作成における実用的な教訓は、「フレームワークのオーバーヘッドはシステムの一部である」ということです。特に、オーバーヘッドが全体の時間に対して大きな割合を占める短いジョブがワークロードに多く含まれる場合は、それを測定し、プロファイリングし、それを考慮して設計する必要があります。まさにその「短いビデオのセットアップコスト」というダイナミクスが、パート1で述べた破綻の引き金の一つでした。


現実 #2: ビデオデコードは核であり、多くの場合はCPUバウンドである

ビデオのインデックス作成について、「GPU推論と少しの接着剤」として語るのは簡単です。実際には、デコードはパイプラインの中で最も影響の大きい部分の一つであり、コーデック、フォーマット、およびハードウェアデコードが利用可能かどうかに応じて、大幅にCPUバウンドになる可能性があります。

  • NVIDIAのNVDECドキュメントでは、このトレードオフを明確にしています。デコードがNVDECにオフロードされると、CPUは他の作業のために解放されます。これは、そのオフロードがない場合のデフォルトパスが、意味のある量のCPUを消費するということを言い換えています。

  • 現代のPyTorchエコシステムツールであっても、CUDAデコードはデコードステップにおいてCPUデコードよりも高速になるため、アクセラレーションパスとして位置づけられています。しかし、重要な注意事項があります。ハードウェアデコーダーでコーデックやフォーマットがサポートされていない場合、CUDAデコードはCPUデコードにフォールバックする可能性があります。

インデックス作成プラットフォームにとって、CPU容量はオプションのバックグラウンドノイズではありません。たとえ「メインのステージ」がGPUモデルであったとしても、それが主要なボトルネックになり得ます。また、最も好ましくない類のリソース使用状態に陥る可能性もあります:CPUデコードが飽和しているためにGPUがアイドル状態になる。これが、「不均一なリソースプロファイル」が抽象的な論点ではない理由です。デコード単体でも、CPUをファーストクラスのスケジューリングディメンションとして扱わざるを得なくなる可能性があります。


現実 #3: 不均一なステージには明示的なリソースモデリングが必要である

インデックス作成のワークロードは、デフォルトでリソースが不均一です:

  • ダウンロードとI/Oフェーズ

  • CPU負荷が高くなり得るデコードフェーズ

  • GPU負荷が高くなり得るエンベディングフェーズ

  • CPUとメモリの負荷が大きく変動し得る後処理フェーズ

これら要件を明示的にモデリングする場合にのみ、統一された実行レイヤーが価値を発揮します。Ray Coreは、タスクとアクターに対するCPUやGPUなどの論理的なリソース要件の指定をサポートしており、十分なリソースを持つノード上でのみそれらをスケジュールします。あるステージが別のステージを黙って枯渇させたり、ボトルネックとなっているステージがサポートできる速度を超えて並行処理が増大したりする障害モードを回避したい場合には、その機能が不可欠です。

これはまた、パート1における「効率化されたレイヤー」への再考が、運用上現実のものとなる場所でもあります。コードをレイヤー化するだけでなく、リソースセマンティクスをレイヤー化するのです。インデックス作成プラットフォームがフローを表現し、実行レイヤーが並行処理と配置を強制し、インフラストラクチャレイヤーが物理的な基盤を提供します。


教訓: 抽象化は作業をなくすわけではなく、置き換えるだけである

強力な実行レイヤーは、エンジニアリングの作業をなくすわけではありません。それを置き換えるだけです。独自のオーケストレーションコードを書く代わりに、リクエストパスの理解、インストルメンテーションとチューニング、そしてフレームワークの挙動とワークロード形状の一致に、より多くの時間を費やすことになります。

また、私たちが学んだ、明示的に述べる価値のある2つ目の教訓があります。それは、早い段階で統一された実行レイヤーを頼りにするのであれば、その背後にあるプラットフォームチームを自社チームの延長として扱うべきだということです。

Ray ServeとAnyscaleは私たちにレバレッジをもたらしてくれましたが、同時に本番規模のビデオワークロード下でしか現れない、真のエッジケースにも遭遇しました。私たちはAnyscaleのRay Serveチームと密接に連携し、ボトルネックを特定し、再現可能なケースを提供し、修正を繰り返しました。一部の問題は最初非常に大変でしたが、このコラボレーションは、時間をかけてこの賭けを持続可能なものにした要素の一部です。変化の激しいサービングスタックにおいて、その関係性は後付けで考えるべきものではありません。それはアーキテクチャの一部なのです。


4 - 乱れなく複数のデプロイ環境をサポートする

図4: 1つの概念的なプラットフォーム、多くの基盤

私たちはパート1で、「デプロイメントの形態は変数であるべきであり、システムの定義機能であってはならない」という強い主張をしました。このセクションは、実際にそれを実現するために何が必要かについてです。


デプロイメントは後回しにするものではなく、設計の軸である

顧客がインデックス作成の出力に依存するようになると、デプロイメントの制約を変更することは困難になります。システムが1つのコントロールプレーンや1つの運用モデルに溶接されている場合、新しい環境を構築するたびに、コードの書き換えかフォークのいずれかが必要になります。

Indexing 3.0では、「どこで実行するか」を後回しのパッケージング作業としてではなく、アーキテクチャへの最優先の入力情報として扱います。


断片化のない柔軟性

複数の環境をサポートすることは、複数のプラットフォームを維持管理することを意味しません。

目的は、環境固有の問題を可能な限り最下層に押し下げた、1つの概念的なシステムにすることです。これはパート1と同じレイヤー化の原則です。アプリケーションロジックの変更を強制することなく、インフラストラクチャは交換可能であるべきです。

実質的には、以下のことを意味します:

  • 環境間でコアとなるインデックス作成動作の一貫性を維持する。

  • 違いを構成設定、デプロイツール、および薄いアダプターに隔離する。

  • 時間の経過とともに密かに分岐していく「特殊ケース」のコードパスを避ける。


デプロイメントの現実を無視することの隠れたコスト

デプロイメントの多様性を無視すると、いずれにせよプラットフォームは断片化します。ただ単に、場当たり的なフォーク、その場しのぎのパッチ、そして環境固有の運用プレイブックを通じて断片化していくだけです。

事前に複数の環境を考慮して設計することは、後からその断片化の代償を支払うよりも費用対効果が高くなります。それはまた、進化できるシステムと、ビジネスがデプロイの前提を変更するたびにリプレイスしなければならないシステムとの違いでもあります。


結論: 人をスケールさせるインフラは、他のすべてをスケールさせる

Indexing 3.0は、パフォーマンス目標から始まったわけではありません。それは、多くのMLチームが最終的に直面する一つの問いから始まりました:

システムは機能しているが、それを真に理解している人物がごく一部であり、かつそれが1つの環境でしか機能しない場合、何が起こるだろうか?

私たちが学んだ答えは、進歩が微妙でありながら複合的な形で遅くなる、ということでした。変更にはより多くの時間がかかるようになります。デプロイは脆くなります。オンボーディングは考古学の探求のようになります。そして、便宜上行われたアーキテクチャ上の決定が、静かに長期的な制約として固まっていきます。

Indexing 3.0の最も有意義な成果は、単一の技術的機能ではなく、システムが可能にする変化です:

  • 調整のボトルネックなしに、より多くのエンジニアが貢献できること

  • 同じコアプラットフォームをクラウド、オンプレミス、および制約のある環境で実行できること

  • デプロイ形態がアーキテクチャの複雑さを左右しなくなること

  • システムがシンプルになるため、コストとパフォーマンスの最適化が扱いやすくなること

より広範な教訓は、ビデオのインデックス作成をはるかに超えて適用できると私たちが信じている教訓です。

MLインフラにおいて、スケーリングがモデルやハードウェアだけで阻まれることはほとんどありません。それは、推論が困難で、当初の想定外の環境へのデプロイが困難で、新しい人々が安全に変更を加えることが困難なシステムによって阻まれるのです。

そのような文脈において、シンプルさとは、意欲の欠如ではありません。それは、局所的な賢さをグローバルなレバレッジと引き換えにする、意図的な設計の選択です。

Indexing 3.0は、今後の取り組みにおいてインフラを解きほぐす作業を減らし、ビデオ理解が可能にするものを前進させることへより集中できるように、そのレバレッジを基礎に組み込むための私たちの試みです。

パート1では、これまでのインデックス作成プラットフォームが「機能して」いたにもかかわらず、なぜスケーリングの限界に達したのかを示しました。その制限要因は、生のモデルのスループットではなく、アプリケーションにインフラストラクチャの前提が組み込まれたマイクロサービス多用のシステムに伴う運用上および組織上のオーバーヘッドでした。チームとプロダクトの領域が拡大するにつれて、調整コスト、サービス間をまたぐデバッグ、デプロイメントの結合が日々のエンジニアリング速度を支配し始めました。核となった再考は、インデックス作成を一貫したポータブルなシステムとして扱うことでした。つまり、マイクロサービスのメッシュから、アプリケーションロジックの可読性を維持する効率化されたレイヤーへと移行し、実行レイヤーが分散処理を担当し、インフラストラクチャは定義的なものではなく交換可能なものにすることでした。このレイヤー化された視点により、コントロールプレーンの相互作用から動作を再導出することなく、ビデオ → 再利用可能な表現 → 下流の検索/生成というエンドツーエンドのパスをより容易に推論できるようになります。

パート2では、その再考を現実にした具体的な設計の選択肢を紐解いていきます。なぜ統合によって拡張性が低下するどころか向上したのか、「シングルコンテナ」がパッケージングの制約として何を意味するのか、統一された実行レイヤーに賭けることで何を得て(そして何を支払うのか)、プラットフォームを断片化することなく複数のデプロイ環境向けにどのように設計したのか、について説明します。


1 - イデオロギーではなく、実現要因としての統合

図1: 境界が減ることで、より迅速な推論が可能に

私たちはパート1で、Indexing 2.0における本当の代償は「コンピュートの不足」ではなく、境界の蓄積であったと主張しました。各ステージが独自のサービス契約、デプロイアーティファクト、および推論すべき障害モードになってしまいました。各ステップが個別のサービス境界になると、システムのデバッグ、パッケージング、および進化が難しくなりました。

Indexing 3.0では、その境界の表面積を削減するためのレバーとして統合を利用しています。これは「ただ単にモノリスを作る」ということではありません。重要なのは、システムが必要な部分ではモジュール性を維持しつつ、真の独立性が得られない場所での調整オーバーヘッドの支払いをやめることです。


境界を減らすことで柔軟性が制限されるどころか向上した理由

プロダクションのMLシステムにおける柔軟性は、最も多くの「箱」を持つことから生まれるわけではありません。フリートの半分を同期させることなく、動作を変更できることから生まれます。

統合は、以下のような方法で役立ちました:

  • 変更時に安定した状態を維持しなければならない、サービス間のデータ契約の数を削減する。

  • ランタイム、トレースシステム、およびデプロイパイプライン間の変換のためだけに存在する「接着コード」を崩壊させる。

  • エンドツーエンドのインデックス作成パスを1つの一貫したフローとしてより容易に推論できるようにする。


開発者体験を倍増させる手段としての統合

私たちはパート1で、言語とランタイムの境界(一部のインフラ用のGo、MLワークフロー用のPython)が摩擦を生み出したことを指摘しました。インターフェースが常にクリーンであるとは限らなかったためです。

統合こそが、その摩擦を解消する手段です。

実際には、以下の点が改善されます:

  • デバッグ:エラーがシリアライズされ、ラップされ、再試行され、コンテキストが失われる場所が減ります。

  • プロファイリング:サービスをまたいでログを繋ぎ合わせることなく、ステージ間のレイテンシと使用率を容易にトレースできます。

  • オンボーディング:エンジニアが1つのコードパスをたどり、メンタルモデルをより迅速に構築できます。


意図的に制限された狭い表面積

統合は、システムの目的が限定されている場合にのみ機能します。インデックス作成は「ビデオが入力され、再利用可能な表現が出力される」変換レイヤーです。そのスコープを明確に保つことで、コードベースを不要なものの寄せ集めにすることなく、統合によって付随的な複雑さを削減できます。


2 - パッケージングの再考:「シングルコンテナ」が実際に意味すること

図2: 各環境で自己完結型のユニットとして実行

パート1で主張したように、デプロイメントの柔軟性は、単なる「あれば良いもの」ではなく、最優先の制約として表れました。「完全なプラットフォーム」のように見える環境もあれば、「コンテナランタイムといくつかのノブ」のように見える環境もあります。Indexing 3.0は、その全領域にわたって動作する必要がありました。

「シングルコンテナ」とは、その制約を表すパッケージングの略称です。


「シングルコンテナ」とは、圧縮ではなく切り離しのこと

目的は、すべてのコンポーネントを1つの肥大化したイメージに詰め込むことではありません。目的は、インフラストラクチャ固有のコントロールプレーンプリミティブに依存することなく、インデックス作成システムを実行可能にすることです。

実用的な定義は以下の通りです:

  • システムを自己完結型のユニットとしてデプロイできること。

  • コアとなるオーケストレーションを実行するために、Kubernetes API(または同様のもの)を必要としないこと。

  • アーキテクチャの分岐なしに、最小限の環境で動作できること。

これは私たちの核となるフレームワークに沿っています。すなわち、デプロイメントはアプリケーションロジックに漏れ出す制約ではなく、最下層のプロパティになります。


オーケストレーションのアプリケーションへの移行

マイクロサービスのメッシュでは、オーケストレーションはアプリケーションの外部に存在する傾向があります。それはルーティング、コントローラー、プラットフォームの動作に分散されています。

パート1のレイヤー化されたモデルでは、オーケストレーションは内部に移動します:

  • インデックス作成アプリケーションが「何が起こるべきか」を定義します。

  • 実行レイヤーがそれを実行し、スケーリングします。

  • インフラストラクチャがその基盤となります。

この反転こそがポータビリティを可能にするものです。なぜなら、システムはもはや単一の動作環境に固定されないからです。


なぜこれが最初に思われた以上に重要だったのか

パッケージングは、どこで実行できるかということだけではありません。以下のようなことにも影響を与えます:

  • ローカル開発がどれほど簡単か。

  • 環境間で動作がどれほど一貫しているか。

  • 新しいデプロイメントがどれだけの運用表面積を引き継ぐか。

パッケージングがシンプルになると、ロールアウト、デバッグ、サポート、オンボーディングなど、下流にあるすべてのこともシンプルになります。


3 - 統一された実行レイヤーの選択:理想と現実

図3: ルーティング、スケーリング、信頼性を担う単一の基盤

パート1では、Indexing 3.0をマイクロサービスメッシュから効率的なレイヤーへと移行するものとして位置づけました。そこでは、アプリケーションロジックは一貫した状態を保ち、実行レイヤーが分散処理を担当し、インフラストラクチャレイヤーは交換可能になります。

このセクションは、そのストーリーの生々しい中間部分です。「私たちのインデックス作成ロジック」と「顧客が持っている任意のコンピュート」の間に位置する実行レイヤーを選択することが実際に何を意味するのか。私たちは、その統一レイヤーとしてRay Serve(Ray CoreおよびRay ServeのマネージドプロバイダーとしてAnyscaleを使用)を選択しました。この決定により実際に大きなメリットが得られましたが、直接言及するに値するコストも伴いました。


単一の抽象化がもたらす理想

統一された実行レイヤーの核となる約束はシンプルです。増大するサービス群全体でそれらのメカニズムを再構築するのではなく、並行処理、スケーリング、およびフォールトハンドリングを表現するための単一の場所を提供します。

Ray Serveのサービングモデルはその約束を具体化します:

  • リクエストはHTTP(またはgRPC)プロキシから入り、キューに入れられて利用可能なレプリカにルーティングされ、ユーザーコードを実行するレプリカアクターによって実行されます。

  • Serveは単一のイングレスポイントだけでなく、スケーラビリティと高可用性のために複数のプロキシをサポートしています。

  • モデルコンポジションのためにサービスがDeploymentHandlesを介して相互に呼び出す場合でも同じリクエストパスが適用されるため、内部コンポジションでルーティング挙動とバッチ処理挙動を共有できます。

インデックス作成プラットフォームを構築している場合、インデックス作成は単一のモデル呼び出しではないため、これは魅力的です。それはマルチステージのフローであり、各ステージには並行処理制御と失敗セマンティクスが必要です。統一された実行レイヤーは、「多くの場当たり的なスケジューラーでこれを繋ぎ合わせた」状況と「標準化できる単一のスケジューリング基盤がある」状況との分かれ目になります。

これは、パート1のパッケージングとデプロイメントの推進要因にも合致します。オーケストレーションロジックが、Kubernetesコントローラーやマイクロサービスの接着コードに分散されるのではなく、実行レイヤー内にある場合、アーキテクチャを書き換えることなくさまざまな環境で実行できるシステムに近づきます。


インデックス作成ワークロードの現実

過小評価されがちな部分は、実行レイヤーはただではないということです。それは独自のリクエストパス、独自のコントロールプレーン、そして独自のパフォーマンス特性をもたらします。Ray Serveの独自のドキュメントでも、最も一般的な問題はリクエストパスにおける高レイテンシと低スループットであり、監視すべき特定のルーターと処理レイテンシの指標を示しています。

ビデオのインデックス作成において、それは重要です。なぜなら、ワークロードの形状がオーバーヘッドを増幅させる傾向があるからです。


現実 #1: リクエスト・ルーティングのオーバーヘッドは本物であり、無視できない

Ray Serveのアーキテクチャは、リクエストをプロキシ経由でルーティングし、キューに入れ、実行前に利用可能なレプリカを選択します。これは一般的なサービングには合理的なデフォルトですが、コードが実行される前にもフレームワーク側の処理が発生していることを意味します。

アプリケーションがステージ間に多くの「小さなホップ」を抱えている場合、そのルーティングオーバーヘッドがエンドツーエンドのレイテンシの測定可能な部分になる可能性があります。抽象化は、システムを構築するのには役立ちますが、同時にコンポジションのコストについても考慮に入れておく必要があることを意味します。

これは仮定の話ではありません。Rayのパフォーマンス調整ガイダンスでは、リクエストパスのボトルネックの診断について明確に議論されており、問題のシグナルとしてルーターのスループットとキューイングのレイテンシを指し示しています。そして、Rayエコシステムは、要求の厳しいサービングワークロードにおけるレイテンシを削減するためのカスタムルーティングの新しいサポートなど、ファーストクラスのパフォーマンスレバーとしてリクエストルーティングへの投資を続けています。

インデックス作成における実用的な教訓は、「フレームワークのオーバーヘッドはシステムの一部である」ということです。特に、オーバーヘッドが全体の時間に対して大きな割合を占める短いジョブがワークロードに多く含まれる場合は、それを測定し、プロファイリングし、それを考慮して設計する必要があります。まさにその「短いビデオのセットアップコスト」というダイナミクスが、パート1で述べた破綻の引き金の一つでした。


現実 #2: ビデオデコードは核であり、多くの場合はCPUバウンドである

ビデオのインデックス作成について、「GPU推論と少しの接着剤」として語るのは簡単です。実際には、デコードはパイプラインの中で最も影響の大きい部分の一つであり、コーデック、フォーマット、およびハードウェアデコードが利用可能かどうかに応じて、大幅にCPUバウンドになる可能性があります。

  • NVIDIAのNVDECドキュメントでは、このトレードオフを明確にしています。デコードがNVDECにオフロードされると、CPUは他の作業のために解放されます。これは、そのオフロードがない場合のデフォルトパスが、意味のある量のCPUを消費するということを言い換えています。

  • 現代のPyTorchエコシステムツールであっても、CUDAデコードはデコードステップにおいてCPUデコードよりも高速になるため、アクセラレーションパスとして位置づけられています。しかし、重要な注意事項があります。ハードウェアデコーダーでコーデックやフォーマットがサポートされていない場合、CUDAデコードはCPUデコードにフォールバックする可能性があります。

インデックス作成プラットフォームにとって、CPU容量はオプションのバックグラウンドノイズではありません。たとえ「メインのステージ」がGPUモデルであったとしても、それが主要なボトルネックになり得ます。また、最も好ましくない類のリソース使用状態に陥る可能性もあります:CPUデコードが飽和しているためにGPUがアイドル状態になる。これが、「不均一なリソースプロファイル」が抽象的な論点ではない理由です。デコード単体でも、CPUをファーストクラスのスケジューリングディメンションとして扱わざるを得なくなる可能性があります。


現実 #3: 不均一なステージには明示的なリソースモデリングが必要である

インデックス作成のワークロードは、デフォルトでリソースが不均一です:

  • ダウンロードとI/Oフェーズ

  • CPU負荷が高くなり得るデコードフェーズ

  • GPU負荷が高くなり得るエンベディングフェーズ

  • CPUとメモリの負荷が大きく変動し得る後処理フェーズ

これら要件を明示的にモデリングする場合にのみ、統一された実行レイヤーが価値を発揮します。Ray Coreは、タスクとアクターに対するCPUやGPUなどの論理的なリソース要件の指定をサポートしており、十分なリソースを持つノード上でのみそれらをスケジュールします。あるステージが別のステージを黙って枯渇させたり、ボトルネックとなっているステージがサポートできる速度を超えて並行処理が増大したりする障害モードを回避したい場合には、その機能が不可欠です。

これはまた、パート1における「効率化されたレイヤー」への再考が、運用上現実のものとなる場所でもあります。コードをレイヤー化するだけでなく、リソースセマンティクスをレイヤー化するのです。インデックス作成プラットフォームがフローを表現し、実行レイヤーが並行処理と配置を強制し、インフラストラクチャレイヤーが物理的な基盤を提供します。


教訓: 抽象化は作業をなくすわけではなく、置き換えるだけである

強力な実行レイヤーは、エンジニアリングの作業をなくすわけではありません。それを置き換えるだけです。独自のオーケストレーションコードを書く代わりに、リクエストパスの理解、インストルメンテーションとチューニング、そしてフレームワークの挙動とワークロード形状の一致に、より多くの時間を費やすことになります。

また、私たちが学んだ、明示的に述べる価値のある2つ目の教訓があります。それは、早い段階で統一された実行レイヤーを頼りにするのであれば、その背後にあるプラットフォームチームを自社チームの延長として扱うべきだということです。

Ray ServeとAnyscaleは私たちにレバレッジをもたらしてくれましたが、同時に本番規模のビデオワークロード下でしか現れない、真のエッジケースにも遭遇しました。私たちはAnyscaleのRay Serveチームと密接に連携し、ボトルネックを特定し、再現可能なケースを提供し、修正を繰り返しました。一部の問題は最初非常に大変でしたが、このコラボレーションは、時間をかけてこの賭けを持続可能なものにした要素の一部です。変化の激しいサービングスタックにおいて、その関係性は後付けで考えるべきものではありません。それはアーキテクチャの一部なのです。


4 - 乱れなく複数のデプロイ環境をサポートする

図4: 1つの概念的なプラットフォーム、多くの基盤

私たちはパート1で、「デプロイメントの形態は変数であるべきであり、システムの定義機能であってはならない」という強い主張をしました。このセクションは、実際にそれを実現するために何が必要かについてです。


デプロイメントは後回しにするものではなく、設計の軸である

顧客がインデックス作成の出力に依存するようになると、デプロイメントの制約を変更することは困難になります。システムが1つのコントロールプレーンや1つの運用モデルに溶接されている場合、新しい環境を構築するたびに、コードの書き換えかフォークのいずれかが必要になります。

Indexing 3.0では、「どこで実行するか」を後回しのパッケージング作業としてではなく、アーキテクチャへの最優先の入力情報として扱います。


断片化のない柔軟性

複数の環境をサポートすることは、複数のプラットフォームを維持管理することを意味しません。

目的は、環境固有の問題を可能な限り最下層に押し下げた、1つの概念的なシステムにすることです。これはパート1と同じレイヤー化の原則です。アプリケーションロジックの変更を強制することなく、インフラストラクチャは交換可能であるべきです。

実質的には、以下のことを意味します:

  • 環境間でコアとなるインデックス作成動作の一貫性を維持する。

  • 違いを構成設定、デプロイツール、および薄いアダプターに隔離する。

  • 時間の経過とともに密かに分岐していく「特殊ケース」のコードパスを避ける。


デプロイメントの現実を無視することの隠れたコスト

デプロイメントの多様性を無視すると、いずれにせよプラットフォームは断片化します。ただ単に、場当たり的なフォーク、その場しのぎのパッチ、そして環境固有の運用プレイブックを通じて断片化していくだけです。

事前に複数の環境を考慮して設計することは、後からその断片化の代償を支払うよりも費用対効果が高くなります。それはまた、進化できるシステムと、ビジネスがデプロイの前提を変更するたびにリプレイスしなければならないシステムとの違いでもあります。


結論: 人をスケールさせるインフラは、他のすべてをスケールさせる

Indexing 3.0は、パフォーマンス目標から始まったわけではありません。それは、多くのMLチームが最終的に直面する一つの問いから始まりました:

システムは機能しているが、それを真に理解している人物がごく一部であり、かつそれが1つの環境でしか機能しない場合、何が起こるだろうか?

私たちが学んだ答えは、進歩が微妙でありながら複合的な形で遅くなる、ということでした。変更にはより多くの時間がかかるようになります。デプロイは脆くなります。オンボーディングは考古学の探求のようになります。そして、便宜上行われたアーキテクチャ上の決定が、静かに長期的な制約として固まっていきます。

Indexing 3.0の最も有意義な成果は、単一の技術的機能ではなく、システムが可能にする変化です:

  • 調整のボトルネックなしに、より多くのエンジニアが貢献できること

  • 同じコアプラットフォームをクラウド、オンプレミス、および制約のある環境で実行できること

  • デプロイ形態がアーキテクチャの複雑さを左右しなくなること

  • システムがシンプルになるため、コストとパフォーマンスの最適化が扱いやすくなること

より広範な教訓は、ビデオのインデックス作成をはるかに超えて適用できると私たちが信じている教訓です。

MLインフラにおいて、スケーリングがモデルやハードウェアだけで阻まれることはほとんどありません。それは、推論が困難で、当初の想定外の環境へのデプロイが困難で、新しい人々が安全に変更を加えることが困難なシステムによって阻まれるのです。

そのような文脈において、シンプルさとは、意欲の欠如ではありません。それは、局所的な賢さをグローバルなレバレッジと引き換えにする、意図的な設計の選択です。

Indexing 3.0は、今後の取り組みにおいてインフラを解きほぐす作業を減らし、ビデオ理解が可能にするものを前進させることへより集中できるように、そのレバレッジを基礎に組み込むための私たちの試みです。

パート1では、これまでのインデックス作成プラットフォームが「機能して」いたにもかかわらず、なぜスケーリングの限界に達したのかを示しました。その制限要因は、生のモデルのスループットではなく、アプリケーションにインフラストラクチャの前提が組み込まれたマイクロサービス多用のシステムに伴う運用上および組織上のオーバーヘッドでした。チームとプロダクトの領域が拡大するにつれて、調整コスト、サービス間をまたぐデバッグ、デプロイメントの結合が日々のエンジニアリング速度を支配し始めました。核となった再考は、インデックス作成を一貫したポータブルなシステムとして扱うことでした。つまり、マイクロサービスのメッシュから、アプリケーションロジックの可読性を維持する効率化されたレイヤーへと移行し、実行レイヤーが分散処理を担当し、インフラストラクチャは定義的なものではなく交換可能なものにすることでした。このレイヤー化された視点により、コントロールプレーンの相互作用から動作を再導出することなく、ビデオ → 再利用可能な表現 → 下流の検索/生成というエンドツーエンドのパスをより容易に推論できるようになります。

パート2では、その再考を現実にした具体的な設計の選択肢を紐解いていきます。なぜ統合によって拡張性が低下するどころか向上したのか、「シングルコンテナ」がパッケージングの制約として何を意味するのか、統一された実行レイヤーに賭けることで何を得て(そして何を支払うのか)、プラットフォームを断片化することなく複数のデプロイ環境向けにどのように設計したのか、について説明します。


1 - イデオロギーではなく、実現要因としての統合

図1: 境界が減ることで、より迅速な推論が可能に

私たちはパート1で、Indexing 2.0における本当の代償は「コンピュートの不足」ではなく、境界の蓄積であったと主張しました。各ステージが独自のサービス契約、デプロイアーティファクト、および推論すべき障害モードになってしまいました。各ステップが個別のサービス境界になると、システムのデバッグ、パッケージング、および進化が難しくなりました。

Indexing 3.0では、その境界の表面積を削減するためのレバーとして統合を利用しています。これは「ただ単にモノリスを作る」ということではありません。重要なのは、システムが必要な部分ではモジュール性を維持しつつ、真の独立性が得られない場所での調整オーバーヘッドの支払いをやめることです。


境界を減らすことで柔軟性が制限されるどころか向上した理由

プロダクションのMLシステムにおける柔軟性は、最も多くの「箱」を持つことから生まれるわけではありません。フリートの半分を同期させることなく、動作を変更できることから生まれます。

統合は、以下のような方法で役立ちました:

  • 変更時に安定した状態を維持しなければならない、サービス間のデータ契約の数を削減する。

  • ランタイム、トレースシステム、およびデプロイパイプライン間の変換のためだけに存在する「接着コード」を崩壊させる。

  • エンドツーエンドのインデックス作成パスを1つの一貫したフローとしてより容易に推論できるようにする。


開発者体験を倍増させる手段としての統合

私たちはパート1で、言語とランタイムの境界(一部のインフラ用のGo、MLワークフロー用のPython)が摩擦を生み出したことを指摘しました。インターフェースが常にクリーンであるとは限らなかったためです。

統合こそが、その摩擦を解消する手段です。

実際には、以下の点が改善されます:

  • デバッグ:エラーがシリアライズされ、ラップされ、再試行され、コンテキストが失われる場所が減ります。

  • プロファイリング:サービスをまたいでログを繋ぎ合わせることなく、ステージ間のレイテンシと使用率を容易にトレースできます。

  • オンボーディング:エンジニアが1つのコードパスをたどり、メンタルモデルをより迅速に構築できます。


意図的に制限された狭い表面積

統合は、システムの目的が限定されている場合にのみ機能します。インデックス作成は「ビデオが入力され、再利用可能な表現が出力される」変換レイヤーです。そのスコープを明確に保つことで、コードベースを不要なものの寄せ集めにすることなく、統合によって付随的な複雑さを削減できます。


2 - パッケージングの再考:「シングルコンテナ」が実際に意味すること

図2: 各環境で自己完結型のユニットとして実行

パート1で主張したように、デプロイメントの柔軟性は、単なる「あれば良いもの」ではなく、最優先の制約として表れました。「完全なプラットフォーム」のように見える環境もあれば、「コンテナランタイムといくつかのノブ」のように見える環境もあります。Indexing 3.0は、その全領域にわたって動作する必要がありました。

「シングルコンテナ」とは、その制約を表すパッケージングの略称です。


「シングルコンテナ」とは、圧縮ではなく切り離しのこと

目的は、すべてのコンポーネントを1つの肥大化したイメージに詰め込むことではありません。目的は、インフラストラクチャ固有のコントロールプレーンプリミティブに依存することなく、インデックス作成システムを実行可能にすることです。

実用的な定義は以下の通りです:

  • システムを自己完結型のユニットとしてデプロイできること。

  • コアとなるオーケストレーションを実行するために、Kubernetes API(または同様のもの)を必要としないこと。

  • アーキテクチャの分岐なしに、最小限の環境で動作できること。

これは私たちの核となるフレームワークに沿っています。すなわち、デプロイメントはアプリケーションロジックに漏れ出す制約ではなく、最下層のプロパティになります。


オーケストレーションのアプリケーションへの移行

マイクロサービスのメッシュでは、オーケストレーションはアプリケーションの外部に存在する傾向があります。それはルーティング、コントローラー、プラットフォームの動作に分散されています。

パート1のレイヤー化されたモデルでは、オーケストレーションは内部に移動します:

  • インデックス作成アプリケーションが「何が起こるべきか」を定義します。

  • 実行レイヤーがそれを実行し、スケーリングします。

  • インフラストラクチャがその基盤となります。

この反転こそがポータビリティを可能にするものです。なぜなら、システムはもはや単一の動作環境に固定されないからです。


なぜこれが最初に思われた以上に重要だったのか

パッケージングは、どこで実行できるかということだけではありません。以下のようなことにも影響を与えます:

  • ローカル開発がどれほど簡単か。

  • 環境間で動作がどれほど一貫しているか。

  • 新しいデプロイメントがどれだけの運用表面積を引き継ぐか。

パッケージングがシンプルになると、ロールアウト、デバッグ、サポート、オンボーディングなど、下流にあるすべてのこともシンプルになります。


3 - 統一された実行レイヤーの選択:理想と現実

図3: ルーティング、スケーリング、信頼性を担う単一の基盤

パート1では、Indexing 3.0をマイクロサービスメッシュから効率的なレイヤーへと移行するものとして位置づけました。そこでは、アプリケーションロジックは一貫した状態を保ち、実行レイヤーが分散処理を担当し、インフラストラクチャレイヤーは交換可能になります。

このセクションは、そのストーリーの生々しい中間部分です。「私たちのインデックス作成ロジック」と「顧客が持っている任意のコンピュート」の間に位置する実行レイヤーを選択することが実際に何を意味するのか。私たちは、その統一レイヤーとしてRay Serve(Ray CoreおよびRay ServeのマネージドプロバイダーとしてAnyscaleを使用)を選択しました。この決定により実際に大きなメリットが得られましたが、直接言及するに値するコストも伴いました。


単一の抽象化がもたらす理想

統一された実行レイヤーの核となる約束はシンプルです。増大するサービス群全体でそれらのメカニズムを再構築するのではなく、並行処理、スケーリング、およびフォールトハンドリングを表現するための単一の場所を提供します。

Ray Serveのサービングモデルはその約束を具体化します:

  • リクエストはHTTP(またはgRPC)プロキシから入り、キューに入れられて利用可能なレプリカにルーティングされ、ユーザーコードを実行するレプリカアクターによって実行されます。

  • Serveは単一のイングレスポイントだけでなく、スケーラビリティと高可用性のために複数のプロキシをサポートしています。

  • モデルコンポジションのためにサービスがDeploymentHandlesを介して相互に呼び出す場合でも同じリクエストパスが適用されるため、内部コンポジションでルーティング挙動とバッチ処理挙動を共有できます。

インデックス作成プラットフォームを構築している場合、インデックス作成は単一のモデル呼び出しではないため、これは魅力的です。それはマルチステージのフローであり、各ステージには並行処理制御と失敗セマンティクスが必要です。統一された実行レイヤーは、「多くの場当たり的なスケジューラーでこれを繋ぎ合わせた」状況と「標準化できる単一のスケジューリング基盤がある」状況との分かれ目になります。

これは、パート1のパッケージングとデプロイメントの推進要因にも合致します。オーケストレーションロジックが、Kubernetesコントローラーやマイクロサービスの接着コードに分散されるのではなく、実行レイヤー内にある場合、アーキテクチャを書き換えることなくさまざまな環境で実行できるシステムに近づきます。


インデックス作成ワークロードの現実

過小評価されがちな部分は、実行レイヤーはただではないということです。それは独自のリクエストパス、独自のコントロールプレーン、そして独自のパフォーマンス特性をもたらします。Ray Serveの独自のドキュメントでも、最も一般的な問題はリクエストパスにおける高レイテンシと低スループットであり、監視すべき特定のルーターと処理レイテンシの指標を示しています。

ビデオのインデックス作成において、それは重要です。なぜなら、ワークロードの形状がオーバーヘッドを増幅させる傾向があるからです。


現実 #1: リクエスト・ルーティングのオーバーヘッドは本物であり、無視できない

Ray Serveのアーキテクチャは、リクエストをプロキシ経由でルーティングし、キューに入れ、実行前に利用可能なレプリカを選択します。これは一般的なサービングには合理的なデフォルトですが、コードが実行される前にもフレームワーク側の処理が発生していることを意味します。

アプリケーションがステージ間に多くの「小さなホップ」を抱えている場合、そのルーティングオーバーヘッドがエンドツーエンドのレイテンシの測定可能な部分になる可能性があります。抽象化は、システムを構築するのには役立ちますが、同時にコンポジションのコストについても考慮に入れておく必要があることを意味します。

これは仮定の話ではありません。Rayのパフォーマンス調整ガイダンスでは、リクエストパスのボトルネックの診断について明確に議論されており、問題のシグナルとしてルーターのスループットとキューイングのレイテンシを指し示しています。そして、Rayエコシステムは、要求の厳しいサービングワークロードにおけるレイテンシを削減するためのカスタムルーティングの新しいサポートなど、ファーストクラスのパフォーマンスレバーとしてリクエストルーティングへの投資を続けています。

インデックス作成における実用的な教訓は、「フレームワークのオーバーヘッドはシステムの一部である」ということです。特に、オーバーヘッドが全体の時間に対して大きな割合を占める短いジョブがワークロードに多く含まれる場合は、それを測定し、プロファイリングし、それを考慮して設計する必要があります。まさにその「短いビデオのセットアップコスト」というダイナミクスが、パート1で述べた破綻の引き金の一つでした。


現実 #2: ビデオデコードは核であり、多くの場合はCPUバウンドである

ビデオのインデックス作成について、「GPU推論と少しの接着剤」として語るのは簡単です。実際には、デコードはパイプラインの中で最も影響の大きい部分の一つであり、コーデック、フォーマット、およびハードウェアデコードが利用可能かどうかに応じて、大幅にCPUバウンドになる可能性があります。

  • NVIDIAのNVDECドキュメントでは、このトレードオフを明確にしています。デコードがNVDECにオフロードされると、CPUは他の作業のために解放されます。これは、そのオフロードがない場合のデフォルトパスが、意味のある量のCPUを消費するということを言い換えています。

  • 現代のPyTorchエコシステムツールであっても、CUDAデコードはデコードステップにおいてCPUデコードよりも高速になるため、アクセラレーションパスとして位置づけられています。しかし、重要な注意事項があります。ハードウェアデコーダーでコーデックやフォーマットがサポートされていない場合、CUDAデコードはCPUデコードにフォールバックする可能性があります。

インデックス作成プラットフォームにとって、CPU容量はオプションのバックグラウンドノイズではありません。たとえ「メインのステージ」がGPUモデルであったとしても、それが主要なボトルネックになり得ます。また、最も好ましくない類のリソース使用状態に陥る可能性もあります:CPUデコードが飽和しているためにGPUがアイドル状態になる。これが、「不均一なリソースプロファイル」が抽象的な論点ではない理由です。デコード単体でも、CPUをファーストクラスのスケジューリングディメンションとして扱わざるを得なくなる可能性があります。


現実 #3: 不均一なステージには明示的なリソースモデリングが必要である

インデックス作成のワークロードは、デフォルトでリソースが不均一です:

  • ダウンロードとI/Oフェーズ

  • CPU負荷が高くなり得るデコードフェーズ

  • GPU負荷が高くなり得るエンベディングフェーズ

  • CPUとメモリの負荷が大きく変動し得る後処理フェーズ

これら要件を明示的にモデリングする場合にのみ、統一された実行レイヤーが価値を発揮します。Ray Coreは、タスクとアクターに対するCPUやGPUなどの論理的なリソース要件の指定をサポートしており、十分なリソースを持つノード上でのみそれらをスケジュールします。あるステージが別のステージを黙って枯渇させたり、ボトルネックとなっているステージがサポートできる速度を超えて並行処理が増大したりする障害モードを回避したい場合には、その機能が不可欠です。

これはまた、パート1における「効率化されたレイヤー」への再考が、運用上現実のものとなる場所でもあります。コードをレイヤー化するだけでなく、リソースセマンティクスをレイヤー化するのです。インデックス作成プラットフォームがフローを表現し、実行レイヤーが並行処理と配置を強制し、インフラストラクチャレイヤーが物理的な基盤を提供します。


教訓: 抽象化は作業をなくすわけではなく、置き換えるだけである

強力な実行レイヤーは、エンジニアリングの作業をなくすわけではありません。それを置き換えるだけです。独自のオーケストレーションコードを書く代わりに、リクエストパスの理解、インストルメンテーションとチューニング、そしてフレームワークの挙動とワークロード形状の一致に、より多くの時間を費やすことになります。

また、私たちが学んだ、明示的に述べる価値のある2つ目の教訓があります。それは、早い段階で統一された実行レイヤーを頼りにするのであれば、その背後にあるプラットフォームチームを自社チームの延長として扱うべきだということです。

Ray ServeとAnyscaleは私たちにレバレッジをもたらしてくれましたが、同時に本番規模のビデオワークロード下でしか現れない、真のエッジケースにも遭遇しました。私たちはAnyscaleのRay Serveチームと密接に連携し、ボトルネックを特定し、再現可能なケースを提供し、修正を繰り返しました。一部の問題は最初非常に大変でしたが、このコラボレーションは、時間をかけてこの賭けを持続可能なものにした要素の一部です。変化の激しいサービングスタックにおいて、その関係性は後付けで考えるべきものではありません。それはアーキテクチャの一部なのです。


4 - 乱れなく複数のデプロイ環境をサポートする

図4: 1つの概念的なプラットフォーム、多くの基盤

私たちはパート1で、「デプロイメントの形態は変数であるべきであり、システムの定義機能であってはならない」という強い主張をしました。このセクションは、実際にそれを実現するために何が必要かについてです。


デプロイメントは後回しにするものではなく、設計の軸である

顧客がインデックス作成の出力に依存するようになると、デプロイメントの制約を変更することは困難になります。システムが1つのコントロールプレーンや1つの運用モデルに溶接されている場合、新しい環境を構築するたびに、コードの書き換えかフォークのいずれかが必要になります。

Indexing 3.0では、「どこで実行するか」を後回しのパッケージング作業としてではなく、アーキテクチャへの最優先の入力情報として扱います。


断片化のない柔軟性

複数の環境をサポートすることは、複数のプラットフォームを維持管理することを意味しません。

目的は、環境固有の問題を可能な限り最下層に押し下げた、1つの概念的なシステムにすることです。これはパート1と同じレイヤー化の原則です。アプリケーションロジックの変更を強制することなく、インフラストラクチャは交換可能であるべきです。

実質的には、以下のことを意味します:

  • 環境間でコアとなるインデックス作成動作の一貫性を維持する。

  • 違いを構成設定、デプロイツール、および薄いアダプターに隔離する。

  • 時間の経過とともに密かに分岐していく「特殊ケース」のコードパスを避ける。


デプロイメントの現実を無視することの隠れたコスト

デプロイメントの多様性を無視すると、いずれにせよプラットフォームは断片化します。ただ単に、場当たり的なフォーク、その場しのぎのパッチ、そして環境固有の運用プレイブックを通じて断片化していくだけです。

事前に複数の環境を考慮して設計することは、後からその断片化の代償を支払うよりも費用対効果が高くなります。それはまた、進化できるシステムと、ビジネスがデプロイの前提を変更するたびにリプレイスしなければならないシステムとの違いでもあります。


結論: 人をスケールさせるインフラは、他のすべてをスケールさせる

Indexing 3.0は、パフォーマンス目標から始まったわけではありません。それは、多くのMLチームが最終的に直面する一つの問いから始まりました:

システムは機能しているが、それを真に理解している人物がごく一部であり、かつそれが1つの環境でしか機能しない場合、何が起こるだろうか?

私たちが学んだ答えは、進歩が微妙でありながら複合的な形で遅くなる、ということでした。変更にはより多くの時間がかかるようになります。デプロイは脆くなります。オンボーディングは考古学の探求のようになります。そして、便宜上行われたアーキテクチャ上の決定が、静かに長期的な制約として固まっていきます。

Indexing 3.0の最も有意義な成果は、単一の技術的機能ではなく、システムが可能にする変化です:

  • 調整のボトルネックなしに、より多くのエンジニアが貢献できること

  • 同じコアプラットフォームをクラウド、オンプレミス、および制約のある環境で実行できること

  • デプロイ形態がアーキテクチャの複雑さを左右しなくなること

  • システムがシンプルになるため、コストとパフォーマンスの最適化が扱いやすくなること

より広範な教訓は、ビデオのインデックス作成をはるかに超えて適用できると私たちが信じている教訓です。

MLインフラにおいて、スケーリングがモデルやハードウェアだけで阻まれることはほとんどありません。それは、推論が困難で、当初の想定外の環境へのデプロイが困難で、新しい人々が安全に変更を加えることが困難なシステムによって阻まれるのです。

そのような文脈において、シンプルさとは、意欲の欠如ではありません。それは、局所的な賢さをグローバルなレバレッジと引き換えにする、意図的な設計の選択です。

Indexing 3.0は、今後の取り組みにおいてインフラを解きほぐす作業を減らし、ビデオ理解が可能にするものを前進させることへより集中できるように、そのレバレッジを基礎に組み込むための私たちの試みです。