MLOpsエンジニアこそフロントエンドやるべきなのではという気分
ポエム。
ワークフローエンジンにせよ実験管理ツールにせよ、機械学習を取り巻く環境には様々なツールが溢れかえっている。じゃあどれを使えばいいのかっていう話になるが、ツールを決める際に「検索がしやすい」「数値が見やすい」みたいな、ロジックとしては何も難しくない、本当にどうとでもなりそうな些細なところを判断基準にするのはイケてないな〜という気分になる。かといって、使いづらいツールを使うというのも残念なことになっていくのは目に見えている。
そもそも、可視化という部分は重要な部分であるのは間違いないはずなのに、より理解しやすいようにビジュアルを作るという点に関してフロントエンドができないばかりに何もできないというのは非常にもどかしいなーと思う。
じゃあフロントエンドエンジニアを連れてきて〜みたいな話になるかもしれないけれども、社内でしか使わないような可視化ツールだの実験管理ツールを作るようなポジション、誰か来るのかな?と思う(多分自分なら嫌)。そもそも、MLOpsエンジニアがなんかフロントからは遠いのの逆で、フロントエンド側で機械学習のことをバチバチに分かっている人というのもすごく少ない気がする。こういう背景踏まえて、誰がやるのっていったらMLOpsエンジニアがやるしかないんじゃないかなというのが今の気分。
フロントもできるようになって、ツール類はできるところはどんどん内製化しちゃえばいいんじゃないかなという気持ち。既存のツールっていろんなライブラリやフレームワーク、プラットフォームに対応していて、だからこそ製品やOSSとして成り立っている気がするけれども、仕事で使う上でそれ全部いることあるのかな?必要な部分といったら本当に限られた機能で、ある程度の規模のチームだったら全然成立するレベルなんじゃないかなという風に思う。
結論としては、かゆいところに手が届かないのって可視化する部分に対してスキルが貧弱だからであって、そこができるようになると数倍できることの範囲が広がるんじゃないかなと思いましたという話。
JAISTに入って一年
JAISTに入って1年が経ちましたので、一年を振り返ってみようかと思います。
学生生活について
この一年まるまるコロナの影響でほぼ東京サテライトの施設は利用できない状態でした。よって講義は全てオンラインでした。個人的には朝が弱いので非常にありがたかったです。朝9:20に品川は多分僕は無理です。
図書館も使えなかったのですが、これに関しては依頼すると大学が自宅に本を郵送してくれたので非常にありがたかったです。
トータルで言えば自分にとっては非常にプラスに働いた面が大きかったと思います。
講義について
この一年、ネットワークやOSに関する講義を中心に履修してきました。
ネットワークについての理解は入学当初よりかなり深まったかなという気がします。かなり手を動かして学ぶタイプの講義もあり、Wiresharkを使ったりnslookupコマンドを叩いたりというような多分ソフトウェアエンジニアとして働いているだけではすることはなかったような経験ができたのは面白かったしいい勉強になったと思います。
OSに関しては変な風にハマってしまい、OSのコードリーディングの本を買って読もうとしたりしているうちに試験は中途半端な感じになってしまいました。が、基本的な動作について(ふんわりと)概要は理解できたので、仕事でもたまに使う話が多いのでこれもとても良かったと思います。
一方で、情報数学や解析学といった講義は東京サテライトでは開講しておらず、かつそれらが前提知識として必要な講義がいくつかあるなという印象です。こういった数学の基礎知識を身につけるのを期待して入学すると思ったようにはならないかなと思います。数理最適化の講義などもテストに向けてやり方は覚えたけれどもすぐ実装できるかと言われると多分できないと思います。
あと欠かせないのが平日授業で、情報系だとおそらく2つ平日開講の講義を取らないといけないのですが、仕事が終わった後の18:30~22:00は本当にきついです。予習が求められる講義もあり、これは本当に辛かったです。
研究について
まずは研究室配属です。本来は入試前に研究室の先生にコンタクトを取り入学した際はその研究室に所属できるよう約束をするのが定石なのですが、自分はしませんでした(というかそういう制度があるのを知ったのが願書提出前日とかでした。その他にも郵送後「多分出願するコースが違う」と学務から確認の連絡をもらったくらいには杜撰な手続きでした)。
そんな背景があるので入学してから研究室訪問(オンライン)を経て所属研究室を決めていきました。
JAISTでは卒業する1年前に研究計画提案書というもの(A42枚程度)を書き、指導教官、副指導教官等から承認をもらわなければ修士研究を行うことができません。なのでつい先日提出したところです。
これが割としんどくて、ちゃんと新規性などを示しつつ書かなければなりません。これまで自分は論文を読むことはありましたがそれは基本知識を得るためであって研究のためではありませんでした。そのため研究のための論文の読み方というのがなかなか分からず、さらに「研究って何をすればいいんだっけ?新規性とは?SOTA出すこと?」みたいに研究のゴールも分からなくなってしまい非常に苦戦しました。
結果なんとか自分的には実現性もまあまあありつつ面白そうな課題設定を見つけることができました。これが今のところJAISTに入ってよかったと思った一番経験でした。
課題の発見、根拠となる情報収集、説明、ソリューションの提案などを(まだまだ未熟ではありますが)学術レベルでできた経験は普段の仕事でも役に立つと思いました。
あとはしっかり手を動かして進めていければと思っています。
まとめ
講義、いわゆるコースワークについては入学前の期待通りという感じではありません。いくら講義を受けようが最後はやはり試験のための勉強になってしまいますし、手を動かさないとスキルにはなりません。しかも基本的に講義が大変で時間がないので手を動かす時間もあまり取れません。
大学院の講義を通してCSの基礎を身につけたいと思って入学しましたが、確かに知識はある程度身につきましたが完全に身についたという実感はあまりありません。結局卒業後色々手を動かしてみる時間が必要なのだな〜と感じています。
研究に関しては期待以上で、成長している実感もありますしやりがいも感じています。
そんな感じで、2年目も頑張って行こうと思います。
おまけ
転職について
JAIST在学中に転職しました。いろんな言えない事情はありますが、中でも大きい理由はこのままでは学費が払えなくなりそうというものでした。 講義を受けながら転職のためのスキルアップや面接、仕事の日々は非常に苦しかったですし、転職してからもキャッチアップをしなければならず、なかなか大変でした。
当たり前ですが、在学中はしなくていいなら転職しない方がいいと思います。修士・博士の学歴を手に入れてからスキルアップを考えている人も当然いると思うのですが、社会人として大学院に入学するのにまず大事なのは安心して長期で就業できる職場に就くことだと思いました。
サバイバーの宿命(さだめ)
最近働いていて分かってきたこと。 変な手癖がかなりついているなぁ…と。
新卒で受けた研修というのもVBAでバブルソート書いたくらいのもので、誰かに教わったという経験があまりない。 要は自分のスキルは「なんかよく分からんけどググりながらガチャガチャやってたらできた」時のまま今まで来ている部分が結構ある。
特にGitはよく分からずかなり雰囲気で使っている節がある。 そらまぁオペレーションミスも起こるわなぁ、、
そんなわけで、あまり理解せずにこのコマンド打っているなぁ…というのをなくしていきたい所存。
あと関係ないけれども、自分は失敗が多い人間だけども失敗した分成長していこうと思っていたけれども、 やっぱりそもそも失敗しない人間の方が成長速いんだよなぁ。
失敗した時、よくよく振り返ってみれば大体「なんであんな愚かなことを…」と思う。 常に「今自分は愚かなことをしていないだろうか」と俯瞰しながらやっていこう。
転職と今後の話
転職して一週間が経ちました。いきなり三連休はありがたいですね。
今回転職を経て、前職の10倍くらい?の従業員数の企業に勤めることになりました。
まぁ当然全員の顔と名前なんて覚えられそうにないし、誰が何の仕事をしてるのかもあんまり覚えられそうにありません。逆の立場もそうで、多分全員が僕の顔と名前を覚えることはないでしょう。
もっと言えば元いた40〜50人規模の会社と比べると自分の仕事が与える影響範囲はかなり小さそうだなと感じました。あくまで相対的な話です。
以前「会社内で各々の部署が自分の仕事の範囲で最適化を行った結果全体的にはパフォーマンスが落ち〜」みたいな話を見た時には今ひとつピンと来なかったんですが、確かにまぁこれくらいの規模になってくると一従業員の視点で全体的な最適化を意識するのはかなり難しいだろうな〜と今は思います。
前職では「何でそんな安定した大きいところにいたのにうちみたいな小さい企業に?」と思うような人がちらほらいましたが、確かにこういう環境に一度身を置くと「もっと自分の影響範囲が大きくなるような環境で仕事をしたい」「小さい組織が成長する過程に立ち会って、自分で組織のルールやカルチャーを作ってみたい」という気持ちが湧くのも分かるなぁと思います。
ただ、リスク承知で飛び込んだそういった人達が自分の思ったような働きが出来ず苦しい思いをする姿を散々見せられたこともあり、多分僕はそのようなキャリアは歩まないだろうと思います。いろんな意味で落とし穴があるというか、世の中そんな自分が思った通りにはいかないんですね。
この点いろいろ大変なことはありましたが大怪我にならずに済んだというか、将来のキャリアに大きく役立つ貴重な経験ができたと思います。
そうなってくると、じゃあ将来自分はどうしていくんだろうということを考えました。
よっぽどのことがない限りいわゆるスタートアップと言われるような50人の壁も越えられていないような組織にはいかないと思います(保険を打ってる時点で行ってしまいそうな気もしますが笑)。
となるとそこそこの規模の会社(もちろん今の会社も含めて)でやっていくことになるとは思うのですが、ここでよくあるマネージャーコースかスペシャリストコースかみたいな話が出てくるわけです。
今の僕からすれば自分がどこまでスペシャリストとしてやっていけるのかというのがまだよく分からないですし、まだまだ現場でやっていきたいのでマネージャーとしてのキャリアもあまりピンときません。
これらのことを踏まえ、今回入社した企業では自分がこの先スペシャリストとしてやっていくのかマネージャーとしてやっていくのか、この問いへの答えを見つけられたらなぁと思います。
Terraformを導入した話
ここ最近の話ですが、Terraformを社内に導入しました。 現在の会社に入社して以来、自分はこれまで既に設計されたものを実装していったり、あるいは既に稼働しているサービスに変更を加えるということしか行ってこなかったため、今回初めて技術選定・導入を行ったことになります。
少し話は変わりますがつい数ヶ月前、自社のサービスのアーキテクチャや使用しているツールについて軽く話す機会があった際、「どうしてこのツール/サービスを使っているの?」という質問に対してしどろもどろになってしまった部分があり、普段自分がいかに社内で使用されているサービスやツールについて「なぜこれを使っているのか」を意識せずに使用しているかを痛感させられました。 その後設計を行った同僚たちに話を聞いたのですが、やはり全てのことにきちんと理由があり、いろんな選択肢の中から選択した結果なのだということを理解しました。
そういった背景があった中で今回IaCツールの技術選定 & 導入を行い、個人的には良い経験ができました。 なので、なぜこの選択をするに至ったのかという整理のために、他にも似たような状況になった人の参考になるように記事にまとめてみることにしました。
背景
これまでの状況
基本的にインフラ構築は手順書を用意し、そこに書かれている指示に沿ってコマンドを実行して行っていました。 社内ではGCPをメインに使用しておりgcloudコマンドを使用すれば特に問題なくインフラが構築できることや、一度作成した環境は基本的に変更を行わないという前提があったためこのような運用になっていたようです。
最近の状況
近頃、社内ではエンジニアの割合に対して分析職のメンバーの割合が増えつつあることや、一度作成した環境に対してGKEのノードプールのマシンタイプを変更したいという要望が出るなど、あまりインフラ面に工数をかけていられないにもかかわらず要望は増えているという状況でした。 また、要望に対してエンジニアの人手が足りていないことから分析職のメンバーが環境構築を行わなければならないという状況も発生しつつありました。
これらのことから、現在社内ではインフラ構築のコストや難易度を下げることと、環境の変更履歴を管理し、安全に破棄&再構築できる仕組みが求められていると考えました。
ツールの選定
自分が今回ツールを選定する際の観点として重視していたのは、
- インフラに関する知識がないメンバーでも気軽に環境を構築できること。できればデプロイとかも自動化できるとよい。
- IaCに慣れたメンバーがいないため、学習コストが低い方がよい。
検討したこと
1. Terraform + Ansibleを使用してインフラ構築と構成管理を行うガチガチIaC導入
最初とりあえずTerraformを触ってみていたのですが、簡単にインフラを立ち上げることができることはできるもののデプロイ作業などにはあまり向いていないのではと感じました。調査をしているとTerraformはクラウドインフラストラクチャオーケストレーションツール、Ansibleは構成管理ツールとして組み合わせて使用する方法があるということを知りました。 そこでAnsibleも触ってみたのですが、1日触ってみてなんとなく雰囲気は掴めたもののこれはあまりに学習コストが高いということでこの仕組みを導入するのはやめました。
2. Terraform + fabricを使用してインフラ構築 & リリース作業自動化
同僚曰く、前職でfabricを使用してリリース作業を自動化していたという話を聞いたため、検討してみました。 しかしfabricにはfabric1とfabric2がありそれぞれでかなり挙動が違い、その上最近はあまり使われていないツールなのかググるとfabric1とfabric2の情報が同程度出てきてしまいます。 このためエラーが発生した際に誤ってfabric1の情報を参照してしまい、トラブルシューティングが困難になってしまうと考えました。 もちろん公式ドキュメントを確認すればよいとは思うのですが、それもそれで分析業務のメンバーが片手間にやるにはあまりにコストが高いと感じました。 これらの理由から、これも不採用としました。
3. Terraformでインフラ構築を自動化 & デプロイはこれまで通り手動
本音を言えばもちろんデプロイも自動化したかったですが、手動でコマンドを打つやり方だと面倒&ミスが起こるかもという問題はあるものの、技術職のメンバーであれば基本的に誰でも難なくできる作業であるため、学習コスト&メンテナンスコストを考えた時にあまりメリットがないという風に感じました。 最終的にはこの方法を選びました。
まとめ
個人的には欲張りすぎて運用が大変になることもなく、かつある程度は業務の負担を軽くすることができたかなと感じています。 ただ、反省点はいくつかありました。
- もう少し技術選定のやり方などを調べながら進められればよかった。
- すぐに他のメンバーに仕事を引き継がなければならず経過を観察することもできないような状況の中で新しいツールを導入することが、果たして妥当であったかどうか。
1.についてですが、セオリー的に考慮しなければならない要素をいくつか見落としていたのではないかという懸念を感じました。今回はあまり時間がないという状況の中でスクリプトの実装まで行わなければならないというスケジュールであったためこのようなことになってしまいましたが、次回ツールの選定を行う時はセオリーを学びながら、考慮しなければならないポイントを洗い出しながら進めていくようにしたいと感じました。
2.についてですが、いろいろあってあまり先まで面倒を見ることができないという状況で新しいツールを導入することが本当に正しいのかという疑念が残りました。難しい状況の中での今回の導入はそこまで間違っていないとは思うのですが、本来はちゃんと自分が導入した技術・ツールについては少なくとも安定して運用していけるようになるまでは責任を持って面倒を見ていかなければならないなと感じました。
データドリフトについて思ったこと
だいぶポエムっぽい内容かもしれません。
日々データを収集していると時が経つにつれてデータの様子が変わっていってしまうことが考えられますが、そのことをデータドリフトと呼びます。 それを可視化するためのツールとしてTensorflow Data Validationというものがあり、これについての記事も書きました。
この記事を書いた時は「データの分布を確認し続けることって大事だよね!TFDVは可視化できて最高!」と考えていたのですが、しかしよくよく考えてみると、データの分布の話ってそこまで単純な話ではないのではという風に感じました。
TFDVにはデータのスキーマが変わっていることに関しては便利な検知機能があるのですが、分布の変化に関しては可視化機能がメインでスキーマ異常検知に比べると検知機能がそこまであるわけではありません。
やはり、そもそも何を持って「分布が変わっているよ!」というのかを定義することすら難しいと思いますし、分布そのものから何か情報を得ているのでない限り、特に機械学習を使用するサービスを運用する中でドリフトの監視を行っている場合、「分布が違うよ!」と言ったって「だから何」という話にしかならないのだと思いました。
上で述べた機械学習を使用するサービスを運用する中でドリフトの監視を行っているケースに限定しますが、監視しないといけないのはデータの分布よりもまずモデルの性能だと思いました。 分布のドリフトが起こっているというというのはどちらかといえばよくはないことではあることは間違いないと思いますが、それがどのくらい困るのかというのは分布にだけ着目していると何も分からないのだと思いました。
まずはきちんとモデルの性能について、劣化していると判定するためのボーダーラインを設定し、それをモニタリングする。 そして、そのボーダーラインを超えた時初めてデータ分布のドリフトが原因で劣化が起こっているのかを調査する。 データの分布のドリフトの監視に関してはこのような運用をしていけば良いのではないかなぁと思いました。
Bigquery ML で Titanic をやる
多分既に誰かがやっているとは思うので、あくまで備忘録的な作業メモ的な。 スタートガイドをやってみたのですが、簡単過ぎて逆に覚えられなかったので…
データ準備
$ mkdir ~/Documents/titanic $ cd ~/Documents/titanic $ wget https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv $ head -n 600 titanic.csv > train.csv $ head -n 1 titanic.csv > valid.csv $ tail -n 292 titanic.csv >> valid.csv # titanic.csvは全部で892行
BQにアップロード
適当なプロジェクトにtitanic
データセットを作成。UIからtrain.csvとvalid.csvをインポートする。
スキーマは自動検出で行けました。
学習
CREATE MODEL `titanic.model` OPTIONS( model_type='logistic_reg', input_label_cols=['Survived'] ) AS ( SELECT * FROM `titanic.train` )
スタートガイドではターゲットとなるカラムにlabel
というエイリアスをつけて学習を行っているみたいですが、ここではエイリアスは使わずinput_label_cols
を使用してターゲットとなるカラムを指定します。
ARRAY
にしないといけないんですね。
評価
SELECT * FROM ML.EVALUATE( MODEL `titanic.model`, ( SELECT * FROM `titanic.valid` ) )
予測
スタートガイドでは何やらいろいろ加工しているので、いったん全部出力してみようと思います。
SELECT * FROM ML.PREDICT( MODEL `titanic.model`, ( SELECT * FROM `titanic.valid` ) )
こんな感じになるから加工が必要なんですね。predicted_label
の意味も分かりました。
必要な形に加工して出力します。
SELECT PassengerId, predicted_Survived, FROM ML.PREDICT( MODEL `titanic.model`, ( SELECT * FROM `titanic.valid` ) )
まとめ
Bigquery ML を使う上で使用するのは主に次の3つの機能で、それぞれ次のような形で使う。
- 学習
CREATE MODEL `dataset.model_name` OPTIONS( model_type='hoge', input_label_cols=['huga'] ) AS ( SELECT * FROM `dataset.train_table_name` )
- 評価
SELECT * FROM ML.EVALUEATE( MODEL `dataset.model_name`, ( SELECT * FROM `dataset.valid_table_name` ) )
- 予測
SELECT * --適当な形に加工する。 FROM ML.PREDICT( MODEL `dataset.model_name`, ( SELECT * FROM `dataset.test_table_name` ) )
こうやってみるとシンプル。 公開当初に比べてAutoML Tablesに対応したりと使える場面は広がっているはず。 フィットすればかなり高速に開発できそう。