モバイル&ワイヤレスブロードバンドでインターネットへ

gwaw.jp
 
GWAW.JP / WEBGPU × AI / WEBLLM
検証編・後編 ブラウザ完結AIの現実

ブラウザでLLM
動くか

前編でベクトル検索をブラウザに載せました。後編では、その先—— LLMそのものをブラウザで動かします。WebLLMで小型モデルを 2つの実機(Android / iPad)で限界まで試し、「どこまでが現実的か」を実測で見極めます。

WebLLM MLC WebGPU Qwen2.5 / Qwen3 オンデバイス推論

01

前編の続き:検索の次はLLM

前編では、 RAGの「検索」部分をブラウザだけで動かせることを確認しました。 残るは「生成」——LLM本体です。これもブラウザで動くなら、 サーバー不要のAIアシスタントが完成します。

STEP 1
埋め込み生成
前編で確認済み
STEP 2
ベクトル検索
前編で確認済み
STEP 3
LLM生成
この記事で検証
🎯 この記事は「スパイク」
作り込んだ製品ではなく、実現可能性を確かめるための最小検証です。 問いはシンプル——「小型LLMはブラウザで動くのか、落ちるのか」。 最小モデルから順に、落ちるまで試します。落ちたら、それがその端末の上限だと分かります。
🧩 WebLLM とは
WebLLM は、LLMをブラウザ内でWebGPU実行するライブラリです。 MLC(Machine Learning Compilation)形式のモデルを使い、 Llama・Phi・Gemma・Qwen などをローカルで動かせます。
手持ちのGGUFは使えません——GGUFはllama.cpp専用で、 WebLLMはMLC独自形式です。モデルは実行時にHugging Faceから自動取得・キャッシュされます。
02

まず動かしてみる(ライブデモ)

以下は実際に動くデモです。あなたの端末で小型LLMをロードし、速度とメモリ限界を実測できます。 モデルはサイズ順に並んでおり、最小モデルから試すことを推奨します。

⚠️ 実行前に
初回はモデルのダウンロード(315MB〜)が発生し、数分かかります。 Wi-Fi環境を推奨します。端末のメモリによってはクラッシュしますが、それも検証結果です。
▶ WEBLLM LIVE DEMO 確認中...
WEBGPU
MAX BUFFER
DEVICE MEMORY
shader-f16
初期化中...
LOAD TIME
DL+展開
PREFILL
プロンプト処理
DECODE
生成速度=体感
STATUS
📊 測る3つの指標
LOAD TIME:初回DL+GPU展開(キャッシュ後は短縮)/ PREFILL:入力プロンプトの処理速度/ DECODE:応答生成の速度(tok/s)。これが体感速度で、 10 tok/s を下回ると「待たされている」と感じます。
03

2つの実機で限界まで試した

Pixel 10(Chrome)iPad mini A17 Pro(Safari)で、 5つのモデルを小さい順にロードし、生成まで試しました。 すべて q4f32_1(4bit量子化・fp32演算)を選択—— 前編でPixel 10のfp16埋め込みがNaNを返した教訓から、f16を避けました。

モデル サイズ iPad decode Pixel decode 品質・判定
Qwen3-0.6B 315MB 39.8 4.9 思考が漏れる(後述)
Qwen3.5-0.8B 420MB 22.6 3.0 内容やや不正確
Qwen2.5-1.5B 787MB 21.8 2.6 ★品質良好・最も安定
Qwen3-1.7B 892MB 20.8 17.5 多言語で崩壊(後述)
Qwen3.5-2B 1.1GB iPad: ロード成功→生成でクラッシュ ★メモリ上限超過
単位: tok/s(decode = 生成速度)。数値が大きいほど速い。

DECODE SPEED: iPad vs Pixel(同じモデル・同じ量子化)

04

発見①:同じモデルで速度が8倍違う

最も衝撃的だったのは、まったく同じモデルなのに、端末で生成速度が8倍違ったことです。

⚡ Qwen2.5-1.5B の decode 速度
iPad mini: 21.8 tok/s(サクサク読める)
Pixel 10: 2.6 tok/s(1文字ずつ待つ体感)
差は8.4倍。Pixelの2.6 tok/sは、実用に耐えるレベルではありません。

興味深いのは、両端末とも shader-f16 に対応し、Device Memory も Pixelは8GBあった点です。スペック上はPixelが不利ではないのに、この差が出ました。 WebGPU経由のLLM推論は、現状Apple GPUに強く最適化されていると考えられます。 同じ「ブラウザで動く」でも、Androidミドル機では体感が伴わない—— これは前編のベクトル検索で見た「カーネルが端末で逆転する」現象と同じ根っこです。

🔍 MAX BUFFER の違いも記録された
Pixel は maxStorageBufferBindingSize128MB、 iPad は 1024MB でした(8倍差)。 前編のベクトル検索で「87,000文書の壁」を生んだあの制限です。 LLMのような大きな重みを扱う場面では、この上限差も効いてきます。
05

発見②:reasoningモデルは小型だと暴走する

モデルの品質はパラメータ数に比例しませんでした。 むしろ新しくて大きいはずの Qwen3 系が、小型量子化で壊れました

Qwen3-0.6B

思考が漏れる

回答の前に「Okay, the user asked about WebGPU. I need to...」と英語の思考過程がそのまま出力されました。

Qwen3-1.7B

多言語で完全崩壊

「墙体_Row… proceso truyền classes(COLOR…」と、中国語・スペイン語・タイ語などが混ざった無意味な出力に。

Qwen2.5-1.5B

最も安定・高品質

非reasoningモデル。WebGPUの説明を正確・自然な日本語で生成。両端末で最も信頼できました。

🧠 なぜ壊れるのか
Qwen3 は推論(reasoning)モデルで、<think>...</think> の 思考ブロックを生成してから答えます。しかし0.6B〜1.7Bに4bit量子化すると、 思考を制御しきれず暴走したり、思考タグがそのまま漏れたりします。
教訓は明確です——オンデバイスでは、素直な非reasoningモデル(Qwen2.5系)の方が実用的。 デモでは <think> を検出して思考過程を分離表示し、抑制も試みています。
06

発見③:ロード成功 ≠ 実用可能

検証の判定基準そのものが、途中で変わりました。当初は「ロードできたか」で見ていましたが、 それでは不十分だと分かったのです。

💥 Qwen3.5-2B(1.1GB)の挙動
iPad mini でロードは成功しました。バーは100%になり、"ロード成功" と表示。 ところが最初の質問を投げた瞬間にクラッシュ——タブが落ちました。
原因はKVキャッシュ。生成時には、モデル重みに加えて 文脈を保持するメモリが必要です。重みは載っても、生成で必要な追加メモリで溢れるのです。

そこでデモの判定を「生成まで成功して初めて実用可能」に改めました。 ロードのプログレスバーは、実用性の保証にはなりません。

生成まで到達して初めて「可」と判定
// ❌ ロード成功で判定してしまうと 2B が「可」になる(実際は生成で落ちる)
// ✅ 生成の try が最後まで通って初めて recordVerdict(true)
try {
  for await (const chunk of stream) { /* ...トークン受信... */ }
  recordVerdict(true);   // 生成完了 = 実用可能
} catch (e) {
  recordVerdict(false);  // 生成でクラッシュ = メモリ上限超過
}
07

見落とせない現実:ロードに数分かかる

速度と品質の裏で、初回ロード時間が実用性に重くのしかかります。

モデル(1.5B)iPadPixelDL容量
Qwen2.5-1.5B ロード 223秒 279秒 787MB
= 約 3分43秒 4分39秒 初回のみ
⏱️ 4分間の白画面は許されない
2回目以降はブラウザキャッシュから読むので速くなりますが、 初回訪問者は数分待つことになります。 一般的なWebサイトのAIアシスタントとしては、この初回コストは致命的です。 「サーバー不要」の代償が、そのままユーザー体験に跳ね返ります。
08

結論:動く。だが「完結」は選ばない

2つの実機で限界まで試した結論です。 ブラウザ完結LLMは、技術的には確かに動きます。 iPad mini なら1.5Bモデルが 21 tok/s・良好な品質で動作しました。これは事実として大きい。

しかし実用の壁は高いと分かりました。3つの現実が重なります。

壁 01

端末依存が激しい

同じモデルで速度が8倍違う。iPadで実用的でも、Androidミドル機では2.6 tok/sで使いものにならない。

壁 02

初回ロードが重い

1.5Bで4分前後・787MBのダウンロード。初回訪問者の離脱は避けられない。

壁 03

品質と安定性

安定して使えるのは1.5Bの非reasoningモデルまで。それ以上は品質崩壊かクラッシュ。

✅ だから「ハイブリッド」を選ぶ
検証の答えは出ました。検索はブラウザで、生成はサーバーで
前編で実証したブラウザのベクトル検索は軽量・高速・端末非依存。 一方生成は、VPS上の安定したLLM(llama.cpp + Qwen2.5-1.5B)に任せる。 ブラウザで暴走したreasoningも、サーバー側なら制御できます。
「すべてブラウザで」という理想は美しいですが、実測が示したのは分業の合理性でした。
📝 この2記事で確かめたこと
前編:ブラウザのベクトル検索は実用的(軽量・高速・GPUで加速)。
後編:ブラウザのLLM生成は動くが実用は苦しい(端末依存・重い・不安定)。
→ 次は、この2つの結論を統合したハイブリッドRAGの設計に進みます。
NEXT — 統合編
ハイブリッドRAGを本番投入する — ブラウザ検索 × VPS生成

『ブラウザでLLMは動くか — WebLLMを2つの実機で限界まで試す』を公開しました。