AndroidのローカルAIで読書ブログ投稿アプリを作ることにした
そんな用途だけに特化したAndroidアプリを作ることにした。
最初はChatGPTアプリを利用した比較的単純な構成を考えていたのだが、AndroidのIntent、Gemini Nano、Google AI Edge Gallery、Gemmaを調べているうちに、アプリの設計そのものがかなり変わっていった。
そもそも、欲しかったのは「本の感想投稿専用アプリ」
きっかけは単純だった。
本を読んだあとBloggerに感想を書こうとすると、本の写真を用意して、文章を書いて、Amazonアソシエイトのリンクを作って、Bloggerへ投稿する必要がある。
一つ一つは難しくない。ただ、毎回同じ作業を繰り返すのが面倒だった。
それなら、一般的なブログエディタではなく、本の感想を投稿することだけに特化したAndroidアプリを作ればいい。
毎回同じことしてるのよね。
汎用ブログアプリにする必要もない。
欲しいのは「ブログを書くアプリ」じゃなくて、本の感想を投稿するためだけのアプリ。
そのくらいに絞れそうだな。
最初はChatGPTアプリへ共有するつもりだった
文章生成にはChatGPTを使うつもりだった。
ただし、OpenAI APIをアプリに組み込むことは考えていなかった。
自分だけが使うアプリなので、Androidの共有機能でChatGPTアプリへ写真やメモを渡し、生成された記事をコピーして自作アプリへ戻せば十分だと思ったからだ。
多少の手作業は残るが、APIキーの管理も料金のことも考えなくていい。
本の写真と自分のメモを渡して、Blogger用の記事にしてもらう。
Intentの話から「他のアプリに丸投げできないか」と考え始めた
ここでAndroidのIntentの話になった。
自分がIntentに感じている一番のメリットは、「別のアプリを開ける」ということではない。
例えばQRコードリーダーのように、自分のアプリから処理対象を渡し、相手側で処理して、その結果だけを返してもらう。
つまり、難しい処理を全部自分で作るのではなく、その機能を持つアプリへ丸投げできるところに魅力を感じていた。
データ渡して、向こうに処理させて、結果だけ返してもらうの。
他のアプリを一つの処理部品みたいに使うって意味か。
自分でコードを書かなくていい部分は、丸投げできるなら丸投げしたい。
もしChatGPTが結果を返すIntentを持っていたら理想だった
ここで考えたのが、もしChatGPTアプリに「プロンプトを渡して、生成した文章を結果として返すIntent」があればどうなるか、ということだった。
これが可能なら、コピー&ペーストすら必要なくなる。
しかし、そこまでできるIntentが公開されてしまえば、かなりの部分でクラウドAPIの代替になってしまう。
実際には、通常の共有はできても、AI生成結果を外部アプリへ返すような公式Intentは公開されていなかった。
ところがAndroid自身がローカルAIを持っていた
ここで状況が大きく変わった。
最近のAndroidでは、AICoreを通じて端末内のGemini Nanoを利用できる。
ML Kit GenAI Prompt APIを使えば、自作アプリの中から直接AIへプロンプトを渡し、生成結果を受け取ることができる。
別のAIアプリへ画面遷移する必要もなければ、コピー&ペーストも必要ない。
でも利用者から見れば同じだな。
「AIで記事を作成」
↓
AIが処理
↓
結果が返る。
まずはJavaでGemini Nanoを実際に動かしてみた
ここまで話したところで、まず本当に動くのか確認することにした。
Android StudioでJava + XML Viewsのプロジェクトを作成し、ML Kit GenAI Prompt APIを組み込んだ。
実機はGoogle Pixel 10 Pro Fold。
画面にはプロンプト入力欄と「ローカルAIで生成」ボタン、生成結果の表示欄だけを置いた。
実際に動かしてみると、Gemini Nanoの利用状態確認から文章生成まで正常に動作した。
しかも普通に速い。
Google AI Edge Galleryを入れたら、さらに話が変わった
Gemini NanoがJavaの自作アプリから問題なく動いたので、この時点ではAICore + Gemini Nanoでそのまま開発を進めるつもりだった。
ところが、Google AI Edge Galleryも試してみたことで、また気になるものが出てきた。
AI Edge Galleryでは、Gemma 4などのローカルAIモデルを実際にAndroid端末上で動かして試すことができる。
そこでGemma 4を動かしてみたのだが、まず驚いたのが反応速度だった。
スマートフォンの中だけで動くAIなので、もっと「考えてから返ってくる」ようなものを想像していたが、実際にはかなり軽快に反応する。
Pixel 10 Pro Foldだから、Gemma 4を使う意味があった
ただし、Gemma 4へ興味が移った理由は「AI Edge Galleryで動かしたら速かった」というだけではない。
今回、開発用の実機として使っているのはGoogle Pixel 10 Pro Foldである。
Pixel 10 Pro FoldにはGoogle Tensor G5が搭載されており、AI処理を担当するTPUも備えている。
つまり、手元にあるスマートフォンには、そもそもローカルAIを高速に実行するための専用ハードウェアが載っている。
LiteRT-LMを利用すれば、Gemma 4のようなモデルをPixelのAI向けハードウェアで動かす構成も狙える。
↓
Google Tensor G5
↓
TPU
↓
LiteRT-LM
↓
Gemma 4
今回作るのは、不特定多数へ配布するアプリではなく、自分が使うための専用アプリである。
それなら、あらゆるAndroid端末へ合わせることを最優先にするより、手元にあるPixel 10 Pro Foldの能力を使い切る方向で作る方が面白い。
Gemma 4をLiteRT-LMから動かすなら、そのハードウェアを活かす構成も狙える。
じゃあ私、AI用の専用ハードウェア持ってるのに、そこをあまり意識せずアプリ作ろうとしてたの?
ただ、自分でモデルまで選んで使うなら、Pixelの性能を活かす方向も選べるってことだ。
せっかくPixel 10 Pro Fold持ってるんだし。
Gemini NanoからGemma 4へ方針を変えることにした
ここが今回の開発で、もう一度大きく方向が変わったところになる。
Gemini Nanoに問題があったわけではない。
実際にJavaから呼び出すことができ、生成速度も十分だった。モデルの管理もAndroid側に任せられるため、アプリを作る側からすると非常に扱いやすい。
それでもGemma 4を直接使う方向へ進みたくなった理由は、大きく3つある。
- Pixel 10 Pro FoldのTensor G5とTPUを活かせること
- 使用するAIモデルを自分で選択・管理できること
- 将来的に別のモデルへ交換できる構成にできること
特に一番大きかったのは、やはりPixel 10 Pro Foldを使っていることだった。
自分専用アプリなら、この端末を基準に設計しても問題ない。
そこで、本番版についてはGemini Nanoを使う構成から、LiteRT-LMを利用してGemma 4を直接動かす構成へ変更することにした。
だから「Gemini Nanoじゃダメだったから変更」ではない。
モデルを自分で選べて、端末側の性能も活かせる。
AI Edge Galleryを使うのではなく、同じAI基盤を自作アプリに組み込む
ここでも最初に少し勘違いしていた。
Google AI Edge GalleryへGemma 4をダウンロードしておけば、そのモデルへ自作アプリから処理を依頼できるのではないかと思っていた。
しかし、そういう仕組みではない。
AI Edge Galleryはあくまで別のAndroidアプリであり、外部アプリからプロンプトを渡して、生成結果を返してくれるようなIntentやAPIを提供しているわけではない。
自作アプリでGemma 4を利用するのであれば、モデルを自分のアプリ用に用意し、LiteRT-LMを使って直接読み込む。
ではなく
自作アプリ
↓
LiteRT-LM
↓
Gemma 4
↓
PixelのAI向けハードウェア
つまりAI Edge Galleryは、今回のアプリに必要なAI機能そのものではない。
「Android端末だけで、これだけ軽快にGemma 4を動かせる」ということを確認するためのきっかけになったアプリ、と考えた方が近い。
本番アプリでは、AI Edge Galleryを起動することも、Galleryとの間でデータを共有することもない。
アプリ内部からLiteRT-LMを呼び、Gemma 4へ直接プロンプトを渡し、生成結果をそのまま画面へ返す。
Galleryはあくまで別アプリだ。
それをLiteRT-LMから直接読み込む。
AI Edge Galleryを使うんじゃなくて、AI Edge Galleryみたいなことを自分のアプリの中でやるのね。
だから本番ではGalleryを開く必要もない。
利用者から見ればGemini NanoでもGemmaでも違いは分からない
内部構造はかなり違う。
Gemini Nanoの場合はAndroidのAICoreにモデル管理を任せる。
GemmaをLiteRT-LMで利用する場合は、数GBあるモデルファイルを自分のアプリ側でダウンロードし、保存して利用する。
しかし実際にアプリを使う人にとっては、そんな違いは関係ない。
どちらも「AIで記事を作成」ボタンを押せば文章が返ってくる。
表に見えるのは、
「AIで記事を作成」
↓
「生成中」
↓
「記事完成」
だけだ。
Gemmaを直接使うため、JavaからKotlinへ方針変更
ここで開発言語の話も変わった。
最初にJavaを選んだのは、単純にJavaの方が自分にとって読みやすかったからだ。
Kotlinはコードを短く書けるという印象はあったが、それだけなら無理に変える必要はないと思っていた。
しかしLiteRT-LMのAndroid向けAPIはKotlin中心で提供されている。
使いたい仕組みが明確になった以上、今回はKotlinを選ぶ理由ができた。
今回は使いたい機能に合わせて言語を選ぶだけだ。
本番版は新しいKotlinプロジェクトとして作り直す
そこで、現在のJavaプロジェクトはそのまま残し、新しくKotlinのAndroidプロジェクトを作成することにした。
まずやることは今のJava版と同じである。
Gemmaのモデルを端末に用意し、LiteRT-LMから読み込み、「AIで生成」ボタンを押すと文章が返るところまで確認する。
それが安定して動いたあとに、本来作りたかった読書ブログ専用画面を作っていく。
新規プロジェクトでKotlin版を作ろう。
Gemmaを呼んで、ボタン一つで文章を返すところまで。
最終的なアプリ構成も少しずつ見えてきた
最終的なアプリには、今のところ4つの基本メニューを用意する予定である。
- ダッシュボード
- Book投稿
- 過去投稿
- 設定
ダッシュボードには投稿件数、最新投稿日、最新記事タイトルなどを表示する。
Book投稿では本の写真、書名、自分のメモを入力し、端末内AIに記事を生成させる。
過去投稿ではこれまでの記事や下書きを確認できるようにする。
設定画面ではBlogger、Amazonアソシエイト、ローカルAIモデルなどの状態を確認する。
また、AIモデルが存在しない、あるいはAIが正常に動作していない場合でも、アプリそのものは起動できるようにする予定だ。
AIが使えないだけで、過去投稿まで見られなくなるのはおかしい。
問題があるなら、その機能だけ止める。
その設計でいい。
最初の構想とはかなり違うアプリになりそうだ
最初は、ChatGPTへ本の写真とメモを共有し、作ってもらった文章をコピーしてBloggerへ投稿するだけのアプリを考えていた。
それが調べていくうちに、
ChatGPT共有型からGemini Nanoを使ったオンデバイスAI型へ変わり、さらにGemmaをLiteRT-LMから直接利用する構成へと変化した。
まだ本番アプリの開発は始まったばかりだが、この試行錯誤自体も面白い。
次回は、新しいKotlinプロジェクトを作成し、Gemmaを自作Androidアプリから直接動かすところから始める予定である。
この記事の構成、文章、会話部分の生成にはOpenAIのChatGPTを使用しています。
アプリ開発についてもChatGPTと相談しながら仕様を整理しています。
一方、今回開発しているAndroidアプリのAI機能については、クラウド上のChatGPT APIを組み込むのではなく、Gemini NanoやGemmaなど、Android端末上で動作するローカルAIを利用する方向で開発を進めています。

0 件のコメント:
コメントを投稿