Chromeの組み込みGemini Nanoで、完全オフラインで使える翻訳サイトを作った
はじめに
Google Chrome 126 から、組み込みの生成AI機能(Gemini Nano)が使えるようになったので、翻訳のデモサイトを作ってみました。
有効化できる環境とできない環境があるみたいです。私の環境でも、Chrome Canary 127で使えていたものが、突然使えなくなったりしました。
2024年6月24日現在、私の環境では以下の環境で利用を確認しています。Chrome dev (128.0.6535.2) では利用できていません。
- mac OS Sonoma 14.1.1(23B81)
- Macbook Air M2 (2022)
- Chrome Canary 128.0.6553.0(Official Build)canary (arm64)
作ったサイト
左側に文章を入れて、セレクトボックスで言語指定をすると、自動で翻訳されます。動画内でも分かる通り、オフラインで動作させています。
なお、翻訳精度はあまり高いとはいえず、実用性はありません。
事前準備
- chrome://flags/#prompt-api-for-gemini-nano を開き「Enabled」にする
- chrome://flags/#optimization-guide-on-device-model を開き「Enabled BypassPerfRequirement」にする
- chrome://components/ を開き「Optimization Guide On Device Model」の「アップデートを確認」ボタンをクリックする (※時間がかかります)
Gemini Nanoが使えない場合、最後の「Optimization Guide On Device Model」が表示されていないです。
コード
ソースコードは公開しています。Vite、React、TypeScriptなどを使っています。
生成AI機能の利用
window.ai
または window.model
を使います。今のところ、どちらを使っても同じです。(window.ai === window.model
)
まず、ブラウザが生成AI機能に対応しているかを確認します。必須ではありませんが、突然非対応になったりするので、自分のためにも確認してエラーメッセージを出すことをおすすめします。
if (window.ai) {
const canCreate = await window.ai.canCreateTextSession();
if (canCreate === "no") {
console.error("AIが使えません");
}
} else {
console.error("AIが使えません");
}
window.ai.createTextSession を使い会話セッションを作成した後、prompt または promptStreaming で生成AIにプロンプトを投げることができます。冒頭の動画の例は、promptStreaming を使ってプロンプトの結果を徐々に取得しているものです。
const session = await window.ai.createTextSession()
const prompt = "英訳してください:光陰矢の如し"
const result = await session.prompt(prompt);
console.log(result);
// または
const stream = await session.promptStreaming(prompt);
for await (const chunk of stream) {
console.log(chunk);
}
TypeScriptの場合、型エラーが発生してしまうので、次のような型を定義し、 window.ai
が使えるようにしています。ブラウザで使うだけの場合(Javascriptの場合)には必要ありません。
interface Window {
ai:
| {
canCreateTextSession(): Promise<"no" | "readily">;
createTextSession(): Promise<AITextSession>;
}
| undefined;
}
interface AITextSession {
execute(text: string): Promise<string>;
executeStreaming(text: string): Promise<AsyncIterable<string>>;
prompt(text: string): Promise<string>;
promptStreaming(text: string): Promise<AsyncIterable<string>>;
destroy(): void;
}
PWA対応
オフラインに対応するために、PWAに対応しています。Viteの場合は、vite-plugin-pwaを使い、以下のような設定をするとPWA対応できます。
import react from "@vitejs/plugin-react";
import { defineConfig } from "vite";
import { VitePWA } from "vite-plugin-pwa";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
VitePWA({
registerType: "autoUpdate",
injectRegister: "auto",
workbox: {
globPatterns: ["**/*.{js,css,html}"],
},
manifest: {
name: "Built-in AI Translator",
short_name: "Built-in AI Translator",
description: "AI Translator using Gemini Nano",
theme_color: "#0E324E",
background_color: "#fff",
display: "standalone",
icons: [
{
src: "/icon-192x192.png",
sizes: "192x192",
type: "image/png",
},
{
src: "/icon-256x256.png",
sizes: "256x256",
type: "image/png",
},
{
src: "/icon-384x384.png",
sizes: "384x384",
type: "image/png",
},
{
src: "/icon-512x512.png",
sizes: "512x512",
type: "image/png",
},
],
},
}),
],
});
まとめ
新しく実験的に搭載された Chrome のローカル生成AIの機能と、PWA によるオフラインサポートに対応することによって、簡易的な完全オフライン翻訳ページを作ることができました。
あくまで実験的なAPIなので動かなくなることがあるかもしれません。また、今後は翻訳専用のAPIなども出る気配がありますので、正式搭載の際にはこちらを使ったほうが良さそうです。
Discussion