- Published on
llama.cppがブラウザに来た — WebGPUバックエンドが16台の実機で測った天井
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- はじめに — ブラウザLLMはデモを卒業したか
- LlamaWeb — llama.cppにWebGPUバックエンドが付くということ
- 本当の制約はVRAMではなくタブだ
- 数字 — 既存のブラウザフレームワーク比
- 天井の名前 — subgroup matrix
- ネイティブとの距離 — 2.5倍から10倍
- 安全はタダではない — bounds checkの請求書
- ここでの量子化は速度技術ではない
- ブラウザ間のばらつき — Firefoxは丸ごと除外された
- 実務者向けまとめ — 機能検出とフォールバック
- で、あなたはブラウザでLLMを動かすべきか
- おわりに
- 参考資料
はじめに — ブラウザLLMはデモを卒業したか
ブラウザでLLMを動かすというアイデアは、もう何年もデモの領域にとどまっていました。WebLLMはタブの中でLlamaを動かして見せ、Transformers.jsはパイプラインAPIをウェブに移植し、そのたびに「サーバーコストゼロ、データは端末の外に出ない」というスローガンがついて回りました。スローガンは事実です。問題はその次の問い — 実際にどれだけ遅く、どれだけ食い、どこで壊れるのか — に答える公開データがほとんどなかったことです。ほとんどのベンチマークは著者のノートPC1台から出たもので、ブラウザGPU性能はハードウェアを超えて一般化しません。
だからこそ、2026年5月20日にarXivへ投稿されたLlamas on the Webが興味深いのです。UC Santa CruzのReese Levine、Tyler Sorensenらが書いたこの論文は、llama.cppのWebGPUバックエンド(論文ではLlamaWebと呼びます)を構築し、8ベンダーのGPU16基、モデル10種、重みフォーマット4種にわたって実測しました。著者らの表現では「単一の推論エンジンフレームワーク内で収集された最大のクロスデバイス・クロスモデル評価データセット」であり、モバイル機器を含む唯一のWebGPUデータセットです。
本稿は、そのデータが語る2026年のブラウザ推論の現実を整理します。結論を先に言えば — 良くなってはいますが、天井がどこにあるかがはっきり見えています。そして、その天井には名前があります。
LlamaWeb — llama.cppにWebGPUバックエンドが付くということ
まず地形を整理しておきましょう。WebGPUは、ブラウザが複数のネイティブAPIの上に載せる抽象化です — macOS/iOSではMetal、LinuxとAndroidではVulkan、WindowsではDirectX。そしてブラウザごとに実装が異なります。Chromium系はDawn、Firefoxはwgpu、SafariはWebKit自前の実装を使います。ここで重要な事実が一つ — DawnはC++で書かれているため、ブラウザの外のネイティブコードからも使えます。この事実が、後で決定的な意味を持ちます。
既存のブラウザ推論フレームワークは、それぞれ違うエンジンに乗っていました。Transformers.jsはONNX Runtime、WebLLMはMLC-LLM。一方LlamaWebは、llama.cpp本体にWebGPUバックエンドを付ける道を選びました。これが重要なのは、llama.cppの資産 — 特にGGUF量子化フォーマットのエコシステム全体 — をそのまま受け継ぐからです。
この作業の中核となるピースの一つは、すでにllama.cpp本体にマージされています。PR #17031(「ggml webgpu: faster matrix multiplication/matrix-vector multiplication」、reeselevine、2025年11月8日マージ)が、行列積カーネルを2種類追加しました。PRの説明をそのまま訳すとこうです — 一つはレジスタタイリング、もう一つは「subgroup matrices」(テンソルコアないし最適化されたsubgroupルーチンへのアクセスを与えるWebGPU機能)を使う実装で、「現在subgroup matricesは実験的であり、サポートされていない機器ではレジスタタイリング方式にフォールバックする」とのことです。
このフォールバックの一文を覚えておいてください。この記事の残り全部が、あの一文についての話です。
本当の制約はVRAMではなくタブだ
ブラウザ推論を初めて扱う人が、最もよく間違えるのがここです。制約はGPUメモリではなく、タブプロセスです。
論文が指摘する既存フレームワークの第一の問題は、メモリの非効率です。LlamaWebは起動時にメモリを静的に確保し、プロンプト長や生成長にかかわらずメモリ使用量が予測可能になるようにしています。複数のカーネルが必要とする中間ストレージまで、モデルが最初に動く前にあらかじめ確保しておきます。
もっと面白いのはモデルのロード側です。著者らは、wllama(元々llama.cppをWASMでCPU専用に動かしていたライブラリ)にWebGPUサポートを載せる過程で、ロード経路を書き直しました。重みをOPFS(Origin Private File System)に保存しておき、WebAssemblyヒープには一切実体化しません。理由は論文の脚注にあり、読むと納得できます。
WASMヒープはgrow-onlyであるため、一度タブが確保したメモリは、そのタブが生きている間は解放できない。
つまり、ロード中に一瞬2GBに触れて手放しても、その2GBはタブが閉じるまで戻ってきません。そこでLlamaWebは、llama.cppの非同期ロードインターフェースを使い、1MBのバッファ4個だけでOPFSからWebGPUバッファへ重みをストリーミングします。論文は「特にSafariはメモリ使用量の上限が厳しく、この変更のおかげでより大きく強力なモデルを提供できるようになった」と述べています。
結果の数字はこうです。ChromeとSafari、複数の機器の組み合わせで測ったピークメモリで、既存のブラウザ推論フレームワーク比で平均29〜33%減少。f16のLlama3.2 1Bを基準にした4つのテスト構成の正規化ピークメモリの幾何平均では、WebLLMより49%、Transformers.jsより41%低くなりました。構成ごとに見ると差はかなり大きく — Apple M4 ProのChromeではWebLLM比13%、Transformers.js比16%の改善にとどまりましたが、同じ機器のSafariでは28%と59%まで広がります。
ただし、この大きな差の一部はLlamaWebがよくできているからではなく、相手が漏れているだけです。論文は、SafariでTransformers.jsのメモリが10GBまで上がってタブが落ちたと明言しており、これはメモリリークに見えると述べています。RTX 5080のWindows構成では、WebLLMが同じように10GB近くまで上がりました。ベンチマークを読むとき、こういう一文を消してはいけません — 「61%少なく使う」のかなりの部分は、相手のバグです。
数字 — 既存のブラウザフレームワーク比
性能比較は、NVIDIA RTX 5080、Apple M4 Pro、AMD RX 7900 XT、Intel Arc B580の4つのGPUで行われました。ベンダーが全部違うというのが肝です。
デコード(トークン生成)スループットでは、LlamaWebはWebLLMより約54%、Transformers.jsより69%高い結果でした。論文のアブストラクトの表現では「4つのGPUにわたりデコードスループットが45〜69%向上」です。
ところが、prefill(プロンプト処理)は逆です。
しかしprefill性能は遅れており、LlamaWebはWebLLMのスループットの49%、Transformers.jsのスループットの79%にとどまる。
半分にも届きません。論文はその原因を二つ挙げています。第一に、WebLLMはTVMの精巧なカーネル融合(kernel fusion)を使い、小さな演算のたびにモデルの重みを繰り返し読み込むコストを削減しています。第二に、Transformers.jsは行列積をsubgroupで最適化した実装を持っています。
ここでブラウザLLMの性格が現れます。デコードはメモリ帯域幅に律速される行列-ベクトル積が支配的で、prefillは演算量に律速される行列-行列積が支配的です。LlamaWebは前者をうまく作り込みましたが、後者ではまだ道具がありません。何の道具かというと —
天井の名前 — subgroup matrix
WebGPUにおけるsubgroupは、ワークグループ内のスレッドがSIMT方式で互いに値をやり取りできるようにする機能です。これはすでに実装済みです — Chrome 134でデスクトップとAndroidの両方でデフォルト有効になっており(Chrome Platform Status)、その後も少しずつ機能が追加されています。subgroup_idはChrome 144、subgroup_uniformityはChrome 145、Subgroup Size ControlはChrome 152で予定されています。(本日時点のstableはChrome 151で、152のstable予定日は2026年8月25日です。)
ところがsubgroup matrixは違います。これはGPUの固定サイズ行列積ユニット — NVIDIA的に言えばテンソルコア — を直接開く機能で、LLMのprefillはまさにそのユニットを欲しがっています。論文のカーネルライブラリには、それを使うsg_matカーネルがすでに入っています。問題はこの一文です。
subgroup matrix機能は、まだstableなブラウザリリースでは使えないが、一部のWebGPU実装ではネイティブに利用できる。
確認してみても、確かにその通りです。Chrome Platform Statusにおけるsubgroup関連の項目は、Subgroups(134、デフォルト有効)、subgroup_id(144)、subgroup_uniformity(145)、Subgroup Size Control(152予定)のみで、subgroup matrixという項目自体が存在しません。Googleが標準化グループにcooperative matrix提案を持ち込むと表明した段階であり、subgroupsのときと同様、議論の相当部分はポータビリティ(移植性)に関するものになると見込まれています。
そこで著者らは迂回路を使います。DawnがC++ライブラリであるという先の事実を思い出してください — 同じバックエンドコードをDawnでネイティブ実行すれば、subgroup matrixを有効にできます。そう測ると、絵は反転します。
実際、LlamaWebをネイティブ実行したprefill数値を使うと、LlamaWebはApple M4ProのWebLLMを除くすべての機器で他フレームワークのprefill数値を上回り、WebLLM比88%、Transformers.js比205%の幾何平均速度向上を示す。
同じコード、同じ機器、違う実行環境。ブラウザの中ではWebLLMの49%、ブラウザの外ではWebLLMの188%。今のブラウザLLMのprefillの天井は、アルゴリズムでもカーネルの品質でもなく、標準化されていないハードウェア機能一つです。
論文の結論も、まさにそのトーンです — 著者らは「subgroup matrixはまだブラウザにないが、一般提供に届けば、LlamaWebは競争力のあるprefill性能を提供できる良い位置にある」と書いています。「ある」ではなく「届けば」です。この条件節を読み飛ばしてはいけません。
ネイティブとの距離 — 2.5倍から10倍
では、ブラウザを離れてネイティブバックエンドと比べるとどうでしょうか。論文はllama.cppのllama-benchで、同じ機器上でネイティブバックエンドを動かして比較しています。
Fig. 5(a)に見られるように、CUDAとVulkanバックエンドは、両方の重みフォーマットで依然としてWebGPUをprefillで最大10倍、デコードで2.5倍上回る。これはテンソルコアのより優れた活用と、非同期メモリロードのようなベンダー固有の高度な機能へのアクセスによるものと見られる。
Apple側も似ています — 「Metalバックエンドは常にWebGPUバックエンドを上回り、prefillで2倍以上、デコードで50%」上回ります。
この差は、先ほど見たPR #17031のベンチマークにもそのまま表れています。PR作者が自分のM3で測った予備的な数値です(つまりベンダー報告ではなく、著者一人の機器一台であり、llama-benchはllama.cppのネイティブCLIベンチマークツールです)。
Llama-3.2-1B-Instruct, Apple M3, llama-bench (PR #17031 作者測定、予備数値)
pp512 (t/s) tg128 (t/s)
F16 WebGPU 1014.17 ± 9.38 28.71 ± 0.19
F16 Metal 1368.47 ± 0.95 35.99 ± 0.78
Q4_0 WebGPU 960.52 ± 6.05 41.76 ± 0.62
Q4_0 Metal 1346.68 ± 1.21 103.92 ± 0.37
Q4_0のデコードを見てください — 41.76対103.92。2.5倍です。先ほどの論文の数値と、まったく同じ桁の差が独立に再現されています。
しかし、方向は一方向だけではありません。これが論文でもっとも驚きの部分ですが、WebGPUがベンダー専用バックエンドに勝つケースが実際にあります。
- AppleにおけるVulkan比: MoltenVKを経由するVulkanバックエンドに対して、WebGPUはprefillで最大59%、デコードで45%速いです。
- AMDでは: ネイティブHIPバックエンドは常にWebGPUを上回りますが、VulkanバックエンドはprefillでWebGPUに3倍遅れます。
- Intelでは: 安全チェックを切ったWebGPUバックエンドがf16モデルのprefillで最速となり、SYCLバックエンドを23%上回り、同じモデルのデコードでもネイティブSYCLを10%上回ります。
論文はこれを、クロスデバイスチューニングの効果と解釈しています — LinuxではWebGPUの下位ランタイムがまさにVulkanであるにもかかわらず、LlamaWebのチューニングされた行列積パラメータがVulkan専用バックエンドに勝つ機器があるということです。「ネイティブは常に速い」という直感は誤りです。正確には、うまくチューニングされた移植可能な実装は、チューニングされていないネイティブ実装に勝つのです。
安全はタダではない — bounds checkの請求書
ブラウザでは、WebGPUコンパイラがシェーダーに安全チェックを挿入します。バッファの範囲外アクセスとゼロ除算を防ぐためです。これは交渉の余地がありません — 任意のウェブページがあなたのGPUにシェーダーを投げつけるというモデルから、これを外すことはできません。
その値がいくらなのかを、論文が測っています。
安全チェックのオン・オフで性能を比較すると、prefillはq4_k_mモデルで平均14%、f16モデルで平均23%遅くなり、デコードではそれぞれ5%と1%遅くなる。このスローダウンは、NVIDIA RTX 5080のprefillで最大42%に達した。
つまり安全チェックは、prefillでは二桁を食い、デコードではほぼタダです。これも一貫した絵です — 演算集約的な行列積ループの中で、インデックスごとにチェックが付くからです。そして先ほどのIntelの事例で、WebGPUがSYCLに勝ったのは「安全チェックを切った」条件だったことを、もう一度見てください。ブラウザではその条件は使えません。
論文の今後の課題リストには、これがそのまま挙がっています — より良い静的解析で不要なbounds checkを除去すること、低精度実行でのモデル安定性を保証するために浮動小数点の差異を言語レベルでより堅牢に扱うこと、そしてu16のような新しいデータ型をWebGPUに追加し、より効率的なメモリロードとネイティブハードウェアアクセラレーションを可能にすること。
ここでの量子化は速度技術ではない
これは、ローカルLLMを扱ったことがある人ほど驚く部分です。
現状では、WebGPU上でのllama.cpp量子化は、与えられたモデルを実行するのに必要なメモリ要件を減らす技術であって、性能最適化ではない。
CPUやCUDAでq4を使う理由は、メモリもメモリですが、帯域幅を節約して速度を得るためでもあります。WebGPUでは、その等式が成立しません。論文はその理由を二つ挙げています。第一に、汎用の重みフォーマットの逆量子化(dequantization)ルーチンが複雑で演算負荷が重いことです — WebGPUがサポートしないnvfp4のようなハードウェアネイティブフォーマットとは違って。第二に、現在のレイアウトが、WebGPUが対象とする多様なGPUでの性能に最適化されていない可能性があることです。
先ほどのM3の表がこれを裏付けています — Q4_0のprefill(960)は、F16のprefill(1014)よりむしろ遅いのです。ファイルサイズは2.30GiBから729.75MiBへと3分の1に縮んだにもかかわらず、です。デコードでは41.76対28.71で量子化が勝ちますが(ここでは帯域幅が支配的なので)、prefillでは逆量子化のコストが利得を食いつぶします。
実務上の含意はシンプルです。ブラウザにおける量子化は、「動かなかったモデルを動くようにする」手段であって、「動いていたモデルを速くする」手段ではありません。そして前節で見た通り、ブラウザの本当の制約がタブメモリであることを考えれば、それだけでも十分に価値があります。
ブラウザ間のばらつき — Firefoxは丸ごと除外された
移植性について語る記事で、この段落を省くのは不誠実でしょう。
FirefoxはWebGPUをサポートしているものの、我々は著しく低い性能を観測した。たとえばApple M3上で、q4_k_m重みのllamaモデルは、Firefoxでは毎秒約1トークン、Chromeでは毎秒約52トークンで実行され、我々は評価からFirefoxの結果を除外する。
50倍です。論文はChromeとその下層のDawnが「多くのプラットフォームで一貫して最も高く最も安定したWebGPU性能を提供した」と記し、そのため特に断りがない限り、すべての実験はChromeで行われました。iOSでは他のブラウザエンジンが使えないため、Safariを使います。
「WebGPUは主要3ブラウザすべてでサポートされている」という文は事実ですが、プロダクションでその文に頼ると痛い目に遭います。機能サポート(feature support)と性能の同等性(performance parity)は別の軸であり、2026年7月現在、後者はまったく整っていません。
浮動小数点側にも地雷があります。論文の脚注を一つ見てください — 開発中、レジスタタイリングカーネルにf16累算(accumulation)を使うと、Qwen2.5のような一部モデルがApple M系GPUで支離滅裂な出力を出し、そのため現在はこのカーネルにf32累算を使っています。著者らの表現では「浮動小数点精度の違いはよく知られた問題であり、WebGPUとその応用の中でこれを扱うことは、解決済みの問題ではない」とのことです。クラッシュではなく静かな品質低下として現れるのが、このタイプのバグの厄介なところです。
実務者向けまとめ — 機能検出とフォールバック
コードレベルで、これがすべて意味することは一つです。機能を仮定せず、問い合わせてください。
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) throw new Error('WebGPU 어댑터 없음');
// subgroups は Chrome 134+ でデフォルト有効だが、
// アダプタが実際に対応を広告しているか確認し、明示的にリクエストする必要がある。
const wanted = ['subgroups', 'shader-f16'].filter((f) => adapter.features.has(f));
const device = await adapter.requestDevice({ requiredFeatures: wanted });
// subgroup matrix は2026年7月現在、どのstableブラウザにも存在しない。
// あるふりをしたコードを書かず、フォールバック経路をデフォルト経路として扱うこと。
const hasSubgroups = device.features.has('subgroups');
LlamaWebの設計はまさにこの形です — sg_matカーネルはあるものの、デフォルト経路ではなく、サポートされていない機器ではレジスタタイリングにフォールバックします。PR #17031の文をもう一度訳せば、「サポートされていない機器では、コードがレジスタタイリング方式にフォールバックする」ということです。ブラウザでは、今、そのフォールバックがすべての機器の経路です。
もう一つ。カーネルコンパイルは、モデルの最初のforward passの間に一回限りのコスト(約1〜5秒)を課し、その後はキャッシュされたパイプラインで実行されます。最初のトークンの遅延を設計するとき、この数秒を忘れてはいけません。
で、あなたはブラウザでLLMを動かすべきか
データを踏まえると、判断基準はかなり明確になります。
コストに見合う場合
- データが端末の外に出てはいけない。これがほぼ唯一の圧倒的な理由です — 2.5倍遅いことを甘受するに値する唯一の要件だからです。
- モデルが小さい。論文が実測したモデルは0.23GBから3.11GBの範囲です。
- デコードが支配的なワークロードである — 短いプロンプト、長い生成。ブラウザ推論が相対的にもっとも負けにくい領域です。
- デプロイがURL一つでなければならない。インストールも、ランタイムも、サーバーもない、というのは依然として本物の価値です。
まだそうではない場合
- prefillが支配的である — 長い文書をまるごと入れるRAGのようなパターン。ここがまさに最大10倍まで差が開く領域であり、それを直す機能はまだ標準に入っていません。
- Firefoxをサポートしなければならない。50倍は性能の問題ではなく、機能の問題です。
- 精度に敏感である。f16累算が静かに出力を壊す事例が、すでに論文にあります。
- サーバーGPUが使え、プライバシー制約がない。それならサーバーで動かせばいいのです。ブラウザ推論はコスト削減技術ではなく、プライバシー・デプロイ技術です。
最後の項目が一番重要です。「サーバーコストゼロ」は事実ですが、その代償としてあなたはユーザーのバッテリーと、2.5〜10倍の性能差と、8ベンダー分のハードウェアばらつきを引き受けることになります。それは節約ではなく、移転(transfer)です。
おわりに
2026年のブラウザLLM推論の状態を一段落でまとめると、こうなります。エンジニアリングは成熟しました — 静的メモリ計画とOPFSストリーミングでメモリを29〜33%削減し、チューニングされた移植可能なカーネルは、一部の機器ではベンダー専用のネイティブバックエンドに勝ちます。ところがprefillでは依然としてネイティブに最大10倍負けており、その理由の大部分は、テンソルコアを開く標準機能がないことです。同じコードをブラウザの外でその機能とともに動かすと順位が逆転する、というのがその証拠です。
だから、この話の教訓は「ブラウザはまだ遅い」ではありません。むしろ逆です — ボトルネックはもはやソフトウェアではなく、標準化のスケジュールにあるということです。subgroupsが元の提案からChrome 134でのデフォルト有効化まで、およそ1年のorigin trialを経たことを考えれば、cooperative matrixがまだ提案段階にあるという事実が何を意味するかは明らかです。そして、その議論の中心は性能ではなく移植性になるでしょう — 8ベンダーの行列ユニットを一つの安全なAPIで覆うことは、そもそも難しいのですから。
それまでは、ブラウザでLLMを動かすという決断は、性能の決断ではなくプライバシーの決断です。そのフレームで捉えれば、この技術は今すでに十分に値打ちがあります。ベンチマークのフレームで捉えれば、がっかりするでしょう。
参考資料
- Llamas on the Web: Memory-Efficient, Performance-Portable, and Multi-Precision LLM Inference with WebGPU (Levineら、arXiv:2605.20706、2026年5月20日)
- ggml webgpu: faster matrix multiplication/matrix-vector multiplication — llama.cpp PR #17031 (2025年11月8日マージ)
- WebGPU Subgroups — Chrome Platform Status (Chrome 134でデフォルト有効)
- WebGPU
subgroup_idfeature — Chrome Platform Status (Chrome 144) - What's New in WebGPU — Chrome for Developers リリースノート索引
- WebAssembly and WebGPU enhancements for faster Web AI, part 2 — cooperative matrix提案の背景
- ブラウザで本物のGPUコンピュート — WebGPUコンピュートシェーダーとWGSL実践ガイド 2026(関連記事)