---
# System prepended metadata

title: 從微調到瀏覽器：JavaScript + WebGPU 加速 LLM 在瀏覽器運行實戰 - Wei
tags: [JSDC2025]

---

# 從微調到瀏覽器：JavaScript + WebGPU 加速 LLM 在瀏覽器運行實戰 - Wei

{%hackmd @JSDC-tw/B1loEcwJZl %}
###### tags: `JSDC2025`

:::warning 
本議程不提供錄影
:::

Slido：https://app.sli.do/event/48M22gQP21J2kVv2peyASA

Slide:
https://drive.google.com/file/d/1eHKnykorI9vkdSGtFydNc4_KZYqNbuAA/view?usp=sharing

> 開始做筆記

從 RAG 開始可以先了解 https://docs.unsloth.ai/

Phi 3 開始研究視覺辨識

---
## 前言（GenAI Era）

### 主流需求 → 個人化需求（Extreme personal experience）

![截圖_2025-11-29_晚上9.42.42](https://hackmd.io/_uploads/ByINko_Z-x.png)

在上一波 AI 技術，推薦系統的革命後，小眾需求的創造者跟需求端能夠更有效率媒合，因此開始越來越多的娛樂內容、SaaS 服務，滿足那些比較個人化、比較特殊的需求(癖好)。 

原本生產力工具上一直難以做到個人化，因為像客製化影片或專屬工具，都需要高昂製作成本。直到 2023 年 ChatGPT 出現後這個問題被解決，像是 Cursor、NotionAI、Custom GPTs 等工具，讓個人即使需求再小眾，也能獲得客製化的效率提升。（這次的簡報跟圖片都是 Gemini 生出來的）

這些原本規模很小的需求，因為都能被 AI 滿足，最終集合成一個非常大的群體。

### How might we build UI/UX that was impossible before?

在這一波 GenAI 的情況下，我們終於有能力可以打造 **超級獨特** 的個人體驗，而 JavaScript 是打造互動或前端界面（打造人的體驗）最好的工具。當我們有了這樣的技術之後，下一步是：要怎麼把這個技術放到我們現有的工具中，讓 **之前做不到的UI/UX** 變得可能。

---
## **現狀（**The Status Quo**）**

### 第三方 API 依賴（Rely heavily on 3rd-party APIs）

如果要在現有產品中整合 AI，基本上主要有兩種做法：

1. 直接發送 HTTP 請求（fetch）
    ![截圖_2025-11-29_晚上9.51.22](https://hackmd.io/_uploads/HkAFJj_--g.png)
2. 使用 OpenAI Node.js SDK
    ![截圖_2025-11-29_晚上9.52.02](https://hackmd.io/_uploads/Hymj1o_Z-e.png)



> 這些方法都高度依賴第三方的 AI 模型，也因此存在多項缺點。
> 

### 痛點（Pain Points）

1. **Token 成本問題（Token Cost Issue）**
    使用者付費還是開發者付費？在傳統 SaaS 中，通常是開發者付費再用訂閱方案收回成本，但在 LLM 時代，LLM 每次運作都需要 Token 費用，成本難以下降，到底 **誰要付這個帳單** 變成一個很大的問題。（前陣子有一位 vibe coding 的 KOL 讓大家使用他做的東西，結果他付帳單）
    
2. **延遲（Latency）**
    呼叫外部 API 的延遲（Network round-trips）會讓有些互動變得不太可能。如果我按一個按鈕希望一秒內回復，呼叫 API 很多時候做不到，或是他很要求網路環境到一定的程度。
    
3. **網絡依賴（Network Dependency）**
    在網路爆掉的情況下，你就沒辦法再用到 AI 的能力。（前陣子的 Cloudflare 🤯 ）
    
4. **單點故障（Single Point of Failure）**
    即使一切都好，公司可能因為太多請求或自身問題，導致產品無法服務。例如，有時會出現 **status code 429** 代表無法回應。
    
5. **糟糕的開發體驗（Bad DX）**
    在開發階段，模擬 AI 的互動是很困難的。如果呼叫固定的 API、定好 Schema 和 Use Case 即可進行模擬，但 AI 互動則難以實現良好的 Mock。
    
---
## **WebLLM 介紹**

**WebLLM** 是一個新的技術框架，它允許我們在 **瀏覽器內部運行大型模型**。

### **WebLLM 效能**

在其原始論文中提到 WebLLM 的效能比直接在電腦本地運行的效能大約有 **20% 的折損**。但在小模型的應用上，這種折損基本上可以忽略不計。

### **運作方式：混合引擎 (The Hybrid Engine)**

WebLLM 結合了兩種核心技術：

- **WebGPU (Inference Engine)**：
    - 允許 Chrome 瀏覽器透過瀏覽器本身與裝置 GPU 互動，直接操作 GPU。
    - 負責較複雜的矩陣運算，特別是 **Transformer** 模型中使用的 **注意力機制**。
- **WebAssembly (WASM)**：
    - 使用靜態類型語言取代動態語言中運算較慢的部分，加速關鍵過程。
    - 負責處理輸入輸出、將模型參數塞入計算、以及將模型計算結果轉換成最終輸出。

在這兩個技術的優化與革新下，**在瀏覽器上跑LLM** 變成一件可行的事情。

---
## MBTI 性格測驗（LIVE DEMO）

[https://github.com/Joshua0128/smarter-form/](https://github.com/Joshua0128/smarter-form/)
WebLLM 被用來協助使用者回答 MBTI 性格測驗中那些含糊不清的問題（例如：「少數」是幾個人）。使用者可以在填寫測驗時直接問 LLM。
### 分支

- 分支 step 0 → 純介面的應用
- 分支 step 1 → 設定 WebLLM
    - (+) script.js → `useLLM`
    - (+) webllm-init.js → `initWebLLM`
- 分支 step 2 → 整合成聊天助手的方式互動
    - (+) chat-assistant.js

### **初始化 LLM** `initWebLLM` [[代碼](https://github.com/Joshua0128/smarter-form/blob/step/1-setup-webllm/webllm-init.js)]

1. 選用模型
    - [http://github.com/mlc-ai/web-llm](http://github.com/mlc-ai/web-llm)
        
        > Here are the primary families of models currently supported:
        > 
        > - **Llama**: Llama 3, Llama 2, Hermes-2-Pro-Llama-3
        > - **Phi**: Phi 3, Phi 2, Phi 1.5
        > - **Gemma**: Gemma-2B
        > - **Mistral**: Mistral-7B-v0.3, Hermes-2-Pro-Mistral-7B, NeuralHermes-2.5-Mistral-7B, OpenHermes-2.5-Mistral-7B
        > - **Qwen (通义千问)**: Qwen2 0.5B, 1.5B, 7B
    
    ```vbnet
    Qwen2.5-1.5B-Instruct-q4f16_1-MLC
    --- -------- --------------------
    模型   大小         參數
    ```
    
2. 呼叫 `webllm.CreateMLCEngine`
3. 設定加載時候的 hook `initProgressCallback`
4. 丟到 `window.llmEngine`

### **WebLLM** 的優勢與實現

- WebLLM **遵循 OpenAI 的 API 格式**，支援像是 Streaming（串流式輸出）、Structured JSON Output（結構化輸出）、以及 Tool Calling（功能調用）等技術。
    - [http://github.com/mlc-ai/web-llm](http://github.com/mlc-ai/web-llm)
        
        > **Full OpenAI Compatibility**
        > 
        > 
        > WebLLM is designed to be fully compatible with [OpenAI API](https://platform.openai.com/docs/api-reference/chat). Thus, besides building a simple chatbot, you can also have the following functionalities with WebLLM:
        > 
        > - [streaming](https://github.com/mlc-ai/web-llm/blob/main/examples/streaming): return output as chunks in real-time in the form of an AsyncGenerator
        > - [json-mode](https://github.com/mlc-ai/web-llm/blob/main/examples/json-mode): efficiently ensure output is in JSON format, see [OpenAI Reference](https://platform.openai.com/docs/guides/text-generation/chat-completions-api) for more.
        > - [seed-to-reproduce](https://github.com/mlc-ai/web-llm/blob/main/examples/seed-to-reproduce): use seeding to ensure a reproducible output with fields `seed`.
        > - [function-calling](https://github.com/mlc-ai/web-llm/blob/main/examples/function-calling) (WIP): function calling with fields `tools` and `tool_choice` (with preliminary support); or manual function calling without `tools` or `tool_choice` (keeps the most flexibility).

- WebLLM 呼叫格式（例如 `chat completion create`）與 OpenAI 幾乎一模一樣，參數（如 `temperature`, `max token`）也相同。但唯一有差別的是 **不能在呼叫時指定模型**。你初始化什麼模型，它就回答什麼模型。
- 演示中，WebLLM 讓 LLM 能夠在瀏覽器上以 **1GB 以內** 的記憶體用量下運行。
- 初次運行時，WebLLM 的模型會被下載並存放在瀏覽器的 **Cache Storage** 中。但基於資安考量，它只在**同一個 Origin** 下緩存模型。如果跳轉到不同的網域 (Origin)，就需要重新下載模型。
- 模型由三個主要檔案組成：
    1. **Model：** 被寫成很多碎片檔的大模型，之後會組起來。
    2. **WebAssembly：** 負責 CPU 加速及參數組裝的邏輯。
    3. **Config：** 存放 LLM 相關的設定。
- 在演示的過程中，**沒有花費任何Token**。
- 沒有呼叫任何外部API，因此可以直接把網路調到 **離線模式** (Offline) 也能執行。
- 這種應用是本來做不到的，因為無法收斂表單的互動。現在，透過 LLM 與設定好的系統提示（System Prompt），可以讓填表單的人體驗更好，而且基本上**不用花費你的算力**，可以盡情的「浪費」。

---
## AI 小鎮物語（LIVE DEMO）


另一個盡情浪費的案例：

[https://minitown.zeabur.app/](https://minitown.zeabur.app/)

此案例是 **muti-agent 架構** 的 Demo。這些 LLM Agent 有不同的設定，會在虛擬世界中觀察周圍的人和事件，並開始行動和做判斷。如果用外部 API 運行三個小時，將會是一筆昂貴的費用。但既然模型放在瀏覽器中，就可以進行「**浪費**」（例如上班時掛在旁邊看）。

> 使用範例：現在中央公園起火了，快去幫忙！
> 

---
## 部署自訂模型（Customizing with your model）

如果你想要把自己的模型丟到瀏覽器上，你需要經過以下步驟：

### 1. 微調 (Fine-Tuning)

- 起手可以使用 **LoRA (Low-Rank Adaptation)** 技術進行微調。
最建議的工具是使用 **unsloth（樹懶）**。
- **LoRA 原理：** 與其直接去修改整個大模型（像一本字典），LoRA 是透過建立許多 **便利貼（補丁）** 來修改關鍵的東西。這樣可以用較少的成本，將新的領域知識或風格灌注到模型中。
- **訓練**：可以在 Google Colab 上完成，Colab 提供免費的 GPU 資源，可以運行從 1.7B 到 32B 的模型，大概可以免費使用 24 小時，之後就要付費。

### 2. 量化 (Quantization)

- 一般模型參數使用 32位（32-bit）長度的浮點數表示，但有時候參數不需要那麼高的精度。
- 量化是透過將參數精度降低（例如從 32-bit 浮點數轉換為 16-bit 或 8-bit 的近似整數），來**縮小模型大小**。
- 需要使用 **MLC-LLM** 進行量化。

### 3. 部署 (Deploy)

部署時需要定義設定檔。
![截圖_2025-11-30_凌晨12.08.47](https://hackmd.io/_uploads/ry9ylsuZZg.png)

- **model：** 定義你量化完的模型檔案存放的網址。
- **model_id：** 模型的名稱。
- **model_lib：** 做模型有分兩種，第一種拿別人的架構去改參數來做模型；第二種則是使用了別人沒有用過的架構（例如自己設計的新架構），你需要自己將這個架構 **compile 成 WebAssembly**，並替換這裡的 model library，才能把自己客製化的東西放上來。

---
## MLC-LLM

將運行在 LLM 上的程式碼轉化為 **適合各種硬體的機械碼**，扮演著「翻譯者」的角色，不論模型是用 Python 或 JavaScript 編寫，經過 MLC 轉換後，它都能在 NVIDIA、Android、iOS、**Web 瀏覽器**等不同平台上運行，從而降低成本與效能。

---
## WebLLM 與 Transformers.js 的比較

| 特性 | Transformers.js | WebLLM (MLC AI) |
| --- | --- | --- |
| **底層優化** | 在瀏覽器環境上執行一個 ONNX Runtime。 | 使用 MLC LLM 將程式碼直接轉換成 **硬體最適化** 的機械碼。 |
| **效能** | 效能較弱，因為多了一層虛擬層在上面運行。 | 效能更高，因為直接優化底層硬體。 |
| **API 支援** | 不支援 OpenAI API 的能力。 | 支援 OpenAI API 的能力。 |
| **適用性** | 任何 Transformer 模型都可運行（包括圖像、聲音、影片）。 | 適用於聊天模型 (Chat Model)。 |


---
## 裝置相容性檢查

使用者可以透過 [**WebGPU Report**](https://webgpureport.org/) 網站檢查自己的電腦是否適合運行 LLM。如果手機是 Android 系統，可能會顯示效能如何；如果是 iOS 系統，則會直接顯示不支援。

---
## 結語

WebLLM 為什麼越來越重要，是因為 **小模型** 正變得越來越強大。在某些應用與分數上，小模型甚至可以 **超越大型模型**（例如超過 GPT-5），小模型也更容易進行微調。

在 GenAI 時代，WebLLM 使得我們能夠以非常小的成本下打造 **超個人化的 UX**，可以用小模型在瀏覽器上做超酷的東西，大家快去玩！

---

> 聊天區
---

{%hackmd @JSDC-tw/jsdc2025_sponsor %}