เผยแพร่เมื่อวันที่ 13 มกราคม 2024
บทความนี้เป็นบทความที่ 2 ในชุดบทความ 3 บทความเกี่ยวกับ LLM กับแชทบ็อต บทความก่อนหน้าได้กล่าวถึงข้อดีและข้อเสียของ LLM ในอุปกรณ์และในเบราว์เซอร์
เมื่อเข้าใจ AI ฝั่งไคลเอ็นต์มากขึ้นแล้ว คุณก็พร้อมที่จะเพิ่ม WebLLM ลงในเว็บแอปพลิเคชันรายการสิ่งที่ต้องทําแล้ว คุณดูโค้ดได้ในสาขา web-llm
ของที่เก็บ GitHub
WebLLM เป็นรันไทม์บนเว็บสําหรับ LLM ที่ Machine Learning Compilation ให้บริการ คุณลองใช้ WebLLM เป็นแอปพลิเคชันแบบสแตนด์อโลนได้ แอปพลิเคชันนี้ได้รับแรงบันดาลใจมาจากแอปพลิเคชันแชทที่ทำงานบนระบบคลาวด์ เช่น Gemini แต่ระบบจะเรียกใช้การอนุมาน LLM ในอุปกรณ์แทนระบบคลาวด์ พรอมต์และข้อมูลของคุณจะไม่ออกจากอุปกรณ์ และมั่นใจได้ว่าจะไม่มีการนำข้อมูลดังกล่าวไปใช้ฝึกโมเดล
WebLLM ใช้ WebAssembly และ WebGPU เพื่อทำการอนุมานโมเดลในอุปกรณ์ แม้ว่า WebAssembly จะทําการคํานวณได้อย่างมีประสิทธิภาพในหน่วยประมวลผลกลาง (CPU) แต่ WebGPU จะให้สิทธิ์เข้าถึงระดับล่างแก่นักพัฒนาแอปในหน่วยประมวลผลกราฟิก (GPU) ของอุปกรณ์
ติดตั้ง WebLLM
WebLLM มีให้บริการเป็นแพ็กเกจ npm
คุณสามารถเพิ่มแพ็กเกจนี้ลงในแอปพลิเคชันรายการสิ่งที่ต้องทำได้โดยการรัน npm install @mlc-ai/web-llm
เลือกรุ่น
ถัดไป คุณต้องเลือก LLM เพื่อเรียกใช้ในพื้นที่ มีโมเดลต่างๆ ให้เลือก
คุณควรทราบคําศัพท์และตัวเลขสําคัญต่อไปนี้เพื่อตัดสินใจ
- โทเค็น: หน่วยข้อความที่เล็กที่สุดที่ LLM ประมวลผลได้
- กรอบบริบท: จำนวนโทเค็นสูงสุดที่โมเดลประมวลผลได้
- พารามิเตอร์หรือน้ำหนัก: ตัวแปรภายในที่เรียนรู้ระหว่างการฝึก ซึ่งนับเป็นจํานวนพันล้าน
- การแปลงค่าเป็นจำนวนเต็ม: จำนวนบิตที่แสดงถึงน้ำหนัก ยิ่งบิตมีจำนวนมากขึ้น ความแม่นยำก็จะยิ่งสูงขึ้น แต่การใช้หน่วยความจําก็จะยิ่งมากขึ้นด้วย
- รูปแบบตัวเลขทศนิยม: ตัวเลขทศนิยม 32 บิต (ความแม่นยำแบบเต็ม, F32) มีความแม่นยำมากกว่า ส่วนตัวเลขทศนิยม 16 บิต (ความแม่นยำแบบครึ่งหนึ่ง, F16) ทำงานได้เร็วกว่าและใช้หน่วยความจำน้อยลง แต่ต้องใช้ฮาร์ดแวร์ที่เข้ากันได้
โดยคีย์เวิร์ดเหล่านี้มักจะเป็นส่วนหนึ่งของชื่อรุ่น ตัวอย่างเช่น Llama-3.2-3B-Instruct-q4f32_1-MLC
มีข้อมูลต่อไปนี้
- โมเดลคือ LLaMa 3.2
- โมเดลมีพารามิเตอร์ 3 พันล้านรายการ
- รูปแบบนี้ปรับแต่งมาเพื่อผู้ช่วยแบบคำสั่งและพรอมต์ (Instruct)
- โดยใช้การแปลงค่าแบบเป็นระเบียบ (_1) 4 บิต (q4)
- โดยจะมีตัวเลขทศนิยม 32 บิตที่มีความแม่นยำเต็มรูปแบบ
- ซึ่งเป็นเวอร์ชันพิเศษที่สร้างขึ้นโดย Machine Learning Compilation
คุณอาจต้องทดสอบรูปแบบต่างๆ เพื่อดูว่ารูปแบบใดเหมาะกับ Use Case ของคุณ
โมเดลที่มีพารามิเตอร์ 3, 000 ล้านรายการและ 4 บิตต่อพารามิเตอร์อาจมีไฟล์ขนาดใหญ่ถึง 1.4 GB ณ เวลาที่เขียนบทความนี้ ซึ่งแอปพลิเคชันจะต้องดาวน์โหลดลงในอุปกรณ์ของผู้ใช้ก่อนใช้งานครั้งแรก คุณอาจใช้โมเดล 3B ได้ แต่โมเดล 7B จะให้ผลลัพธ์ที่ดีกว่าในด้านความสามารถด้านการแปลหรือความรู้รอบตัว แต่ไฟล์ที่มีขนาด 3.3 GB ขึ้นไปจะมีขนาดใหญ่กว่ามาก
หากต้องการสร้างเครื่องมือ WebLLM และเริ่มการดาวน์โหลดโมเดลสำหรับแชทบ็อตรายการสิ่งที่ต้องทำ ให้เพิ่มโค้ดต่อไปนี้ลงในแอปพลิเคชัน
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 Cache API เป็นแคชที่ตั้งโปรแกรมได้ซึ่งอยู่ภายใต้การควบคุมของนักพัฒนาซอฟต์แวร์โดยสมบูรณ์ ซึ่งแตกต่างจากแคช HTTP
เมื่อดาวน์โหลดแล้ว WebLLM จะอ่านไฟล์โมเดลจาก Cache API แทนที่จะขอไฟล์ผ่านเครือข่าย ซึ่งทำให้ WebLLM ทำงานแบบออฟไลน์ได้อย่างเต็มที่
แคชจะแยกตามต้นทางเช่นเดียวกับพื้นที่เก็บข้อมูลเว็บไซต์ทั้งหมด ซึ่งหมายความว่าต้นทาง 2 รายการ ได้แก่ example.com และ example.net จะแชร์พื้นที่เก็บข้อมูลเดียวกันไม่ได้ หากเว็บไซต์ทั้ง 2 ต้องการใช้โมเดลเดียวกัน จะต้องดาวน์โหลดโมเดลแยกกัน
คุณสามารถตรวจสอบแคชโดยใช้เครื่องมือสำหรับนักพัฒนาซอฟต์แวร์โดยไปที่แอปพลิเคชัน > พื้นที่เก็บข้อมูล แล้วเปิดพื้นที่เก็บข้อมูลแคช
ตั้งค่าการสนทนา
โมเดลสามารถเริ่มต้นด้วยชุดพรอมต์เริ่มต้น โดยปกติแล้ว บทบาทของข้อความมี 3 บทบาท ดังนี้
- พรอมต์ของระบบ: พรอมต์นี้จะกำหนดลักษณะการทำงาน บทบาท และบุคลิกของโมเดล นอกจากนี้ยังใช้เพื่อกราวด์ได้อีกด้วย ซึ่งก็คือการให้ข้อมูลที่กำหนดเองแก่โมเดลที่ไม่ได้อยู่ในชุดการฝึก (เช่น ข้อมูลเฉพาะโดเมน) คุณระบุพรอมต์ของระบบได้เพียงรายการเดียว
- พรอมต์ของผู้ใช้: พรอมต์ที่ผู้ใช้ป้อน
- พรอมต์ของ Assistant: คำตอบจาก Assistant (ไม่บังคับ)
พรอมต์ของผู้ใช้และพรอมต์ของผู้ช่วยสามารถใช้สำหรับการพรอมต์แบบ N-shot ได้โดยการให้ตัวอย่างภาษาที่เป็นธรรมชาติแก่ 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()
ในพร็อพเพอร์ตี้นี้ สำหรับ Use Case ของคุณ คุณต้องการสตรีมคำตอบเพื่อให้ผู้ใช้เริ่มอ่านได้ในขณะที่ระบบกำลังสร้างคำตอบอยู่ ซึ่งจะช่วยลดเวลาที่ผู้ใช้รู้สึกว่าต้องรอ
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);
}
ปรากฏว่าเว็บต้องจัดการกับการตอบสนองแบบสตรีมอยู่เสมอ คุณสามารถใช้ API เช่น DOMImplementation เพื่อดำเนินการกับคำตอบแบบสตรีมเหล่านี้และอัปเดต HTML ได้อย่างมีประสิทธิภาพ
ผลลัพธ์จะอิงตามสตริงเท่านั้น คุณต้องแยกวิเคราะห์ก่อนหากต้องการตีความเป็น JSON หรือรูปแบบไฟล์อื่นๆ
อย่างไรก็ตาม WebLLM มีข้อจํากัดบางอย่าง แอปพลิเคชันต้องดาวน์โหลดรูปแบบขนาดใหญ่ก่อนใช้งานครั้งแรก ซึ่งแชร์ข้ามต้นทางไม่ได้ แอปเว็บอื่นจึงอาจต้องดาวน์โหลดรูปแบบเดียวกันอีกครั้ง แม้ว่า WebGPU จะมีประสิทธิภาพการอนุมานใกล้เคียงกับเนทีฟ แต่ก็ไม่ได้มีประสิทธิภาพถึงระดับเนทีฟอย่างเต็มรูปแบบ
สาธิต
ข้อเสียเหล่านี้ได้รับการแก้ไขโดย Prompt API ซึ่งเป็น API สําหรับการสํารวจที่ Google เสนอให้ใช้งาน ซึ่งทำงานฝั่งไคลเอ็นต์ด้วยเช่นกัน แต่ใช้โมเดลกลางที่ดาวน์โหลดลงใน Chrome ซึ่งหมายความว่าแอปพลิเคชันหลายรายการสามารถใช้โมเดลเดียวกันที่ความเร็วในการดำเนินการสูงสุดได้
อ่านเพิ่มเติมเกี่ยวกับการเพิ่มความสามารถของแชทบ็อตโดยใช้ Prompt API ในบทความถัดไป