モリカトロンAIラボGAMEゲームMUSIC音楽ARTアートTECHNOLOGY先端技術SCIENCEサイエンスMORIKATRONモリカトロンTAGモリカトロン株式会社運営「エンターテインメント×AI」の最新情報をお届けするサイトです。取り組み」でCygamesの立福寛氏が講演したのは、社内の共通基盤ツールへのAI機能の導入についてです。AIモデルの学習プロセスについてはもちろん、インフラ構築、作業分担、デプロイ環境など、機能を支える背景の部分も取り上げた、新規にAI導入する際に非常に参考になる内容になっています。物体検出/画像認識アルゴリズムを利用した自動タグ付けまず取り掛かったのが、画像認識による自動タグ付けです。キャラクターが一人以上ふくまれる画像を入力すると、キャラクターの名前が表示される機能をリソース管理ツールに実装します。リソース管理ツールはWebベースで画像や動画のアップロードと検索閲覧、一括ダウンロードを行うことができます。タグ付けは手動で行っていますが、その作業プロセスにAIを使った自動レコメンド機能を追加します。Detector)」を使っています。検出した物体に対しタグ付けを行うというもので、学習を行った後のモデルに画像を与えると物体の領域とクラス名が出力されます。そのうち、今回はクラス名だけをタグとして使用しています。実装にはオープンソースの「PyTorch」を使っています。学習用のデータはすでに登録された画像データです。複数プロジェクトに使われており、1プロジェクト当たり数千枚の画像が登録されています。そのうち1プロジェクト分の画像を使って学習を行いました。対象は1キャラクターのみがふくまれる画像となります。これは、2人以上のキャラクターがふくまれた場合にどちらが誰か判別できないためです。今回はキャラクターが200人程度、画像の数はキャラクターごとに差があり、7枚から70枚です。画像に対し、OpenCVのアニメ顔認識モデルを適用し、キャラクターの顔の領域を取り出します。これにより、「画像」と「顔の領域」と「キャラクターの名前」の3つがセットで取得できます。物体検出アルゴリズム(SSD)SSDで学習した結果ローカルPCで1日程度の学習を行ったところ、テストの精度は90%台前半という結果が出ました。これについて立福氏は次のようにまとめています。学習データが多いキャラクターは認識精度が高い(逆も然り)顔や髪型に特徴が少ない一部のキャラクターは誤認識が多い大きくデフォルメされた画像の認識精度は低い(大きくデフォルメされた画像を学習データに入れると精度が大幅に下がった)そのため、大きくデフォルメされた画像については別のモデルを用意したほうがよいと言えます。ゲームのキャラクターに特有の表現、例えば「顔に大きな角度が付いている」「片目が隠れている」などの場合は認識精度が落ちることも指摘しています。背景画像については、画像認識アルゴリズムを使っています。Sagemaker」を使って、1,400枚程度の画像データで学習を行いました。分類するクラスは180程度です。実際のデータでの精度は7割ほどです。自動タグ付け機能のデプロイ環境について次はデプロイ環境について解説しました。リソース管理ツールはAWS上に構築されているので、AWSで完結できればそれに越したことはありません。Sagemaker」(以下、Sagemaker)に統一することにしました。SagemakerはAWS上で機械学習モデルを利用するための統合環境で、さまざまな機械学習モデルの学習からエンドポイントの作成まで行うことができます。前述のように、背景画像のタグ付けに物体検出アルゴリズムをSagemaker上で使っています。キャラクターの顔認識も物体検出アルゴリズムで行います。Gateway→Lambda→Sagemakerという構成で呼び出します。初期実装ただし、コスト面で問題が起こったため、最初に使用したオープンソースのSSDの実装をLambda上で動かすよう変更しました。Lambdaでは最大10GBまでユーザーのdockerイメージを動かすことができます。Pythonの機械学習モジュールはデプロイ時に問題になりやすいものの、dockerイメージで丸ごと持っていけるのは非常に楽であるため、お勧めの構成だと立福氏は言います。最終的な実装リソース管理ツール上で画像のアップロード中にタグの予測ボタンを押すと、自動タグ付け機能が呼び出され、ダグのレコメンドが行われます。確信度が80%以上の場合のみタグとして出します。自動タグ付け機能の処理は数秒ですが、Lambdaの仕様により初回呼び出し時は20秒程度かかるとのことです。自動タグ付け機能の開発が終わり社内でヒアリングを行ったところ、シナリオ執筆ツールで誤字を検出してほしいという要望が出たことから、次に誤字検出機能を開発することになりました。シナリオ執筆ツールはWebベースのシナリオ作成環境で、シナリオの執筆、監修、台本の印刷、音声の管理ができます。APIでシナリオを一括で取得することができ、フォーマットも完全に統一されており、AIの学習データを簡単に用意することができます。シナリオ執筆ツールの概要シナリオ執筆ツール向けの表記揺れ機能の概要こちらは形態素解析とルールベースでの実装です(参考論文:シナリオ執筆ツールへの表記揺れ機能)。形態素解析とは文章をトークンと呼ばれる単語単位に分割する処理のことで、この形態素解析を使って次のように表記揺れを検出します。入力された文章を形態素解析し、名詞を取り出します。この時に連続している名詞は結合して1つの単語として扱います。次に、単語と単語を比較して表記揺れスコアを求めます。このスコアが高いほど表記揺れの可能性が高いことになります。図のように「たこ焼」「たこ焼き」の表記揺れ、「一時間」「1時間」の表記揺れと判断できます。形態素解析とは表記揺れ機能のアルゴリズム形態素解析モジュールには代表的なものにmecabなどがありますが、比較した結果、juman++を採用しました。juman++はRNNを用いて単語の並びの意味的な自然さを考慮した解析を行う点が特徴で、話し言葉が多いゲームのシナリオには適していると判断したのです。2つの形態素解析モデル今回はスコアの高い順に30個を返す関数として実装しました。スコアの計算は先に挙げた論文を参考にしています。この時、計算に必要な要素は「編集距離」と「出現回数」です。単語Aを単語Bにするために必要な手順の数を編集距離とし、単語間の編集距離が小さいほどスコアが大きくなるという仕組みです。単語の出現回数の差が大きい場合にスコアが大きくなるようにしています。「たこ焼き」を「タコ焼」にするには2つの文字を置き換えることになるので編集距離は2です。出現回数も10と1なので、スコアは高くなります。Lambdaへ持っていきました。この機能の開発時はまだLambda上でdockerイメージが使えなかったため、通常のLambdaパッケージを作っています。EFSファイルシステムをLambdaにマウントして、大きいファイルはそちらから読み込んで関数を実行します。Lambdaでの実装シナリオ執筆ツール上で表記揺れを調べたいシナリオを選択してボタンを押すと、表記揺れ機能のAPIが呼び出されるという仕組みです。表記揺れの可能性がある部分が赤くハイライトされて正しい候補が右側に表示されます。シナリオ執筆ツールへの組み込み社内のユーザーからも好評で、名詞に加えて動詞の表記揺れ検出機能も欲しいというリクエストにも対応しています。同時に単語を指定して表記揺れを探す機能も追加しました。シナリオ執筆ツールにおける誤字検出機能こちらも社内のユーザーからの要望に応え、開発した機能です。機械学習を利用した誤字検出は有料のサービスが複数存在しますが、毎月の課金がかかるのとデータの機密の問題もあり、独自実装することになりました。LSTMを用いた誤字脱字検出システム」を参考に、一部のアルゴリズムを変更して新たな自然言語処理モデルとして実装しています。自然言語処理モデル「BERT」を使って、入力された文章を「誤字がないもの」と「誤字があるもの」に分類します。次に、誤字があると判断された文章を形態素解析して単語ごとの出現順を別のBERTモデルで求めます。出現順が低い単語は誤字の可能性が高いということになります。単語ごとの出現順をランダムフォレストと呼ばれるモデルに入力して最終的な誤字の位置を求めています。BERTは2018年にGoogleが発表した自然言語処理モデルで、翻訳や文章分類などのタスクで当時の最高スコアを出したことで一躍有名になりました。今回は文章分類、単語の出現順の推論の2つのタスクに使っています。現在、BERTよりも新しいモデルが出ていますが、広く利用されて情報が多い点と、日本語の学習済みモデルが複数公開されていることが利点です。各機械学習モデルの説明になりますが、「文章を誤字なし・ありに分類する」モデルにはBERTの文書分類タスクが使われています。学習データとして、ニュース記事とジャンルの組み合わせを用意して学習させ、学習済みのBERTへニュース記事を入力すると適切なジャンルが取得されるというものです。ここでは「誤字がない文章」と「誤字がある文章」の2種類を分類するBERTモデルを作ります。実装はBERTとTensorflow、形態素解析はSentencePieceという構成です。学習データは「誤字なし」と「誤字あり」の2つ、元の文章と誤字をふくむ文章を1:5で用意してBERTの文章分類で学習させます。誤字のパターンはシナリオ執筆ツールを利用している社内のユーザーから文章校正のテキストを提供してもらい、そこから抽出しています。元の文章と誤字を入れた文章を先ほど学習したモデルへ入力して推論を行います。この時出力されるのは、単語ごとの出現順のリストです。この値を次のモデルの学習データとして使います。この時誤字を入れた位置を目的変数として追加しておきます。誤字がない文章の場合は「-1」を入れます。最後は、誤字の位置を求めるモデルです。前のモデルから出力された単語の出現順の並びから最終的な誤字の位置を決定します。前のモデルから出力された値のうち、誤字の位置が機械学習における目的変数、それ以外の単語の出現順の値が説明変数となります。この2つをセットにした学習データを使って学習を行います。使用するモデルはランダムフォレスト、scikit-learnの実装を使っています。誤字の位置を求めるモデルの実行結果ただ、こちらの精度は35〜45%程度という結果です。当初は誤字のパターンを少なくしていたので精度が高かったのですが、誤字のパターンを増やしたところ精度が下がってしまいました。誤字の位置を間違って検出してしまうケースが15%程度、残りの50%は誤字があるのに誤字がないと推論してしまうようです。図で示す例は「イベントは大盛況のちに終わった」という文章の「のち」の部分に誤字があるケースで、これは正しく予測できています。1つは、「素敵な歌詞になたと思う」という文章の「なた」の部分に誤字があるのですが、「素敵な」の部分に誤字があると間違えて予測した例です。Lambda上へ持っていきました。Dockerのイメージが大きくなると、Lambdaの更新に時間がかかるため、学習したモデルをDockerイメージにふくめずに別のファイルシステムから読み込む形にしています。Lambdaで実行してみたところインフラ側の制限時間(30秒)に引っかかってしまうことがわかりました。真ん中の単語の出現順を求めるモデルが非常に重く、CPU実行では大半の時間をそこで使ってしまうのです。そこで、AWSのStepFunctionsによる非同期呼び出しの仕組みを追加しました。最初にLambdaで関数の実行を開始し、しばらく経ってから結果を問い合わせて、終わっていれば結果を受け取るという形です。これにより、Lambdaの最大タイムアウト時間の10分まで処理を行えるようになりました。StepFunctionsによる非同期呼び出しこの非同期呼び出しの仕組みに合わせてシナリオ執筆ツールのUIを変更し、処理を開始すると画面をすぐに戻し、実行中の処理は別の画面で見るようにしました。表記揺れも同じ扱いです。このように、UIを工夫することでAIの処理時間を隠蔽することができます。機能に関しては、AIエンジニア、インフラエンジニア、ツール開発者の3人での作業分担でしたが、誤字検出ではAIエンジニアがインフラ構築も担当する形になっています。これについて立福氏は、機械学習向けのインフラ構築はゲーム運用やWebサービス運用とは勝手が違ってインフラ担当でも実績がないこともあり、AIエンジニアが試行錯誤できるようにインフラ構築まで兼任したほうが話が早い場合もあると分析しています。CDK」を使うことで、簡単にインフラ構築が行えたそうです。functionを追加した形になっています。今回の試みの背景には、ゲーム開発におけるAIの導入事例も増え、情報にアクセスしやすくなったことがあります。リソース管理ツールやシナリオ執筆ツールのような共通基盤ツールがあると、機械学習の学習データを用意するのが比較的容易になります。このあたりが開発現場にAIを導入する際のポイントになると言えそうです。画像生成AIをめぐる倫理的問題の最新事情。