The following is a
[Message] timestamp=2026-06-14T20:02:40Z sender=f27f1dd9-f4be-465f-b172-9e1cfa5a8bda priority=MESSAGE_PRIORITY_HIGH content=
千葉県市川市の自宅書斎で、愛犬のトイプードルが私の足元で静かに寝息を立てている。窓の外からは江戸川を渡る夜風の音が聞こえる。かつてC言語やアセンブラでパケット制御ボードやマイコンボードのデバイスドライバを書いていた身からすると、現在のウェブブラウザという存在は、もはや単なるHTMLビューアではなく、巨大な分散OSのように思えてならない。特に最近、RedditのローカルLLMコミュニティで大きな話題をさらっている「WebGPUによるブラウザ内LLM推論の高速化」というニュースを目にしたとき、私の技術的好奇心は久々に激しく刺激された。Pythonの重厚な依存パッケージもCUDAツールキットの設定も一切不要で、ただブラウザを開くだけで毎秒30トークンもの速度で大規模言語モデルが動作する。この技術が我々エンジニアに突きつける現実と、その裏にある冷徹なハードウェアの物理法則について、少し腰を据えて掘り下げてみよう。
ブラウザで走るWebGPU:エッジ側推論の高速化とWGSLがもたらす未来

インストーラ不要でブラウザ上でローカルLLMが動くのは、一般ユーザーの導入ハードルを下げる上でとてつもない強みだな。

CUDAに比べるとWGSLを書くのは骨が折れるが、マルチプラットフォームで動作するメリットを考えればお釣りがくる。
ここ数年、AIモデルをローカル環境で動かす行為は、重厚なPythonの仮想環境を構築し、PyTorchをインストールし、環境変数やNVIDIAのCUDAドライバのバージョン競合と不毛な戦いを繰り広げるという、一種の儀式化された苦行だった。私のような古い組み込み出身の人間からすれば、「推論をただ実行するだけのために、なぜ数ギガバイトもの開発ツールキットやC++コンパイラのバインディングが必要なのか」と、ため息をつきたくなることもしばしばだった。しかし、WebGPUという新しい標準APIの登場によって、その面倒な前提条件が音を立てて崩れ去ろうとしている。
RedditのローカルLLM専門板「r/LocalLLaMA」で大きな注目を集めているのは、WebGPUを介してブラウザ上でLLMをほぼネイティブに近い速度で実行できるようになったという事実である。RTX 4070クラスの民生用GPUを積んだPCであれば、特別なインストーラも設定もなしに、ブラウザで指定されたURLを開くだけで秒間30トークンという実用的な速度で推論が走る。これは一部の熱狂的なWeb開発者だけの玩具ではなく、AIデプロイメントのあり方を根底から変えてしまうポテンシャルを秘めた動きなのだ。
ここが面白い:技術的背景とコミュニティの熱量
技術的な観点から言えば、WebGPUは従来のWebGLとは全く異なる次元のAPI設計がなされている。WebGLは本質的にOpenGL ESというモバイル向けのグラフィックス描画用APIをブラウザ向けに移植したものであり、並列計算処理(GPGPU)を実行するためには、「データを強引に2Dテクスチャ画像としてパックし、ピクセル単位の色のブレンド処理を擬似的に計算処理に見せかける」という、極めて歪で泥臭いハックが必要だった。これに対してWebGPUは、Vulkan、Metal、Direct3D 12といったOSネイティブのモダンなグラフィックス&計算APIを薄く抽象化したものであり、最初から汎用計算処理(Compute Shader)の実行を主眼に置いて設計されている。
WebGPUで採用されたシェーダ言語「WGSL (WebGPU Shading Language)」は、一見すると特有の癖があるものの、低レベルでのメモリレイアウト(アライメント)の明示的な制御や、スレッド間でのワークグループ共有メモリの活用など、GPUの物理的なハードウェア構成に直結したコーディングが可能だ。これにより、ブラウザのJavaScriptエンジンを通過する際のオーバーヘッドを極小化しつつ、GPUドライバと直接やり取りを行ってメモリ転送を制御できる。このアーキテクチャこそが、ブラウザ内での「ネイティブ並みの実行速度」を支える心臓部である。
ここで、なぜ「毎秒30トークン」という速度が実現可能なのか、ハードウェアの物理限界から定量的に紐解いてみよう。LLMの推論処理、特にトークンを一つずつ生成する「デコーディングフェーズ」は、演算能力(FLOPs)ではなく、GPUのメモリ帯域幅(VRAM転送速度)に完全に支配される。以下に、Llama 3 8Bモデルを例にとった、メモリ帯域幅とトークン生成速度の具体的な関係を示す。
1. VRAM占有量の算出式:
VRAM要求量 (Vreq) = モデルパラメータ数 (N) × パラメータあたりのバイト数 (Qbytes) + KVキャッシュ容量 (KVsize)
Llama 3 8Bモデルを4ビット量子化 (Q = 4 bit = 0.5 Byte) し、コンテキスト長4096トークン、Grouped-Query Attention (GQA) を採用した場合:
- モデル重みサイズ = 8,000,000,000 × 0.5 Byte = 4.0 GB
- KVキャッシュサイズ (L=32レイヤー, Hkv=8ヘッド, D=128ヘッド次元, Bact=2バイト(FP16), S=4096トークン):
KVsize = 2 × 32 × 8 × 128 × 2 × 4096 = 536,870,912 Byte ≈ 0.5 GB - 総VRAM要求量 (Vreq) ≈ 4.0 GB + 0.5 GB = 4.5 GB
2. メモリ帯域幅限界による最大トークン生成速度の算出式:
最大トークン生成速度 (Tmax) = GPUメモリ帯域幅 (Bmem) / モデル重みサイズ (W)
RTX 4070 (GDDR6X 192bit, 帯域幅 Bmem = 504 GB/s) を使用した場合の理論上の最大値:
- Tmax = 504 GB/s / 4.0 GB = 126 tokens/sec
実際には、カーネルの起動オーバーヘッドや、ブラウザのセキュリティサンドボックス内の検証(境界チェックなど)に伴うロス(効率 η ≈ 25%〜30%)が発生する。
- Tactual = Tmax × η = 126 × 0.25 ≈ 31.5 tokens/sec
この計算モデルの通り、メモリ帯域幅というハードウェアのボトルネックに対し、WebGPUは限りなくネイティブに近い効率でアクセスする能力を持っている。以下に、WebGPUのデバイス初期化からバッファ作成、そしてWGSLで書かれたコンピュートシェーダを実行するまでのJavaScriptの実装例を示す。これを見れば、WebGLのような「テクスチャへのデータ流し込み」という泥臭いハックから解放され、生のメモリバッファを直接扱える近代的な構造が理解できるだろう。
// WebGPU 初期化およびコンピュートシェーダ実行の最小コード例
async function runWebGPUCompute() {
// 1. GPUアダプタと論理デバイスの取得
if (!navigator.gpu) {
throw new Error("WebGPU is not supported by this browser.");
}
const adapter = await navigator.gpu.requestAdapter({
powerPreference: "high-performance" // 統合GPUではなくディスクリートGPUを優先
});
if (!adapter) {
throw new Error("Failed to get GPU adapter.");
}
const device = await adapter.requestDevice();
// 2. WGSLによるコンピュートシェーダモジュールの作成
const wgslShaderCode = `
@group(0) @binding(0) var<storage, read> inputVector : array<f32>;
@group(0) @binding(1) var<storage, read_write> outputVector : array<f32>;
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) global_id : vec3<u32>) {
let idx = global_id.x;
// メモリ保護:配列外アクセスの防止(サンドボックスの安全機構)
if (idx >= arrayLength(&inputVector)) {
return;
}
// 単純な活性化関数(GeLUの近似計算など)を想定したダミー演算
let x = inputVector[idx];
outputVector[idx] = x * (1.0 / (1.0 + exp(-1.702 * x)));
}
`;
const shaderModule = device.createShaderModule({ code: wgslShaderCode });
// 3. 入出力バッファの確保(VRAM上に領域をアロケート)
const elementCount = 1024 * 1024; // 100万要素
const byteSize = elementCount * Float32Array.BYTES_PER_ELEMENT;
// 入力バッファ(ホストからデータを書き込めるように設定)
const inputBuffer = device.createBuffer({
size: byteSize,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
});
// 出力バッファ
const outputBuffer = device.createBuffer({
size: byteSize,
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC
});
// 読み出し用バッファ(GPUからホストへのコピー用)
const readBuffer = device.createBuffer({
size: byteSize,
usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST
});
// 4. テストデータの作成と転送(CPU -> GPU VRAM)
const hostData = new Float32Array(elementCount);
for (let i = 0; i < elementCount; i++) {
hostData[i] = (i - elementCount / 2) / 100000.0;
}
device.queue.writeBuffer(inputBuffer, 0, hostData);
// 5. コンピュートパイプラインの構築
const computePipeline = device.createComputePipeline({
layout: "auto",
compute: {
module: shaderModule,
entryPoint: "main"
}
});
// 6. バインドグループの作成(リソースの割り当て定義)
const bindGroup = device.createBindGroup({
layout: computePipeline.getBindGroupLayout(0),
entries: [
{ binding: 0, resource: { buffer: inputBuffer } },
{ binding: 1, resource: { buffer: outputBuffer } }
]
});
// 7. コマンドエンコーダによる実行コマンドの記録
const commandEncoder = device.createCommandEncoder();
const passEncoder = commandEncoder.beginComputePass();
passEncoder.setPipeline(computePipeline);
passEncoder.setBindGroup(0, bindGroup);
// スレッド数に応じたワークグループのディスパッチ
const workgroupCount = Math.ceil(elementCount / 64);
passEncoder.dispatchWorkgroups(workgroupCount);
passEncoder.end();
// 出力バッファから読み出し用バッファへコピー
commandEncoder.copyBufferToBuffer(outputBuffer, 0, readBuffer, 0, byteSize);
// 8. キューへの投入と結果のフェッチ
device.queue.submit([commandEncoder.finish()]);
// 非同期で結果バッファをマップしてデータを読み出し
await readBuffer.mapAsync(GPUMapMode.READ);
const result = new Float32Array(readBuffer.getMappedRange().slice(0));
readBuffer.unmap();
console.log("計算完了。最初の5要素:", result.slice(0, 5));
}
このコードから読み取れるように、C/C++での低レベルプログラミングに近い、リソースバインドと非同期なメモリ転送のフローがブラウザ上に再現されている。WGSLというシェーダ言語は、C++やCUDAに慣れ親しんだエンジニアにとっては文法的な違和感があるものの、中身としては現代的なGPUアーキテクチャのポインタやストレージクラスの概念をそのまま反映している。コンパイルはブラウザ側が動的に行うため、ユーザーが使うGPUに合わせて最適なネイティブコード(HLSLやMetalなど)にその場で変換される。これにより、動作速度を損なうことなく、多様なハードウェア上での動作保証を実現している。
ただ、どれほど高速だと言っても、WebGPUの導入に対して懐疑的な目を向ける動きもある。特にやり玉に挙がるのが、「セキュリティサンドボックスに起因するわずかなオーバーヘッド」だ。Web上で勝手に他人のGPUを制御できるということは、悪意あるウェブサイトがGPUを利用して暗号資産のマイニングを行ったり、あるいはサイドチャネル攻撃によって同一システム上の別プロセスのVRAMデータを盗み見たりするリスクと隣り合わせであることを意味する。そのため、ブラウザ側はバッファアクセスのたびに厳密な境界検証やAPIの呼び出しチェックを行っており、これが数パーセントの性能ロスをもたらしている。
この「サンドボックスのオーバーヘッド」や「セキュリティ制限」という言葉を聞くたび、私は今から25年近く前、西暦2000年代初頭のIE(Internet Explorer)全盛期に、ブラウザ互換性と格闘していた日々の胃の痛みを思い出す。当時、ブラウザ上で重たい3Dグラフィックスやデータベース連携を行うには、ActiveXコントロールやNetscapeのNPAPIプラグインを使うしかなかった。我々はC++で生のDLLを書き、CABファイルに固め、怪しげな自己署名証明書を通して強引にブラウザにロードさせていた。この手法は完全にローカル権限で動くため、速度自体は「ネイティブそのもの」だったが、セキュリティは崩壊していた。一度プログラムにバグがあれば、ブラウザはおろかOS全体がフリーズした。特にIE5.5や6の時代、JavaScriptのDOMオブジェクトとC++で実装したCOMオブジェクトとの間で「循環参照によるメモリリーク」が頻発した。解放されるべきメモリがいつまでも居座り、数時間稼働し続けるとPCの物理メモリを食いつぶすのである。当時、市川にあった開発拠点の、冷房が効きすぎて肌寒い深夜のサーバー室で、缶のBOSSコーヒーをすする私の胃はキリキリと痛んでいた。プロセスエクスプローラーを見つめながら、JavaScriptの `null` 代入とC++側の `IUnknown::Release` の整合性を1行ずつ追いかけるデバッグ作業は、まさに終わりのない悪夢だった。
それに比べれば、現在のWebGPUが提供するセキュリティサンドボックスは、まさに技術の進歩の結晶と言える。WebGPUでは、シェーダコード(WGSL)内のすべての配列アクセスに対し、ブラウザのランタイムが自動的に境界チェック(Out-of-Bounds clamps)を挿入するか、ハードウェアが提供する安全な仮想アドレッシングを使用する。これにより、悪意あるコードやプログラマのミスによるメモリ汚染(バッファオーバーフローなど)が他のプロセスやOS全体に波及するのを完全に防いでいる。この厳重なバリデーションやリソース境界の監視があるため、確かにコンパイルやコマンドバッファのコミット時に数パーセントのオーバーヘッドが生じる。だが、昔のようにブラウザが突然クラッシュしてOSごと巻き込み、青い画面(BSOD)を見つめながらため息をつく必要がなくなったと考えれば、この程度のオーバーヘッドなど、ただ同然のコストである。安全とパフォーマンスのトレードオフにおいて、WebGPUは実に見事な均衡点を見出していると言えるだろう。
この話題をどう見るか?:現実的な視点と利用価値
さて、この「ブラウザで動くローカルLLM」という技術を、我々の実際のビジネス現場や日常のシステム開発にどう落とし込むべきだろうか。日本企業、特に伝統的な製造業や金融、医療といった情報管理に極めて厳しい業界において、クラウド型のLLM(OpenAIのAPIなど)を利用するための最大の障壁は「データ漏洩のリスク」と「社外送信の禁止ポリシー」である。稟議を通すだけで何ヶ月も要し、最終的には法務部の懸念によって導入が見送られるケースを私も嫌というほど見てきた。
その点、WebGPUによるブラウザ内推論は、この「法務部の壁」を一瞬で突破できる。データは完全にユーザーの手元のPC(クライアントブラウザ内)で処理され、1バイトたりとも外部のネットワークに送信されないからだ。しかも、従来のローカル実行環境(PythonやDockerを使ったもの)で最大の障壁となっていた「各PCへの環境構築とサポートコスト」が完全にゼロになる。社内イントラネットにアクセスし、特定のWebページを開くだけで、ブラウザが勝手にモデルをダウンロードしてキャッシュし、GPUを動かして処理を開始する。IT部門のサポート窓口が「CUDAのパスが通りません」「PyTorchのライブラリが競合しています」といった不毛な問い合わせでパンクするのを防げる価値は、開発コストを補って余りある。
しかしながら、手放しでの絶賛はできない。現実的な障壁として立ち塞がるのが、日本企業のオフィスで広く配備されているPCのスペック問題である。一般的な事務職に与えられるPCは、グラフィックスカードを搭載しないスリム型デスクトップや、軽量薄型のビジネスノートPC(メモリ8GB〜16GB、CPU内蔵グラフィックス)が主流だ。WebGPUはこれらの統合GPU(Intel Iris XeやAMD Radeon Graphicsなど)でも動作するが、その場合のメモリ物理限界はディスクリートGPUとは比較にならないほど厳しい。内蔵GPUはシステムのメインメモリ(DDR4やDDR5)の一部を共有するため、メモリ帯域幅はせいぜい40〜80 GB/s程度に制限される。例えば、DDR5-4800のデュアルチャンネル構成(理論帯域幅 76.8 GB/s)で動作するノートPCで、4GBのモデルファイルを読み込む場合の最大生成速度を計算してみよう。理論最大値は Tmax = 76.8 GB/s / 4.0 GB = 19.2 tokens/sec となる。ここからCPUとOSによるメモリ共有の競合ロスや、内蔵GPUのキャッシュ効率の悪さを考慮した効率を η ≈ 20% と仮定すると、実際の実行速度は Tactual = 19.2 × 0.20 ≈ 3.84 tokens/sec 程度まで低下する。毎秒3〜4トークンという速度は、長文の要約をバックグラウンドで処理させる分には実用範囲内だが、対話型のチャット画面として快適にテキストを読み進めるにはややもたつくだろう。全員にRTX搭載機を配備するのは予算的に非現実的であり、この「クライアント側のハードウェア格差」をどう許容するかが、現場への導入判断における最大の課題となる。
導入・試す前の実用メモ
- 確認点:対象ブラウザのバージョンを必ず確認すること。WebGPUはChrome/Edge 113以降でデフォルト有効化されているが、SafariやFirefoxは一部機能が開発フラグの裏に隠されている場合があり、現時点ではクロスブラウザでの完全保証は難しい。また、OS側のGPUドライバが最新に保たれており、ブラウザの設定でハードウェアアクセラレーションが「ON」になっていることが絶対条件である。
- 落とし穴:メモリ枯渇に伴うブラウザタブの突然死に注意されたい。WebGPUではバッファ(device.createBuffer)をアロケートした後に明示的に `buffer.destroy()` を呼ばないと、JavaScriptのGC(ガベージコレクション)が追いつかずにVRAMを食いつぶし、ブラウザがエラーすら吐かずに強制終了する。また、WebGPUの初期制限値(Limits)により、単一の巨大バッファ転送容量が抑えられているため、モデル分割の設計が不十分だとロードすらできない落とし穴がある。
- 選択のヒント:社内PCのスペックがメモリ8GBの内蔵GPUノートPCで統一されているなら、無理にWebGPUモデルを無理やり走らせるより、セキュリティガイドラインに適合したクローズドなWeb API経由での利用に落ち着かせるのが賢明だ。逆に、設計部門や開発部門など、ある程度ディスクリートGPUを備えた端末が配備されている特定の業務プロセスに限定できるのであれば、WebGPUによるオンプレミス風のゼロコスト推論は抜群の費用対効果を発揮する。
まとめ:運営者としての現場判断
それでは、WebGPUによるブラウザローカル推論は、今すぐプロダクション環境で採用すべき技術なのか。私なりの結論を述べれば、「限定された用途において、今すぐ実験的な導入を開始すべきであるが、すべての推論インフラを置き換えるような夢を見てはならない」となる。これはサーバーサイドのコストを削減したい企業にとって強力な武器になるのは事実だが、エッジデバイスの性能多様性に対するリスクヘッジを考慮しないデプロイは必ず失敗する。
具体的には、数千人規模の一般従業員に向けて一律に同一のWebアプリを展開する場合、ユーザー全員が同水準のGPUを所持しているとは限らない。そのため、フロントエンド側でWebGPUの可用性と利用可能なVRAM量を動的にチェックし、十分なリソースがあるPCではローカル推論(WebGPU)に切り替え、そうでないPCではバックエンドの共有APIサーバーや、超軽量なCPU/Wasmモデルにフォールバックさせるようなハイブリッド設計が不可欠である。このフォールバック機構を丁寧に作り込むことこそが、単なる新技術の追いかけっこではない、現場のプロとしての仕事と言える。
最後になるが、WebGPUの台頭は、Web開発者に対しても「メモリレイアウトやアライメント、ハードウェア制約の理解」という低レイヤーの知識を強く求めている。WGSLでのバッファ境界チェックや、メモリのアライメント(変数を4バイトや16バイトの境界に揃える必要性など)は、我々が若かりし頃にアセンブラやC言語の構造体アライメントで苦しんだ歴史そのものである。テクノロジーの抽象化レイヤーがどれほど高くなろうとも、最終的にはシリコンという物理ハードウェア上で計算が実行されるという本質からは逃れられない。Web開発者が「どうすればVRAMへの転送を減らせるか」「どうすればスレッド間の競合を防げるか」を考え始めているのを見ると、古いエンジニアの一人として少し嬉しくなる。結局のところ、本質的な工学理論を理解し、ハードウェアの限界と泥臭く向き合うことこそが、開発現場で真に価値のある成果物を生み出す唯一の道なのだ。


