リクルートのエンジニアが内製している機械学習基盤について詳しく解説していく本連載。初回はリクルートでクラウドネイティブな機械学習基盤を内製した理由について。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
本連載では、リクルートでデータエンジニアとして社内のデータ活用基盤の構築に携わりデータ活用を推進してきた宮井と、データサイエンティストとして分析業務や機械学習システムの開発に取り組んできた秋庭が、どのような機械学習基盤を内製してきたのか詳しく紹介していきます。
筆者らが所属するリクルートは、企業と人(B2C)、企業と企業(B2B)、人と人(C2C)、全ての間に立ち、双方にとって最適なマッチングを図る「場」を提供しています。
リクルートが提供している主なサービスを下図に示します。
このようにリクルートは複数のサービスを展開しているのが特徴です。さまざまな規模のサービスがあり、蓄積されるデータのサイズも異なります。
さまざまな規模のサービスを提供、運用していくに当たって最適なコストで機械学習基盤を構築しようとすれば、それぞれのサービスが要求する性能に合わせた柔軟なスケーリングが欠かせません。また事業のビジネス要件から特定の時間帯などに処理が集中することもあり、そういった観点からもスケーリングを検討する必要があります。大規模な組織なので高いスケーラビリティも求められます。
データセキュリティの観点では、提供しているサービスが複数あるため組織間での権限分離などを適切に実施すること、組織をまたぐ形でのデータ参照を防ぐ仕組みの導入が欠かせません。またデータの漏えいを防ぐための暗号化は必須です。
これらの要件を整理すると、オンプレミスで機械学習基盤を構築するよりクラウドを利用した機械学習基盤が適しているという結論になりました。特にオンプレミスの場合、スケーラビリティは最大のサービス規模に合わせざるを得ず、サーバリソースが余ってしまいコストの無駄が発生しかねません。またビジネス面の変化で早急な対応が必要になるサーバリソースの増減も難しくなります。セキュリティ面でも、クラウドが提供する機能を利用すればセキュリティに必要な機能を検討して構築する必要がありません。開発、運用コストの双方でメリットが多いことからクラウドでの構築を前提に設計しました。
他方で、機械学習を活用したシステムを企画、構築していくとさまざまな課題に直面します。
案件ごとに同じようなソースコードが増え、何かやるたびにインフラの準備から始めなければならない、データサイエンスに集中したいのにセキュリティやインフラなどの他の知識まで必要といった課題です。
これらの課題は機械学習に関わる三者の立場に立って要件にすると以下のようなものです。
これらの課題の方策を検討した結果、以下の3つを達成すれば解決につながると判断しました。
「機械学習を利用したシステム開発を自動化する基盤を提供」は、主にITプランナーの課題を解決するものです。データサイエンティストの作ったモデルを簡単に利用できるようにし、データエンジニアに依頼しなくても細かい設定ができる基盤を提供しようと考えました。
「データ処理プロセスを再利用可能な『モジュール』として提供」はデータサイエンスやエンジニアリングの課題を解決するものです。モジュールとは、入出力が一定のフォーマットに沿って作られたコンテナイメージのことです。再利用可能なモジュールを用意して提供することで、データサイエンスやエンジニアリングの中で同じようなコードの乱発の防止につながります。
「スケーラビリティ、セキュリティの確保されたインフラを自動で提供」はデータサイエンティストやエンジニアが注力すべきタスクに集中できることを意味しています。データサイエンスやエンジニアリングのそれぞれの領域の中でより創造性の高いタスクに注力できるよう、一定の品質を担保した環境を自動的に提供することを目指します。
これまで述べた3つの方策を満たすシステムを考えていくと「データ・ソリューション・キッチン」という概念にたどり着きました。データを食材に見立てて、ITプランナー、データサイエンティスト、エンジニアが連携してデータを料理する場=キッチンになることを示した造語です。三者がシェフとして料理に集中できるよう、他の作業を引き受けるのです。またレストランのように管理の行き届いた場で適切なデータを適切に扱うことも意味しています。こうした概念ができたことでプロダクトの方向性が定まりました。
ここからは課題を解決するために内製した社内プロダクトである「Crois(クロイス)」「Crafto(クラフト)」を紹介します。Croisは機械学習処理をメインのターゲットとしたコンテナベースのジョブスケジューラー、ワークフローエンジンです。YAMLで記述されたワークフローに従ってコンテナイメージを実行します。Craftoは機械学習の自動化基盤です。機械学習に関する深い専門知識がない担当者でも簡単にモデルを構築できます。
CraftoはCroisの機能を利用した別アプリケーションとなっており、Craftoを使うユーザーはCroisを背後で利用していることになります。Croisは単体でもジョブスケジューラとして利用できます。Craftoの機械学習処理を実行するためのコンテナ実行基盤を別途用意しようとすると開発、運用コストがかかってしまいます。そこでバックエンドにCroisを利用することでCrafto自身は機械学習関連の機能に集中して開発できるため、このような構成を採用しています。
なぜ2つのアプリケーションを分けたのか疑問に思う人もいるかもしれません。Craftoが対象としているのはアドホックな分析です。Croisのターゲットとしている定常的なバッチと用途が異なり、使われ方も異なります。
アドホックな分析では可視化機能やモデル構築特有の設定画面などが必要になります。そうしたCrafto特有の機能をCrois側に入れてしまうと、通常のバッチ用途で使っているユーザーには邪魔になってしまいます。またCraftoとCroisではターゲットとしているユーザー層にも差があり、Craftoはコードを書かなくてもよいノーコードの思想に近く作られています。このような差があるため、2つのアプリケーションを別々に提供しました。
Croisが提供している機能は以下の4つがあります。
「コンテナイメージのカタログ」は、過去に作成したコンテナイメージの再利用性を高めたいという目的で用意されたもので、Croisの大きな特徴の一つです。モジュールの一覧画面を紹介します。モジュールはCrois側から提供しているものもありますが、ユーザーが自由に登録、公開可能で、社内でのエコシステムができることを狙っています。
「ジョブスケジューラー、ワークフローエンジン」はワークフローとして定義されたフローを実行できる機能とスケジュールに沿った実行ができる機能です。CroisではワークフローをYAMLで記述し、それをシステム内部の表現にコンパイルするような処理をしてジョブを実行しています。ワークフロー設定画面とジョブ実行中の画面を紹介します。
「コンテナの実行基盤」はモジュールを実行する機能で、データに対する処理を担います。コンテナを実行するだけの機能ですが、スケーラビリティが大きく必要とされる箇所です。上の図で紹介した画面では、ダイヤグラム上の各ステップに相当します。
最後の「権限管理システム」は大規模なチームで使われることを想定した機能です。ユーザーをまとめたグループ単位でジョブの実行権限やワークフローの編集権限などを付与できる仕組みです。この機能はシステムを開発しているチームと運用をしているチームで権限を分けたいときに利用します。
Croisではこれらの提供機能を全てAPI経由で操作でき、Craftoをはじめとする他システムへの組み込みも容易です。提供しているWebUIも、APIを利用したSingle Page Application(SPA)として構築されています。
Craftoは、以下のような機能を提供しています。
「データセットの解析」は、データセットの登録時に、データタイプの推定や統計情報を計算します。Craftoでは、ローカルファイルのアップロードと「Amazon S3(Simple Storage Service)」の連携によるデータセットの登録をサポートしています。登録時に、各カラムに対して、数値、カテゴリー、テキスト、タイムスタンプを用いてデータタイプを推定します。このデータタイプは、モデル構築時のデータ変換に利用します。自動で推定されたデータタイプをそのまま使うことも、必要に応じてユーザーが変更もできます。
各カラムの平均値や最大値、欠損レコード数などの情報も自動で計算され、データタイプに応じた分布を表示できます。
「機械学習モデルの自動構築」では、複数のモデルを用いて学習します。ハイパーパラメーターサーチの実行だけでなく、データタイプに応じた欠損値の補完やエンコーディングをするため、担当者がデータ変換の前処理をする必要はありません。基本的にボタン一つで学習は完結しますが、機械学習に関する専門知識を持つ担当者向けに、最適化指標やパーティション手法の選択もできるようにしています。
「機械学習モデルの評価、可視化」の機能で、構築したモデルの理解を深めることができます。特徴量インパクトは、どのカラムが予測の精度に貢献していたかを確認できます。部分依存やワードクラウド、混同行列など、さまざまな可視化機能を用意しています。
「学習済みモデルのバッチ予測」は、未知のデータセットに対して予測します。入力となるデータセットは、学習時と同様にローカルファイルとAmazon S3に対応しています。
Croisを内製した理由は大きく分けて2つあります。1つ目はCroisの大きな特徴でもあるコンテナイメージのカタログです。モジュールを共有して、データの処理プロセスにおける車輪の再発明を少なくすることに主眼を置きました。これは他のジョブスケジューラー、ワークフローエンジンにはない機能だったため、内製で構築する必要がありました。
2つ目の理由はスケーラビリティを最小の運用工数で実現するためです。開発が始まった当時のCroisのチームメンバーは数人しかおらず、運用工数がかかりすぎると開発に手が回らない可能性もありました。また休日や深夜対応の体制も十分ではありませんでした。
一部の機能を内製して、他の機能は既存のOSS(オープンソースソフトウェア)やマネージドサービスをラップする形で構築できるでしょう。しかし、既存のOSSではマスターノードやワーカーノードを運用する必要があり、サービスが急速にスケールした場合その運用工数が課題となる可能性があります。できる限り運用に手がかからない構成を目指そうと考えていたため、既存のOSSは利用しませんでした。またフルスクラッチで開発しても同様の問題が起きるため、Croisのジョブ実行部分はマネージドサービスを活用した形で作ることになりました。そうすることで運用面の工数をクラウドサービス側に任せることが可能になり、運用の省力化が実現できます。
社内でパブリッククラウドサービスとして多く利用しているのが「Amazon Web Service(AWS)」と「Google Cloud Platform(GCP)」です。ジョブ実行部分として利用できそうなマネージドサービスはAWSに「AWS Step Functions」、GCPには「Cloud Composer」があります。
Cloud Composerは「Apache Airflow」をマネージドサービスとして提供しているものです。Airflowは、ベースとなる有向非巡回グラフ(DAG:Directed Acyclic Graph)をPythonで記述できるため柔軟性が高いメリットがあります。一方、利用を検討した当時は柔軟なスケーリング機能が提供されておらず、インスタンスサイズを変えることが難しい状況でした。
冒頭で述べた通り、リクルートには大中小さまざまな規模のサービスが複数存在しており、データサイズもさまざまです。インスタンスサイズを柔軟に設定できないと無駄なコストやスペック不足などの問題に直面することが考えられたため、検討当時のCloud Composerは要件に合わないと判断しました。選択肢はAWS Step Functionsに絞られたため、おのずとAWSで構築する流れとなりました。
次回は構築したCroisの設計を通じて、どのようにAWS Step Functionsを活用したか紹介していきます。AWS Step Functionsというフルマネージドなサービスの存在がスケーラビリティと運用工数最小化の鍵となっています。CroisはAWS Step Functionsをそのまま使うだけでは簡単に実現できないパラメーターの挿入やエラーハンドリングなどをラップすることでうまく実現しています。合わせてCraftoがどのようにCroisと連携しているかも設計と合わせて紹介する予定です。
リクルート プロダクト統括本部 プロダクト開発統括室 データ推進室 データテクノロジーユニット アジリティテクノロジー部 所属
大阪大学大学院で経営学修士および工学修士を取得。複数の企業でログ解析基盤の構築に携わり、2018年にリクルートコミュニケーションズに中途入社。データエンジニアとしてデータ解析基盤の構築に関わる。
リクルート プロダクト統括本部 プロダクト開発統括室 データ推進室 データプロダクトユニット データプロダクトマネジメント1部 所属
早稲田大学大学院を卒業後、リクルートコミュニケーションズに新卒で入社。分析業務や機械学習システムの開発に、機械学習エンジニアとして携わる。
Copyright © ITmedia, Inc. All Rights Reserved.