跪拜 Guibai
← All articles
JavaScript · React.js · Architecture

Loading a 1.5B-Parameter LLM in the Browser with WebGPU and Transformers.js

By Jasper_L ·
Read original on juejin.cn ↗ Google Translate ↗ Alt translation

Running a 1.5B-parameter reasoning model in a browser with no backend server eliminates the Python/CUDA dependency that gatekeeps local LLM experimentation. The Worker-thread pattern and progress-callback pitfall documented here are directly reusable for any browser-side ML project.

Summary

The dpsk-webgpu project demonstrates how to load the ONNX-converted DeepSeek-R1-Distill-Qwen-1.5B model directly in a browser tab. It uses React 19, TypeScript, and Tailwind CSS for the UI, with transformers.js as the sole dependency. Model weights are cached in the browser's Cache Storage, so subsequent loads skip the download entirely.

A Web Worker handles all heavy lifting—WebGPU detection, model downloading, and eventually inference—while the main thread manages only UI state. The two communicate through a simple postMessage protocol with status codes like 'webgpu-check', 'download', and 'ready'. A progress bar driven by transformers.js's progress_callback gives real-time download feedback, with a specific warning: only messages with status 'progress' carry a numeric percentage; the 'download' status is just a start notification and will break the bar if used.

The project's generate function is currently a stub that echoes input. The infrastructure—Worker channel, state management, GPU detection, and progress reporting—is complete and ready for real inference via tokenizer.encode and model.generate.

Takeaways
transformers.js loads ONNX models via WebGPU and caches weights in the browser's Cache Storage, so repeat loads are instant.
All model loading and inference must run in a Web Worker to prevent the main thread from freezing during multi-hundred-MB downloads.
WebGPU detection is a two-step check: navigator.gpu must exist, and requestAdapter() must return a non-null adapter.
The quantized dtype 'q4f16' compresses a 1.5B-parameter model to a few hundred MB, making browser downloads practical.
transformers.js's progress_callback emits multiple status types; only messages with status 'progress' contain a numeric progress field. Using the 'download' status will yield undefined and a stuck progress bar.
The Worker lifecycle requires both removeEventListener and terminate in the cleanup function to avoid memory leaks and stray error events.
The project's generate function is currently a stub; real inference will require wiring tokenizer.encode and model.generate into the existing Worker message protocol.
Conclusions

Browser-side LLM loading is now practical enough that the infrastructure—Worker channels, progress reporting, GPU detection—can be treated as a solved pattern and reused across projects.

The progress_callback pitfall with transformers.js is a sharp edge that will silently break any UI relying on download progress; the library's status naming ('download' vs 'progress') is misleading enough to warrant a warning in its own documentation.

Using a static singleton pattern for the pipeline inside a Worker ensures the model and tokenizer are loaded exactly once, which matters when the Worker stays alive for the page session.

Concepts & terms
WebGPU
A browser API that gives JavaScript direct access to the GPU for computation. Unlike WebGL, it's designed for general-purpose GPU workloads, not just graphics, making it suitable for ML inference.
transformers.js
Hugging Face's official JavaScript port of the Python transformers library. It loads ONNX-format models and runs inference via WebGPU or WASM backends, with an API that mirrors from_pretrained and AutoTokenizer.
Web Worker
A browser mechanism for running JavaScript on a background thread. It prevents computationally heavy tasks like model loading from blocking the main UI thread, and communicates with the main thread via postMessage.
ONNX
An open format for representing machine learning models. It allows models trained in frameworks like PyTorch to be exported and run in different environments, including browsers via transformers.js.
q4f16 quantization
A compression technique that stores model weights in 4-bit integers while performing computations in 16-bit floating point. It reduces model size to roughly one-quarter of the original, enabling multi-hundred-MB models to download and run in a browser.
Source: juejin.cn ↗ Google Translate ↗ Backup ↗