AzureMLを使いこなすのが難しかった話

前書き

この記事は「Unagi-Network Advent Calendar 2023 3日目」の記事です。
Unagi-Network Advent Calendar 2023 - Adventar

お久しぶりです!
最終更新が2年前なのですが、今回Advent Carenderにお誘いしていただき、
この2年間ぐらいで溜めておいたものを適当に書いていこうと思います。

前口上

皆さん!機械学習やっていますか!?
最近はクラウドサービスで機械学習ができるものも多くあったりして、ハードルは下がっていると思います。
3大クラウドサービスと言えば、Azure、AWSGCPですね。各社ともに機械学習のサービスをもちろん持っています。
Google機械学習系のサービスが強く、AWSもSageMakerや巨大なサービスを持っていますね。
この2つはインフルエンサーも比較的多い印象です。
さて、ではAzureはどうでしょうか。
AzureはAzure Machine Learning(通称AzureML)というサービスを提供しているのですが、実はあんまり使われていないのでは?
この度色々ありAzureMLを使うことになったのですが、AzureMLを使いこなすのが難しかった話を書いてみようと思います。
※他の機械学習サービスをあまり使ったことが無いためかなり偏見が入っていると思います。

AzureMLとは

一応紹介だけしておきます。
公式紹介では以下のように紹介されています。
「Azure Machine Learningとは企業向け仕様のAI サービスを、
エンドツーエンドの機械学習ライフサイクル全体で利用できます。」
まあよくわかりませんね。
ざっくり説明すると、データの分析、機械学習のモデル作成、デプロイ、運用という機械学習を用いたサービスを作って運用するまでの
一連の流れがすべて1つのプラットフォーム上でできるというものです。
詳しくは以下のURLをご覧ください。
Azure Machine Learning - サービスとしての ML | Microsoft Azure
今回は前書きでも書きましたが、AzureMLを使うことがあったのですが
使うのが難しかった話(罠)を記載してみたいと思います。
※2023年11月時点での話をしております。

破壊的バージョンアップがある件

まず前提として、AzureMLは今リリースされているものとして、v1とv2があります。
バージョンと記載されているので過去の機能は当然使えるものと思っているそこのあなた。
まずその考え方を捨てましょう。

AzureMLはv1とv2では大きく違い、概念そのものが変更されている場合があります。
詳細は以下のサイトとか見てもらうと良いかもしれないです。
Azure Machine Learning SDK v2の基本的な使い方紹介 - ISID テックブログ
MLOps のための Azure Machine Learning CLI v2 / SDK v2 #Azure - Qiita
クラス名や使い方含め大きく変わっているところもあるので自分が今どちらを使っているかを意識する必要があります。

新しい方を使っておけばいいからv2一択では?と思う人も多いでしょう。
実際にMS公式でもv2を推奨しているようです。
Azure Machine Learning CLI と SDK v2 - Azure Machine Learning | Microsoft Learn
もちろん新しい方を使うのはごく普通の考え方だと思います。
しっかりv1からアップデートされているのであればですが…

このv1からv2へのアップデート、機械学習に必要な機能がすべて移行されているわけでは無さそうです。
例えばドリフトと呼ばれる学習するデータに変化が発生しているかを確認する機能はv2には存在しないようです。
(しかもv1もプレビュー版)
そのため、すべての機能を使いこなすためには、v1とv2の情報を両方追う必要があります。
v2で調べて、無ければv1で調べて…という2重に調査する必要があります。

というわけで、自分が今触っているのがv1なのか、v2なのか。そしてその機能は使えるのかをしっかりと調べる必要があります。
(せめてv2のSDKで、v1でできるazuremlの機能は触らせてくれ~)

欲しい情報が探しづらい件

というわけでv1やv2の違いがあるので、情報をしっかりと探す必要があります。
ただ、情報を探すところにも一苦労あります。

例えば、今回触ることになったログ周辺についてですが、
v1ではazureml_runというクラスを用いていたのですが、v2ではmlflowに統合されたようです。
じゃあmlflowのドキュメントを探しに行きましょう。

例えば、ここですね
Python API — MLflow 2.8.1 documentation
MLflowでログが取得したいときにはやはり公式を見るのが一番!
というわけでmlflowの公式を見に来ました。

では混合行列が記録したいので「mlflow.log_table」とかのメソッド使ってみましょう。

実は上記は罠です。azuremlのmlflowにlog_tableというメソッドなどありません。
MLflow を使ったメトリック、パラメーター、ファイルのログ - Azure Machine Learning | Microsoft Learn
azureml公式にも使えるなどとはどこにも書いてありません。
azureml公式をしっかり見ない方が悪いです。

というわけで、外部のOSSをインポートしたとしても
azureml公式に書いてある方が正しかったりします。
(おそらくですが、内部で何か改造されているのかと…嘘だろとは思いますが…)

ちなみにv1時代にはパッケージは違いますがあったそうなので更に混乱を極めます。
SDK v1 から MLflow へのログの移行 - Azure Machine Learning | Microsoft Learn

ドキュメントに書いてない仕様が存在する件

ではしっかりと公式のドキュメントを探してみましょう。
今回はpipelineをデプロイするためのYAMLファイルの書き方を見てみましょう。
※補足説明

  • pipeline:学習や推論など一連の流れを順序指定してまとめて実行するもの、複数のjobからなる
  • job:実行の最小単位。例えばechoコマンドやpythonコマンドのようにコマンドが実行できる。

CLI (v2) パイプライン ジョブの YAML スキーマ - Azure Machine Learning | Microsoft Learn

$schema: https://azuremlschemas.azureedge.net/latest/pipelineJob.schema.json
type: pipeline
display_name: hello_pipeline_abc
settings:
    default_compute: azureml:cpu-cluster
  
inputs:
  hello_string_top_level_input: "hello world"
jobs:
  a:
    command: echo hello ${{inputs.hello_string}}
    environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
    inputs:
      hello_string: ${{parent.inputs.hello_string_top_level_input}}
  b:
    command: echo "world" >> ${{outputs.world_output}}/world.txt
    environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
    outputs:
      world_output:
  c:
    command: echo ${{inputs.world_input}}/world.txt
    environment: azureml:AzureML-sklearn-1.0-ubuntu20.04-py38-cpu@latest
    inputs:
      world_input: ${{parent.jobs.b.outputs.world_output}}

pipelineは順番が大事なので上記の例だと
a⇒b⇒cの順番で実行してほしい…のですが
じつはこいつら、各ジョブの入力と出力に依存関係が無いと順番に実行してくれません。
なので上記例だと、aとbは並列に実行し、b⇒cは順番に実行されます。

そんなことどこに書いてあるかって?
「そこに無ければ無いですね」

じゃあ各ジョブで出力が無い場合はどうすれば依存関係が作れるの?
答え:YAMLファイルでpipelineを定義する場合には依存関係は出力以外では作れません。

そんなことどこに書いてあるかって?
「そこに無ければ無いですね」

というわけで細かな仕様に関しては、実行してみるまで分かりません。
実行して、try and errorで進めていく必要がありました。

嘘を書いてある件

とりあえず、ドキュメントに書いてないことは試してみるしかないので試して
では書いてあることはその通りに動くという事で進めましょう。

ではデータドリフト検出機能を使ってみましょう。
※補足説明

  • データドリフト監視:学習データの傾向を見て異常な学習データの変化が発生していないかをモニターする監視。この時のデータの変化をドリフトという。

データセットでデータ ドリフトを検出する (プレビュー) - Azure Machine Learning | Microsoft Learn
(すでにv1しかない and プレビューという記載で嫌な予感しかしないのは置いときましょう。)

とりあえずチュートリアルに従って、独自のデータを用いながら記載してみると…
6か月分のデータを突っ込んでいるのに1カ月分のデータしか出ません。
なぜ…

とりあえず怪しそうな箇所を一通り見ていると、frequencyというパラメータがありました。説明は以下と記載されていました。
パイプラインの実行頻度を示すオプションの頻度。 "Day"、"Week"、または "Month" をサポートしています。
英語で見ても、「Optional frequency indicating how often the pipeline is run. Supports "Day", "Week", or "Month".」
そのままですね。これはただの監視の実行頻度なので関係なさそうです。

…と思ったそこのあなた。まだまだですね。
これ実は半分嘘です。このfrequencyを変えるとデータの表示期間が増えます。
なぜなら、プレビューページに以下の記載があるからです。
「履歴データ分析時の時間範囲は、モニターの頻度設定の 31 間隔までに制限されます。」
なので、実行頻度を変えるとなぜかモニターで表示されるデータの期間も増えます。

このように、ドキュメントに書いてあることでも誤っている場合があるので注意が必要です。
まさしく「公式が勝手に言ってるだけ」状態ですね。

上記踏まえチーム開発で発生したこと

上のようなドキュメントを読みながら、チーム開発をするとどうなるか皆さん想像してみてください。
書いてない、書いてあることが違う、なぜか動かんとかをチーム内で議論するとお祭り状態です。
さらに他の人がなんか一瞬見たことあるけどどこに書いてあったか忘れたみたいなことも容易に発生します。
聞いてもそれが本当かどうかわからないので結局実行したりソースコードを読んだりしてみないとわからない
というオーバーヘッドが半端ではない開発が楽しめます。

まとめ

というわけでそれなりに苦労した難しかった話でした。
あんまり有用な情報が無いので公式を頼るしかないのですがその公式が結構めちゃくちゃでした。
まあ動いたやつが正義という感覚で進めるのも悪くはないのですが
正式にリリースして運用するとなると、どうしてこの記載方法なのかのリファレンスを残したりは
しなければいけないので、自分が実行してそうだったから以外に説明のしようがないのはつらいですね。

ただ、まだプレビュー版だったり、ml環境の発展じたいがすごいスピードで進んでいるので
これから他のクラウドに追いつくレベルで発展してくれればいいなーと思いながらお付き合いしていくことになるのでしょう。。。

最後に一言
「さすがに嘘書くのはやめろ」