エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

AI・機械学習チームベストMR(Merge Request)決定戦 2024

この記事はエムスリー Advent Calendar 2024 23日目の記事です。 AI・機械学習チームの中村伊吹(@inakam00)です。

ソフトウェア開発において、優れたコードの変更は時としてアート作品のような美しさや、抜群の機能改善をもたらすことがあります。GitHubでPull Request(PR)を使ったことがある人なら、感動するようなコード修正に出会った経験があるのではないでしょうか。

エムスリーAI・機械学習チームでは、この感動を共有し称え合うために、年に一度「ベストMerge Request(MR)決定戦」を開催しています。MRとはGitLabのMerge Requestの略称です。 GitHubでいうところのPR(Pull Request)にあたります。

普段は全国各地でリモートで働いているAI・機械学習チームも年に数回全員集合する機会があります。先週金曜日に社内ライブラリやOSSにコントリビュートをしようという企画を実施しました。

今年も、チームメンバー全員で「これはすごかった!」と感じたコード変更をノミネートし、投票の結果トップ10を選出しました。シンプルな改善から斬新なアイデアまで、いろんな「職人技」が詰まっています。

AI・機械学習チームの全MRを1年前まで遡るにはページネーションの227ページ目までいく必要がある(約4500件)。Renovateなどのメンテナンスを除いてもおそらく1000件以上。

このブログでは、実際にコードを書いた人や、レビューを通じてその価値を高めることに関わったメンバーたちが、それぞれのMRの魅力について語っていきます。では、第10位から見ていきましょう!

第10位 機械学習モデルの性能向上施策

  • 紹介者: 鴨田

AI・機械学習チームでは、様々な機械学習モデルの開発や運用をしています。その中のあるモデルの簡素化や取り回しの良さに着目したバージョンアップにおいて、v2モデルがv1モデルと比較して精度が悪化するという課題に直面しました。

調査の結果、主原因の1つが特徴量に対して強制的にSVD(特異値分解)による圧縮を適用していたことだと判明しました。特徴圧縮の処理を見直すことでv2モデルの精度をv1と同等のレベルにまで回復させることに成功しました。

調査から原因究明、対応までなんと2日というスピード感も相まって堂々の10位入賞となりました。

第9位 localディスクキャッシュの活用

  • 紹介者: 池嶋

AI・機械学習チームでは様々な分析用関数を共有リポジトリに実装していますが、一部処理に時間がかかるものがありました。例えばデータのダウンロードなどは何度やっても結果は同じなので結果をキャッシュすることで流用したいところです。普段、AI・機械学習チームではgokartを使って処理を書いているので、結果をキャッシュできているのですが、gokart化されていない関数でもキャッシュを使って高速化したくなっていました。

このMRでは、キャッシュしても安全な関数を洗い出してlocalキャッシュを有効化することで全体の処理を3倍程度高速化できるようになり、分析の生産性向上に寄与しました。

第7位(同率) gokartへのmypy pluginの追加

github.com

  • 紹介者: 山本

エムスリーが公開しているOSSであるgokartにmypy pluginを追加したPRです。

これまでコンストラクタに引数の型と異なったものを渡したとしても、mypyで検知できませんでした。 そこで、dataclassやpydanticのことを思い出し、mypy pluginを実装することで上記の問題を解消しました。

詳しくは次のブログを参考にしてください。 www.m3tech.blog

第7位(同率) Kubernetesクラスター都合でのバッチの中断をリトライ回数にカウントしない

  • 紹介者: 三浦

AI・機械学習チームのGKE*1では、約300個のバッチが稼働しています。GKEでは、ノードへのバッチの配置最適化や、スポットインスタンス*2の停止により、バッチが中断・再実行されることがあります。このような中断もリトライにカウントされ、リトライ上限に達した結果、バッチがSLAを満たさないことがありました。

これに対し、リトライのカウントを制御する機能をKubernetesのドキュメントを発見し、採用しました。本来着目したいリトライ要因のみ*3にフォーカスできるようになり、コストを抑えつつ*4監視・運用の質を向上できました。

第6位 ある日突然BigQueryのdownloadが遅くなっていました。さてなぜでしょう?

  • 紹介者: 中村(伊)

正解は、BigQuery Storage APIを使わない設定になってしまっていたからです。

AI・機械学習チームではBigQueryを操作するための社内ライブラリを整備することによって、100個近いプロダクトでも処理の共通化を実現しています。その際に、BigQuery Storage APIを利用することでBigQueryのダウンロードを高速化していたのですが、pandas-gbq v0.22からデフォルトでは利用できなくなっていたことを修正するMRです。

github.com

発見の経緯として、紹介者の中村(伊)が諸事情で数日間メンテナンスができない間に、代わりにプロダクトの保守を行なってくれたチームリーダーの北川が動作検証中に発見しました。AI・機械学習チームはプロダクト数が多いため、スピードを優先するためにある程度の属人化を許容するという体制をとっています。そんな中でも他人の仕事を気にかけ、さらに改良まで行ってしまうチームリーダーの動きはさすがでした。

来年はベストMR決定戦〜タイトル部門〜をやりたいので、内容は伝わるが絶妙なタイトルのMRをこれからは作成していきたいですね。

第5位 gokartのlinterを追加

  • 紹介者: 氏家

エムスリーがOSSとして公開しているgokartに対してlinterを作成したMRになります。

AI・機械学習チームではgokartが様々なプロダクトで利用されており、社内では知見が溜まっています。しかし、新メンバーなどが入ったときはレビューで「これ使わないほうが良いですよ」と言うなど、口頭での普及をしている状態が続いていました。人手のチェックでは見逃しなども発生するので完全に統一するにはなかなか難しいです。

そこでこのMRでは、そのような知見をLinterとして機械的にチェックすることによって、レビューを挟まずにチェックできる仕組みを作りました。 詳しくはブログを出しているので、ぜひそちらも御覧ください。 www.m3tech.blog

第4位 コード検索基盤を構築するためのインデックス作成フロー

  • 紹介者: 中村(弘)

コード検索基盤を構築するためのインデックス作成フローの開発のためのMRです。

エムスリーでは今までCloud Source Repositoryを利用したコード検索を利用していましたが、サービスのEnd of Salesがアナウンスされてしまいました。移行先を調査していたところ、Sourcegraphの内部で利用されているZoektというコード検索エンジンを見つけました。Zoektを使ったコード検索基盤を社内向けに構築することで、他サービスに課金することなくコード検索基盤を実現でき、コストを大幅に節約することに成功しました。

コード検索基盤の詳細についてはエムスリーテックブック7で公開しています。 techbookfest.org

第3位 Google Cloud ArtifactRegistryのクリーンアップ

数十個のリポジトリに一括適用されたため、ラベルの反映などが大量に行われた

  • 紹介者: 横本

みなさん、古くなったDockerイメージはきちんと掃除出来ていますでしょうか。恥ずかしながらAI・機械学習チームではGoogle Cloud ArtifactRegistry(以下GARと省略)のCleanup設定が徹底出来ていない状態でした。言うまでもなく古過ぎるイメージはストレージ料金の浪費ですし、またGARは前身であるContainerRegistry(以下GCRと省略、非推奨・提供終了予定でチームでも移行)よりもストレージ料金が割高です。

そこでちゃんと削除ポリシーを徹底しようということになったのですが、チームには多くのプロダクトがあり、対象のGARリポジトリも多数。メンバーみんなで分担して設定祭りか…と思われたところ「まとめてやっちゃいます」と数十個のリポジトリを一括で対応してくれた本MRに感謝が集まり第3位に輝きました!

なおGARはシングルリージョンに閉じることで通信料金を回避できるため、(ちゃんとストレージを節約すれば)トータルではお得なケースが多いと思われます。GAR移行していきましょう。

第2位 TaskOnKartへ型を追加

github.com

  • 紹介者: 北川

エムスリーがOSSとして公開しているMLワークフローライブラリであるgokartへのPRになります。

近年Pythonには型に関する機能が増えています。その型の機能をふんだんに使ってgokartの弱点であったタスク間の型の受け渡しをできるようにしたのがこのPRの内容になります。 これによって実行前にエラーに気づきやすくなっただけではなく、コードリーディングを容易にするなどの効果が得られました。

詳しくは次のブログを参考にしてください。 www.m3tech.blog

第1位 ロードバランサー一括監視

  • 紹介者: 須藤

AI・機械学習チームでは、Google CloudのCloud Monitoringでロードバランサーを監視しています。以前はプロダクト毎にロードバランサーを監視しており、監視設定はプロダクト担当者がTerraformで設定していました。しかし、AI・機械学習チームはプロダクト数が多く、監視設定をプロダクト担当者が実施する運用だと設定漏れが発生していました。

そこで、このMRでは、個別で監視を設定するのではなく、1つの設定で全ロードバランサーを監視するようにしました。これにより、各プロダクト担当者が監視の設定をする必要がなくなり、監視漏れを無くすことができました。

まとめ

今年の第1位は須藤さんの一括ロードバランサー監視でした。このMRは大量にプロダクトを生み出すAI・機械学習チームにとって漏れの起きやすい「監視」を自動化するというスマートな変更でした。

AI・機械学習チームではレビュー時に「ベストMR候補」とコメントしておくことで、ベストMR決定戦に備えていると同時に、より革新的なMRを生み出そうというモチベーションを高めています。2024年はチームの人数がこれまで以上に増え、MR数も多くなりました。来年はどういった改善が行われるのか期待ですね。

それでは、またベストMR決定戦2025で会いましょう!

We are hiring !!

エムスリーAI・機械学習チームでは、どんどん改修を進めていく意欲のあるエンジニアを募集しています。 新卒・中途それぞれの採用だけでなく、カジュアル面談やインターンも常時募集しています!

エンジニア採用ページはこちら

jobs.m3.com

カジュアル面談もお気軽にどうぞ

jobs.m3.com

インターンも常時募集しています

open.talentio.com

*1:Google Kubernetes Engine. Google Cloudが提供するマネージドKubernetesクラスター

*2:可用性が担保されない反面、格安で利用できるノード。Preemptible VM, Spot VMとも

*3:例えば、社内外のAPIなど、連携するコンポーネントへの疎通

*4:単にリトライ上限を増やすでも解決できますが、例えばコードのバグや設定ミスなどリトライで解決しない場合に、不要なインスタンスの起動時間とそれに伴う費用が発生します