研究開発部の takahi_iです。本稿ではクックパッド研究開発部の機械学習チームに所属するメンバがタスクに取り組む体制および、働く環境について解説します。
準備
機械学習はそれら単体が学ぶのにコストが掛かる分野で、高い専門性を獲得するためには多くの時間をかける必要があります。そのため機械学習の専門家はソフトウェア開発を十分に経験する 機会を得られにくい状況にあります。
このような前提において民間企業で機械学習を導入する場合、二つの可能性が考えられます。一つは完全に分業する方向で、機械学習のエキスパートはモデルだけを作り、ソフトウェアエンジニアが導入 を引き受けます。もう一つは機械学習の実験、モデル作成から導入までを一人がおこないます。
分業による利点と欠点
機械学習は日進月歩の分野です。機械学習エンジニアやデータサイエンティストといった職が単体で存在します。特に大きな組織では、機械学習のモデル作成を担当する機械学習 エキスパート(リサーチャー)とモデルの導入および運用を担当するソフトウェアエンジニアは区別されていることが多いです。
分業体制の利点
分析を担当する機械学習エキスパートと導入を担当するソフトウェアエンジニアが担当箇所を分けることで、以下のような利点があります。
- 各自が自分の専門性を追求できる
- 分業による効率化
各自が自身の専門性を磨けるので、新規性のある構成を追求したいメンバは満足できる環境です。また、うまくリソース配分ができれば、各自は自分の専門性に適合するタスクだけが与えられるために 高い生産性が期待できます。
分業体制の問題点
次に問題点を考えてみると、以下のようなものがあります。
コスト
機械学習エキスパートが機械学習のモデルだけをつくればよいという環境を作るにはコストがかかります。シンプルには社内に Jupyter サーバを立てて、そこで作業をしてもらうのが考えられますが、実際にサービスで利用するにはもう少し大掛かりな機構が必要になります。Jupyter Notebook で作ったモデルを自動でプロダクション環境にデプロイする機構や、自動デプロイされたモデルのバージョン管理、自動テストをシステムとして作り込む必要があります。
また一つのプロジェクトを遂行するにはマネージメントのコストも発生します。よくあるのがモデルは完成したが、それを組み込んでくれるソフトウェアエンジニアのリソースが足りないため数ヶ月待たされるというものです。
さらに将来システムに問題が起こった時にも、複数名をアサインする必要があるため十分な人員を確保しつづけるには頭のいたい問題です。
担当箇所が曖昧になりやすい
機械学習タスクの実装を細かく分業すればするだけ、だれが個々の箇所を担当するのかが曖昧になっていきます。たとえば多くの機械学習タスクは単純に学習器自体を適用するだけではなく、前処理を駆使して精度を上げてゆきます。この前処理部分は実験をしている時に作られ Jupyter Notebook にべた書きされています。
この前処理部分がプロダクション環境に移植されないと、入力データをモデルに入れても動作しません。ではこの前処理部分をプロダクション環境に持ってゆくのは誰でしょうか。タスクやアルゴリズムを理解しているという意味では、機械学習エキスパートですし、システムへの組み込みに慣れていることを優先するのであればソフトウェアエンジニアが適任と言えます。
通常この前処理部分の組み込みはソフトウェアエンジニアがモデルを作った機械学習エキスパート指示を受けつつ作成します。残念ながら、この共同作業は機械学習エキスパートもソフトウェアエンジニアも理解が中途半端な部分がありつつ仕上げるので、バグが混入しやすいです。さらに、精度向上が必要になった場合、前処理の書き換えが必要になる場合があります。前処理の書き換えが発生するすると、共同作業が必要になりコストは更に膨らんでゆきます。
クックパッド研究開発部の体制〜メンバがモデルの配備まで責任を持つ
現在クックパッドの研究開発部では、機械学習のモデル生成のみを担当するメンバはいません。メンバ全員が機械学習エンジニアです。ここで言う機械学習エンジニアはモデルの作成からモデルの結果を配備するところまでの責任を持ちます。
このような一人で一気通貫するシステムにも利点と欠点があります。
利点
タスクを一気通貫して受け持つ体制には以下のメリットがあります。
責任の所在が分かりやすい(責任の空白地帯が発生しにくい)
分離型ではタスクのなかの自分が興味のある部分だけ貢献して、別プロジェクトに移って行ってしまうタスクをつまみ食いするモラルハザード(タスクホッピング)が起こりがちです。
このような状況だと問題が起こった時に、貢献した人はすでに別プロジェクトをしているから問題解決は別の人がやってくれという話になります。しかし実装から数ヶ月、数年経った機械学習プロジェクトの問題解決は実装した当事者でも難しい問題です。別の人が解決にあたる場合には、さらに大きなコストが掛かってしまいます。
これに対して個人が責任を負うシステムでは、基本モデルを作ったエンジニアが責任を持つので、責任がはっきりし前処理やつなぎ込み部分において責任の空白地帯が発生しません。将来問題が起こっても、作った(もしくは正式に引き継いだ)メンバが問題の解決にあたってくれることが期待できます。
省コスト
大規模なシステムの作り込みを必要としません。機械学習エンジニアは Jupyter Notebook で実験し、自分でコードを整形、ライブラリ化し、それらをプロダクション環境にデプロイします。すくなくとも通常のサービスへのデプロイではモデル配備のために特別に自動化されたインフラは必要ありません。
問題点
とはいえ、このやり方にも問題点があります。具体的には以下の問題点があります。
知見が共有しにくい
各自が一気通貫して作業するので、各タスクの知識を一人だけが保持するという事態が起こりやすくなります。そのため、タスクの実装が適当になってしまいやすいという問題があります。
クックパッドの研究開発部ではプロジェクトの規約を提案してくれたメンバがいて、プロダクションで利用されるプロジェクトはその規約にしたがって作られています。規約には、実サービスに導入するレポジトリにはテストをつけ CI を導入する。ほかに関連するリソース(S3)の置き場、利用する Role などがあります。
専門性を磨く時間が削られる
機械学習の結果をサービスに繋ぎこむ部分にもコストがかかります。そのため各自が専門性を磨く時間は分業体制に比べて少なくなります。この状況に対応するため、研究開発部として学習をサポートする仕組みを導入しています。「5%ルール」呼ばれる仕組みで、二週間に一回(半日の間)、新しい技術をキャッチアップする時間を自由に取得できるようになっています。
さらに、この問題についてはクックパッド社の社員に提供されている作り込まれたインフラでかなり改善できていると感じています。以下の節で、機械学習エンジニアがインフラからどのような恩恵を受けているのかについて解説します。
インフラによるサポート
クックパッドで機械学習プロジェクトの作業をしていて、助かっていると感じる部分が二つあります。一つは DWH(データウェアハウス)、もう一つは各自が構築できるインフラです。
データウェアハウス(DWH)
クックパッドの社員は DWH を使って必要なデータをほぼ全て取得できます。社員がデータ取得するには分析用 SQL を入力するだけです。データ取得 SQL は機械学習用の前処理スクリプトからでも埋め込んで実行できます(詳しくはこちらを参照してください)。これによって、日々変化してゆくデータを取り込んだ状態の機械学習モデル及び出力結果をすくないコストで提供し続けられます。
作り込まれたインフラ
現在、クックパッドのインフラは ECS 上に構築されています(くわしくはこちらを参照してください)。提供される仕組みのおかげで機械学習エンジニアはプロダクション環境にインスタンスを自由に構築できます(もちろんレビューを受ける必要はあります)。
我々が機械学習に関するコンポーネントをプロダクション環境に構築するには、まずバッチや API サーバを Docker コンテナで動作するようにまとめたレポジトリを作ります。次に、Jsonnet で記述する設定ファイルに Docker イメージ、Role、環境変数などの設定を記述します。このような環境だとサーバ構築にコストがかからないですし、必要であればサーバの構成(CPU、メモリ)も設定ファイルの書き換えにより簡単に修正できます。チーム間の複雑なやり取りが必要ないので、機械学習エンジニアはすくないコストでプロダクション環境に機械学習周りの計算機リソースを構築できます。
研究開発部における省力化の取り組み
これまで述べてきたように社内環境に助けてもらっていますが、研究開発部でも実験や導入作業が効率化できるようにいろいろな取り組みをしています。
一つには研究開発部にはインフラに強いメンバがいます。彼らが高速な研究開発を支える GPU 計算機環境を作ってくれ、メンバが必要とする計算機リソースを常に確保できる状態になっています。
機械学習エンジニア自身も各自がツールをつくって自分の業務を効率化するのに役立てています。たとえば Kelnerという爆速で Keras のモデルから API サーバを構築するツールを作っているメンバもいますし、私も各プロジェクトごとに異なるポートフォーワードの設定を管理するツール、pfmを自作して自身の業務を効率化してます。
また、機械学習プロジェクトはタスクは異なっても、デプロイ方法は似ているものが多いです。たとえば、機械学習が出力する判別結果の多くはいくつかの方法で利用されます。DB や Redshift のテーブルに入れる。API サーバを立てる。検索エンジンのインデクスに登録するなどです。このあたりはタスクが変わってもやり方は変わらないため、過去の Issue やそれらを抽象化したドキュメントが役に立ちます。チームメンバが各自経験したタスクをもとにしたドキュメントを書いてくれているので、自分自身が 初めてやるタスクでも比較的低コストに実装できる環境になっています。
まとめ
このエントリではクックパッドの研究開発部における機械学習エンジニアの役割について解説しました。クックパッド研究開発部は今後も様々な取り組みに挑戦していきます。メンバを募集しているので、ご興味がある方は是非ご応募ください!