paint-brush
Gemma-2b と MediaPipe を使用して Simon Says を再生するby@darrylbayliss
665
665

Gemma-2b と MediaPipe を使用して Simon Says を再生する

Darryl Bayliss11m2024/03/29
Read on Terminal Reader

Gemma は、ローカル マシンやモバイル デバイス上で実行できるほど小さい、Google の新しい LLM です。 MediaPipe を使用して、デバイス上の LLM とインターフェイスし、要求を要求できます。 2b モデルはうまく機能していないようで、7b モデルは改良されています。 v1 バージョンでは、これらがモバイル デバイス上で動作するのは印象的です。
featured image - Gemma-2b と MediaPipe を使用して Simon Says を再生する
Darryl Bayliss HackerNoon profile picture
0-item
1-item


数週間前、私は Google の Gemma Developer Day に参加しました。 Google に特化した日で、Gemma と呼ばれる最新の LLM モデルの機能、移植性、オープン性を紹介します。


これらのモデルは、生成 AI に刺激的な新しい段階をもたらします。ローカル デバイスに展開できるほど小さいモデルでも、魅力的で役立つエクスペリエンスを提供できます。


久しぶりに Mobile AI を見てインスピレーションを感じながら一日を終えました。これらのモデルを Android アプリで試してみるとどうなるかを確認してみることにしました。

アプリ

ジェマに簡単でありながら斬新な挑戦をしてみたかったのです。サイモン・セイズのゲームをプレイしています。


ルールは簡単です。プレイヤーの 1 人がサイモンになります。彼らの役割は、他のプレイヤーに実行するタスクを与えることです。サイモンとしてプレイするプレイヤーは、タスクを与える前に「サイモンが言う」と言う必要があります。


3つの画面を持つアプリを作成しました。入力画面、指示画面、ジェマがコミュニケーションをとってタスクを与えることができるチャット画面。


サイモンはアプリの画面について語る


チャット画面の構築を迅速化するには、 Meyta Talitiのこのブログ投稿が非常に役に立ちます。

画面が作成されたので、次のタスクは Gemma を統合することでした。このために、私は MediaPipe と呼ばれる、私が学んだ一連のツールに依存しました。

メディアパイプ

MediaPipe は、AI モデルを Android、iOS、Web 上のアプリに簡単に統合することを目的としたツールのコレクションです。 MediaPipe を使用すると、ニーズに応じて多くの選択肢があります。


メディアパイプのロゴ


すぐに始めたい場合は、MediaPipe が AI モデルを呼び出すためのTasksと呼ばれる API を提供します。これらの API は、ビジョン、テキスト、オーディオなどのさまざまな領域に分割されています。


MediaPipe は、アプリ内に埋め込むための事前トレーニング済みモデルのコレクションも提供します。繰り返しますが、すぐに始めるのに役立ちます。


もっとカスタムなものが必要で、最初からモデルを作成したくない場合は、MediaPipe がModel Makerと呼ばれるツールを提供します。 Model Maker は、転移学習と呼ばれるプロセスを使用して、既存の機械学習モデルを再トレーニングし、新しいデータを提供します。このアプローチの利点は、時間を節約し、新しいモデルを作成するために必要なトレーニング データが少なくなることです。


モデル メーカーは、このプロセスを通じて、作成されたモデルのサイズを小さくすることもできます。このプロセスにより、モデルは既存の知識の一部を「忘れる」ことに注意してください。


MediaPipe の最後のツールはMediaPipe Studioで、カスタム モデルを評価および調整するための Web アプリケーションです。導入前にモデルのベンチマークを行い、モデルがどの程度うまく機能するかを理解したい場合に役立ちます。


私たちのニーズに合わせて、MediaPipe の新しい API である LLM Interfence API を利用します。これにより、Gemma と通信して応答を受け取ることができます。

MediaPipe を機能させる

MediaPipe を使用するには、まずそれを Gradle 依存関係としてアプリに追加する必要があります。

 implementation ("com.google.mediapipe:tasks-genai:0.10.11")


次に、 LlmInferenceのインスタンスを作成します。これは、Gemma との通信に使用するオブジェクトです。


 val llmInference = LlmInference.createFromOptions( context, LlmInference.LlmInferenceOptions.builder() .setModelPath("/data/local/tmp/llm/gemma-2b-it-cpu-int8.bin") .build() )


.setModelPath使用して設定されたパスに注意することが重要です。これは、デバイス上で Gemma モデルが存在する場所です。使用される Gemma モデルがgemma-2bバージョンであることも重要です。 7bバージョンは MediaPipe ではまだサポートされていません。これが何を意味するかについては後ほど詳しく説明します。とりあえずモデルをダウンロードしてみましょう。


Gemma はKaggleからダウンロードできます。データ サイエンティストと機械学習に特化した Web サイト。モデルをダウンロードするには、アカウントを作成し、利用規約に同意する必要があります。 Gemma のページはここにあります。


この投稿に従う場合は、 TensorFlow Liteタブでモデルのgemma-2b-it-cpuバージョンのみをダウンロードすることを忘れないでください。 gemma-2b-it-gpuバージョンを試す場合は、自己責任で行ってください。


モデルがダウンロードされたら。 Android Studio のデバイス エクスプローラーを使用して、 .setModelPathに設定されたパスにモデルをインポートします。パスまたはモデル名を変更した場合は、必ずパス名を更新してください。


モデルがインポートされたら、 .generateResponseメソッドを使用してプロンプトを Gemma に渡し始めることができます。以下は、Simon Says をプレイするために Gemma に渡すプロンプトの例です。


 private const val SimonSaysPrompt = """ You are a Simon in a game of Simon Says. Your objective is to ask the player to perform tasks. For every task you give, you must prefix it with the words "Simon says". You must not ask the player to do anything that is dangerous, unethical or unlawful. Do not try to communicate with the player. Only ask the player to perform tasks. """ val gemmaResponse = llmInference.generateResponse(SimonSaysPrompt)


以前に LLM を使用したことがあり、プロンプト エンジニアリングの基本を理解している場合は、これに馴染みがあるはずです。念のため、プロンプトに予防措置の指示を含めました。 Simon がユーザーに疑わしい操作を要求することは望ましくありません。


これをデバイス上で実行しようとすると、次のようなことが起こる可能性があります。


  1. アプリが応答するまでに少し時間がかかる場合があり、最終的には応答が返されます。

  2. アプリがクラッシュする可能性があります。 Logcat を見ると、MediaPipe がモデルを見つけられないというメッセージが表示されます。正しいモデルパスを設定しましたか?

  3. アプリがクラッシュする可能性があります。 Logcat を見ると、多くのネイティブ コードのログと、リサイクルされているメモリに関する情報が表示されます。


私の経験は 2 番目と 3 番目のカテゴリーに分類されました。すべてを正しくセットアップし、高スペックの物理デバイスを使用している場合は、体験が異なる場合があります。


これらのエーテルを持っていない場合。エミュレータを通じて利用可能な RAM の量を増やすという別のオプションもあります。

RAMを増やしたAndroidエミュレータの作成

使用可能な RAM の量を増やすと通常、メモリを大量に使用する環境では効果がありますが、メモリを大量に消費する LLM ではなぜ違うのでしょうか?これを行うために、Android エミュレータが使用する RAM の量をカスタマイズしました。


既存のエミュレータをお持ちの場合は、RAM フィールドが無効になっていることに気づくかもしれません。デバイス マネージャーで右側にある 3 つの点をクリックすると、使用可能な RAM の量を更新できます。


[ディスク上に表示]をクリックし、テキスト エディターでconfig.iniファイルとhardware-qemu.iniファイルを開きます。各ファイルのhw.ramSizeの値を変更します。このStack Overflow の質問に、その方法についての答えを与えてくれたことに感謝します。


Android エミュレータがディスク上に表示される


あるいは、Android Studio のデバイス マネージャーに移動し、 [仮想デバイスの作成]をクリックしてから、 [新しいハードウェア プロファイル]をクリックして、カスタム エミュレーターを作成することもできます。カスタマイズするオプションの一部として、RAM の量を選択できます。


Android Studio エミュレータのハードウェア プロファイルの構成


8GBのRAMは比較的うまく動作することがわかりました。 22GBのRAMも試してみました。期待したほどではありませんが、速度の点ではわずかに優れています。


エミュレータの残りの部分は流動的に実行されるため、Gemma がメモリにロードされるときにどこかにボトルネックがあるのではないかと思います。おそらくどこかで改善できるかもしれません。

ジェマ 2b & ジェマ 7b

MediaPipe と互換性のある Gemma モデルはgemma-2bバージョンです。 2b 20 億のパラメータを表します。モデルを機能させるために連携して機能するパラメーターの量。


これらは、Gemma に質問するときに相互間の接続と推論を提供するために、トレーニング中にモデル内に設定される値です。


70 億のパラメーターを使用するgemma-7bコレクションもあります。ただし、これらは MediaPipe ではサポートされていません。いつの日にか!


LLM に関するパラメータについてさらに詳しく知りたい場合は、このページをお勧めします。


20 億のパラメータ モデルをモバイル デバイスにロードして実行できることは、素晴らしい成果です。それはどの程度うまく機能しますか?確認してみましょう。

gemma-2b-it-cpu-int4

gemma-2b-it-cpu-int4 4 ビット LLM です。これは、モデルで使用される各パラメーターのメモリ サイズが 4 ビットであることを意味します。この場合の利点は、モデルの合計サイズが小さくなることですが、各パラメータのメモリ サイズが削減されるため、モデルの精度と品質も影響を受けます。


それでは、 gemma-2b-it-cpu-int4どのように動作するのでしょうか?正直に言うとそれほど素晴らしいものではありません。以下は、上記のプロンプトを使用して Simon Says をプレイし、一般的な質問を試みたときのスクリーンショットです。


gemma-2b-it-cpu-int4 の会話

反応は予想外で、モデルに Simon Says のゲームに似た動作をさせるのはイライラしました。別の話題にそれてしまい、不正確な情報が幻覚のように流れてしまいます。


幻覚は、LLM が虚偽や真実でないことをあたかも事実であるかのように話す現象です。上の例で言えば、火星まで時速60マイルで60分で行けるというのは真実ではありません。とにかくまだです。 😃


文脈認識の欠如もありました。つまり、以前の会話で私が言ったことを思い出せなかったのです。これは、モデルのサイズに制限があることが原因であると考えられます。


しばらくして、私はこのモデルを諦め、より大きな 8 ビット サイズのモデルを試してみることにしました。

gemma-2b-it-cpu-int8

gemma-2b-it-cpu-int8 8 ビット LLM です。 4 ビットの兄弟よりもサイズが大きくなります。つまり、より正確で質の高い回答が得られるということです。それで、ここでの結果はどうなったのでしょうか?


gemma-2b-it-cpu-int8 の会話


このモデルはサイモン・セッズのアイデアを理解することができ、すぐにサイモンの役割を引き受けました。残念なことに、これも文脈認識の欠如に悩まされていました。


これに対抗するには、Simon Says のルールに従ってモデルに毎回再プロンプトを表示し、それを別のプロンプトと組み合わせてタスクの提供を要求する必要がありました。


タスク プロンプトはリストからランダムに選択されて Gemma に渡され、要求されるタスクに多様性が与えられます。


以下に何が起こっているかの例を示します。


 private const val SimonSaysPrompt = """ You are a Simon in a game of Simon Says. Your objective is to ask the player to perform tasks. For every task you give, you must prefix it with the words "Simon says". You must not ask the player to do anything that is dangerous, unethical or unlawful. Do not try to communicate with the player. Only ask the player to perform tasks. """ private const val MovePrompt = SimonSaysPrompt + """ Give the player a task related to moving to a different position. """ private const val SingASongPrompt = SimonSaysPrompt + """ Ask the player to sing a song of their choice. """ private const val TakePhotoPrompt = SimonSaysPrompt + """ Give the player a task to take a photo of an object. """ private val prompts = listOf( MovePrompt, SingASongPrompt, TakePhotoPrompt ) val prompt = prompts.random() val response = llmInference.generateResponse(prompt)


時折、性格から外れているように見える変化球の反応を投げます。これをモデルのサイズに合わせて計算します。これは v1 のみであることも考慮する価値があります。


プロンプトが固まったら、プロンプトのみに依存し、ユーザー入力を考慮しないことが便利であることがわかりました。モデルにはコンテキスト認識が欠如しているため、ユーザー入力によって Simon Says の再生が停止され、代わりに入力に応答します。


このちょっとしたトリックの追加は満足のいく結果ではありませんでしたが、ジェマがサイモン・セーズを演じ続けるには必要でした。

感想と考察

それで、Gemma は Android デバイスで Simon Says をプレイできますか?私は「助けを借りて」と言います。


Gemma 2b の 4 ビット バージョンがより直感的に応答することを望みます。 Gemma 2b にコンテキストを認識させて、リクエストごとに再プロンプトを表示する必要を回避し、ユーザー入力に注意することも役立ちます。


単一のプロンプトのみを必要とする単純なリクエストの場合。 Gemma 2b がこれらのタスクを快適に処理できることがわかります。


これらはモデルの v1 であることにも留意する価値があります。彼らがモバイル オペレーティング システム上で実行および動作するという事実は、素晴らしい成果です。

オンデバイス LLM の将来

モバイルデバイス上の LLM の将来はどうなるでしょうか?障壁が 2 つあると思います。ハードウェアの制限と実際の使用例。


ハイエンドのデバイスだけがこれらのモデルを効果的に実行できる段階に来ていると思います。思い浮かぶデバイスは、Tensor G チップを搭載した Pixel 7 または Pixel 8 シリーズの携帯電話や、Neural Engine チップを搭載した Apple の iPhone です。


この種の仕様がミッドレンジの携帯電話にまで適用されることを確認する必要があります。


興味深いアイデアは、検索拡張生成を活用するデバイス上の LLM から生まれる可能性があります。 LLM が外部データ ソースと通信して、回答を提供するときに追加のコンテキストを取得するための手法。これはパフォーマンスを向上させる効果的な方法となる可能性があります。


2 番目の障壁は、実用的なユースケースを見つけることです。デバイスがインターネット経由でより強力な LLM と通信できる一方で、これらは制限されていると思います。たとえば、OpenAI の GPT-4 は、1 兆を超えるパラメータをサポートすると噂されています。


ただし、これらのモデルをモバイル デバイスに展開するコストが、クラウドでホストするよりも安くなる時代が来る可能性があります。最近はコスト削減が大流行しているため、これが実行可能なユースケースであることがわかります。


また、自分の個人用 LLM を使用すると、デバイスの範囲外に情報が一切出ないため、プライバシー上の利点もあります。プライバシーを重視するアプリユーザーにとって魅力的な便利な特典です。


LLM がデバイスに定期的に展開されるまでには、まだ数年かかると思います。

役立つリソース

モバイル デバイスで Gemma を実際に試してみたい場合は、次のリソースが役に立ちます。


Gemma : Gemma の公式 Web サイトには、ベンチマーク、クイック スタート ガイド、責任ある生成 AI 開発に対する Google のアプローチに関する情報など、豊富な情報が含まれています。


MediaPipe : MediaPipe には独自のGoogle 開発者セクションがあり、MediaPipe の詳細と使用方法を学ぶことができます。読むことを強くお勧めします。


Google Developer Group Discord : Google Developer Group Discord には、Generative AI の専用チャネルがあります。 #gemma、#gemini、#ml チャンネルをチェックして、同じ考えを持つ人々とチャットしてください。


Simons Says App:このブログ投稿のサンプル コードをクローンして実行し、動作を確認します。 MediaPipe からの画像分類タスクの使用法も含まれます。セットアップ手順は README に記載されています。


脚注

IO スレッドからの LLM 推論の呼び出しについて言及するために 23/03/24 を更新しました。


  1. この記事を書いた後で、gemma の呼び出しはファイルの読み取り/書き込み操作であることに気づきました。 .generateResponse()メソッドを IO スレッドに移動すると、gemma がメモリにロードされるときの巨大なジャンクが回避されます。

     suspend fun sendMessage(): String { return withContext(Dispatchers.IO) { val prompt = prompts.random() llmInference.generateResponse(prompt) } }


ここにも登場します。