中級 12 分毎日の計画

WebLLM:AI モデルを navigateur

WebLLM:ブラウザで動くAIモデル

WebLLMは、WebGPUを利用して、マシンのGPU上でブラウザーのタブ内でLLMを実行するJavaScriptライブラリです。システム側へのインストールは不要ですが、確認すべき条件が三つあります。ブラウザーの互換性、モデルのダウンロード、そしてページの実際の挙動です。GPU上で計算が実行されていても、ページがオフラインで動作することも、メッセージが手元にとどまることも証明されません。このガイドではその確認方法を説明します。ベンチマークは含まれていません。

著者 Mohamed Meguedmi·更新 2026-11-09·Windows・macOS・Linuxでテスト済み
!
このガイドの限界
執筆日の2026年11月9日時点で、WebLLMのリポジトリとドキュメントは再確認できておらず、このガイドのコードはQuelLLMでは一切実行していません。WebLLMのコード例は、私たちが把握している範囲のAPIを示したもので、バージョンは保証されません。相違がある場合はリポジトリのREADMEが優先されます。WebGPU、ストレージ、セキュリティポリシーに関する情報は、2026年11月9日に再確認したMDNに基づいています。

#WebLLM:このライブラリが行うこと

Ollamaでは、マシンにインストールされたプログラムがモデルを読み込み、http://localhost:11434で応答します。WebLLMでは、すべてがWebページを通じて行われます。ページがエンジンのJavaScriptとWebAssemblyのコードを読み込み、モデルの重みを取得し、WebGPUを介してGPUに計算を送ります。起動するサービスも、開放するポートもありません。

開発者側から見ると、APIはOpenAIのAPIと同じ形式に従っています。エンジンを作成し、メッセージのリストを渡してengine.chat.completions.createを呼び出します。そのため、この形式向けに書かれたアプリケーションは比較的すぐに対応できます。ただし、エンジンはページ内で動作します。Open WebUI、コードエディター、Pythonスクリプトから接続できるHTTPサーバーではありません。

WebGPU
計算のためにGPUへのアクセスを提供するブラウザAPIです。これがない場合、または利用可能なアダプターがない場合、エンジンはGPU上で動作できません。
WebAssembly
エンジンの一部が提供される形式です。JavaScriptと同様に、ページが読み込む必要のあるものに含まれます。
モデルの重み
ページのコードとは別の大容量ファイルです。設定で指定されたアドレスからダウンロードされ、その後ブラウザーにキャッシュされます。
MLC形式
WebLLM は自身のエンジン向けにコンパイルされたモデルを使用します。これらは識別子の MLC という接尾辞で見分けられます。Ollama や LM Studio 用にダウンロードした GGUF ファイルは、そのままでは読み込めません。

#WebLLMかOllamaか:用途別にどちらのツールを選ぶか

自分だけのAIアシスタントを作るためのキット一式。

私たちの経験とガイド付きルートを活かして、ローカルアシスタントを作り、AIを毎日の作業に取り入れましょう。

  • 永久に利用できるオンラインスペース
  • PDF + ファイル
  • 30日間返金対応

WebLLMは従来のローカルインストールの代わりにはなりません。その価値は別のところにあります。何もインストールしない人々に向けて、Webページ内でAI機能を提供できることです。

WebLLM が適している用途
公開デモ、社内Webツール、アプリケーションに組み込まれたアシスタント、何もインストールできない端末での手早い試用。
Ollama または LM Studio が適している用途:
日常的な利用、豊富なカタログからの選択、より大きなモデル、他のツールから再利用できるAPI、タブの制約に左右されない動作。
受け入れるべきコスト
カタログはMLC形式でコンパイルされたモデルに依存し、利用可能なメモリーはブラウザーの制限にも左右されます。また、キャッシュは予告なく消去されることがあります。

速度の比較は掲載していません。本ガイドには、手順とハードウェアが文書化された計測による裏付けがないためです。プロジェクトにとって重要であれば、対象マシンで、同じモデルと同じ量子化を使って計測し、ブラウザとドライバーのバージョンを記録してください。

#前提条件とWebGPUの互換性

2026年9月2日更新のページでも、MDNはWebGPUをまだ限定的な対応、つまりBaselineではないと分類していました。このAPIは広く使われている一部のブラウザでは動作しません。サポート状況は、ブラウザ、OS、グラフィックドライバーの組み合わせによって決まります。そのため、同じブラウザでもあるシステムではWebGPUが使え、別のシステムでは使えないことがあります。すぐに古くなるバージョン一覧に頼るのではなく、MDNの互換性表を参照したうえで、対象となる各マシンでテストしてください。

セキュアコンテキスト
MDNによると、このAPIはすべて安全なコンテキストでのみ利用できます。ページはHTTPSで配信するか、開発中はlocalhostで配信してください。ローカルネットワークのアドレスでHTTPで開いたページでは動作しません。
ブラウザーとドライバー
両方とも最新の状態にしてください。ドライバーやブラウザーがアクセスをブロックしている場合、新しいGPUだけでは不十分です。
GPU メモリ
通常の構成におけるQ4でのQuelLLMの目安:3Bで約2 GB、7Bで約5 GB。これはおおよその規模感であり、WebLLMでの計測値ではありません。
ディスク容量と接続
モデルを保存し、少なくとも一度ダウンロードできるだけの容量と接続が必要です。実際のサイズは読み込みの進捗表示で確認してください。

このテストは、HTTPSまたはlocalhostのページで、開発者ツールのコンソールに貼り付けて実行します。標準APIのみを使用し、モデルは一切読み込みません。MDNによると、適切なアダプターが利用できない場合、requestAdapterはnullを返します。したがって、navigator.gpuが存在するだけでは判断できません。

ブラウザのコンソール:WebGPU をテストする
if (!navigator.gpu) {
  console.log('WebGPU absent : navigateur non compatible, API désactivée ou contexte non sécurisé');
} else {
  const adapter = await navigator.gpu.requestAdapter();
  if (!adapter) {
    console.log('API présente, mais aucun adaptateur disponible');
  } else {
    console.log('shader-f16 :', adapter.features.has('shader-f16'));
    console.log('maxBufferSize :', adapter.limits.maxBufferSize);
    console.log('maxStorageBufferBindingSize :', adapter.limits.maxStorageBufferBindingSize);
  }
}

shader-f16の行は、バリアントを選ぶ際の手がかりになります。WebLLMの識別子では一般に、この機能を必要とするq4f16モデルと、必要としないq4f32モデルが区別されています。二つのバッファ上限は、ブラウザーがどこまでの割り当てを受け入れるかを示します。グラフィックカードに十分なメモリーがあっても、これらの上限によって大きなモデルが読み込めないことがあります。

#ダウンロードが意味すること

初回の読み込み時に、ページは設定に記載されたアドレスからモデルのファイルと関連するコンパイル済みコードを取得します。私たちの知る限り、WebLLMの事前構築済みリストでは、これらのアドレスはHugging FaceやGitHubなどの外部リポジトリを指しています。ネットワークタブで確認してください。その場合、まだメッセージを一つも送信していなくても、これらのホスティング事業者にはあなたのIPアドレスと要求されたモデルが見えます。

ファイルはその後、ページのオリジンに紐づいたブラウザのストレージに保存されます。MDNは知っておくべきルールを説明しています。デフォルトでは、このストレージはベストエフォートモードであり、ブラウザはディスク容量が逼迫するとユーザーに通知することなくデータを削除でき、最も長く使われていないオリジンから順に削除されます。削除されたオリジンは、すべてのデータを一度に失います。また、Safariではクロスサイトトラッキング防止が有効な場合、ブラウザの使用日数で七日間インタラクションのなかったオリジンについて、スクリプトが作成したデータを削除することがあります。

ページのコンソール:クォータと永続ストレージ
const { usage, quota } = await navigator.storage.estimate();
console.log('Utilisé :', usage, 'octets sur un quota estimé de', quota);

const persistant = await navigator.storage.persist();
console.log('Stockage persistant accordé :', persistant);
→
永続化を要求しても何も保証されない
Firefoxはユーザーに確認を表示します。Chrome、Edge、Safariはサイトとのインタラクション履歴に基づいて独自に判断します(MDN、2026年1月5日更新のページ)。persistがfalseを返した場合は、モデルが再ダウンロードされる可能性を想定しておいてください。

#ページにWebLLMを導入する手順

この手順は、Vite などのビルドツールを使用する JavaScript プロジェクトを前提としています。CDN からインポートするのではなくプロジェクトにパッケージをインストールすることで、ページ読み込み時にサードパーティのドメインが増えるのを避けられ、オフラインでの動作も容易になります。

ターミナル(プロジェクト内で実行)
npm install @mlc-ai/web-llm
  1. 01
    バージョンを固定する
    package-lock.jsonでインストールされたバージョンを記録し、対応するREADMEを読んでください。その際、パッケージのライセンスとモデルのライセンスも確認してください。この二つは別物です。
  2. 02
    提供されているモデルを一覧表示する
    記事から識別子を書き写さないでください。リストは変化します。インストール済みのバージョンで、以下の最初のコード例を使ってリストを読み取ってください。そこに示されるメモリの項目は目安であり、保証ではありません。
  3. 03
    小さく始める
    まずは用途を満たす最小のモデルを選んでください。前のテストでshader-f16が利用できないと判明した場合はq4f32を選びます。最初の試行が成功すれば、コードの問題とメモリの問題を切り分けられます。
  4. 04
    進捗を表示する
    ダウンロードには時間がかかることがあります。視覚的なフィードバックがないとページが固まったように見えるため、initProgressCallbackが提供する進捗テキストを表示してください。
  5. 05
    Web Workerに移す
    読み込みと生成をメインスレッドで実行すると、UIの動作を妨げることがあります。そのためにWebLLMはCreateWebWorkerMLCEngineを提供しており、ワーカー側ではWebWorkerMLCEngineHandlerを使用します。公開前に組み込んでおいてください。
  6. 06
    対象マシンでテストする
    開発用ワークステーションでの結果は、内蔵GPUのノートPCでの動作について何も示しません。WebGPUが利用できない場合は、空白のページではなく、わかりやすいメッセージを表示するようにしてください。
インストール済みバージョンのモデルを一覧表示する
import { prebuiltAppConfig } from '@mlc-ai/web-llm';

console.table(prebuiltAppConfig.model_list.map((m) => ({
  id: m.model_id,
  vramMo: m.vram_required_MB,
})));
モデルを読み込み、応答をストリーミングで読み取る
import { CreateMLCEngine } from '@mlc-ai/web-llm';

// Remplacez par un identifiant relevé dans la liste ci-dessus
const modelId = 'IDENTIFIANT_DU_MODELE';

const engine = await CreateMLCEngine(modelId, {
  initProgressCallback: (p) => console.log(p.text),
});

const stream = await engine.chat.completions.create({
  messages: [{ role: 'user', content: 'Explique WebGPU en deux phrases.' }],
  stream: true,
});

let reponse = '';
for await (const chunk of stream) {
  reponse += chunk.choices[0]?.delta?.content || '';
}
console.log(reponse);

#WebLLMページの確認:ネットワーク、スクリプト、オフライン

WebLLMが保証できるのは、せいぜい計算がどこで実行されるかまでです。それ以外は組み込み先のページ次第です。アクセス解析スクリプト、ウィジェット、送信機能などは入力欄の内容を読み取って送信できます。ページに読み込まれたスクリプトはすべてページにアクセスできるためです。この確認は、ブラウザ内AIをうたうあらゆるサイトに当てはまり、あなた自身のサイトも例外ではありません。

  1. 01
    クリーンなプロファイルを用意する
    拡張機能のないブラウザープロファイルを開いてください。ページ上で許可された拡張機能は表示内容を読み取ることができ、結果を歪めます。ネットワークタブを開き、ログの保持を有効にします。
  2. 02
    読み込みを記録する
    ページを読み込み、通信先の各ドメインとその役割(ページ、エンジン、モデル、フォント、アクセス解析、広告)を記録してください。役割が明確でないドメインは、すべて説明が必要なものとして扱います。
  3. 03
    メッセージ送信時の通信を記録する
    モデルの読み込みが完了したら、ログをクリアしてください。たとえば TEST-MARQUEUR-7Q2X のような架空のマーカーを含むメッセージを送信し、[ネットワーク]タブの検索機能でログ内を検索します。また、生成中に送信された各リクエストも、WebSocket メッセージを含めてすべて確認してください。
  4. 04
    スクリプトとセキュリティヘッダーを調べる
    [ソース]タブで、スクリプトの配信元ドメインを一覧にしてください。ドキュメントのレスポンスヘッダーでContent-Security-Policyを探します。厳格なconnect-srcディレクティブは通信先を制限しますが、それがないからといって何かが証明されるわけではありません。
  5. 05
    ディスクに残っているものを確認する
    「アプリケーション」または「ストレージ」タブで、IndexedDB、Cache、ローカルストレージを開きます。通常はモデルがそこに保存されていますが、会話も保存されている場合があり、そのセッションを使う人なら誰でも平文で読めます。
  6. 06
    ネットワークを確実に切断する
    ページを閉じ、Wi-Fiを無効にするかケーブルを抜いてから、アドレスを開き直して新しいメッセージを送信します。ページが読み込まれ、応答が返ってくる必要があります。ブラウザーを閉じた後にも同じ手順を繰り返してください。
!
モデルがキャッシュされていても、ページがオフラインで動くわけではない
ページのHTML、JavaScript、WebAssemblyも(通常はService Workerによって)保存されていなければ、モデル全体がディスク上にあっても、ネットワークなしではそのアドレスを開けなくなります。したがって、すでに開いているエンジンが切断後も応答し続けても、オフラインで動作する証明にはなりません。判断材料になるのは再読み込みのテストだけです。

これらの確認には限界があります。マーカーが見つからなくても、スクリプトによって暗号化またはエンコードされた送信がないとは言い切れません。WebRTC接続はネットワークタブに通常のリクエストとして表示されません。Chromeではchrome://webrtc-internalsで確認できます。最後に、サイトの運営者はいつでもスクリプトを変更できるため、結果はテストしたバージョンにしか当てはまりません。

「オフラインで動作する」と言えます
テストしたブラウザで、テスト当日に、ネットワークを切断した状態でページの再表示と新しいメッセージの送信が成功した場合です。キャッシュが削除される可能性があることも明記してください。
「送信は観察されなかった」と言える条件
テストしたバージョンで、記載した手順に従った結果、ログにメッセージに関連するリクエストが一つも見られなかった場合です。これは日付付きの観察結果です。
「完全にプライベート」とは言えません
ただし、配信されるすべてのコードとその更新を管理し、サードパーティのスクリプトを一切使わず、さらにこの確認をコードの精読で補う場合は除きます。その場合でも、モデルのホスティング事業者にはダウンロードが見えますし、拡張機能のリスクも残ります。

#すべて自分のドメインから配信する

社内ツールの場合、最も管理しやすい構成は、ページ、エンジン、モデルを同一オリジンから配信し、サードパーティのスクリプトを一切使わないことです。WebLLMはカスタム設定を受け付け、その中で各モデルの重みのアドレスとコンパイル済みライブラリのアドレスを指定できます。以下のパスは例なので、環境に合わせて変更してください。

カスタム設定(例示用のアドレス)
import { CreateMLCEngine } from '@mlc-ai/web-llm';

const appConfig = {
  model_list: [{
    model: 'https://outil.example.fr/modeles/mon-modele/',
    model_id: 'mon-modele',
    model_lib: 'https://outil.example.fr/libs/mon-modele.wasm',
  }],
};

const engine = await CreateMLCEngine('mon-modele', { appConfig });

エンジンは、このプレフィックスをもとにファイルのアドレスを自動で組み立てます。Hugging Face と同様のディレクトリ構造を前提としている場合があります。リクエストが 404 で失敗する場合は、[ネットワーク]タブで実際に要求されたパスを確認し、サーバー上で同じ構成を再現してください。コンパイル済みライブラリはモデルに対応している必要があります。無作為に別のモデルと組み合わせないでください。

すべてを手元に移したら、セキュリティポリシーによって約束を技術的な制約に変えることができます。MDNによると、connect-srcは特にfetch、XMLHttpRequest、WebSocket、EventSource、sendBeaconを制限し、指定がない場合はdefault-srcにフォールバックします。次の例はWebLLMでテストしていません。まずContent-Security-Policy-Report-Onlyモードでデプロイし、コンソールを確認してください。

HTTPヘッダー(ページに合わせて変更してください)
Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self'; connect-src 'self'

このヘッダーはHugging Faceからのダウンロードもブロックします。これは意図どおりの動作であり、その場合モデルは自分のドメインから配信する必要があります。別のアドレスへのページ遷移など、考えられるすべての外部送信をカバーするわけではありません。オフライン対応には、ページのファイルをキャッシュするService Workerを追加してください。WebLLMはこの用途向けのエンジンCreateServiceWorkerMLCEngineも提供しています。詳しくはそのREADMEを参照してください。

#トラブルシューティング

navigator.gpu が undefined になる
まずアドレスを確認してください。HTTPS または localhost である必要があります。次に、お使いのブラウザとシステムについて MDN の互換性表を確認し、両方を更新してください。
requestAdapterがnullを返す
APIは存在しますが、適切なアダプターが利用できません。ドライバーを更新し、ブラウザのハードウェアアクセラレーションが有効になっていることを確認してください。原因を切り分けるため、別のブラウザも試してください。
shader-f16に関するエラー
選択したモデルが、お使いのアダプターにない機能を必要としています。q4f32 版があれば、そちらを選んでください。
QuotaExceededError
オリジンのクォータを超過しています。MDNによると、このエラーはIndexedDB、Cache、OPFSで発生します。空き容量を確保するか、より小さいモデルを選び、コード内でエラーを捕捉してください。
読み込みの終盤でのクラッシュまたはGPUの喪失
メモリ不足、またはバッファの上限に達した可能性があります。重いタブを閉じ、モデルのサイズを一段階小さくして、コンソールに表示される正確なメッセージを確認してください。
モデルが再ダウンロードされる
プライベートブラウジング、ストレージの退避(エビクション)、サイトデータの消去、またはオリジンの変更が原因です(ドメインごとにストレージが分かれているため)。私たちの知る限り、パッケージはhasModelInCacheを公開しており、読み込みを開始する前にこれを確認できます。
生成中にUIが固まる
エンジンがメインスレッドで動作しています。CreateWebWorkerMLCEngineに切り替えてください。
コンソールにセキュリティポリシーのエラーが表示される
メッセージには、ブロックされたディレクティブとアドレスが示されます。ルールを緩める前に、そのアドレスが正当なものか確認してください。外部への送信がないページだと公表している場合は特に重要です。

#さらに詳しく

ページに組み込まれた機能ではなく、自分自身で使うアシスタントを探している場合は、一般的なローカルインストールのほうが管理しやすいでしょう。無料ソリューションの比較が出発点として適しています。機密性の高い用途では、このガイドの確認に加えてプライバシーのチェックリストも実施してください。

このガイドは役に立ちましたか?

ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。