Tangle ってなに? Shopify 規模で構築されたオープンソースの ML 実験プラットフォーム

はじめに

Shopify エンジニアリングブログで 2025/12/2 に書かれていた「Tangle」理解したいけれど、内容が理解しきれなかったので、元のブログ内容を噛み砕いてみて解読してまた。

原文はこちら

 

Shopify 規模で構築されたオープンソースの MLって?

ML とは「Machine Learning(機械学習)」の略称のようです。

※sidekick解説, Gemini3図

 

 

 

原文翻訳


Alexey Volkov、スタッフエンジニア、検索製品およびツール担当

開始するには

ついに実験が終了しました。6時間後、チームメイトから再現を依頼されました。どのバージョンのノートブックを使ったのか、最新のデータを取り込んだのか、午前2時にどのパラメータを変更したのか、思い出せません。すでに行った実験を再現するために、さらに8時間かけて実験を行う必要があります

機械学習の開発はこのようには機能しないはずですが、実際にはそうなっています。開発時間の 80% は、アルゴリズムではなくデータ エンジニアリングに費やされています。

Shopify全体のチームがこの苦痛を感じていましたが、特に数十億件のクエリから数百万もの商品をランク付けする検索&ディスカバリー部門は特にそうでした。私たちはこの摩擦を許容できませんでした。 

そこで私たちは、商業規模で実戦テストを実施した機械学習実験プラットフォーム「Tangle」を構築しました。導入以来、1年以上のコンピューティング時間の節約を実現しています。

本日、プラットフォームをオープンソース化しました。

 

Tangleをオープンソース化する理由

Shopify の検索 & 検出チームは、信頼性を犠牲にすることなく ML 実験を加速するために Tangle (元々は Cloud Pipeline Studio、Shopify に入社する前に私が作成したツール) を構築しました。 

TangleはShopify全体のチームにとって有用であることが証明されています。Shopifyの規模で動作します。データサイエンティストは反復処理を高速化し、エンジニアはカスタムパイプラインコードのメンテナンスを削減します。チームメンバーはパイプラインと実行を共有し、グローバルキャッシュによりインフラコストを削減します。

Shopifyは、オープンソースへの貢献を通じて、ウェブを可能な限り良くすることに尽力しています。機械学習コミュニティ全体が私たちと同様の課題に直面していることを認識しているため、Tangleをオープンソース化することは当然の決断でした。これにより、Tangleの影響を拡大し、世界中の研究者や実務家との協力を促進できます。

問題: ML開発の6つの失敗モード

  1. エンジニアは、各実験ごとに作成したカスタム クエリを記憶し、どの段階でどのクエリが使用されたかを追跡するためのログを保持する必要があり、ミスや速度低下の原因となります。 

  2. ノートブックは構造化されずに蓄積されます。 

  3. 実験のための何時間にもわたるデータ準備が頻繁に繰り返されます。

  4. 古い結果 を再現できません。

  5. 展開にはトレーニングよりも時間がかかります

  6. 共有はできません。チームメンバーが協力したり、独自のバリエーションを試したりすることはできません。

ほとんどのプラットフォームは、これらの障害の一部は解決できますが、残りの部分は解決できません。私たちはTangleを使って、これらすべてに対処しようと決意しました。

私たちのソリューション: ビジュアルパイプライン + あらゆるコード

Tangle は、プラットフォームに依存しないオープンソースの実験プラットフォームであり、チームがビジュアル インターフェースを通じて ML およびデータ パイプラインを構築し、ローカル開発のセットアップを必要とせずにクラウド環境で実行できるようにします。

既存のツールの中には、特殊なデータ処理や機械学習の学習しかできないものもありますが、Tangleはこれらすべてを単一のパイプラインで、あらゆる組み合わせで実行できます。さらに、必要なその他の非定型的な処理も実行できます。モデルのデプロイ、人間の判断による結果ラベルの取得、人間ベースのメトリクスの計算といった、処理以外のタスクも処理します。

Tangle は、異なる言語で記述されたコンポーネントを橋渡しする場合でも、連携するように設計されていないツールを統合する場合でも、ワークフロー内のあらゆるものを接続する接着剤と考えてください。

このプラットフォームは、次の基本原則に基づいて構築されています。

プラットフォームに依存しない

Tangle は、あらゆるプログラミング言語の既存のコードベースと統合され、コードを変更することなく、あらゆるクラウド プロバイダーまたはローカル インフラストラクチャ上で実行されます。

堅牢なキャッシュ

システムはタスク実行とその成果物を追跡し、チームメンバーによるすべてのパイプライン実行において重複する計算を自動的に再利用できるようにします。生成に数時間かかった結果も、キャッシュから数秒で自動的に再利用されます。また、他のシステムとは異なり、Tangleは完全に成功したタスク実行だけでなく、まだ実行中のタスク実行も再利用できます。

ビジュアルパイプライン編集

開発者は、完全なデータ フローを有向非巡回グラフ (DAG) としてレンダリングするインタラクティブなドラッグ アンド ドロップ インターフェイスを通じてパイプラインを構築し、ノートブック コードを解析することなくパイプライン構造をすぐに確認できます。

言語中立アーキテクチャ

Tangleコンポーネントは、ファイルの読み書きを行う既存の任意のコマンドラインプログラムをラップします(ユーザーがフレームワーク固有の構造を使用してコードを書き直す必要はありません)。Python、Shell、Javascript、C#、C++、Rust、Java、Go、R、またはCLI実行が可能なあらゆる言語で記述されたコンポーネントをサポートします。

アーキテクチャ: Tangleの仕組み

Tangle のアーキテクチャは、単純な階層構造に従います。

  • コンポーネント:概念的には関数定義に似ています。コンポーネントのメタデータ (名前、説明、注釈)、インターフェース (入力/出力)、実装 (コンテナ化された CLI プログラムのテンプレート化されたコマンドライン、またはタスクのグラフ) を記述する再利用可能な仕様です。

  • タスク:概念的にはコード内の関数呼び出し行に似ています。指定された入力引数を持つコンポーネントのインスタンスを構成します。

  • 実行:概念的には関数呼び出しに似ています。パイプラインを送信すると、各タスクが実行され、出力アーティファクトが生成されます。

  • グラフ: 1つのタスクからの出力が別のタスクに入力として渡される、接続されたタスクのグラフ

  • パイプライン:ルートグラフコンポーネント。その実装はタスクのグラフです。

この宣言型モデルは、コード中心のアプローチに比べて多くの利点があります。コンポーネントはプレーンテキストのYAMLファイルであり、ライブラリとして整理、インデックス作成、検索が可能で、あらゆるソース(GitHub、ウェブ、クラウドストレージ)から安全に読み込むことができます。グローバルにインストールされたPythonパッケージとは異なり、コンポーネントは個別にバージョン管理できます。ユーザーはコンテンツハッシュで正確なバージョンを参照したり、異なるバージョンのコンポーネントを同じパイプラインに混在させて比較したり、依存関係の悪化なしに特定のコンポーネントバージョンを共有したりできます。

コンポーネント: 再利用可能なビルディングブロック

コンポーネントとは、YAML仕様で定義された自己完結的な機能単位です。コンポーネントは明確な規約に従い、入力を受け取り、特定のタスクを実行し、出力を生成し、完全に独立して動作します。

コンポーネント仕様の例を次に示します。

name: Filter text
inputs:
- {name: Text}
- {name: Pattern, default: '.*'}
outputs:
- {name: Filtered text}
implementation:
  container:
    image: python:3.11
    command:
    - sh
    - -ec
    - |
      # This is how additional packages can be installed dynamically
      python3 -m pip install pip six
      # Run the rest of the command after installing the packages.
      "$0" "$@"
    - python3
    - -u  # Auto-flush. We want the logs to appear in the console immediately.
    - -c  # Inline script
    - |
      import os
      import re
      import sys

      text_path = sys.argv[1]
      pattern = sys.argv[2]
      filtered_text_path = sys.argv[3]

      regex = re.compile(pattern)

      os.makedirs(os.path.dirname(filtered_text_path), exist_ok=True)
      with open(text_path, 'r') as reader:
          with open(filtered_text_path, 'w') as writer:
              for line in reader:
                  if regex.search(line):
                      writer.write(line)
    - {inputPath: Text}
    - {inputValue: Pattern}
    - {outputPath: Filtered text}

インライン JavaScript スクリプト コンポーネントの例を次に示します。

name: Filter Text
inputs:
  - {name: Text}
  - {name: Pattern, default: '.*'}
outputs:
  - {name: Filtered text}
implementation:
  container:
    image: node:18-slim
    command:
      - node
      - --eval
      - |
        const fs = require("fs");
        const readline = require("readline");
        const args = process.argv.slice(1);
        const [input_path, pattern, output_path] = args;
        
        const inputStream = fs.createReadStream(input_path);
        const outputStream = fs.createWriteStream(output_path);
        
        readline.createInterface({ input: inputStream })
          .on("line", (line) => {
            if (line.match(pattern)) {
              outputStream.write(line + "\n");
            }
          });
      - {inputPath: Text}
      - {inputValue: Pattern}
      - {outputPath: Filtered text}


コンテンツベースのキャッシュ

ほとんどのMLプラットフォームは系統ベースのキャッシュを使用しています。上流コンポーネントが変更されると、下流コンポーネントはすべて再実行する必要があります。Tangleはコンテンツベースのキャッシュを使用します。下流コンポーネントは出力コンテンツのハッシュをチェックし、出力が同一であればキャッシュされた結果を再利用します。これにより、パフォーマンスが大幅に向上します。

 

実世界への影響: 1つのコンポーネントのみを変更すると、10時間のパイプラインが20分で完了します。出力は同一です。

グローバルなアーティファクトの再利用: Tangleのキャッシュは、すべてのユーザー間でグローバルに動作します。3人のデータサイエンティストが前処理ステップを共有する実験を送信すると、Tangleは前処理を1回実行し、3つのパイプラインすべてでアーティファクトを共有します。これは、まだ実行中の実行であっても同じです。

データフローアーキテクチャ

Tangle コンポーネントは、メモリ内のオブジェクトではなく、ファイル パスを介して通信します。

  1. プロデューサーはローカルパスに書き込みます
  2. ストレージ(GCS、S3 など)へのシステムのアップロード
  3. コンシューマーはローカルパスから読み取ります
  4. システムは 透過的に取得します
  def filter_text(
    text_path: InputPath(),
    filtered_text_path: OutputPath(),
    pattern: str,
):
    with open(text_path, 'r') as reader:
        with open(filtered_text_path, 'w') as writer:
            for line in reader:
                if re.search(pattern, line):
                    writer.write(line)

システムは実行時にプレースホルダーを実際のファイルの場所に置き換えます。コンポーネントは標準的なファイル入出力を実装しますが、ストレージは抽象化されたままです。

実行フロー

パイプラインを送信すると、Tangle のオーケストレーターが自動的に実行を管理します。

  1. キュータスク:各タスクはキュー状態で開始されます。
  2. 依存関係を確認する:アップストリーム タスクが完了するまで待機し、入力成果物が利用可能であることを確認します。
  3. キャッシュをチェックする:実行キャッシュ キーを計算し、再利用可能な実行 (成功またはまだ実行中) を検索します。
  4. 実行または再利用:キャッシュにヒットした場合は既存の結果を再利用します。それ以外の場合は、クラウドクラスターでコンテナを起動します。
  5. 監視:コンテナの状態を追跡し、ログをキャプチャし、実行状態を更新します。
  6. 最終処理:出力成果物のメタデータ (サイズ、ハッシュ、小さな値) を保存し、下流のタスクに信号を送ります。

これは自動的に行われます。提出するとシステムが調整し、結果を監視します。

オプション型システム

Tangleはオプションの型付けを使用します。型はツールにメタデータを提供しますが、強制されるものではありません。つまり、

  • コンポーネントはI/O型(String、Float、JsonObject、ApacheParquet、TensorflowModel)を指定します。型名は任意ですが、一貫性を保つ必要があります。
  • システムは、すべてのアーティファクト データを不透明な BLOB/文字列(またはディレクトリ) として扱います。
  • 集中的なデータ検証は行われず、消費コンポーネントが独自の入力を検証します。

これが私たちの設計の根拠です:

  • オープン性:どのユーザー/チームでも独自の特殊型を宣言できる
  • パフォーマンス:実行時の検証オーバーヘッドなし
  • セキュリティ:集中検証による脆弱性の解析なし
  • 柔軟性:厳格なスキーマのないバージョン互換性

ビジュアルエディター: パイプライン開発

Tangle はパイプラインをインタラクティブな有向非巡回グラフ (DAC) としてレンダリングするため、ノートブック コードを解析する必要がなくなります。

視覚的に構築する

  • ライブラリからコンポーネントを追加する
  • 出力を入力に接続する
  • インラインでパラメータを設定する
  • ワンクリックで送信

リアルタイムで監視

  • タスク実行ステータスを追跡する
  • アーティファクトとログを表示する
  • キャッシュされたステップを識別する
  • パフォーマンスのボトルネックを発見

迅速に反復する

すべての実行は完全な系統で保存されます。これにより、実験履歴を失うことなく高速な反復処理が可能になります。

はじめる

Tangle のアーキテクチャは、どこでも実行できるように設計されています。インストールレシピのリストを拡張しています。

現時点では、Tangle はローカル (Docker/Podman ランチャーを使用) または HuggingFace (HuggingFace ジョブ ランチャーを使用) で使用できます。

ハギングフェイスから始めましょう

Tangle を試す最も簡単な方法は、HuggingFace を使用することです。

こちらにアクセスして構築を始めましょう。パイプラインの作成には登録は必要ありませんが、パイプラインを実行するには、HuggingFaceアカウントとProサブスクリプション(月額9ドル)が必要です。

パイプラインを構築する

サンプルの XGBoost トレーニング パイプラインから開始するか、最初から新しいパイプラインを構築します。

  1. コンポーネントをキャンバスにドラッグ
  2. コンポーネントを接続する(出力を入力に)
  3. タスク引数を設定する
  4. パイプラインを実行のために送信する(ログインが必要です)
  5. パイプラインの実行をリアルタイムで監視する

パイプラインを編集します。

パイプラインの実行を監視します。

すべてのパイプライン実行のリストを表示します。

HuggingFace x Tangleの統合

私たちは、ストレージ、コンピューティング、認証に HF インフラストラクチャを使用するマルチテナント サービスとして、Tangle を HuggingFace Spaces に導入しました。 

共有マルチテナントインスタンスはここで稼働しています 

Tangleのマルチテナントアーキテクチャは、中央テナントデータベース(ユーザーID、アクセストークン、オーケストレーター設定を保存)に加え、テナントごとに個別のSQLiteデータベースをメインのTangleML/tangle HuggingFace Space永続ストレージに保持します。各ユーザーのパイプラインは、そのユーザーのHuggingFaceジョブを介して実行され、実行ログと出力アーティファクトはユーザー専用のHuggingFaceデータセットリポジトリ(user/tangle_data)に保存されます。UIには、アーティファクトとHuggingFaceジョブの両方にクリック可能なリンクが用意されています。 

独自のシングルテナントインスタンスをデプロイすることもできます。これを行うには、TangleスペースをHFアカウントに複製し、HFトークンを提供します。これらのシングルテナントTangleデプロイメントでは、データベースが独自のHFスペース永続ストレージに保存されるため、完全な制御とデータの分離が可能になります。

Tangle を組織に複製すると、チーム用のシングルテナント マルチユーザー Tangle デプロイメントが実現し、複数のチーム メンバーが互いのパイプライン実行を確認し、組織全体のキャッシュを利用できるようになります。

 

ローカルで始める

GitHubのインストール手順に従ってください。 

  • Dockeruvをインストールする
  • アプリコードをダウンロードします(1回実行する必要があります)。

 

  git clone https://github.com/TangleML/tangle.git tangle/backend --branch stable
git clone https://github.com/TangleML/tangle-ui.git tangle/frontend_build --branch stable_local_build --single-branch --depth 1
  • アプリを起動します:
    Linux および Mac OS: cd tangle && backend/start_local.sh
    Windows: cd tangle && backend\start_local.cmd
  • ターミナルに start_local: オーケストレーターを開始しています」というメッセージが表示されたら、Web ブラウザーでhttp://localhost:8000 URLを開き、アプリの使用を開始します。
  • 新しいパイプラインの構築を開始するには、上部の「新しいパイプライン」ボタンをクリックします。

タングルを選ぶ理由

 

Tangle は、チームや個人向けに機械学習をより良くするために構築されました。

組織向け

  • 自動追跡と再現性: すべてのパイプライン実行は、グラフ構造、実行ログ、アーティファクトのメタデータ、メトリクスといった完全な系統情報とともに記録されます。中間データは変更不可能で上書きされることがないため、実験のリスクが軽減され、チーム間で安全に共有できます。チームメンバーは、同僚のパイプライン実行を複製し、問題を調査したり、パラメータを変更したり、再送信したりできます。これらはすべて自動的に追跡されます。
  • 時間とコンピューティングの節約: 以前に実行されたタスクはコンテンツベースのキャッシュを通じて自動的に再利用されるため、実行時間とクラウド コストの両方が節約されます。
  • コンポーネント ライブラリ: チームは再利用可能なコンポーネントの共有ライブラリを構築し、一貫したパターンを確立して開発速度を加速します。
  • エンジニア以外のユーザーもアクセス可能: プロダクト マネージャーやアナリストは、コードを記述したり開発環境を設定したりすることなくパイプラインを作成して実行できるため、実験を実行し、メトリクスを独自に追跡できます。

個人エンジニア向け

  • 摩擦のない追跡: 手動で記録する必要なく、自動的にバージョン管理と実行履歴を作成します。
  • 手動キャッシュは不要: データはインテリジェントな再利用により変換間で自動的に渡されるため、カスタム キャッシュ ロジックは必要ありません。
  • 非侵入的な統合: コンポーネントは、任意の CLI プログラム、言語、またはコンテナーを使用して、既存のコードを変更することなくラップします。
  • 構成可能な知識:コンポーネントは自己完結的で再利用可能な知識の集合体です。それぞれが複雑なフレームワークではなく、単純な関数のように動作します。TensorFlowのトレーニングループの書き方を忘れてしまった場合は、1,000行のチュートリアルを解析する代わりに、50行のコンポーネントを参照できます。コンポーネントは独立しているため、依存関係の競合がなく、複数のパイプラインで共有でき、異なるバージョンを同時に使用して比較することも可能です。
  • 言語の相互運用性: 互換性の問題なしに、Python、Java、Shell、Ruby、C++、JavaScript コンポーネントを同じパイプラインに接続します。

Shopify規模で実戦テスト済み

Tangleは、Shopifyの検索・発見チームをはじめとする多くの企業の本番環境向けMLインフラストラクチャを支え、数百万件の検索クエリと数十億点もの商品を処理しています。私たちはTangleを以下の用途に使用しています。

  • 数百万のSKUにわたる製品ランキングモデル
  • クエリスケールでのセマンティック検索実験
  • 推奨システムのトレーニング 
  • リアルタイム特徴エンジニアリングパイプライン

測定された利益

  • 反復速度:データ サイエンティストはインフラストラクチャに依存せずに毎日新しいランキング モデルを展開します。
  • 完全な再現性: 6か月前のあらゆる実験を、完全なアーティファクトの由来とともに2回のクリックで再現できます。
  • コスト最適化:グローバルキャッシュにより、毎月数千時間の無駄な計算時間を削減
  • チームコラボレーション:共有コンポーネントライブラリにより開発が加速され、一貫したパターンが確立されます

次は何か

TangleはShopifyで本番環境で稼働しています。コミュニティからのフィードバックに基づき、今後の機能の優先順位付けを進めています。 

計画されている機能

  • 主要なクラウドを直接サポート(GCP はすでにサポートされていますが、導入ドキュメントが必要です)
  • 拡張および強化されたコンポーネントライブラリ 
  • アーティファクトの可視化 

 

B!