發布日期:2024 年 1 月 13 日
這是三部曲系列文章的第二篇,主題是 LLM 和聊天機器人。上一篇文章討論了裝置端和瀏覽器端大型語言模型的優缺點。
您現在已進一步瞭解用戶端 AI,因此可以將 WebLLM 新增至待辦事項清單網頁應用程式。您可以在 GitHub 存放區的 web-llm
分支中找到這段程式碼。
WebLLM 是機器學習編譯提供的大型語言模型網頁式執行階段。您可以試試將 WebLLM 做為獨立應用程式。這個應用程式受到雲端支援聊天應用程式 (例如 Gemini) 的啟發,但 LLM 推論是在裝置上執行,而非在雲端執行。您的提示和資料絕不會離開裝置,而且您可以確保這些資料不會用於訓練模型。
為了在裝置上執行模型推論,WebLLM 會結合 WebAssembly 和 WebGPU。WebAssembly 可讓您在中央處理器 (CPU) 上進行高效率的運算,而 WebGPU 則可讓開發人員以低階方式存取裝置的圖形處理器 (GPU)。
安裝 WebLLM
WebLLM 可做為 npm 套件使用。您可以執行 npm install @mlc-ai/web-llm
,將這個套件新增至待辦事項清單應用程式。
選取模型
接下來,您需要決定要執行哪個 LLM。我們提供多種型號。
如要做出決定,請先瞭解下列重要術語和數據:
- 符記:大型語言模型可處理的最小文字單位。
- 脈絡窗口:模型可處理的符記數量上限。
- 參數或權重:在訓練期間學習到的內部變數,以十億為單位計算。
- 量化:代表權重位元的位元數。位元越多,精確度越高,但記憶體用量也會增加。
- 浮點數格式:32 位元浮點數 (完整精度,F32) 可提供更高的精確度,而 16 位元浮點數 (半精度,F16) 則可提供更快的速度和更少的記憶體用量,但需要相容的硬體。
這些關鍵字通常是型號名稱的一部分。例如,Llama-3.2-3B-Instruct-q4f32_1-MLC
包含下列資訊:
- 模型為 LLaMa 3.2。
- 模型有 30 億個參數。
- 這項功能經過精細調整,可用於指示和提示式助理 (Instruct)。
- 使用 4 位元 (q4) 均勻 (_1) 量化。
- 它具有完整精確度的 32 位元浮點數。
- 這是由機器學習編譯功能建立的特殊版本。
您可能需要測試不同的模型,找出最適合用途的模型。
在撰寫本文時,如果模型有 30 億個參數,且每個參數有 4 位元,檔案大小可能會達到 1.4 GB,而應用程式需要在首次使用前將該檔案下載到使用者的裝置上。您可以使用 3B 模型,但在翻譯功能或瑣事知識方面,7B 模型的結果會更好。不過,如果檔案大小為 3.3 GB 以上,則會大得多。
如要建立 WebLLM 引擎,並為待辦清單 Chatbot 啟動模型下載作業,請在應用程式中加入下列程式碼:
import {CreateMLCEngine} from '@mlc-ai/web-llm';
const engine = await CreateMLCEngine('Llama-3.2-3B-Instruct-q4f32_1-MLC', {
initProgressCallback: ({progress}) => console.log(progress);
});
CreateMLCEngine
方法會使用模型字串和選用的設定物件。您可以使用 initProgressCallback
方法查詢模型的下載進度,並在使用者等待期間向他們顯示。
Cache API:讓 LLM 離線執行
模型會下載至網站的快取儲存空間。Cache API 與 Service Worker 一同推出,可讓網站或網路應用程式離線執行。這是快取 AI 模型的最佳儲存機制。與 HTTP 快取不同,Cache API 是可程式設計的快取,完全由開發人員控管。
下載完成後,WebLLM 會從 Cache API 讀取模型檔案,而非透過網路要求,讓 WebLLM 可完全離線運作。
和所有網站儲存空間一樣,快取會依來源進行隔離。也就是說,兩個來源 example.com 和 example.net 無法共用相同的儲存空間。如果這兩個網站想要使用相同的模型,就必須分別下載模型。
如要使用開發人員工具檢查快取資料,請依序前往「應用程式」 >「儲存空間」,然後開啟快取儲存空間。
設定對話
您可以使用一組初始提示來初始化模型。通常有三種訊息角色:
- 系統提示:這個提示會定義模型的行為、角色和角色人物。也可以用於建立基礎,也就是將自訂資料提供給非訓練集的模型 (例如特定領域的資料)。您只能指定一個系統提示。
- 使用者提示:使用者輸入的提示。
- Google 助理提示:Google 助理的回覆 (選用)。
使用者和助理提示可用於 N 次拍攝提示,方法是向 LLM 提供自然語言示例,說明該如何運作或回應。
以下是為待辦事項應用程式設定對話的簡易範例:
const messages = [
{ role: "system",
content: `You are a helpful assistant. You will answer questions related to
the user's to-do list. Decline all other requests not related to the user's
todos. This is the to-do list in JSON: ${JSON.stringify(todos)}`
},
{role: "user", content: "How many open todos do I have?"}
];
回答第一個問題
在先前建立的 WebLLM 引擎 (engine.chat.completions
) 上,對話完成功能會公開為屬性。下載模型後,您可以對此屬性呼叫 create()
方法,執行模型推論。針對您的用途,您希望串流回應,讓使用者在回應產生時開始閱讀,進而縮短等待時間:
const chunks = await engine.chat.completions.create({ messages, stream: true, });
這個方法會傳回 AsyncGenerator
,這是隱藏 AsyncIterator
類別的子類別。使用 for await...of
迴圈,等待區塊傳入。不過,回應只包含新的符記 (delta
),因此您必須自行組合完整的回覆。
let reply = '';
for await (const chunk of chunks) {
reply += chunk.choices[0]?.delta.content ?? '';
console.log(reply);
}
事實上,網頁總是必須處理串流回應。您可以使用 DOMImplementation 等 API 處理這些串流回應,並有效更新 HTML。
結果完全以字串為基礎。如果您想將這些檔案解讀為 JSON 或其他檔案格式,必須先剖析這些檔案。
不過,WebLLM 有一些限制:應用程式必須在首次使用前下載大型模型,且無法跨來源共用,因此其他網頁應用程式可能必須再次下載相同模型。雖然 WebGPU 可達到接近原生推論的效能,但無法達到完整的原生速度。
示範
這些缺點可透過提示 API 解決。這是 Google 提出的探索性 API,同樣會在用戶端執行,但會使用下載至 Chrome 的中央模型。也就是說,多個應用程式可以以完整執行速度使用相同的模型。
如要進一步瞭解如何使用 Prompt API 新增聊天機器人功能,請參閱下一篇文章。