はじめに
11月末から2週間、エンジニアリンググループ AI・機械学習チームでの新卒ソフトウェアエンジニアインターンに参加した山口 (@chimaki_yama821)です。この記事では私が取り組んだことと2週間の感想について書いたので、エムスリーが気になっているという他の学生の参考になれば幸いです。
インターンの課題について
やったことの概要
インターンでは、「動画のタグづけをする」というタスクについて取り組んでいました。扱いたい対象となる動画について確認したのちに、
- アウトプットイメージの検討
- タグづけアルゴリズムの実装
- クラウドへのデプロイ(途中で終了)
ということに取り組みました。ここで、「タグづけ」とは以下の図のようなことを意味しています。
扱う動画について
エムスリーのサービスには、MRさん*1 が医師に薬剤の説明動画を提供するというプラットフォームがあります。そこで、私はこのインターンで「MRさんが提供している5分〜10分ほどの薬剤に関する説明動画に対して使いやすい形でタグづけをする」というタスクをいただき、これについて取り組んできました。
やったこと
アウトプットイメージの検討
上記のような動画へタグづけを行う、ということで 誰が・どのように嬉しいか? ということを考慮しながらアウトプットイメージを検討しました。メンターさんとの 1on1 や他の社員さんとのコミュニケーションを通じて、以下の三つにつながると嬉しいと考えました:
① コンテンツ作成者が次の動画作成に役立つ
過去に作成した動画についての「s秒からt秒までで〇〇を話していた」という情報と視聴者がどこまで見たかの情報を合わせて「タグごとの視聴率」を取得することができます。これを得ることができれば、コンテンツ作成者が 次の動画作成時に気を付けるべきことが分かります。
例えば、下の図では、 "foo", "bar" について話している時には視聴率が高かったものの "baz" についての話で多くの視聴者が脱落して視聴率が下がってしまっていることが分かります。そこで、次の動画を作る時には "baz" を分かりやすくする・ "qux" を先に説明する、などの工夫をしようと考えることができます。
② 医師が見たいところを見るのに役立つ
次に、ある動画についてのタグづけを行うことによって、医師(動画視聴者)が 見たいところを選んで見るのに役立つ と思います。下の図のように、時刻と話している内容をリンク付きで用意することによって、例えば「薬剤Xについては大体知っているがZとの併用効果が気になる」という視聴者が 3:55 から動画を見れば良いことが分かります。
③ 他のデータと組み合わせてより深い分析をするのに役立つ
最後に、作成したタグとユーザーごとの視聴状況を元に、さらなる分析に繋げることに役立つと考えます。例えば、薬剤Xについての動画で "Zとの併用効果" の部分を見ていないユーザーの方に対して、Zとの併用効果のみの短い動画や記事をレコメンドすることに繋げることができます。また、 「"Zとの併用効果" をみたユーザーでの薬剤Xの利用率」などを分析してさらに他のこともできるかもしれません。
以上を踏まえて、インプットとして受け取った動画に対して「タグ+開始時刻+終了時刻」というデータを自動生成することを目指すことになりました。この形でアウトプットが得られれば①〜③のいずれにも使いやすいと考えたためです。他の人が使いやすくするために、「GCS に配置された動画に対してタグづけを行い BigQuery に保存するバッチ処理」 という形を最終系として目標に掲げました。
タグづけアルゴリズムの実装
実際に動画に対してタグづけを行うにあたっては、 OpenAI の Whisper で文字起こしを行い、その後の処理に GPT を使いました。このうち、 Whisper についてはローカルの CPU 環境でモデルを動かしました。
Whisper による文字起こし
Whisper を使うことで、そこそこ高速に文字起こしをすることができました。また、動画で話されていた内容を約1文単位で「文字起こし+開始時刻+終了時刻」という形で得ることもできます。
Whisper にはパラメータサイズの異なる複数のモデルがあるのですが、今回はいくつか試して十分な正確さがあって比較的高速に動作するという点で 'medium' (要求 RAM: 5GB ほど)を使用しました。日本語で専門用語を多く含む動画に対しても正確に文字起こしすることができていて、とても役立つものだと感じました。
GPT によるタグづけ
Whisper によって取得した文字情報を、GPT によって構造化することでタグづけを行いました。1文ずつでは開始時刻・終了時刻がわかっているため、それをいくつかのセクションに分割して各セクションの概要をタグとして取得する、ということを目指しました。
色々と試していく中で、下の図のように「まず文字起こしした全文をセクションごとに分けて要約させて、次にその出力も用いて1文ずつ各セクションに配置する」ということを行いました。一度の生成ではうまくいかなかったのですが、最初に要約を作成させて一度の生成での仕事を減らすことでやりたいことが実現できました。モデルは gpt-4o-mini を使いました*2。
クラウドへのデプロイ
上記のようにして動画からタグづけを行うまでの処理はコードを実行することでできるようになったのですが、それをどのようにして動かすかが問題になりました。インターン後半ではこの部分に取り組んでいました。
機能追加と GitLab リポジトリ作成
まずは作成したタグを BigQuery にアップロードする部分と動画を GCS からダウンロードする部分を Python で実装しました。どちらも公式の Python Client が用意されているため比較的容易に行うことができました。
これらの機能が整ったところで「プロダクトとしてリポジトリを作ろう」という話になり、 Vermouth(ベルモット) *3という名前で作成しました。 これまで自分はアプリ開発の経験がほとんどなかったため、コードの整理や Poetry などのパッケージ管理ツールの活用には苦戦しました。しかし、MR(マージリクエスト)を作成してレビューを受け、そのフィードバックを踏まえて修正とマージを繰り返すことで、徐々にリポジトリを充実させていくことができました。
コンテナでの動作とデプロイ
次にローカルのコンテナ上で動かせるようにしました。Docker はほとんど触れたことがなかったのですが、AI チームの皆さんに丁寧に教えていただくことで何をしているか理解しながらコマンドを実行したり Dockerfile を書いたりすることができました。
最後に GKE 上にデプロイしてバッチ処理を行う、というのを途中までやりました。Terraform での BigQuery, GCS リソース管理や権限設定、k8s や Skaffold など、はじめて触れるものだらけでとても勉強になりました。最後まで動かすことはできなかったのはとても悔しいですが、貴重な経験ができました。
感想
色々なことに挑戦できてとても楽しい10日間でした。特に、毎日のメンターさんとの 1on1 で今後の方針や困っていることの質問などをしているときに、 すぐに答えを言わずにこちらに考えさせてくれた のがよかったです。例えば最初に述べた「何が嬉しいか検討」のところではこちらが答えたことに対して何度も深掘り質問をしてくださったおかげで一人では考えられなかったことまで整理できました。後半にコンテナ周りの分からないことだらけで困っていた時に同じことを何度か聞いてしまったり忘れてしまったりしたことがあったので、聞いた内容をきちんと整理することは今後の課題だと感じました。
初日と最終日以外はリモートでのインターンということで集中して取り組めるか不安でしたが、とても充実した期間になりました。毎朝のミーティングや仕事とは関係ない雑談をする夕会でカメラオンで話す機会があることで、コミュニケーションが取りやすいのがよかったです。また、slack での会話や zoom での会話がとても賑やか*4なのもはじめは驚きましたが働きやすさにつながっていると感じました。氏家さんの記事 で AI・機械学習チームのリモートワークに関することが書かれているので気になる方はこちらもご覧ください。
上に述べたことのほかにも、社員さんとの 1on1 ・技術共有会・tech talk など色々なことができました。1on1 ではエムスリーに関する話や就活の話をたくさんできてとても勉強になりました。技術共有会では技術書や論文の輪読会が行われていました。インターン期間中にここで発表もしたかったけど時間が足りずできなかったのが残念。
最後に
私は競プロやデータ分析コンペでちょっとしたコードを書く程度しかしておらず、研究でもコードを書くことがないのですが、今回の経験を通じて自分で何かアプリを作ってみたいと思うようになりました。技術力がついただけでなく、考え方や技術への姿勢まで変わった気がします。
メンターの北川さん(@kitagry)、AI・機械学習チームの皆さん、本当にありがとうございました!
エムスリーに興味を持っている学生の皆さん、ぜひインターン参加してみてください!