記事のサマリー(TL;DR)
- Hugging Face が207個の WebGPU カーネルを Hub 上に公開、ORT WebGPU 比で幾何平均 2.57 倍高速
- JavaScript ライブラリ
@huggingface/kernelsが Hub からカーネルを直接ダウンロード・実行する仕組みを提供 - ブラウザ上の実機ベンチツール「Fleet」でクラウドソーシング型の性能・正確性データを収集
ブラウザ上の生成 AI 推論を検討する国内エンジニア・情シスが押さえておくべき点
WebGPU はすでに Chrome・Edge・Safari の主要バージョンで有効化されており、ユーザー端末の GPU を活用してサーバーレスに AI 推論を実行できる環境が整いつつあります。今回の @huggingface/kernels は npm で導入でき、Hugging Face Hub 上のカーネルをバージョン指定でロードできるため、プロダクト側のコードを変えずにカーネル実装だけを差し替えることが可能です。国内でも kintone や Salesforce の専用 UI 上でブラウザ完結型の AI 補助機能を組み込むユースケースが増えており、サーバー転送コストや個人情報の外部送信リスクを抑えたいシーンで選択肢になります。また、Hugging Face は ONNX Runtime チームとのアップストリーム連携も進めており、既存の ONNX ベースの推論フローと組み合わせやすい点も評価ポイントです。
詳細
なぜカーネルから着手するのか
ブラウザで動くモデルは最終的に GPU オペレーションの連続に分解されます。行列積(MatMul)、正規化(Normalization)、畳み込み(Convolution)、アテンション、量子化、データレイアウト変換などです。WebGPU はこれらをポータブルな API として提供し、WGSL(WebGPU Shading Language)はシェーダー記述の共通言語として機能します。
しかし「ポータブル=高速」ではありません。同じ演算を実装した2つのシェーダーが同一出力を返しながら、GPU アーキテクチャによって全く異なるパフォーマンスを示すことは珍しくありません。ワークグループサイズ、メモリアクセスパターン、ベクトル化、データ型、Fusion 戦略がすべて効いてきます。さらに入力形状・デバイス・ブラウザ・利用可能な WebGPU 機能によって最適解が変わります。
カーネルを個別に「発見可能・テスト可能・ベンチマーク可能・バージョン管理可能」にしておくことで、上位レイヤーのランタイムに安定したコントラクトを提供しながら、土台だけを継続改善できる構造になります。
カーネルリポジトリの構造:シェーダー単体ではなく「パッケージ」として
207 個の各カーネルは Hub 上に独自リポジトリを持ち、カーネルカードが以下を文書化しています。
- 演算のセマンティクス、入出力、属性、対応データ型
- すぐ動く
@huggingface/kernelsのサンプルコード
例として ai.onnx.Add(要素ごとの加算+多方向ブロードキャスト)を見ると、リポジトリ内には以下のファイルが同梱されています。
| ファイル | 役割 |
|---|---|
manifest.json |
入出力・属性・型制約・形状導出ルールの正規定義 |
metadata.json |
カーネル識別子・ダイジェスト・出所情報 |
test.json |
正確性検証ケース |
bench.json |
ベンチマーク・チューニングケース |
*.wgsl.jinja |
リクエストとデバイスに応じてシェーダーを生成するテンプレート |
この構造により、WGSL を読まなくてもインターフェースを検査でき、正確性・性能ケースが実装と一緒に移動し、バージョン指定ロードができます。カスタム WebGPU カーネルを構築する開発者向けのリファレンス実装としても機能します。
@huggingface/kernels の使い方
インストール
npm install @huggingface/kernels@preview
WebGPU 対応ブラウザが必要です(JavaScript で "gpu" in navigator を確認)。
バイアス加算のサンプルコード
import { getKernel } from "@huggingface/kernels";
const add = await getKernel("webgpu-kernels/ai.onnx.Add", { version: 1 });
const { c } = await add({
a: { data: new Float32Array([1, 2, 3, 4, 5, 6]), shape: [2, 3] },
b: { data: new Float32Array([10, 20, 30]), shape: [3] },
});
b は第1次元にブロードキャストされ、出力形状 [2, 3] の c が自動アロケートされます。getKernel の呼び出しパターンは ai.onnx.MatMul のような重い演算でも同じです。リポジトリ ID と入力を変えるだけで済みます。
version: 1 はカーネルコントラクトのバージョンを指定します。ONNX opset やモデルリビジョンとは独立しており、アプリケーション側の API を安定させながらカーネル実装を更新できます。
実測パフォーマンス:ORT WebGPU との比較
測定環境:Apple M4 GPU、ONNX Runtime Web 1.30.0-dev.20260826-b1f76d586a
全207演算の1,756テストケースから、両者が一致する出力と信頼できるタイミングを示した 809ケースを抽出して比較した結果:
| 指標 | 値 |
|---|---|
| 幾何平均速度比 | 2.57 倍高速 |
| 中央値速度比 | 1.90 倍高速 |
| 勝敗 | 629勝・176敗・4引分 |
主要演算の個別比較(GPU 処理時間のみ、セットアップ除く):
| 演算 | 比較ケース数 | 本カーネル | ORT WebGPU | 高速化倍率 |
|---|---|---|---|---|
| Add | 5 | 0.064 ms | 0.227 ms | 3.52x |
| MatMul | 29 | 0.115 ms | 0.131 ms | 1.14x |
| Softmax | 12 | 0.114 ms | 0.240 ms | 2.11x |
| LayerNormalization | 6 | 0.061 ms | 0.135 ms | 2.22x |
特殊ケースでは極端な差も生じています。二線形 Einsum(i,ij,j、サイズ4096)は本カーネルが 0.136 ms に対し ORT WebGPU は 1,396 ms と 10,000 倍以上の差。行方向の CumSum([256, 4096])は 0.016 ms 対 4.784 ms で 301 倍高速でした。これらは一般的なケースではなく、汎用実装がスローパスにはまった際に専用カーネルが有効な例です。
なお、GPU アーキテクチャやブラウザによって数値は変化するため、単一デバイスの結果は参考値として扱うべきです。Hugging Face は ONNX Runtime チームと連携し、これらの改善を ORT WebGPU へアップストリームする作業も進めています。
Fleet:ブラウザ上のクラウドソーシング型ベンチマークツール
WebGPU の性能は GPU・ブラウザ・ドライバの組み合わせで大きく変動します。単一デバイスのベンチ結果だけでは全体像を把握できません。
Fleet はブラウザ上で正確性・性能チェックを実行し、ユーザーの同意のもとで以下を収集します。
- デバイス固有の不具合(誤った出力、極端に遅いケース)の発見
- カーネルバリアント間の比較データ
- バリアント選択ルールの改善材料
従来のテストラボでは再現不可能な実機 GPU の多様性をカバーすることが目標です。
ブラウザ AI の共有基盤として
207 個のカーネルは出発点に過ぎません。Hub 上でのカーネル管理は、CUDA・ROCm・Metal 向けカーネルと同一の「Kernels」ページに統合されており、プラットフォームでフィルタリングや並べ替えが可能です。
3つのコンポーネントが相互補完する設計になっています。
- カーネルリポジトリ:透明でバージョン管理されたオペレーションコントラクトを定義
@huggingface/kernels:Hub からのロード・実行を JavaScript で簡潔に実現- Fleet:従来のベンチラボでは得られない実世界の広範なデバイスカバレッジを確保
Hugging Face は今後、これらのカーネルを上位レベルのモデルツールと接続し、オペレーションカバレッジを拡大して、ブラウザ上のローカル AI 推論をさらに使いやすくする方針です。