Re:ゼロから始めるML生活

Standing on the shoulders of Giants

ゆるふわMLOps入門(Facebook : FBLearner)

最近MLOpsに関して勉強していて、その一環で具体例の調査をしていました。

今回はFacebookのFBLearnerです。

この辺を参考にしました。

engineering.fb.com

https://s3-us-west-2.amazonaws.com/com.cloudpulsestrat/public/TWIML_ML_Platforms.pdf

https://research.fb.com/wp-content/uploads/2017/12/hpca-2018-facebook.pdf

以下は、自分があまり英語強くないので、後で見直す用に日本語のメモになります。 基本的には上の記事の内容そのままなので、悪しからず。。。

背景

facebookにおいて機械学習は、ニュースフィードのランク付けや攻撃的なコンテンツのフィルタリング、トレンドトピックのハイライトなど、多くのサービスに入り込んでいます。 こうした体験は機械学習のモデルによって実現されますが、経験を積んだ機械学習バックグラウンドのエンジニアでないとfacebookのインフラを利用することは難しい状況でした。

機械学習・AIの開発をうまく進めるには、精度の大幅な向上が必要です。 それは多くの場合、アルゴリズムの変更よりも、実験や特徴量エンジニアリング、モデルのチューニングから来ることが経験的に分かっていました。 ところが、古典的なパイプラインシステムではこうした実験的なアプローチが取りにくく、実験結果から結果の可視化や変更の副作用を捉えることも困難でした。

そのようにして、2014年には最新の機械学習・AIアルゴリズムをすべてのエンジニアが活用できるように、機械学習開発のプラットフォームの見直しをはじめました。

FBLearner

FBLearner は

  • 再利用性
  • スケーラビリティ
  • 簡単さ
  • 再現性

を重視してデザインされています。

f:id:nogawanogawa:20200229091844j:plain:w600

極力無駄な形式的な作業を排除することで特量量エンジニアリングなどに集中できるようにし、日々何千という実験を可能にしています。

現在ではFBLearnerはエンジニアリングチームの1/4に使用され、一秒に600万もの予測がなされているほどとなっています。

FBLearner Feature store

Feature Storeはエンジニアが構築済みの特徴量を発見できるようにしたしくみです。 Feature Storeによって、学習と配信時に特徴量を効果的に使用することができ、それらはfacebook内で共有され使用されていくことで開発が効率化します。

特徴量の生成facebookのデータウェアハウスから決まった手順で生成されます。 高度な型システムも有しており、これによって後続のFBLearner Flowで特徴量を使うことができます。

FBLearner Flow

FBLearner Flowは学習から評価までを受け持つプラットフォームです。

FBLearnerでの記述

FBLearner Flowでは、ユーザーはPythonと特殊なDecoratorを使用して処理を記述していきます。 これによって、各workflowを管理・実行していきます。

FBLearner Flow内で使用される抽象化された概念は下記のようなものがあります。

  • Workflows
    • FB Learner内で定義されるパイプラインの単位で、学習や評価といった単位の処理を表す
  • Operators
    • WorkFlowの構成要素で、Pythonの関数のようなもの
  • Channels
    • Operatorの入出力

構成要素

上記のような概念モデルを使用してパイプラインを記述し、実行管理までできるようになっています。

ワークフローの記述と実行環境

ブログ記事にあるサンプルコードは下記の様になっています。

# The typed schema of the Hive table containing the input data
feature_columns = (
    ('petal_width', types.INTEGER),
    ('petal_height', types.INTEGER),
    ('sepal_width', types.INTEGER),
    ('sepal_height', types.INTEGER),
)
label_column = ('species', types.TEXT)
all_columns = feature_columns + (label_column,)

# This decorator annotates that the following function is a workflow within
# FBLearner Flow
@workflow(
    # Workflows have typed inputs and outputs declared using the FBLearner type
    # system
    input_schema=types.Schema(
        labeled_data=types.DATASET(schema=all_columns),
        unlabeled_data=types.DATASET(schema=feature_columns),
    ),
    returns=types.Schema(
        model=types.MODEL,
        mse=types.DOUBLE,
        predictions=types.DATASET(schema=all_columns),
    ),
)
def iris(labeled_data, unlabeled_data):
    # Divide the dataset into separate training and evaluation dataset by random
    # sampling.
    split = SplitDatasetOperator(labeled_data, train=0.8, evaluation=0.2)

    # Train a decision tree with the default settings then evaluate it on the
    # labeled evaluation dataset.
    dt = TrainDecisionTreeOperator(
        dataset=split.train,
        features=[name for name, type in feature_columns],
        label=label_column[0],
    )
    metrics = ComputeMetricsOperator(
        dataset=split.evaluation,
        model=dt.model,
        label=label_column[0],
        metrics=[Metrics.LOGLOSS],
    )

    # Perform predictions on the unlabeled dataset and produce a new dataset
    predictions = PredictOperator(
        dataset=unlabeled_data,
        model=dt.model,
        output_column=label_column[0],
    )

    # Return the outputs of the workflow from the individual operators
    return Output(
        model=dt.model,
        logloss=metrics.logloss,
        predictions=predictions,
    )

ここでいうところの、"@workflow"デコレータがiris関数を、Pythonの関数ではなくworkflowだと指定しています。 @workflowで記述されているのは、入出力のデータ形式になっています。

iris関数の中は、各種オペレータで記述され、処理の中身は抽象化されています。 これによって実行時に、DAGの解析とDAGに基づくOperatorの実行が行われます。 上記の様に記述されたOperatorの依存関係から、DAGが構築され並列実行を可能になっています。

f:id:nogawanogawa:20160509092522j:plain:w600

実行時には、必要な実行リソースがoperatorごとに割り当てられ、それぞれ実行されるようになっています。

実験管理UI

facebook内でも大量のworkflowが実行されており、これらを可視化することは重要な課題でした。 それぞれのworkflowの内部の詳細を理解することなく、処理を実行・確認できるカスタムUIを実装しています。

ワークフローの実行

各workflowには入力が定義されますが、それをGUIで制御できるようになっています。 これによって、複雑なデータ形式でもかんたんに取り扱うことができるようになります。

f:id:nogawanogawa:20160509092608j:plain:w600

出力の可視化

UIから、workflowの実行結果を確認できるようになっており、タグやメタデータの修正、作成されたworkflowを本番環境にデプロイ作業などができるようになっています。

f:id:nogawanogawa:20160509092652j:plain:w600

実験管理

日々何千もの実験を行っているため、その管理も必要になります。 FBLearnerでは、各workflowはElasticsearchによってインデックスされて管理されており、多様な切り口で検索できるようになっています。 これによって、最適な実行パラメータを見つけやすくなっていたりします。

f:id:nogawanogawa:20160509092733j:plain:w600

アルゴリズムの構築

FBLearnerの肝は、特定のアルゴリズムに縛られないことです。これによって、様々な組み合わせのアルゴリズムが可能になります。 もちろん新しいworkflowを記述することも可能で、オープンソースで提供されたツールをworkflowにかんたんに組み込むことも可能になっています。

FBLearnerのworkflowのうち、事前定義済みのアルゴリズムも各種提供されています。

  • Neural networks
  • Gradient boosted decision trees
  • LambdaMART
  • Stochastic gradient descent
  • Logistic regression

FBLearner Predict

学習後のモデルはFBLearner Predictを通じてデプロイされます。 Predictorはスケーラブル、低レイテンシ、マルチテナントモデル配信環境です。 これによって、本番稼働中のモデルについてモデルについての実験・比較が可能になったりします。

将来的には

さらに効率を向上させたい

ときには、50万ものワークフローがクラスタ上で実行されることもあり、それらは計算リソースと時間を非常に使用します。 これらの実験の効率を向上させ、実験のレイテンシを最小に留めつつ、プラットフォームをスケールできる様にしていきたいと考えています。 そのためにもリソースの需要と供給の状況を把握し、データの管理しているところから近くなる様に計算リソースを分配するしくみを考えています。

速度向上

現在でも日々何兆ものデータを収集し、何千ものモデルをオフライン・オンラインで学習しています。これを更に、常に最新のデータを活用して実験できるだけのワークフローの速度向上が必要だと考えています。

機械学習の自動化

多くの機械学習のアルゴリズムは多数のハイパーパラメータを持っています。 facebookの場合、1%の性能向上であっても非常に大きなUXのインパクトにつながるため、ハイパーパラメータの自動チューニングが必要になると考えています。

感想

facebookの中で使われているMLプラットフォームを調べてみました。 言われて見ればfacebookで機械学習使っているところって結構ありますね。 この規模だと機械学習の精度を少し上げることがビジネスに大きなインパクトがありそうだなと感じました。