תאריך פרסום: 13 בינואר 2024
זהו החלק השני בסדרה בת שלושה חלקים בנושא מודלים מסוג LLM ו-chatbots. במאמר הקודם התייחסנו להיתרונות והחסרונות של מודלים LLM במכשיר ובדפדפן.
עכשיו, אחרי שהבנתם טוב יותר את ה-AI בצד הלקוח, אתם מוכנים להוסיף את WebLLM לאפליקציית אינטרנט של רשימת משימות. הקוד נמצא בהסתעפות web-llm
במאגר GitHub.
WebLLM הוא סביבת זמן ריצה מבוססת-אינטרנט ל-LLMs שסופקו על ידי Machine Learning Compilation. אתם יכולים לנסות את WebLLM כאפליקציה עצמאית. האפליקציה מבוססת על אפליקציות צ'אט שמבוססות על ענן, כמו Gemini, אבל ההסקה של LLM פועלת במכשיר במקום בענן. ההנחיות והנתונים שלכם אף פעם לא יוצאים מהמכשיר, ואנחנו לא משתמשים בהם לאימון מודלים.
כדי לבצע הסקת מודל במכשיר, WebLLM משלב בין WebAssembly לבין WebGPU. בעוד ש-WebAssembly מאפשר לבצע חישובים יעילים במעבד המרכזי (CPU), WebGPU מעניק למפתחים גישה ברמה נמוכה למעבד הגרפי (GPU) של המכשיר.
התקנת WebLLM
WebLLM זמין כחבילת npm.
כדי להוסיף את החבילה הזו לאפליקציית רשימת המשימות, מריצים את הפקודה npm install @mlc-ai/web-llm
.
בחירת דגם
בשלב הבא, צריך להחליט איזה LLM להריץ באופן מקומי. יש מגוון מודלים זמינים.
כדי להחליט, כדאי להכיר את המונחים והנתונים הבאים:
- אסימון: יחידת הטקסט הקטנה ביותר ש-LLM יכול לעבד.
- חלון הקשר: המספר המקסימלי של האסימונים שהמודל יכול לעבד.
- פרמטרים או משקלים: המשתנים הפנימיים שנלמדו במהלך האימון, שמספרם מגיע למיליארד.
- Quantization: מספר הביטים שמייצגים את המשקלים. יותר ביטים מאפשרים רמת דיוק גבוהה יותר, אבל גם שימוש גדול יותר בזיכרון.
- פורמטים של מספרים עם נקודה צפה: מספרים עם נקודה צפה של 32 ביט (רמת דיוק מלאה, F32) מציעים רמת דיוק גבוהה יותר, בעוד שמספרים עם נקודה צפה של 16 ביט (רמת דיוק חצי, F16) מציעים מהירויות גבוהות יותר ושימוש קטן יותר בזיכרון, אבל הם דורשים חומרה תואמת.
מונחי המפתח האלה בדרך כלל נכללים בשם המודל. לדוגמה, השדה Llama-3.2-3B-Instruct-q4f32_1-MLC
מכיל את המידע הבא:
- המודל הוא LLaMa 3.2.
- המודל כולל 3 מיליארד פרמטרים.
- הוא מותאם במיוחד לעוזרים שמבוססים על הוראות והנחיות (Instruct).
- הוא משתמש בקידוד (_1) אחיד (q4) של 4 ביט.
- הוא כולל מספרי נקודה צפה (floating-point) של 32 ביט ברמת דיוק מלאה.
- זוהי גרסה מיוחדת שנוצרה על ידי Machine Learning Compilation.
יכול להיות שתצטרכו לבדוק מודלים שונים כדי לקבוע איזה מהם מתאים לתרחיש לדוגמה שלכם.
מודל עם 3 מיליארד פרמטרים ו-4 ביט לכל פרמטר יכול להגיע כבר לגודל קובץ של 1.4GB נכון לזמן כתיבת המאמר הזה, והאפליקציה צריכה להוריד אותו למכשיר של המשתמש לפני השימוש הראשון. אפשר לעבוד עם מודלים של 3 מיליארד, אבל כשמדובר ביכולות תרגום או בידע בטריוויה, מודלים של 7 מיליארד מניבים תוצאות טובות יותר. עם 3.3GB ומעלה, הם גדולים יותר באופן משמעותי.
כדי ליצור את מנוע 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 Workers כדי לאפשר לאתר או לאפליקציית האינטרנט לפעול במצב אופליין. זהו מנגנון האחסון הטוב ביותר לשמירת מודלים של AI במטמון. בניגוד לאחסון במטמון של HTTP, Cache API הוא מטמון שניתן לתכנת, שנמצא בשליטה מלאה של המפתח.
לאחר ההורדה, WebLLM קורא את קובצי המודל מ-Cache API במקום לבקש אותם מהרשת, כך ש-WebLLM יכול לפעול במצב אופליין לחלוטין.
כמו כל האחסון באתר, המטמון מבודד לפי מקור. המשמעות היא ששני מקורות, example.com ו-example.net, לא יכולים לשתף את אותו נפח אחסון. אם שני האתרים האלה ירצו להשתמש באותו מודל, הם יצטרכו להוריד את המודל בנפרד.
כדי לבדוק את המטמון באמצעות DevTools, עוברים אל Application (אפליקציה) > Storage (אחסון) ופותחים את האחסון במטמון.
הגדרת השיחה
אפשר לאתחל את המודל באמצעות קבוצה של הנחיות ראשוניות. בדרך כלל יש שלושה תפקידים של הודעות:
- הנחיה למערכת: ההנחיה הזו מגדירה את ההתנהגות, התפקיד והאופי של המודל. אפשר גם להשתמש בהם לצורך יצירת בסיס, כלומר להזין נתונים מותאמים אישית למודל שלא נכללים בקבוצת האימון שלו (כמו נתונים ספציפיים לדומיין). אפשר לציין רק הנחיה מערכתית אחת.
- הנחיה למשתמש: הנחיות שהמשתמש הזין.
- הנחיה מ-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()
במאפיין הזה. בתרחיש לדוגמה, אתם רוצים להעביר את התשובות בסטרימינג כדי שהמשתמש יוכל להתחיל לקרוא בזמן שהן נוצרות, וכך לקצר את זמן ההמתנה שנראה למשתמש:
const chunks = await engine.chat.completions.create({ messages, stream: true, });
השיטה הזו מחזירה AsyncGenerator
, Subclass של הכיתה המוסתרת 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 מתקבלים ביצועים של הסקת נתונים (inference) שקרובים לביצועים של הסקה נתונים מקומית, אבל לא מגיעים למהירות המלאה של הסקה נתונים מקומית.
הדגמה (דמו)
כדי להתמודד עם החסרונות האלה, Google הציעה את Prompt API – ממשק API לבדיקה שגם הוא פועל בצד הלקוח, אבל משתמש במודל מרכזי שהורד ל-Chrome. המשמעות היא שאפשר להשתמש באותו מודל במספר אפליקציות במהירות ביצוע מלאה.
מידע נוסף על הוספת יכולות של צ'אטבוט באמצעות Prompt API זמין במאמר הבא.