# 從微調到瀏覽器: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 %}