🤖

Chromeの組み込みGemini Nanoで、完全オフラインで使える翻訳サイトを作った

2024/06/24に公開

はじめに

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)

作ったサイト

https://builtin-ai-translator.yamitzky.dev/

スクリーンショット

左側に文章を入れて、セレクトボックスで言語指定をすると、自動で翻訳されます。動画内でも分かる通り、オフラインで動作させています。

なお、翻訳精度はあまり高いとはいえず、実用性はありません

事前準備

  • 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」が表示されていないです。

コード

https://github.com/yamitzky/builtin-ai-translator

ソースコードは公開しています。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