WebGPU が GPU の能力を解き放ち、機械学習のパフォーマンスを向上させ、グラフィック レンダリングを改善する方法について学びます。
新しい WebGPU API により、グラフィック ワークロードと ML ワークロードで大幅なパフォーマンス向上を実現できます。この記事では、WebGPU が現在の WebGL ソリューションよりも優れている点と、今後の開発について説明します。まず、WebGPU が開発された理由について説明します。
WebGPU の背景
WebGL は 2011 年に Chrome に導入されました。WebGL では、ウェブ アプリケーションで GPU を利用できるため、Google Earth やインタラクティブなミュージック ビデオ、3D 不動産ウォークスルーなど、ウェブ上で驚きの体験を実現できます。WebGL は、1992 年に初めて開発された OpenGL ファミリーの API をベースとしています。かなり前ですね。それ以降、GPU ハードウェアは大幅に進化しています。
この進化に対応するため、最新の GPU ハードウェアをより効率的に操作するための新しい API が開発されました。Direct3D 12、Metal、Vulkan などの API です。これらの新しい API は、機械学習の急増やレンダリング アルゴリズムの進歩など、GPU プログラミングの新しい要求の厳しいユースケースをサポートしています。WebGPU は WebGL の後継であり、この新しいクラスの最新 API の先進的な機能をウェブに提供します。
WebGPU により、ブラウザで GPU プログラミングの可能性が大きく広がります。最新の GPU ハードウェアの仕組みをより適切に反映し、将来の高度な GPU 機能の基盤を築きます。この API は 2017 年から W3C の「GPU for the Web」グループで開発されており、Apple、Google、Mozilla、Microsoft、Intel などの多くの企業が協力して開発しています。6 年にわたる開発を経て、ウェブ プラットフォームに追加される最大の機能の一つが、ついに利用可能になりました。
WebGPU は現在、ChromeOS、macOS、Windows 版 Chrome 113 で利用できます。他のプラットフォームにも近日中に対応する予定です。これを実現するために協力してくれた他の Chromium コントリビューター、特に Intel に心から感謝いたします。
では、WebGPU によって可能になる魅力的なユースケースをいくつか見てみましょう。
レンダリング用の新しい GPU ワークロードを活用する
コンピューティング シェーダーなどの WebGPU 機能により、新しいクラスのアルゴリズムを GPU に移植できます。たとえば、シーンに動的で詳細なディテールを追加したり、物理現象をシミュレートしたりできるアルゴリズムなどです。これまで JavaScript でしか実行できなかったワークロードも、GPU に移行できるようになりました。
次の動画は、これらのメタボールのサーフェスを三角形分割するために使用されるマーチング キューブ アルゴリズムを示しています。動画の最初の 20 秒間、JavaScript で実行されているアルゴリズムは、ページが 8 FPS でしか実行されていないため、追いつくことができません。その結果、アニメーションがぎくしゃくします。JavaScript でパフォーマンスを維持するには、詳細レベルを大幅に下げる必要があります。
同じアルゴリズムをコンピューティング シェーダーに移行すると、動画の 20 秒目以降に示すように、パフォーマンスが大幅に向上します。パフォーマンスが大幅に向上し、ページがスムーズに 60 FPS で実行されるようになりました。他のエフェクトに使用できるパフォーマンスの余裕もまだ十分にあります。また、ページのメインの JavaScript ループが他のタスクのために完全に解放されるため、ページの操作が常に応答するようになります。
また、WebGPU では、これまでは実用的ではなかった複雑な視覚効果も実現できます。次の例は、一般的な Babylon.js ライブラリで作成されています。海面はすべて GPU でシミュレートされています。リアルなダイナミクスは、多くの独立した波を重ね合わせることで作成されます。ただし、各波を直接シミュレートすると費用がかかりすぎます。
そのため、このデモでは 高速フーリエ変換という高度なアルゴリズムを使用しています。すべての波を複雑な位置データとして表すのではなく、計算を実行する際にはスペクトル データを使用するため、はるかに効率的です。次に、各フレームでフーリエ変換を使用して、スペクトル データから波の高さを表す位置データを変換します。
ML 推論の高速化
WebGPU は、近年 GPU の主要な用途となっている ML の高速化にも役立ちます。
長い間、クリエイティブ デベロッパーは、WebGL のレンダリング API を再利用して、機械学習の計算など、レンダリング以外のオペレーションを実行してきました。ただし、この方法では、計算を開始する方法として三角形のピクセルを描画し、より汎用的なメモリアクセスではなく、テクスチャ内のテンソルデータを慎重にパックと解凍する必要があります。
このように WebGL を使用すると、デベロッパーは描画専用に設計された API の要件にコードを無理やり合わせる必要があります。計算間での共有メモリ アクセスなどの基本機能が不足していることも相まって、作業が重複し、最適なパフォーマンスが得られません。
コンピューティング シェーダーは WebGPU の主な新機能であり、これらの問題を解消します。コンピューティング シェーダーは、レンダリング オペレーションの厳格な構造に制約されることなく、GPU の超並列性を利用できる、より柔軟なプログラミング モデルを提供します。
コンピューティング シェーダーを使用すると、シェーダー処理のグループ内でデータと計算結果を共有できるため、効率性が向上します。これにより、同じ目的で WebGL を使用しようとしたこれまでの試みよりも大幅なパフォーマンス向上が期待できます。
これによって得られる効率性の向上の一例として、TensorFlow.js の画像拡散モデルの最初のポートは、WebGL から WebGPU に移行したときに、さまざまなハードウェアでパフォーマンスが 3 倍向上しています。テストした一部のハードウェアでは、画像が 10 秒未満でレンダリングされました。これは初期段階の移植であるため、WebGPU と TensorFlow.js の両方でさらに改善できると考えています。2023 年のウェブ ML の最新情報をご覧ください。Google I/O セッション。
しかし、WebGPU は GPU 機能をウェブに導入するだけではありません。
JavaScript 向けに設計
このようなユースケースを実現する機能は、プラットフォーム固有の PC デベロッパーとモバイル デベロッパーが長い間利用してきました。ウェブ プラットフォームの自然な一部のようにこれらの機能を公開することが、Google の課題でした。
WebGPU は、10 年以上にわたって WebGL で素晴らしい成果を上げてきたデベロッパーの経験を活かして開発されました。ユーザーから寄せられた問題、ボトルネック、問題をすべてこの新しい API にフィードバックしました。
WebGL のグローバル状態モデルでは、堅牢でコンポーザブルなライブラリやアプリケーションを作成することが難しく、脆弱であることがわかりました。そのため、WebGPU では、GPU コマンドを送信する際にデベロッパーが追跡する必要がある状態の量が大幅に削減されます。
WebGL アプリケーションのデバッグが面倒だという声をよく聞きます。WebGPU には、パフォーマンスを低下させない、より柔軟なエラー処理メカニズムが含まれています。また、API から返されるすべてのメッセージがわかりやすく、実用的な内容になるよう、細心の注意を払っています。
また、JavaScript 呼び出しが多すぎることによるオーバーヘッドが、複雑な WebGL アプリケーションのボトルネックになることもよく見られました。その結果、WebGPU API の通信量が減り、関数呼び出しを減らしてより多くのことを実現できるようになります。重量級の検証を事前に実行し、重要な描画ループを可能な限りスリムに保つことに重点を置いています。また、レンダリング バンドルなどの新しい API も提供されています。これにより、大量の描画コマンドを事前に記録し、1 回の呼び出しで再生できます。
レンダリング バンドルなどの機能がもたらす劇的な違いを示すために、Babylon.js の別のデモを紹介します。この WebGL 2 レンダラは、すべての JavaScript 呼び出しを実行して、このアートギャラリーのシーンを 1 秒あたり約 500 回レンダリングできます。かなり良いです。
ただし、WebGPU レンダラでは、スナップショット レンダリングと呼ばれる機能が有効になっています。WebGPU のレンダリング バンドル上に構築されたこの機能により、同じシーンを 10 倍以上速く送信できます。これによりオーバーヘッドが大幅に削減され、WebGPU はより複雑なシーンをレンダリングできるようになりました。また、アプリケーションは JavaScript でより多くのことを並行して行うことができるようになりました。
最新のグラフィック API は複雑で、シンプルさを犠牲にして極端な最適化の機会を追求しているという評判があります。一方、WebGPU はクロスプラットフォームの互換性に重点を置いており、リソースの同期など、従来は難しかったトピックをほとんどの場合自動的に処理します。
これにより、WebGPU の学習と使用が容易になります。画像や動画の読み込みなどにはウェブ プラットフォームの既存の機能を使用します。また、非同期オペレーションには Promise などのよく知られた JavaScript パターンを利用します。これにより、必要なボイラプレートコードの量を最小限に抑えることができます。50 行未満のコードを記述するだけで、最初の三角形を画面に表示できます。
<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const context = canvas.getContext("webgpu");
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format });
const code = `
@vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
@builtin(position) vec4f {
const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
return vec4f(pos[i], 0, 1);
}
@fragment fn fragmentMain() -> @location(0) vec4f {
return vec4f(1, 0, 0, 1);
}`;
const shaderModule = device.createShaderModule({ code });
const pipeline = device.createRenderPipeline({
layout: "auto",
vertex: {
module: shaderModule,
entryPoint: "vertexMain",
},
fragment: {
module: shaderModule,
entryPoint: "fragmentMain",
targets: [{ format }],
},
});
const commandEncoder = device.createCommandEncoder();
const colorAttachments = [
{
view: context.getCurrentTexture().createView(),
loadOp: "clear",
storeOp: "store",
},
];
const passEncoder = commandEncoder.beginRenderPass({ colorAttachments });
passEncoder.setPipeline(pipeline);
passEncoder.draw(3);
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
</script>
まとめ
WebGPU がウェブ プラットフォームにもたらす新しい可能性に期待しています。WebGPU の新しいユースケースがどのように広がっていくのか、楽しみです。
WebGL を中心に、ライブラリとフレームワークの活気あるエコシステムが構築されています。このエコシステムは、WebGPU を積極的に採用しています。多くの一般的な JavaScript WebGL ライブラリで、WebGPU のサポートが進行中または完了しています。場合によっては、1 つのフラグを変更するだけで、WebGPU のメリットを活用できます。
今回の Chrome 113 での最初のリリースは、ほんの始まりにすぎません。最初のリリースは Windows、ChromeOS、macOS を対象としていますが、近い将来、Android や Linux などの残りのプラットフォームにも WebGPU を導入する予定です。
WebGPU のリリースに向けて取り組んでいるのは Chrome チームだけではありません。Firefox と WebKit でも実装が進行中です。
また、ハードウェアで利用可能になったときに公開できる新機能が W3C ですでに設計されています。たとえば、Chrome では、機械学習のパフォーマンスをさらに向上させるため、まもなくシェーダーでの 16 ビット浮動小数点数をサポートし、DP4a クラス命令を有効にすることを計画しています。
WebGPU は、投資すれば驚異的なパフォーマンスを発揮する包括的な API です。今回は、WebGPU のメリットについて概要のみ説明しました。WebGPU を使い始めるにあたっては、入門用 Codelab「初めての WebGPU アプリ」をご覧ください。この Codelab では、古典的なコンウェイのライフゲームの GPU バージョンを作成します。この Codelab では、GPU 開発を初めて行う場合でも試すことができる、手順を順を追って説明します。
WebGPU サンプルも、API の雰囲気をつかむのに適しています。従来の「Hello Triangle」から、より完全なレンダリング パイプラインとコンピューティング パイプラインまで、さまざまなテクニックが示されています。その他のリソースもご覧ください。