Qiita全国学生対抗戦 Advent Calendar 2023 シーズン6、22日目の記事です。
シアトルの画像生成系のアプリを提供するスタートアップに、1年足らずソフトウェアエンジニアインターンを行ったので、その経験について書きます。
目次
1.はじめに
2.インターン探し (2022年1月~2023年3月)
3.採用面接 (2023年3月)
4.開発と英語について (2023年4~5月)
5.リモートワーク (2023年5~7月)
6.ウェブアプリ開発 (2023年7~12月)
7.まとめ
1. はじめに
僕は機械学習を使ったサービスを作るのが趣味の大学生です。Twitterのアカウントはmasaishi2001、Githubはmasaishiです。Stable Diffusionを使った動画フィルターライブラリのVidDiffusionなどを作っています。
高校卒業後、ワシントン州シアトルにあるコミュニティカレッジ(日本における短大)に留学し、ESL(英語準備コース)などを経て2023年3月に卒業しました。そして、同年9月からカリフォルニアにあるUniversity of California Santa Cruzに編入し、現在は学部3年生です。
インターンを始めたのはコミュニティカレッジ卒業後の2023年4月からで、職場勤務を約4ヶ月間、リモートで5ヶ月間程働きました。僕は日本での業務経験がないので、日本と比較することはできませんが、アメリカでインターンを見つけるためにやったことや、スタートアップ文化で驚いたことなどについて、時系列に沿って書きたいと思います。
2. インターン探し (2022年1月~2023年3月)
インターン自体は、2年前の2022年1月から探していて、その頃にレジュメ(履歴書)とカバーレター(志望動機や自己PRを書いた送付状のようなもの)を書きました。
レジュメには以下の内容を記述しました:
- KaggleのPetFinder.my - Pawpularity Contestの銅メダル
- Courseraの"How to Win a Data Science Competition: Learn from Top Kagglers"というコースの修了証明書
- Tokyo Analyzerという、AIを用いた立地分析Webサービスの開発
- 高校課題研究の、日本語学習アプリ開発
- 小6、中1時に獲った中高生国際Rubyプログラミングコンテスト in Mitakaの優秀賞
そして、Linkedinやindeedでインターンの求人を探し、30個以上のポジションに申し込みました。しかし、1つもオファーをもらうことができず、もっと強い活動実績を積むか、別のアプローチを試さなければならないと実感しました。
そのため、インターン先を見つけるまでの1年強の間は、活動実績を増やすためにも、ML/AIの勉強をしたり、サービスやアプリの開発をしていました。
またそれ以外にも、meetupというイベントを見つることができるサービス(テック以外のイベント情報もあるconnpassのようなもの)で、テックイベントを見つけたくさん参加しました。
アメリカでは、人脈が重要な気がします。1部の大学や大学院入学に推薦状が必要だったり、就職においてもReferralと呼ばれる、採用されたい会社の社員からの推薦があると有利だったりします。人脈を自分で広げるのも1つの能力だと重視されているように感じたため、英語でテック系のことについて話す練習も兼ね、多くのイベントに参加しました。
よく参加していたイベントは、クラフトビール屋でのもくもく会、スタートアップ関連の人がクラフトビールを飲みながら話すソーシャルイベント、クラフトビール屋でAI論文について議論する会、などです。
イベント参加者は、Google、Microsoft、AWSなどのエンジニアが多く、話すだけでとても勉強になりました。特に、スペースXのエンジニアから、ロケットのプログラムを書く大変さについて聴けたり、AWSでRustのコードを書いているエンジニアから、直接Rustの面白さなどを教えてもらえたりできるのは、アメリカならではだと思います。なので、アメリカに旅行に行く機会があったら、meetupで、codeやtechなどのキーワードで検索して、試しにイベントに参加してみることをおすすめします。
1年ほどたった2023年2月から、インターン探し活動を再開し、様々なイベントで作ったもののデモを見せつつ、インターンを探していることのアピールを始めました。
そんな活動を初めて1ヶ月ほど経った頃、スタートアップ関連の人が集まるイベントで、AIスタートアップのCEOと話すことができ、当時開発していたStable Diffusionを使った動画フィルターのデモを見せました。その結果、非常に興味をもってもらい、トントン拍子でオンライン面接を行ってくれることになりました。
3. 採用面接 (2023年3月)
3月下旬に、コミュニティカレッジ最後のクラスの、学期末テストを終え無事に卒業をし、次の週にCEOとCTOにオンライン面接を行ってもらいました。コードテストなどはなく、実際に僕が今まで作ってきたプログラムの説明を行い、相手からの質問に答えるという形式でした。
僕は、Stable DiffusionのTextual Inversionを活用した写真フィルタースマホアプリを見せたり、同じくStable Diffusionを使い、精度は良くないけれどフレームごとの整合性がとれるように工夫した、動画フィルターのデモを見せました。
そのスタートアップは、Stable DiffusionのDreamBoothモデルによる画像生成を提供するiOSアプリを開発していたため、質問によってpythonでその推論サーバーに関われる技術力があるかを測られていた気がします。
最初に聞かれたのは、僕が作った写真フィルターアプリにおいて、Stable Diffusionをどのようにアプリから呼び出せるようにしているかです。僕はモデルのデプロイにAWSのSageMakerを使っており、自分でサーバーのコードを書いていませんでした。そのため、補足として立地分析サービスのTokyo Analyzerを開発したときに、Flaskでkerasで作ったCNNの推論サーバーのコードを書き、DigitalOceanのレンタルサーバーでデプロイした話をすることで、推論サーバーに関われることをアピールしました。
次に、動画フィルターの精度を上げるためにどのように工夫しているかを聞かれました。huggingfaceのDiffusersを扱えることと、モデルの精度を上げる工夫ができることをアピールするため、実際にコードを見せながら、どのような実験を行い、どのような効果が得られたから、このような工夫を行っている、といったことを説明しました。
また、Swiftができるかと聞かれましたが、僕が最後にSwiftのコードを書いたのは3年程前のため、実際のiOS開発に参加するのは難しいと伝えました。その会社では、iOSアプリの他に、ウェブアプリをReactで開発しており、ウェブ開発に参加できるかとも聞かれました。そちらは、TRPG_AIという、ChatGPT APIにゲームマスターをやらせるブラウザーゲームを、ReactをベースにしたNext.jsで開発していたため、そのことを説明し、ウェブのフロントエンド開発は行うことができると答えました。
CEOとCTOが欲しているであろう、画像生成AI関連の開発、pythonでAI推論サーバー開発、Swiftを用いたiOS開発、Reactを用いたウェブアプリ開発の4つの開発能力のうち、3つを過去に経験したこともあり、次の日には無事に採用してもらえることになりました。自分が興味を持っていた範囲のスタートアップのCEOに、たまたまイベントで出会えるという幸運を活かせて良かったと本当に思います。
4. 開発と英語について (2023年4~5月)
そのスタートアップは、University of Washingtonが持っている、スタートアップ用シェアオフィスのデスクを借りていました。
スタバのコーヒーマシンを使い放題だったり、休憩スペースで他のスタートアップの人たちと話をする機会があったりと、素晴らしい場所でしたが、普段出社するのは僕とCEOだけでした。CEOも家から働くことが多く、1人でオフィスから開発する日も多かったです。他の州や他の国からリモートで働いている人も多く、グローバルなチームでした。
最初はプロジェクトに慣れるため、準備期間を設けてくれており、その間にサーバーのコードや、ウェブアプリのコードなどを読み、実装について確認しました。AIの推論インフラを担当していたのが、MLでPhDを持っていて、実装力も高いスーパーハッカーで、その人の書いた複数のモデルを、GPUのメモリー不足を引き起こさないようにスケーリングするコードなどの設計が素晴らしく、読むだけで勉強になりました。
僕の最初の仕事は、開発中のウェブアプリに機能を追加することでした。僕は以前、GPUを動かせるサーバーレンタルが高すぎて、サービスを作るのを諦めていましたが、業務として給料をもらいながら、多くのDreamBoothモデルを動かすPythonで書かれたサーバーに機能を追加するなど、得難い経験をすることができました。
僕は英語が苦手なため、チャットによるテキストコミュニケーションが大変でした。チームのほとんどがリモートで働いていたため、主にSlackを使ってコミュニケーションを取っていました。誤解を招く可能性のあるメッセージには、誤解を避けるために絵文字を加えたり、言葉選びに気をつけるなどの工夫をしていました。
特に相手の意見に反対したい時は特に大変で、GitHubレポジトリのDiscussionsなどを参考に適切な言い回しを見つけるようにしていました。
日本人は僕だけでしたが、チームは合計8カ国からのメンバーで構成されていました。そのため、そもそも英語ネイティブな人の方が少なく、大学の授業などと比べるとそこまで困ることはありませんでした。
5. リモートワーク (2023年5~7月)
日本に一時帰国することを決め、日本からリモートでインターン業務を続けました。日本での生活が楽しすぎたため、多くの時間を働くことができなかったものの、画像生成の精度を向上させる実験や、ウェブアプリへの新機能の追加などを行いました。
以前ウェブ開発を行っていたメンバーが6月からプロジェクトに参加しなくなったため、以降のウェブ開発は僕が担当しました。
6. ウェブアプリ開発 (2023年7~12月)
日本から戻ると、インド人のMLOpsエンジニアとメキシコ人のデザイナーという2人が新しく採用されており、オフィスで3人で業務を行う機会が増えました。2人と年が近かったこともあり、3人で昼休みにサッカーをしたり、仕事終わりにパブでクラフトビールを飲みながら開発中のサービスについて議論したり、楽しく働ける素晴らしい環境でした。
当時、ウェブアプリのメイン機能の1つであるtext2image機能は、テキストフォームにプロンプトを入力し各種パラメータを変更することで画像を生成するというシンプルな構成でした。それをもっと使いやすくするために、キャンパス上に生成した画像を描画し、様々な変更をペイントソフトのように行えるように変更しました。
画像をブラウザー上で操作し、生成した画像を組み合わせimg2imgやControlNetに再利用するような機能の実装過程で、コンポーネントをどう分割するかや、どのようにコードを設計すべきなどについて考えるスキルが上がった気がします。しかし、その上で改めてOSSで開発されているサービスなどのコードを読むと、自分のコードとは比べ物にならないほどよく考えられて設計されているようと実感します。なので、もっと良いコードをたくさん読み、自分が書く量も増やさなければならないと感じました。
キャンパス機能を実装した後、アプリ全体のリファクタリングを行ったり、CypressでE2Eのテストを自動化したり、コマンド機能や、チャットによってプロンプトを作成する機能を作りました。
リモートでウェブ開発担当が2人新しく採用されました。僕は大学編入に伴ってカリフォルニアに引っ越すので、その前にREADME.mdを書いたりzoomで引き継ぎのミーティングを数回行いました。
9月にカリフォルニアに引っ越した後も、リモートで時間があるときにプルリクをいくつか閉じたり、僕が書いたコードの質問に答えたりしていましたが、12月にSlackのグループからも抜け、僕は完全にインターンをやめました。
7. まとめ
このインターンは僕にとって非常に価値のある体験でした。個人開発だけでは得られない様々な経験が得られ、他人にコードレビューされるというプレッシャーのおかげで、普段よりきれいなコードを書こうと意識ができ、コーディング能力自体も向上したように感じます。
僕は4年制大学卒業後、エンジニアとして働きたいのか、スタートアップを作りたいのか、大学院に進み研究をしたいのか、自分の中で結論は出ていません。しかし、社会に出る前に、実際にスタートアップで開発に携わる経験を得られたのは、自分の進路を考えるいい材料になりました。
心地よい環境で、優秀なチームメンバーとともに、1つのプロジェクトに参加できたのは、自分の人生において素晴らしい経験の1つになりました。このような機会を与えてくれたCEOやチームメンバー、そしてアメリカに留学させてくれた両親に、心から感謝を込めて、この記事を締めくくらせていただきます。