WebGPU 학습 로드맵
WebGPU를 효과적으로 학습하기 위해 개념 이해 → 실습 → 활용 사례의 흐름으로 진행합니다. 먼저 WebGPU의 개념과 동작 원리를 살펴보고 WebGL 등 기존 기술과 어떻게 다른지 이해합니다. 그런 다음 간단한 코드 예제를 통해 WebGPU를 사용하는 방법을 실습해봅니다. 마지막으로 WebGPU가 실제로 사용되는 활용 사례(머신러닝 가속, 데이터 시각화, 게임 등)를 알아보면서 배운 내용을 응용합니다. 이러한 단계별 로드맵으로 진행하면, 개념을 이론적으로 이해한 뒤 직접 코드를 실행하며 체득하고, 최종적으로 실무 활용 감각까지 얻을 수 있습니다.
- 1단계: 개념 학습: WebGPU의 정의, 등장 배경 및 내부 작동 원리를 학습하고, WebGL이나 CUDA 등의 기존 기술과의 차이를 이해합니다.
- 2단계: 코드 실습: WebGPU를 사용할 수 있는 환경을 구축하고, 기본 API 문법과 간단한 그래픽/계산 예제 코드를 따라하며 실제 동작을 확인합니다.
- 3단계: 활용 사례: WebGPU로 무엇을 할 수 있는지 대표 사례들을 통해 알아보고, 머신러닝/딥러닝, 데이터 시각화, 게임 분야에서의 WebGPU 활용을 탐색합니다.
이러한 로드맵을 통해 개념 → 실습 → 응용의 흐름으로 WebGPU를 체계적으로 학습할 수 있습니다.
WebGPU 개념 및 원리
WebGPU란 무엇인가?
WebGPU는 웹 브라우저나 Node.js와 같은 자바스크립트 환경에서 GPU(그래픽 처리 장치)의 성능을 활용할 수 있게 해주는 웹 표준 API입니다 (WebGPU - Wikipedia) (WebGPU API - Web APIs | MDN). 쉽게 말해, 웹에서 GPU 가속 그래픽과 병렬 계산을 수행하도록 하는 차세대 기술입니다. WebGPU는 2011년에 등장한 WebGL의 뒤를 잇는 후속 기술로서, 현대 GPU의 기능을 웹에 반영하기 위해 고안되었습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). WebGPU를 통해 웹 페이지에서도 데스크톱 애플리케이션 못지않은 복잡한 3D 그래픽 렌더링이나 고성능 GPGPU 연산(범용 GPU 연산)을 수행할 수 있게 되었습니다 (WebGPU API - Web APIs | MDN) (WebGPU API - Web APIs | MDN).
WebGPU의 특징은 크로스 플랫폼 및 범용성입니다. 브라우저 내에서 동작할 때는 각 운영체제의 GPU API(예: Windows에서는 Direct3D 12, 리눅스/안드로이드에서는 Vulkan, macOS/iOS에서는 Metal)를 내부적으로 활용하여 GPU와 통신합니다 (WebGPU - Wikipedia) (WebGPU… Better Than WebGL? | Hackaday). 이러한 추상화 계층 덕분에, 개발자는 WebGPU 하나만 알면 OS나 GPU 종류에 상관없이 일관된 방식으로 GPU 프로그래밍을 할 수 있습니다. WebGPU는 자바스크립트뿐만 아니라 C/C++, Rust 등 다양한 언어 바인딩을 제공하는데, 예를 들어 C++의 Dawn 라이브러리나 Rust의 wgpu 라이브러리를 통해 웹이 아닌 환경에서도 동일한 WebGPU 코드를 실행할 수 있습니다 (WebGPU - Wikipedia) (Capturing the WebGPU ecosystem | Blog | Chrome for Developers).
요약하면, WebGPU는 최신 GPU 기능을 웹 환경에 가져온 강력한 API로, 웹에서 고성능 그래픽과 병렬 연산을 가능하게 해주는 기술 표준입니다 (WebGPU API - Web APIs | MDN).
WebGPU와 WebGL, CUDA, Vulkan, Metal, Direct3D12의 비교
WebGPU는 기존의 여러 GPU 기술들의 장점을 웹 플랫폼에 녹여낸 기술입니다. 다음은 WebGPU를 WebGL, CUDA 및 주요 네이티브 그래픽 API들과 비교한 내용입니다:
-
WebGL과 WebGPU: WebGL은 2010년대 초반에 등장한 브라우저용 GPU 그래픽 API로 OpenGL ES 2.0 기반이었습니다. WebGL을 통해 웹에서도 3D 그래픽이 가능해졌지만, 그래픽 렌더링에 초점되어 있고 일반적인 GPU 연산(GPGPU)에는 제약이 있었습니다 (WebGPU API - Web APIs | MDN). 또한 OpenGL 기반이라 현대 GPU의 새로운 기능들을 반영하지 못하고, 글로벌 상태 기반 API이기에 복잡한 그래픽 앱에서 관리가 어려운 측면이 있었습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers).
WebGPU는 WebGL의 한계를 극복하기 위해 만들어졌습니다. 모던 GPU의 동작 방식에 맞춘 설계로 더 낮은 오버헤드와 고급 기능을 제공합니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU API - Web APIs | MDN). WebGPU에서는 디바이스(Device) 와 파이프라인(Pipeline) 개념을 도입하여, WebGL처럼 상태를 계속 변경해가며 그리는 대신 한번에 렌더링 파이프라인을 구성하는 방식으로 바뀌었습니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). 이로 인해 CPU 부하를 줄이고 많은 객체를 효율적으로 렌더링할 수 있으며, 컴퓨트 셰이더 등 범용 계산 기능도 1급 시민으로 지원합니다 (WebGPU API - Web APIs | MDN) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). 예를 들어 WebGL로는 삼각형을 그리는 방식으로 우회해야 했던 머신러닝 계산도 WebGPU에선 전용 Compute Shader로 직접 수행할 수 있어 더 효율적입니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). 또한 WebGPU는 WebGL 대비 오류 처리가 개선되고, API 호출 수도 줄여 성능을 높였습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). 한마디로, WebGL이 오래된 OpenGL의 얇은 래퍼였다면 (WebGPU… Better Than WebGL? | Hackaday), WebGPU는 Vulkan/Metal 등의 최신 API 디자인을 웹에 맞게 재해석한 것이라 볼 수 있습니다 (WebGPU… Better Than WebGL? | Hackaday). -
CUDA와 WebGPU: CUDA는 NVIDIA GPU에서 동작하는 범용 GPU 컴퓨팅 플랫폼으로, 머신러닝 등 고성능 연산에 널리 쓰입니다. 그러나 CUDA는 NVIDIA 전용이고 웹 브라우저에서는 동작하지 않으며, C++/Python 같은 네이티브 환경에서 사용됩니다. 반면 WebGPU는 특정 제조사에 종속되지 않고 모든 플랫폼에서 동작하도록 설계되었으며 (WebGPU - Wikipedia), 브라우저나 Node.js 환경에서 곧바로 GPU를 활용할 수 있다는 점이 다릅니다. 성능 면에서 CUDA가 현재는 더 최적화되어 높은 처리량을 낼 수 있지만, WebGPU는 웹 접근성과 범용성 측면에서 강점이 있습니다 (At First Glance: WebGPU vs CUDA - Aircada Blog) (At First Glance: WebGPU vs CUDA - Aircada Blog). WebGPU의 등장으로, GPU 가속이 필요한 애플리케이션을 굳이 네이티브로 만들지 않고도 웹에서 구현하는 것이 가능해졌으며, 학습曲선을 낮춰 더 많은 개발자가 병렬 GPU 프로그래밍에 접근할 수 있게 될 것으로 기대됩니다 (물론 초창기인 현시점에서 WebGPU의 성능 최적화는 계속 진행 중입니다).
-
Vulkan, Metal, Direct3D12와 WebGPU: Vulkan(크로노스 그룹), Metal(애플), Direct3D12(마이크로소프트)는 운영체제에서 GPU를 제어하기 위한 로우레벨 네이티브 API입니다. 이들은 모두 2010년대 중반 이후 등장하여 기존 OpenGL/DirectX11의 한계를 개선한 모던 그래픽 API로, 개발자에게 더 직접적인 GPU 제어와 높은 성능을 제공합니다 (WebGPU API - Web APIs | MDN). WebGPU는 이러한 현대적인 디자인을 웹 환경에 맞게 추상화한 것으로 볼 수 있습니다. 실제로 WebGPU 구현체는 내부적으로 Vulkan, Metal, Direct3D12 중 적절한 것을 사용하여 동작하며 (WebGPU - Wikipedia) (WebGPU… Better Than WebGL? | Hackaday), 개발자는 WebGPU를 통해 한 번의 코드로 여러 플랫폼의 GPU API를 모두 제어할 수 있습니다. 네이티브 Vulkan/Metal/D3D12는 매우 복잡하고 보일러플레이트 코드도 많지만, WebGPU는 웹 개발자 친화적으로 간소화된 API를 제공하여 보다 적은 코드로 비슷한 작업을 수행할 수 있게 합니다 (At First Glance: WebGPU vs CUDA - Aircada Blog) (At First Glance: WebGPU vs CUDA - Aircada Blog). 요약하면, WebGPU는 Vulkan/Metal/DirectX 12급의 저수준 제어력을 가지면서도 웹 통합과 사용 편의성을 겸비한 기술입니다.
이처럼 WebGPU는 WebGL의 후계자이자, CUDA급의 GPGPU를 웹 표준으로 구현한 것이며, Vulkan/Metal 등의 로우레벨 API를 웹에서 간접적으로 활용할 수 있게 해주는 추상화 계층입니다. 이러한 비교를 통해 WebGPU의 위치를 정리하면, **"웹을 위한 차세대 GPU API"**라고 할 수 있습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU API - Web APIs | MDN).
WebGPU의 내부 동작 원리
WebGPU를 이해하려면 GPU 접근을 위한 추상화 계층과 파이프라인 구조를 알아야 합니다. 내부적으로 WebGPU는 물리 GPU 장치부터 브라우저 환경까지 몇 가지 계층을 거쳐 동작합니다 (WebGPU API - Web APIs | MDN) (WebGPU API - Web APIs | MDN):
-
물리 GPU와 네이티브 API: 실제 하드웨어인 GPU는 각 운영체제의 네이티브 GPU API(Direct3D, Metal, Vulkan 등)를 통해 제어됩니다. OS의 드라이버가 이 API 호출을 받아 GPU 작업을 수행하지요 (WebGPU API - Web APIs | MDN). WebGPU는 여기까지는 직접 손대지 않고, 해당 OS API를 백엔드로 활용합니다.
-
브라우저의 WebGPU 구현체 (어댑터): 브라우저(또는 Node.js)는 WebGPU 표준을 구현한 엔진을 내장합니다. 이를 통해 WebGPU JS API 호출을 받아 적절한 네이티브 GPU API로 전달하는 역할을 합니다 (WebGPU API - Web APIs | MDN). WebGPU의 어댑터(adapter) 는 사용 가능한 물리 GPU 및 드라이버의 표현으로, 브라우저가 감지한 GPU 장치를 나타냅니다 (WebGPU API - Web APIs | MDN). 예를 들어 PC에 내장 GPU와 외장 GPU 두 개가 있다면, 두 개의 어댑터 중 하나를 선택할 수 있습니다.
-
디바이스(Device): WebGPU에서 GPU 디바이스는 실제 GPU를 웹 앱이 사용하도록 만든 가상화된 논리 장치입니다 (WebGPU API - Web APIs | MDN). 하나의 물리 GPU도 여러 앱이 동시에 쓸 수 있는데, 각 웹앱은 자신만의 논리 디바이스를 얻어 안전하게 GPU를 사용할 수 있습니다 (WebGPU API - Web APIs | MDN). WebGPU 디바이스 객체(
GPUDevice
) 를 통해 버퍼 생성, 명령 전달 등 모든 GPU 작업을 수행하게 됩니다 (WebGPU API - Web APIs | MDN) (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). -
큐(Queue)와 명령 버퍼(Command Buffer): GPU는 CPU와 독립적으로 동작하므로, WebGPU에서는 작업 지시를 명령 버퍼에 기록해 한꺼번에 GPU에 보내는 모델을 취합니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers) (Get started with GPU Compute on the web | Capabilities | Chrome for Developers).
GPUQueue
를 통해 커맨드 버퍼들을 GPU에 제출(submit)하면 GPU가 비동기로 처리합니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers) (Get started with GPU Compute on the web | Capabilities | Chrome for Developers). 이로써 CPU는 GPU 작업을 맡긴 뒤 다른 일을 할 수 있어 병렬 처리가 극대화됩니다. -
셰이더(Shader)와 파이프라인(Pipeline): WebGPU에서 그래픽 및 계산 동작은 셰이더 프로그램으로 정의되고 GPU에서 실행됩니다. WebGPU는 자체 셰이더 언어인 WGSL (WebGPU Shading Language) 을 사용하는데, C 스타일 문법으로 벡터/행렬 연산 등에 최적화되어 있습니다 (WebGPU - Wikipedia). WebGPU에서는 렌더 파이프라인(Render Pipeline) 과 컴퓨트 파이프라인(Compute Pipeline) 두 종류의 파이프라인을 정의합니다.
-
렌더 파이프라인은 버텍스 셰이더 + 프래그먼트 셰이더 + 래스터화 등 그래픽 렌더링 상태를 모두 포함하는 객체입니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). WebGL에서는 프로그램 객체에 셰이더만 연결하고 나머지 상태는 글로버르게 설정했다면, WebGPU는 한 파이프라인에 해당 렌더링에 필요한 모든 설정을 캡슐화합니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). 파이프라인을 생성할 때 입력 정점 버퍼 레이아웃, 셰이더 코드, 렌더링 타겟의 픽셀 포맷, 블렌딩 옵션 등을 한꺼번에 지정합니다. 한번 파이프라인이 만들어지면, 매 프레임마다 이 파이프라인을 바인드하여 사용함으로써, 상태 변경 비용을 최소화하고 많은 객체도 효율적으로 그릴 수 있습니다 (WebGPU API - Web APIs | MDN). 또한 Render Bundle 등 기능을 통해 미리 명령 시퀀스를 녹화해두고 재사용하는 등 CPU 호출 부담을 줄이는 기능도 있습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers).
-
컴퓨트 파이프라인은 단일 컴퓨트 셰이더로 이루어진 파이프라인으로, 화면 출력 없이 범용 데이터 연산을 수행합니다. 예를 들어 행렬 곱셈, 물리 시뮬레이션, 이미지 필터 처리 같은 작업을 GPU의 병렬 연산으로 처리할 때 사용됩니다. WebGPU의 Compute Shader는 전통적인 CUDA 커널이나 OpenCL 커널과 유사하게, 다수의 스레드에서 병렬로 실행되며 workgroup 단위의 공유 메모리 등 GPU 연산에 특화된 기능을 제공합니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). WebGL에서도 GPGPU를 흉내내려면 프래그먼트 셰이더로 억지로 계산했지만 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers), WebGPU에선 컴퓨트 파이프라인을 통해 GPU를 일반 계산용으로 자연스럽게 활용할 수 있습니다.
정리하면, WebGPU의 내부 구조는 GPU 하드웨어 <- OS GPU API <- 브라우저의 WebGPU엔진 <- WebGPU 자바스크립트 API로 이루어져 있고 (WebGPU API - Web APIs | MDN) (Capturing the WebGPU ecosystem | Blog | Chrome for Developers), 개발자는 WebGPU API를 통해 디바이스, 파이프라인, 명령버퍼 등을 조작하여 GPU에게 일괄 작업 지시를 하는 방식으로 동작합니다. 이러한 설계는 현대 GPU의 동작 원리를 반영하여 고성능을 끌어내면서도, Web 환경의 보안과 편의성을 함께 고려한 것입니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers).
WebGPU와 WebAssembly와의 관계
WebGPU는 WebAssembly(WASM) 와도 밀접한 관계가 있습니다. WebAssembly는 브라우저에서 고성능 네이티브 코드를 실행하기 위한 이식성 높은 이진 포맷인데, WebGPU를 WebAssembly에서 호출할 수 있기 때문입니다. 즉, C/C++이나 Rust로 작성된 코드를 WebAssembly로 컴파일하여 브라우저에서 실행할 때, 해당 코드가 WebGPU C API를 통해 GPU를 사용할 수 있습니다 (Capturing the WebGPU ecosystem | Blog | Chrome for Developers). 실제로 W3C WebGPU 표준에는 C 헤더(webgpu.h
) 규격이 정의되어 있어, 각 언어에서 이 공통 C API를 바인딩하는 방식으로 WebGPU를 활용할 수 있습니다 (Capturing the WebGPU ecosystem | Blog | Chrome for Developers).
예를 들어 Emscripten(C/C++용 WebAssembly 컴파일러)은 WebGPU를 지원하므로, PC용으로 WebGPU를 사용해 만든 C++ 애플리케이션을 손쉽게 웹용으로 이식할 수 있습니다 (Capturing the WebGPU ecosystem | Blog | Chrome for Developers). 마찬가지로 Rust 진영에서도 wgpu 라이브러리를 통해 WebGPU를 사용한 코드를 작성하고, 이것을 wasm 타겟으로 컴파일하면 동일하게 브라우저에서 동작시킬 수 있습니다 (Capturing the WebGPU ecosystem | Blog | Chrome for Developers).
이러한 WebAssembly와의 결합 덕분에 WebGPU는 웹 밖의 생태계와도 연결됩니다. 즉, WebGPU는 단순한 자바스크립트 API가 아니라 WebAssembly와 함께 쓰여 언어 불문하고 GPU를 활용하는 범용 플랫폼으로 발전하고 있습니다 (Capturing the WebGPU ecosystem | Blog | Chrome for Developers) (Capturing the WebGPU ecosystem | Blog | Chrome for Developers). WebAssembly를 통해 성능이 중요한 로직을 작성하고, WebGPU로 병렬 처리를 함으로써 브라우저 안에 사실상 작은 GPU 가속 네이티브 앱을 구현하는 것이 가능해지고 있습니다.
실습 가이드
이제 WebGPU를 직접 사용해보는 방법을 알아보겠습니다. 환경 설정부터 기본 API 사용법, 그리고 간단한 그래픽/컴퓨팅 예제 코드까지 단계별로 실습을 진행합니다. WebGPU는 아직 비교적 신기술이므로 실습을 위해서는 지원 환경을 갖추는 것이 중요합니다.
WebGPU 환경 설정 (크로미움 기반 브라우저, Node.js)
브라우저 환경: 현재(2025년 초 기준) WebGPU는 Chromium 계열 브라우저인 Google Chrome(버전 113 이상) 과 Microsoft Edge(113 이상) 에서 기본 지원됩니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). Windows, macOS, ChromeOS 등에서 최신 크롬/엣지를 사용하면 별도 플래그 없이 WebGPU를 사용할 수 있습니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). 다만 리눅스와 안드로이드의 경우 정식 지원이 조금 늦었는데, 곧 지원이 추가되거나 실험 플래그를 통해 활성화할 수 있습니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). Safari는 기술 미리보기 버전에서 부분 지원 중이고, Firefox도 개발자 버전에서 구현을 진행하고 있습니다 (2023년까지는 정식 활성화 전이었습니다 (WebGPU - Wikipedia)). 브라우저 지원 여부는 navigator.gpu
객체의 존재로 확인할 수 있습니다. 예를 들어 콘솔에 navigator.gpu
를 입력해서 undefined
가 아니면 WebGPU를 사용할 준비가 된 것입니다.
만약 Chrome에서 WebGPU를 사용하는데 문제가 있다면, chrome://flags
페이지에서 *"Unsafe WebGPU" 또는 *"Enable WebGPU" 옵션을 찾아 Enabled로 설정하고 브라우저를 재시작해야 할 수 있습니다 (WebGPU… Better Than WebGL? | Hackaday). (최신 버전에선 기본 활성화되어 있을 가능성이 높습니다.) 개발 중이라 특정 버전에서는 원활하지 않을 수 있으므로, Chrome 최신 버전을 사용하는 것이 좋습니다.
Node.js 환경: WebGPU는 Node.js 20 버전부터 실험적으로 내장 지원되기 시작했습니다 (Capturing the WebGPU ecosystem | Blog | Chrome for Developers). Node.js에서는 브라우저의 navigator.gpu
대신 자체 모듈을 통해 WebGPU를 사용할 수 있는데, 크롬의 WebGPU 구현(Dawn)을 기반으로 동작합니다 (Capturing the WebGPU ecosystem | Blog | Chrome for Developers). Node 20 이상에서 --experimental-webgpu
플래그를 주어 실행하거나, 혹은 navigator.gpu
객체를 전역에 주입해주는 방법으로 사용할 수 있습니다 (Node 실행시 --experimental-global-webgpu
옵션). 또는 NPM 패키지인 webgpu
를 설치하여 (npm i webgpu
) WebGPU 기능을 불러올 수도 있습니다 (webgpu - NPM). 이 패키지는 내부적으로 Dawn 라이브러리를 바인딩하여 Node에서 WebGPU를 사용할 수 있게 해줍니다. Node 환경에서 WebGPU를 사용하면 브라우저 창 없이도 GPU 가속 연산을 수행할 수 있으므로, 서버 사이드에서 GPU를 활용하는 실험도 가능합니다.
요약하면, WebGPU 실습을 위해 크로미움 기반 브라우저(Chrome/Edge 최신 버전)나 Node.js 최신 버전을 준비해야 합니다. 여기서는 주로 브라우저를 기준으로 실습을 설명하겠습니다.
WebGPU API 기본 사용법
WebGPU API의 사용 흐름은 전통적인 그래픽 API와 유사하지만, 자바스크립트의 비동기 패턴(프라미스 등)을 사용한다는 점이 특징입니다. 기본적인 사용 단계는 다음과 같습니다:
-
어댑터 및 디바이스 획득: 먼저 브라우저에서 사용 가능한 GPU 어댑터(adapter) 를 요청하고, 선택된 어댑터로부터 디바이스(device) 를 생성합니다. 이 디바이스 객체가 이후 GPU 작업의 핵심 핸들입니다. 예시 코드를 살펴보겠습니다:
const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice();
위 코드로 얻은
device
를 통해 버퍼, 파이프라인 등을 만들게 됩니다. (requestAdapter()
나requestDevice()
는 Promise를 반환하므로await
혹은.then
으로 처리해야 합니다.) 어댑터를 얻지 못하면 (adapter
가 null) 해당 환경에선 WebGPU를 지원하지 않는 것이니, 폴백을 고려해야 합니다. -
캔버스 컨텍스트 구성 (그래픽의 경우): WebGPU로 그래픽을 출력하려면 HTML
<canvas>
엘리먼트와 연결된 GPUCanvasContext가 필요합니다. 이는canvas.getContext('webgpu')
로 얻습니다 (WebGPU API - Web APIs | MDN). 컨텍스트를 얻은 후context.configure({...})
메서드로 렌더링 설정을 해야 합니다 (WebGPU API - Web APIs | MDN). 구성 옵션에는 사용할device
, 출력 텍스처 포맷(format), 알파블렌딩 모드 등이 있습니다. 예를 들면 다음과 같습니다:const canvas = document.querySelector('canvas'); const context = canvas.getContext('webgpu'); context.configure({ device: device, format: navigator.gpu.getPreferredCanvasFormat(), alphaMode: 'premultiplied' });
위에서는
getPreferredCanvasFormat()
으로 브라우저 권장 포맷을 선택했습니다 (WebGPU API - Web APIs | MDN). 이렇게 하면 이 캔버스에 WebGPU가 그릴 준비가 완료됩니다. -
GPU 리소스 생성 (버퍼, 셰이더 등): GPU에 보낼 데이터는 버퍼(Buffer) 또는 텍스처(Texture) 로 만들어야 합니다. 예를 들어 삼각형의 정점 데이터를 전달하려면 정점 배열을 Float32Array 등으로 만들고,
device.createBuffer()
로 GPU 버퍼를 생성합니다. 이때usage
플래그로 이 버퍼가 어떻게 사용될지 지정해야 합니다 (정점용, 유니폼용, 저장용 등). 간단한 예시를 살펴보겠습니다:const vertexData = new Float32Array([ // x, y, z, r, g, b for 3 vertices 0.0, 0.5, 0.0, 1,0,0, // vertex1: pos + color -0.5,-0.5, 0.0, 0,1,0, // vertex2 0.5,-0.5, 0.0, 0,0,1 // vertex3 ]); const vertexBuffer = device.createBuffer({ size: vertexData.byteLength, usage: GPUBufferUsage.VERTEX, mappedAtCreation: true }); // 버퍼에 데이터 초기값 쓰기 new Float32Array(vertexBuffer.getMappedRange()).set(vertexData); vertexBuffer.unmap();
위 코드는 3개의 정점 위치와 색상이 담긴 배열을 만들고, 정점 버퍼로 GPU에 올리는 과정입니다.
mappedAtCreation: true
로 지정하면 CPU에서 쓸 수 있는 배열 버퍼를 얻을 수 있고, 거기에 데이터를 복사한 뒤unmap()
하여 GPU에서 읽을 수 있게 합니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers) (Get started with GPU Compute on the web | Capabilities | Chrome for Developers). WebGPU에서는 CPU와 GPU 메모리 동시접근을 피하기 위해 이렇게 명시적으로 맵/언맵 과정을 거칩니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers) (Get started with GPU Compute on the web | Capabilities | Chrome for Developers).또한 셰이더 코드도 준비해야 합니다. WebGPU에서는 WGSL로 셰이더를 작성하며, 자바스크립트 소스 내에 문자열로 넣거나 별도 파일에서 불러올 수 있습니다. 예를 들어 위의 정점 데이터에 대응하는 간단한 셰이더 예시는 다음과 같습니다 (정점 셰이더에서 입력 위치를 그대로 출력 위치로 삼고, 색상 데이터를 프래그먼트로 넘겨 그대로 출력):
struct VertexOut { @builtin(position) position : vec4<f32>, @location(0) color : vec4<f32> }; @vertex fn vs_main(@location(0) inPos: vec4<f32>, @location(1) inColor: vec4<f32>) -> VertexOut { var out : VertexOut; out.position = inPos; out.color = inColor; return out; } @fragment fn fs_main(in: VertexOut) -> @location(0) vec4<f32> { return in.color; }
이 WGSL 코드에서
@location(0)
으로 정점 입력 위치를,@location(1)
으로 색상을 받도록 했습니다. 이 문자열을device.createShaderModule({code: shaders})
로 모듈화하면 WebGPU에서 사용 가능한 셰이더 객체가 됩니다 (WebGPU API - Web APIs | MDN). -
파이프라인 생성: 이제 RenderPipeline을 생성하여 셰이더와 렌더 상태를 결합합니다. 파이프라인 생성은 WebGPU에서 가장 복잡한 부분 중 하나지만, 기본적인 경우는 자동 레이아웃을 사용해 비교적 간단히 만들 수 있습니다. 다음은 위의 셰이더를 이용한 파이프라인 생성 예시입니다:
const pipeline = device.createRenderPipeline({ layout: 'auto', // 자동으로 파이프라인 레이아웃 생성 vertex: { module: shaderModule, entryPoint: 'vs_main', // 정점 버퍼 구조 기술 buffers: [{ arrayStride: 6 * 4, // float32 6개 (포지션3 + 컬러3) attributes: [ { shaderLocation: 0, offset: 0, format: 'float32x4' }, // position (vec4) { shaderLocation: 1, offset: 4*4, format: 'float32x2' } // color (vec2)? ] }] }, fragment: { module: shaderModule, entryPoint: 'fs_main', targets: [{ format: navigator.gpu.getPreferredCanvasFormat() }] }, primitive: { topology: 'triangle-list' } });
위 코드는
vertex.buffers
에서 정점 버퍼의 메모리 배치를 정의하고 (arrayStride
는 한 정점의 바이트 크기,attributes
는 셰이더 로케이션과 오프셋), 프래그먼트 출력은 캔버스 포맷에 맞춘 것을 지정했습니다.primitive.topology
는 우리가 그릴 도형이 삼각형 목록임을 의미합니다.layout: 'auto'
는 바인드 그룹 레이아웃 등을 자동 설정하게 해줍니다. (만약 유니폼이나 스토리지 버퍼를 셰이더에서 쓴다면 명시적으로 레이아웃을 정의해야 합니다.)컴퓨트 파이프라인의 경우
device.createComputePipeline({ compute: { module, entryPoint: ... } })
로 생성하며, 렌더 파이프라인과 달리 버텍스/프래그먼트 구성이 없고 대신compute
단계만 지정합니다. -
명령 인코딩 및 제출: GPU 작업을 수행하려면 명령 버퍼에 구체적인 드로잉/연산 명령을 기록해야 합니다. 렌더링의 경우
device.createCommandEncoder()
로 CommandEncoder를 만들고, 거기서encoder.beginRenderPass({...})
로 렌더 패스(RenderPassEncoder) 를 시작합니다. 이때 어떤 색상 버퍼에 그릴지 등 정보를 제공해야 하는데, 일반적으로context.getCurrentTexture()
로 현재 캔버스의 텍스처를 얻고, 그것의createView()
로 뷰를 만들어 colorAttachment로 지정합니다. 다음은 간략한 예시입니다:const commandEncoder = device.createCommandEncoder(); const textureView = context.getCurrentTexture().createView(); const renderPass = commandEncoder.beginRenderPass({ colorAttachments: [{ view: textureView, clearValue: { r: 0.0, g: 0.0, b: 0.2, a: 1.0 }, // 파란색 배경 loadOp: 'clear', storeOp: 'store' }] }); renderPass.setPipeline(pipeline); renderPass.setVertexBuffer(0, vertexBuffer); renderPass.draw(3, 1, 0, 0); // 정점 3개 그리기 renderPass.end(); const commandBuffer = commandEncoder.finish(); device.queue.submit([commandBuffer]);
위에서는 배경을 파란색(clear)으로 지우고 삼각형을 하나 그리는 명령을 기록했습니다.
setPipeline
으로 사용할 파이프라인을 바인드하고,setVertexBuffer
로 아까 만든 정점 버퍼를 슬롯 0에 연결한 뒤,draw
로 3개의 정점을 그리도록 했습니다. 그리고 renderPass를.end()
로 종료하고, encoder를.finish()
하여 명령 버퍼를 얻은 뒤,device.queue.submit
에 제출하면 GPU가 이 명령을 실행하여 캔버스에 삼각형이 렌더링됩니다.Compute의 경우에는
encoder.beginComputePass()
로 ComputePassEncoder를 얻고, 유사하게pass.setPipeline(computePipeline)
,pass.setBindGroup(0, bindGroup)
(셰이더에 바인딩된 버퍼들 설정),pass.dispatchWorkgroups(x)
등의 명령을 기록합니다. 그리고.end()
로 종료하면 됩니다. ComputePass에서는 렌더링 대상이 없고 대신 결과를 버퍼에 쓰겠죠.WebGPU에서는 모든 명령 실행이 비동기로 이뤄지므로,
submit
한 직후에는 GPU가 작업을 끝내지 않은 상태입니다. 결과를 읽으려면 (예: 연산 결과 버퍼를 CPU에서 읽기)buffer.mapAsync(GPUMapMode.READ)
등의 프라미스를 통해 GPU 연산이 완료되기를 기다려야 합니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers).
이상의 흐름을 요약하면, WebGPU 기본 사용 패턴은: 디바이스 준비 → 리소스 준비(버퍼, 셰이더 등) → 파이프라인 구성 → 명령 기록 및 제출 순서입니다. 처음에는 진입장벽이 있어 보이지만, 하나씩 따라가다 보면 WebGPU의 저수준 동작을 이해하면서 GPU를 직접 다루는 경험을 할 수 있습니다.
기초 그래픽 실습: 삼각형 그리기 예제
위에서 설명한 절차를 이용해 간단한 그래픽 예제를 실습해보겠습니다. 목표는 파란 캔버스 배경에 컬러 삼각형 하나를 그려보는 것입니다. 이 예제는 그래픽스 프로그래밍의 "Hello Triangle"에 해당하며, WebGPU에서도 기본적인 단계들을 익히기에 좋습니다.
-
HTML 설정: HTML 파일에
<canvas id="gpuCanvas" width="640" height="480"></canvas>
를 추가하고,<script type="module" src="main.js"></script>
로 자바스크립트 파일을 불러옵니다. (WebGPU는 최신 기능이므로 type="module"로 ES6 모듈 환경에서 사용하는 것을 권장합니다.) -
디바이스 초기화 (
main.js
):const canvas = document.getElementById('gpuCanvas'); if (!navigator.gpu) { alert("이 브라우저는 WebGPU를 지원하지 않습니다."); } const adapter = await navigator.gpu.requestAdapter(); const device = await adapter.requestDevice(); const context = canvas.getContext('webgpu'); context.configure({ device: device, format: navigator.gpu.getPreferredCanvasFormat(), alphaMode: 'opaque' });
먼저 캔버스의 WebGPU 컨텍스트를 구성합니다. (alphaMode를 'opaque'로 해서 캔버스의 알파채널을 무시하도록 설정.)
-
정점 데이터 및 버퍼 준비:
const vertices = new Float32Array([ // x, y, z, r, g, b 0.0, 0.5, 0.0, 1.0, 0.0, 0.0, // 상단 정점 (빨강) -0.5, -0.5, 0.0, 0.0, 1.0, 0.0, // 좌하단 정점 (초록) 0.5, -0.5, 0.0, 0.0, 0.0, 1.0 // 우하단 정점 (파랑) ]); const vertexBuffer = device.createBuffer({ size: vertices.byteLength, usage: GPUBufferUsage.VERTEX, mappedAtCreation: true }); new Float32Array(vertexBuffer.getMappedRange()).set(vertices); vertexBuffer.unmap();
3개의 정점 위치와 색상을 포함하는 배열을 만들고, GPU에 정점 버퍼로 올립니다.
-
WGSL 셰이더 작성 및 모듈 생성:
const shaderCode = ` struct VertexOut { @builtin(position) position : vec4<f32>, @location(0) color : vec4<f32> }; @vertex fn vs_main(@location(0) pos: vec3<f32>, @location(1) color: vec3<f32>) -> VertexOut { var out: VertexOut; out.position = vec4<f32>(pos, 1.0); out.color = vec4<f32>(color, 1.0); return out; } @fragment fn fs_main(in: VertexOut) -> @location(0) vec4<f32> { return in.color; }`; const shaderModule = device.createShaderModule({ code: shaderCode });
WGSL로 간단한 정점/프래그먼트 셰이더를 작성합니다. 정점 셰이더는 입력으로 위치와 색상을 받아 (
@location(0)
,@location(1)
), 출력으로position
내장 변수와 보간될 color를 설정합니다. 프래그먼트 셰이더는 인터폴레이트된 color를 그대로 출력합니다. 이 코드를 ShaderModule로 생성합니다. -
렌더 파이프라인 생성:
const pipeline = device.createRenderPipeline({ layout: 'auto', vertex: { module: shaderModule, entryPoint: 'vs_main', buffers: [{ arrayStride: 6 * 4, attributes: [ { shaderLocation: 0, offset: 0, format: 'float32x3' }, { shaderLocation: 1, offset: 3 * 4, format: 'float32x3' } ] }] }, fragment: { module: shaderModule, entryPoint: 'fs_main', targets: [{ format: navigator.gpu.getPreferredCanvasFormat() }] }, primitive: { topology: 'triangle-list' } });
이 파이프라인 설정은 정점 버퍼의 구조(스트라이드 24바이트, 첫 12바이트는 position, 다음 12바이트는 color)를 지정하고 셰이더를 연결합니다. primitive.topology를 'triangle-list'로 설정해 세 정점을 하나의 삼각형으로 그리도록 합니다.
-
명령 버퍼 레코딩 및 제출:
const commandEncoder = device.createCommandEncoder(); const textureView = context.getCurrentTexture().createView(); const renderPass = commandEncoder.beginRenderPass({ colorAttachments: [{ view: textureView, clearValue: { r: 0, g: 0, b: 0.2, a: 1 }, loadOp: 'clear', storeOp: 'store' }] }); renderPass.setPipeline(pipeline); renderPass.setVertexBuffer(0, vertexBuffer); renderPass.draw(3, 1, 0, 0); renderPass.end(); const commandBuffer = commandEncoder.finish(); device.queue.submit([commandBuffer]);
여기까지 실행하면, 캔버스에 배경이 남색(0,0,0.2)으로 칠해지고 삼각형이 렌더링됩니다. 결과를 확인하여 빨강-초록-파랑 색상의 삼각형이 제대로 보이는지 확인합니다.
이 예제를 통해 WebGPU에서 그래픽 파이프라인 설정과 드로우 콜의 흐름을 경험했습니다. WebGL에 익숙한 개발자라면 초기화와 파이프라인 설정이 다소 장황하게 느껴질 수 있지만, 한번 파이프라인이 설정되면 이후에는 효율적으로 렌더링이 가능하다는 점을 기억해야 합니다 (WebGPU API - Web APIs | MDN). 더 복잡한 장면을 그릴 때는 이 파이프라인과 버퍼들을 적절히 조합하여 여러 개의 draw 호출을 한 프레임에 수행하면 됩니다.
기초 컴퓨팅 연산 예제 코드
WebGPU의 강력한 기능 중 하나는 GPGPU(범용 GPU 연산) 입니다. 이번에는 간단한 계산 예제로, WebGPU를 이용해 두 배열의 요소별 합을 계산해보겠습니다 (GPU를 이용한 벡터 합산).
-
입력 데이터와 버퍼 준비: 두 개의 입력 배열과 결과를 받을 배열을 준비하고 GPU 버퍼로 생성합니다.
const dataSize = 1024; const a = new Float32Array(dataSize); const b = new Float32Array(dataSize); for (let i = 0; i < dataSize; ++i) { a[i] = Math.random(); b[i] = Math.random(); } const gpuBufferA = device.createBuffer({ size: a.byteLength, usage: GPUBufferUsage.STORAGE, mappedAtCreation: true }); new Float32Array(gpuBufferA.getMappedRange()).set(a); gpuBufferA.unmap(); const gpuBufferB = device.createBuffer({ size: b.byteLength, usage: GPUBufferUsage.STORAGE, mappedAtCreation: true }); new Float32Array(gpuBufferB.getMappedRange()).set(b); gpuBufferB.unmap(); // 결과를 받을 버퍼 (초기 데이터 불필요) const resultBufferSize = a.byteLength; const gpuBufferResult = device.createBuffer({ size: resultBufferSize, usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC });
여기서는 STORAGE 용도로 버퍼를 생성했습니다. STORAGE는 셰이더에서 읽기/쓰기가 가능한 버퍼 타입입니다. 결과 버퍼는 나중에 CPU로 복사하기 위해 COPY_SRC 플래그도 추가했습니다.
-
Compute Shader 작성 (WGSL): 배열 원소의 합을 계산하는 간단한 셰이더를 작성합니다.
@group(0) @binding(0) var<storage, read> bufA : array<f32>; @group(0) @binding(1) var<storage, read> bufB : array<f32>; @group(0) @binding(2) var<storage, read_write> bufResult : array<f32>; @compute @workgroup_size(64) fn main(@builtin(global_invocation_id) GlobalId : vec3<u32>) { let index = GlobalId.x; if (index < arrayLength(&bufResult)) { bufResult[index] = bufA[index] + bufB[index]; } }
이 WGSL 코드는 세 개의 스토리지 버퍼를 바인딩해서, 같은 인덱스의 값을 더해 결과 버퍼에 저장합니다.
@builtin(global_invocation_id)
를 통해 현재 스레드의 전역 인덱스를 받아와 그에 해당하는 배열 원소를 처리합니다.@workgroup_size(64)
는 한 워크그룹에 64개의 스레드를 사용하겠다는 뜻입니다. -
Compute 파이프라인과 바인드 그룹 생성:
const computeModule = device.createShaderModule({ code: computeShaderCode }); const computePipeline = device.createComputePipeline({ layout: 'auto', compute: { module: computeModule, entryPoint: 'main' } }); const bindGroup = device.createBindGroup({ layout: computePipeline.getBindGroupLayout(0), entries: [ { binding: 0, resource: { buffer: gpuBufferA } }, { binding: 1, resource: { buffer: gpuBufferB } }, { binding: 2, resource: { buffer: gpuBufferResult } } ] });
컴퓨트 파이프라인을 생성하고, 셰이더에서 정의한 binding 0,1,2에 대응하는 버퍼들을 BindGroup으로 묶습니다.
layout: 'auto'
를 사용했으므로getBindGroupLayout(0)
으로 자동 생성된 레이아웃을 받아 사용합니다. -
명령 버퍼 작성 및 디스패치:
const commandEncoder = device.createCommandEncoder(); const passEncoder = commandEncoder.beginComputePass(); passEncoder.setPipeline(computePipeline); passEncoder.setBindGroup(0, bindGroup); // 전체 데이터 크기만큼 워크그룹 디스패치 (1024개 요소, workgroup_size 64 -> 16 workgroups 필요) passEncoder.dispatchWorkgroups(Math.ceil(dataSize / 64)); passEncoder.end(); // GPU에서 결과를 읽을 수 있도록 복사 명령 추가 const gpuReadBuffer = device.createBuffer({ size: resultBufferSize, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ }); commandEncoder.copyBufferToBuffer(gpuBufferResult, 0, gpuReadBuffer, 0, resultBufferSize); const commands = commandEncoder.finish(); device.queue.submit([commands]);
여기서
dispatchWorkgroups(n)
으로 컴퓨트 셰이더를 실행합니다.n
은 워크그룹 개수로, 요소 1024개를 64개씩 처리하려면 16개의 워크그룹이 필요하여Math.ceil(1024/64)=16
을 지정했습니다. computePass를 끝낸 후에는, 결과를 읽기 위해gpuBufferResult
내용을gpuReadBuffer
로 복사했습니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers). 이제 CPU에서gpuReadBuffer
를 매핑하여 읽으면 됩니다:await gpuReadBuffer.mapAsync(GPUMapMode.READ); const arrayBuffer = gpuReadBuffer.getMappedRange(); const resultArray = new Float32Array(arrayBuffer); console.log("첫 10개 결과: ", resultArray.slice(0, 10)); gpuReadBuffer.unmap();
mapAsync
가 resolve된 이후에getMappedRange()
를 호출하면 GPU가 쓴 데이터를 읽을 수 있습니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers). -
검증: CPU에서 동일한 계산을 수행한 결과와 GPU 결과 배열을 비교해봅니다. 두 결과가 동일하다면 WebGPU를 이용한 GPGPU 계산이 성공적으로 수행된 것입니다. 이 예제에서는 단순한 덧셈이지만, 더 복잡한 연산(예: 행렬 곱셈)도 유사한 패턴으로 구현할 수 있습니다. 실제로 WebGPU Compute Shader를 사용하면 대량의 행렬 연산도 병렬화하여 CPU 대비 훨씬 빠르게 수행할 수 있으며 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers), 이는 머신러닝의 기초 연산들을 가속화하는데 응용될 수 있습니다.
머신러닝과의 연계 실습 (TensorFlow.js 예시)
WebGPU의 GPGPU 능력은 머신러닝/딥러닝 분야에서도 유용합니다. 웹에서 머신러닝을 수행할 때 많이 사용되는 TensorFlow.js는 기존에 WebGL을 사용해왔는데, 최근 버전에서는 WebGPU 백엔드를 제공하여 학습 및 추론을 가속화하고 있습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). TensorFlow.js에서 WebGPU를 사용해보는 간단한 방법을 소개합니다.
먼저 TensorFlow.js 라이브러리와 WebGPU 백엔드 패키지를 설치하거나 불러옵니다. CDN 스크립트를 이용한다면 다음과 같이 HTML에 포함합니다:
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@4"></script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-backend-webgpu@0.4"></script>
(버전 번호는 예시이며, 실제 최신버전으로 사용하세요.) 이렇게 하면 TFJS와 WebGPU 백엔드가 로드됩니다.
그런 다음 자바스크립트에서 WebGPU 백엔드로 초기화합니다:
// TensorFlow.js를 WebGPU 백엔드로 초기화
tf.setBackend('webgpu'); // WebGPU 백엔드를 선택
await tf.ready(); // 백엔드 초기화가 완료될 때까지 대기
console.log(tf.getBackend()); // 'webgpu' 확인
위 코드에서 tf.setBackend('webgpu')
로 WebGPU를 사용하도록 지정하고, await tf.ready()
를 호출하여 백엔드가 준비될 때까지 기다립니다 (How to activate webgpu backend on Tensorflow.JS - Stack Overflow) (How to activate webgpu backend on Tensorflow.JS - Stack Overflow). (WebGPU 백엔드는 초기화에 시간이 조금 걸릴 수 있습니다.)
이제 TensorFlow.js에서 GPU 가속을 자동으로 WebGPU로 이용합니다. 예를 들어 간단한 행렬 곱셈을 실행해보겠습니다:
const mat1 = tf.randomNormal([1000, 1000]);
const mat2 = tf.randomNormal([1000, 1000]);
console.time('matmul');
const result = mat1.matMul(mat2);
await result.data(); // 실제 계산 실행 및 결과를 CPU로 가져오기
console.timeEnd('matmul');
위 코드에서 matMul
연산은 WebGPU 상에서 병렬로 수행되고, .data()
를 호출하는 시점에 GPU에서 계산이 이루어집니다. WebGL backend 대비 WebGPU backend에서는 이 연산이 훨씬 빠르게 완료됨을 확인할 수 있습니다. 실제로 Google I/O 2023에서 발표된 바에 따르면, TensorFlow.js의 이미지 디퓨전 모델을 WebGL에서 WebGPU로 옮겼더니 약 3배 성능 향상이 있었다고 합니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). 이는 WebGPU의 컴퓨트 셰이더가 WebGL의 제한을 없애주었기 때문인데, WebGL에서는 텍스처로 우회하던 연산을 WebGPU에서는 곧장 메모리에 접근하여 수행하므로 불필요한 데이터 포맷 변환과 복사가 줄어듭니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers).
TensorFlow.js 외에도, ONNX.js나 WebDNN 등 다른 웹 ML 프레임워크들도 향후 WebGPU 지원을 추가하거나, 커스텀 WebGPU 커널을 통해 성능 개선을 도모하고 있습니다. WebGPU를 활용하면 브라우저에서 딥러닝 학습까지는 아니어도 실시간 추론이나 간단한 파인튜닝 정도는 실현 가능한 시대가 열리고 있습니다. WebGPU를 통한 머신러닝 실습으로 예를 들면, 간단한 신경망을 만들어 훈련시켜보거나, 사전 학습된 모델(MobileNet 등)의 추론 속도를 WebGL vs WebGPU로 비교해보는 것도 좋은 경험이 될 것입니다.
활용 사례
이제 WebGPU가 실제로 어떻게 활용되는지 대표적인 사례들을 알아보겠습니다. WebGPU는 그래픽과 병렬 연산 능력을 모두 갖추고 있어 머신러닝, 데이터 시각화, 게임/3D 그래픽 등 다양한 분야에서 가능성을 열어주고 있습니다.
머신러닝 / 딥러닝 가속
WebGPU의 등장은 브라우저 상에서 돌아가는 머신러닝의 성능을 크게 끌어올리고 있습니다. 앞서 실습에서 다룬 것처럼, TensorFlow.js는 WebGPU 백엔드를 통해 신경망 연산을 가속화합니다. 복잡한 딥러닝 모델(예: 이미지 분류, 스타일 트랜스퍼, GAN 등)의 추론(inference) 은 물론, 경량 모델의 학습(training) 도 WebGPU를 통해 웹에서 수행 가능해졌습니다. 이는 WebGL 시절에는 제한적으로 가능하던 것을 큰 폭으로 확장한 것입니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers).
예를 들어, Stable Diffusion과 같은 딥러닝 기반 이미지 생성 모델을 WebGPU로 브라우저에서 돌려보는 실험들이 이뤄지고 있습니다. 아직 최첨단 대형 모델을 실시간으로 구동하기에는 한계가 있지만, 이미지 처리나 간단한 신경망 추론의 경우 WebGPU가 CPU 대비 수십 배 이상의 속도 향상을 보여줍니다. 앞서 언급했듯이 TensorFlow.js 팀은 이미지 생성 모델을 WebGPU로 포팅하여 WebGL 대비 3배 이상 빠른 성능을 확인하였습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). 특히 WebGPU는 컴퓨트 셰이더로 Shared memory 같은 기능을 활용할 수 있어, WebGL로는 구현 어려웠던 최적화 기법들을 적용할 수 있습니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers).
또한 WebGPU는 브라우저에서 WebNN API와 조합되어 사용될 전망도 있습니다. WebNN은 딥러닝 추론에 특화된 웹 API인데, 내부적으로 WebGPU를 사용하도록 설계되어 있습니다. 이를 통해 브라우저 상에서 TensorCore나 Apple Neural Engine 같은 전용 AI 하드웨어까지 활용하는 길이 열리고 있습니다.
요약하면, 머신러닝/딥러닝 분야에서 WebGPU는 "브라우저를 머신러닝 플랫폼으로" 바꾸어놓고 있습니다. 사용 사례로는:
- 브라우저에서 실시간 영상/음성 처리 (예: 가상 배경 제거, 음성 인식) 가속
- 웹 기반 AutoML 또는 데이터 분석 도구에서 대규모 연산 가속
- 분산되지 않은 Federated Learning 시나리오에서, 각 클라이언트 브라우저에서 모델 학습 수행 등
이러한 활용이 가능해지면서, 웹에서 머신러닝을 하는 시대가 성큼 다가오고 있습니다.
데이터 시각화 (대규모 데이터 렌더링)
대용량 데이터를 시각화하는 일은 기존에는 주로 전용 데스크탑 앱이나 GPU 지원이 있는 네이티브 환경에서 이루어졌습니다. WebGPU는 웹에서도 방대한 데이터를 GPU의 힘으로 렌더링하고 실시간 상호작용할 수 있게 해줍니다.
예를 들어 수백만 개의 데이터 포인트를 포함한 산점도나, 거대한 그래프 네트워크를 시각화한다고 생각해봅시다. CPU로는 매우 힘든 작업이지만, WebGPU를 사용하면 GPU의 수천 개 코어를 이용해 이러한 데이터들을 병렬 처리하고 화면에 뿌릴 수 있습니다. Compute Shader를 이용하면 시각화에 필요한 전처리나 계산(예: 군집화, 이상치 탐지 등)도 GPU에서 수행한 후 결과를 렌더링하는 것도 가능합니다. 실제로 WebGPU의 스토리지 버퍼와 컴퓨트 셰이더를 이용하면 대용량 데이터에 대한 임의의 병렬 계산을 수행할 수 있어, 복잡한 데이터 시각화 연산을 단순화해줍니다 ([PDF] Interactive Visualization of Terascale Data in the Browser).
구체적인 활용 사례로, 지리 정보 시각화를 들 수 있습니다. 수십만 개의 좌표 데이터를 3D 지도로 표현하거나, 시계열로 변화하는 데이터를 애니메이션으로 보여줄 때 WebGPU는 그 진가를 발휘합니다. 기존 WebGL 기반의 예로 deck.gl 같은 라이브러리는 GPU로 많은 양의 데이터를 그려주지만, WebGPU를 사용하면 더 큰 데이터세트도 처리할 수 있고, GPU 계산을 통해 클라이언트에서 데이터 가공도 수행할 수 있게 됩니다. 일례로, 연구에 따르면 WebGPU를 활용해 테라바이트급의 과학 데이터를 브라우저에서 시각화하는 가능성도 논의되고 있습니다 ([PDF] Interactive Visualization of Terascale Data in the Browser).
또한 볼륨 렌더링, 의료 영상 시각화 등 3차원 데이터 셋을 다루는 분야에서도 WebGPU는 웹 기반 솔루션을 촉진시킬 것입니다. 의료 영상(CT/MRI) 3D 볼륨을 WebGPU로 렌더링하거나, 점진적 수준별 세부 표현(LOD)을 GPU 계산으로 구현하여 대규모 점군(point cloud)을 실시간 탐색하는 등의 응용이 가능합니다.
요약하면, WebGPU는 웹에서 대규모 데이터 시각화를 가능케 하는 게임체인저로, 그 병렬 데이터 처리 능력과 고성능 렌더링으로 인해 웹 대시보드, BI 툴, 과학 시각화 등에서 활발히 활용될 것으로 기대됩니다.
게임 및 3D 그래픽
WebGPU의 출현은 웹 기반 게임과 3D 그래픽 분야에도 큰 영향을 줍니다. WebGL로도 많은 웹게임과 3D 콘텐츠가 제작되어왔지만, 성능 면에서 네이티브에 비해 제약이 있었던 것이 사실입니다. WebGPU는 이러한 격차를 줄이고 웹에서도 콘솔/PC 게임에 가까운 그래픽 효과와 성능을 구현하도록 해줍니다.
우선, 그래픽 품질 측면에서 WebGPU는 상향식의 최신 그래픽 API 기능을 제공하므로, WebGL로는 힘들었던 여러 효과들을 지원합니다. 예를 들어 계산 셰이더 기반 파티클 시스템이나 실시간 후처리 효과(블룸, 모션블러, 피사계심도) 등을 WebGPU를 통해 구현할 수 있습니다 (WebGPU API - Web APIs | MDN). 또한 다수의 조명, 그림자, 복잡한 쉐이더 계산도 GPU의 성능을 최대한 활용하여 처리할 수 있어, 장면의 디테일과 스케일을 키울 수 있습니다. GPU 상에서의 애니메이션 스킨닝이나 프러스텀 컬링 등도 지원되므로, 캐릭터가 많은 게임에서도 CPU 병목을 줄일 수 있습니다 (WebGPU API - Web APIs | MDN).
성능 측면에서도 WebGPU는 드로우콜 수 처리에 유리하고 CPU 부하를 줄여주므로, 복잡한 3D 씬에서 프레임레이트 향상을 기대할 수 있습니다 (WebGPU API - Web APIs | MDN). WebGPU의 파이프라인 구조는 한 번 세팅해두면 상태 변경 오버헤드가 낮아서, 수천 개 이상의 오브젝트를 그리는 상황도 WebGL보다 유리하게 처리합니다. 게다가 앞서 언급된 Render Bundle이나 명령 버퍼 재사용 기법은 많은 물체를 그릴 때 CPU->GPU 호출을 줄여줘, 대규모 인스턴싱 렌더링 등에 효과적입니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers).
현재 주요 웹 3D 엔진들도 속속 WebGPU를 지원하고 있습니다. Babylon.js는 이미 정식으로 WebGPU 렌더러를 지원하고 있고 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon), Three.js도 실험적인 WebGPU 렌더러 옵션을 제공하여 개발자들이 시험해볼 수 있습니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). 게임 엔진 Unity는 2023.2 버전에 초기 WebGPU 지원을 선보였으며, Unreal Engine 역시 향후 WebGPU 지원을 검토하고 있습니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). 이러한 엔진들의 지원으로, 앞으로 웹으로 내보내는 게임/그래픽 애플리케이션은 WebGPU를 기본 타겟으로 삼을 가능성이 높습니다. 이는 웹에서 돌아가는 게임이 그래픽 품질이나 규모 면에서 한층 도약할 수 있음을 의미합니다.
또 다른 활용 사례로 픽셀 스트리밍 없이 직접 웹에서 고품질 3D를 구현하는 것이 있는데, 예를 들어 자동차 쇼케이스나 건축물 시각화 같은 분야에서 WebGPU를 이용하면 별도 플러그인 없이도 사실적인 3D 렌더링을 제공할 수 있습니다. 또한 VR/AR (WebXR API와 결합) 콘텐츠에서도 WebGPU의 고성능은 더 현실감있는 경험을 뒷받침할 것입니다.
정리하면, 게임/3D 그래픽 분야에서 WebGPU는 *"웹을 완전한 3D 플랫폼으로 격상"*시키는 역할을 합니다. 고사양 그래픽, 물리 시뮬레이션, 복잡한 장면 구성도 이제 웹에서 가능해지며, 이는 개발자들에게 플랫폼에 구애받지 않는 배포의 자유로움과 사용자들에게 설치 없이 즉시 이용 가능한 고퀄리티 콘텐츠를 제공한다는 큰 이점을 가져옵니다.
참고 자료
WebGPU에 대해 더 깊이 공부하고 싶다면 아래 공식 문서, 레퍼런스, 튜토리얼 및 오픈소스 프로젝트를 참고하시기 바랍니다:
-
W3C WebGPU 공식 사양: WebGPU 표준 초안 문서로, WebGPU의 모든 API와 동작을 정의합니다 (WebGPU - Wikipedia). 상세한 내용이 담겨 있지만 난이도가 높으므로 필요한 부분을 찾아보는 참고용으로 권장합니다.
-
MDN WebGPU 문서: Mozilla 개발자 네트워크의 WebGPU 가이드로, WebGPU의 개념 설명과 간단한 코드 예제가 정리되어 있습니다 (WebGPU API - Web APIs | MDN). *“WebGPU API: MDN”*을 검색해서 전체 개요와 하위 API 문서를 살펴보세요.
-
Chrome Developers 블로그 (WebGPU): Google Chrome 팀에서 WebGPU 관련하여 올린 블로그 글들로, WebGPU 출시 소식 및 사용법, 사례 등이 잘 정리되어 있습니다. 특히 *“WebGPU: Unlocking modern GPU access in the browser”*라는 글은 WebGPU의 배경과 장점을 설명하고 있어 읽어볼 만 합니다 (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers) (WebGPU: Unlocking modern GPU access in the browser | Blog | Chrome for Developers). 또한 “Get started with GPU Compute on the web” 튜토리얼에서는 WebGPU 컴퓨트 셰이더로 행렬 곱셈을 구현하는 과정을 상세히 다룹니다 (Get started with GPU Compute on the web | Capabilities | Chrome for Developers) (Get started with GPU Compute on the web | Capabilities | Chrome for Developers).
-
HackerNoon - WebGL에서 WebGPU로 마이그레이션: WebGPU와 WebGL의 차이점을 한국어로 친절히 설명한 기사로, 초기화 방식, 파이프라인 개념 등의 비교를 다룹니다 (WebGL에서 WebGPU로 마이그레이션 | HackerNoon) (WebGL에서 WebGPU로 마이그레이션 | HackerNoon). WebGPU로 전환하려는 개발자에게 유용한 인사이트를 줍니다.
-
WebGPU 샘플 모음 (GitHub): GPUWeb GitHub 조직의 webgpu-samples 리포지토리에는 다양한 WebGPU 예제 코드들이 있습니다. 예를 들어 기본 삼각형 그리기부터, 계산 셰이더 예제, 실시간 광선추적 등 흥미로운 샘플들이 포함되어 있으므로, 소스코드를 참고하며 배울 수 있습니다.
-
WebGPU 기반 오픈소스 프로젝트:
-
Babylon.js: 대표적인 웹 3D 엔진으로 WebGPU를 지원합니다. 공식 문서에서 WebGPU 사용 방법과 제약사항 등을 안내합니다.
-
Three.js: WebGPU 렌더러가 구현 진행 중인 유명 3D 라이브러리입니다. 최신 릴리즈의 WebGPU 예제들을 통해 WebGPU 사용법을 엿볼 수 있습니다.
-
TensorFlow.js: 앞서 실습한대로 tfjs-backend-webgpu 패키지를 통해 WebGPU 가속을 사용합니다. GitHub 저장소에서 구현 상태와 지원 연산 목록 등을 확인할 수 있습니다.
-
wgpu (Rust): Rust용 WebGPU 구현체로, Rust 개발자들은 이를 이용해 네이티브 또는 웹용 GPU 코드를 작성합니다. wgpu 문서에는 Rust 관점에서 WebGPU의 개념과 사용법이 정리되어 있어 참고가 됩니다.
-
기타 학습 자료:
-
WebGPU Fundamentals: WebGL 입문서를 만든 Gregg Tavares가 운영하는 WebGPU 학습 사이트 (webgpufundamentals.org)로, 그림과 함께 단계별로 WebGPU 개념을 풀어 설명합니다.
-
Surma의 블로그 (surma.dev): 웹 기반 병렬 컴퓨팅에 관심이 많은 개발자 Surma의 글 *“WebGPU — All of the cores, none of the canvas”*는 WebGPU 컴퓨트 활용을 쉽게 풀어낸 글입니다 (WebGPU — All of the cores, none of the canvas - surma.dev).
-
유튜브 강좌 / 컨퍼런스 발표: “WebGPU Crash Course”, “Intro to WebGPU” 등의 영상 자료도 많이 나오고 있습니다. 공식 행사인 SIGGRAPH, Chrome Dev Summit 등의 WebGPU 세션도 찾아보면 도움이 됩니다.
이상의 자료를 통해 이론과 실제 코드를 함께 공부해보면, WebGPU의 개념부터 구현까지 폭넓게 이해하는 데 큰 도움이 될 것입니다. WebGPU는 발전 중인 분야이므로, 최신 동향을 문서와 커뮤니티를 통해 지속적으로 추적하며 학습하시길 권장합니다.
이 글은 OpenAI의 Deep Research 기능으로 정리한 글로, 참고 문헌의 내용 또는 의도와 다르게 정리된 내용이 있을 수 있습니다. 관심있는 내용이시라면 각 링크의 참고 문헌들도 함께 읽어주세요! 읽으시면서 어색하거나 잘못된 내용을 발견하시면 덧글로 알려주시기를 부탁드립니다.
파이토치 한국 사용자 모임
이 정리한 이 글이 유용하셨나요? 회원으로 가입하시면 주요 글들을 이메일
로 보내드립니다! (기본은 Weekly지만 Daily로 변경도 가능합니다.)
아래
쪽에 좋아요
를 눌러주시면 새로운 소식들을 정리하고 공유하는데 힘이 됩니다~