LLM Inference API מאפשר להריץ מודלים גדולים של שפה (LLMs) לגמרי בדפדפן של אפליקציות אינטרנט, וניתן להשתמש בהם לביצוע מגוון רחב של משימות, כמו יצירת טקסט, אחזור מידע בצורת שפה טבעית וסיכום מסמכים. המשימה מספקת תמיכה מובנית במספר מודלים גדולים של שפה (LLM) מסוג טקסט לטקסט, כך שתוכלו להחיל את מודלי ה-AI הגנרטיביים העדכניים ביותר במכשיר על אפליקציות האינטרנט שלכם.
המשימה תומכת באפשרויות הבאות של Gemma: Gemma-2 2B, Gemma 2B ו-Gemma 7B. Gemma היא משפחה של מודלים פתוחים וקלים לשימוש, שנוצרו על סמך אותו מחקר וטכנולוגיה ששימשו ליצירת המודלים של Gemini. הוא תומך גם בדגמים החיצוניים הבאים: Phi-2, Falcon-RW-1B ו-StableLM-3B.
אתם יכולים לראות את המשימה הזו בפעולה בהדגמה של MediaPipe Studio. מידע נוסף על היכולות, המודלים והאפשרויות להגדרה של המשימה הזו זמין בסקירה הכללית.
קוד לדוגמה
באפליקציית הדוגמה ל-LLM Inference API מופיעה הטמעה בסיסית של המשימה הזו ב-JavaScript. אתם יכולים להשתמש באפליקציית הדוגמה הזו כדי להתחיל ליצור אפליקציה משלכם ליצירת טקסט.
אפשר לגשת לאפליקציית הדוגמה של LLM Inference API ב-GitHub.
הגדרה
בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח ופרויקטי הקוד, באופן ספציפי לשימוש ב-LLM Inference API. מידע כללי על הגדרת סביבת הפיתוח לשימוש ב-MediaPipe Tasks, כולל דרישות לגבי גרסת הפלטפורמה, זמין במדריך להגדרה לאינטרנט.
תאימות דפדפן
כדי להשתמש ב-LLM Inference API, נדרש דפדפן אינטרנט עם תאימות ל-WebGPU. רשימה מלאה של דפדפנים תואמים מופיעה במאמר תאימות דפדפנים ל-GPU.
חבילות JavaScript
קוד ה-API של LLM Inference זמין בחבילה @mediapipe/tasks-genai
. אפשר למצוא את הספריות האלה ולהוריד אותן מהקישורים שמופיעים במדריך ההגדרה של הפלטפורמה.
מתקינים את החבילות הנדרשות ל-staging מקומי:
npm install @mediapipe/tasks-genai
כדי לפרוס בשרת, משתמשים בשירות של רשת להעברת תוכן (CDN) כמו jsDelivr כדי להוסיף קוד ישירות לדף ה-HTML:
<head>
<script src="https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai/genai_bundle.cjs"
crossorigin="anonymous"></script>
</head>
דגם
כדי להשתמש ב-MediaPipe LLM Inference API, נדרש מודל מאומן שתואם למשימה הזו. באפליקציות אינטרנט, המודל צריך להיות תואם ל-GPU.
מידע נוסף על מודלים מאומנים שזמינים ל-LLM Inference API זמין בקטע 'מודלים' שבסקירה הכללית של המשימה.
הורדת מודל
לפני שמפעילים את LLM Inference API, צריך להוריד אחד מהמודלים הנתמכים ולשמור את הקובץ בספריית הפרויקט:
- Gemma-2 2B: הגרסה האחרונה של משפחת הדגמים Gemma. חלק ממשפחה של מודלים פתוחים וקלים לייצור, שמבוססים על אותם מחקר וטכנולוגיה ששימשו ליצירת המודלים של Gemini.
- Gemma 2B: חלק ממשפחה של מודלים פתוחים וקלים לשימוש, שנוצרו על סמך אותו מחקר וטכנולוגיה ששימשו ליצירת המודלים של Gemini. מתאים למגוון משימות של יצירת טקסט, כולל מענה לשאלות, סיכום ושיוך.
- Phi-2: מודל טרנספורמר עם 2.7 מיליארד פרמטרים, שמתאים במיוחד לפורמטים של שאלות ותשובות, צ'אט וקוד.
- Falcon-RW-1B: מודל של מפענח סיבתי עם מיליארד פרמטרים, שאומן על 350 מיליארד אסימונים של RefinedWeb.
- StableLM-3B: מודל שפה של מפענח בלבד עם 3 מיליארד פרמטרים, שאומן מראש על טריליון אסימונים של מערכי נתונים מגוונים של אנגלית וקוד.
בנוסף למודלים הנתמכים, אפשר להשתמש ב-AI Edge Torch של Google כדי לייצא מודלים של PyTorch למודלים של LiteRT (tflite
) עם חתימות מרובות. מידע נוסף זמין במאמר ממיר גנרטיבי של Torch למודלים של PyTorch.
מומלץ להשתמש ב-Gemma-2 2B, שזמין ב-Kaggle Models. מידע נוסף על המודלים האחרים הזמינים זמין בקטע 'מודלים' בסקירה הכללית של המשימה.
המרת המודל לפורמט של MediaPipe
ה-LLM Inference API תואם לשתי קטגוריות של מודלים, חלק מהן מחייבות המרה של המודל. בטבלה הבאה מפורטות השיטות הנדרשות לכל מודל.
דגמים | שיטת ההמרה | פלטפורמות תואמות | סוג הקובץ | |
---|---|---|---|---|
דגמים נתמכים | Gemma 2B, Gemma 7B, Gemma-2 2B, Phi-2, StableLM, Falcon | MediaPipe | Android, iOS, אינטרנט | .bin |
מודלים אחרים של PyTorch | כל המודלים של PyTorch LLM | ספריית AI Edge Torch Generative | Android, iOS | .task |
אנחנו מארחים את קובצי ה-.bin
המומרים של Gemma 2B, Gemma 7B ו-Gemma-2 2B ב-Kaggle. אפשר לפרוס את המודלים האלה ישירות באמצעות LLM Inference API. בקטע המרת מודלים מוסבר איך ממירים מודלים אחרים.
הוספת מודל לספריית הפרויקט
שומרים את המודל בספריית הפרויקט:
<dev-project-root>/assets/gemma-2b-it-gpu-int4.bin
מציינים את הנתיב של המודל באמצעות הפרמטר modelAssetPath
של האובייקט baseOptions
:
baseOptions: { modelAssetPath: `/assets/gemma-2b-it-gpu-int4.bin`}
יצירת המשימה
משתמשים באחת מהפונקציות createFrom...()
של LLM Inference API כדי להכין את המשימה להרצת המסקנות. אפשר להשתמש בפונקציה createFromModelPath()
עם נתיב יחסי או מוחלט לקובץ המודל המאומן. בדוגמה לקוד נעשה שימוש בפונקציה createFromOptions()
. מידע נוסף על אפשרויות ההגדרה הזמינות זמין במאמר אפשרויות הגדרה.
הקוד הבא ממחיש איך ליצור את המשימה הזו ולהגדיר אותה:
const genai = await FilesetResolver.forGenAiTasks(
// path/to/wasm/root
"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm"
);
llmInference = await LlmInference.createFromOptions(genai, {
baseOptions: {
modelAssetPath: '/assets/gemma-2b-it-gpu-int4.bin'
},
maxTokens: 1000,
topK: 40,
temperature: 0.8,
randomSeed: 101
});
אפשרויות הגדרה
למשימה הזו יש את אפשרויות התצורה הבאות לאפליקציות אינטרנט ול-JavaScript:
שם האפשרות | תיאור | טווח ערכים | ערך ברירת מחדל |
---|---|---|---|
modelPath |
הנתיב שבו המודל מאוחסן בתוך ספריית הפרויקט. | PATH | לא רלוונטי |
maxTokens |
המספר המקסימלי של אסימונים (אסימוני קלט + אסימוני פלט) שהמודל מטפל בהם. | מספר שלם | 512 |
topK |
מספר האסימונים שהמודל מתייחס אליהם בכל שלב של היצירה. הגבלת התחזיות ל-k האסימונים האפשריים הטובים ביותר. | מספר שלם | 40 |
temperature |
מידת האקראיות שמתווספת במהלך היצירה. טמפרטורה גבוהה יותר מובילה ליצירת טקסט יצירתי יותר, ואילו טמפרטורה נמוכה יותר מובילה ליצירת טקסט צפוי יותר. | מספר ממשי (float) | 0.8 |
randomSeed |
הזרע האקראי שמשמש ליצירת הטקסט. | מספר שלם | 0 |
loraRanks |
דירוגים של LoRA שישמשו את המודלים של LoRA במהלך זמן הריצה. הערה: האפשרות הזו תואמת רק לדגמי GPU. | מערך של מספרים שלמים | לא רלוונטי |
הכנת הנתונים
LLM Inference API מקבל נתוני טקסט (string
). המשימה מטפלת בעיבוד מקדים של קלט הנתונים, כולל יצירת אסימונים ועיבוד מקדים של טנסורים.
כל העיבוד המקדים מתבצע בתוך הפונקציה generateResponse()
. אין צורך בעיבוד מקדים נוסף של טקסט הקלט.
const inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday.";
הרצת המשימה
ב-LLM Inference API נעשה שימוש בפונקציה generateResponse()
כדי להפעיל מסקנות.
בסיווג טקסט, המשמעות היא החזרת הקטגוריות האפשריות לטקסט הקלט.
הקוד הבא מראה איך לבצע את העיבוד באמצעות מודל המשימה.
const response = await llmInference.generateResponse(inputPrompt);
document.getElementById('output').textContent = response;
כדי להעביר את התגובה בסטרימינג, משתמשים בקוד הבא:
llmInference.generateResponse(
inputPrompt,
(partialResult, done) => {
document.getElementById('output').textContent += partialResult;
});
טיפול בתוצאות והצגתן
LLM Inference API מחזיר מחרוזת שכוללת את טקסט התשובה שנוצר.
Here's a draft you can use:
Subject: Lunch on Saturday Reminder
Hi Brett,
Just a quick reminder about our lunch plans this Saturday at noon.
Let me know if that still works for you.
Looking forward to it!
Best,
[Your Name]
התאמה אישית של מודל LoRA
אפשר להגדיר את Mediapipe LLM inference API כך שיתמוך בהתאמה ברמה נמוכה (LoRA) למודלים גדולים של שפה. באמצעות מודלים מותאמים של LoRA, המפתחים יכולים להתאים אישית את ההתנהגות של מודלים LLM באמצעות תהליך אימון חסכוני.
התמיכה של LoRA ב-LLM Inference API פועלת בכל הווריאנטים של Gemma ובמודלים של Phi-2 לקצה העורפי של GPU, כאשר משקלי LoRA רלוונטיים לשכבות תשומת הלב בלבד. ההטמעה הראשונית הזו משמשת כ-API ניסיוני לפיתוח עתידי, ואנחנו מתכננים להוסיף תמיכה במודלים נוספים ובסוגי שכבות שונים בעדכונים הבאים.
הכנת מודלים של LoRA
פועלים לפי ההוראות ב-HuggingFace כדי לאמן מודל LoRA מותאם אישית במערך הנתונים שלכם עם סוגי המודלים הנתמכים, Gemma או Phi-2. המודלים Gemma-2 2B, Gemma 2B ו-Phi-2 זמינים ב-HuggingFace בפורמט safetensors. מאחר ש-LLM Inference API תומך רק ב-LoRA בשכבות תשומת לב, צריך לציין רק שכבות תשומת לב כשיוצרים את LoraConfig
באופן הבא:
# For Gemma
from peft import LoraConfig
config = LoraConfig(
r=LORA_RANK,
target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
)
# For Phi-2
config = LoraConfig(
r=LORA_RANK,
target_modules=["q_proj", "v_proj", "k_proj", "dense"],
)
לצורך בדיקה, יש מודלים LoRA מכווננים שזמינים לכולם ומתאימים ל-LLM Inference API ב-HuggingFace. לדוגמה, monsterapi/gemma-2b-lora-maths-orca-200k עבור Gemma-2B ו-lole25/phi-2-sft-ultrachat-lora עבור Phi-2.
אחרי האימון במערך הנתונים שהוכנו ושמירת המודל, מתקבל קובץ adapter_model.safetensors
שמכיל את משקלות המודל של LoRA שהותאמו.
קובץ safetensors הוא נקודת הבדיקה של LoRA שמשמש להמרת המודל.
בשלב הבא, צריך להמיר את משקלי המודל ל-Flatbuffer של TensorFlow Lite באמצעות חבילת Python של MediaPipe. בשדה ConversionConfig
צריך לציין את האפשרויות של מודל הבסיס וגם אפשרויות LoRa נוספות. חשוב לזכור שה-API תומך רק בהסקת LoRA עם GPU, ולכן צריך להגדיר את הקצה העורפי כ-'gpu'
.
import mediapipe as mp
from mediapipe.tasks.python.genai import converter
config = converter.ConversionConfig(
# Other params related to base model
...
# Must use gpu backend for LoRA conversion
backend='gpu',
# LoRA related params
lora_ckpt=LORA_CKPT,
lora_rank=LORA_RANK,
lora_output_tflite_file=LORA_OUTPUT_TFLITE_FILE,
)
converter.convert_checkpoint(config)
הממיר יפיק שני קובצי flatbuffer של TFLite, אחד למודל הבסיס והשני למודל LoRA.
הסקת מודל LoRA
ממשקי ה-API של LLM Inference לאינטרנט, ל-Android ול-iOS עודכנו כדי לתמוך בהסקת מודלים של LoRA.
באינטרנט יש תמיכה ב-LoRa דינמי במהלך זמן הריצה. כלומר, המשתמשים מכריזים על הדירוגים של LoRA שבהם הם מתכוונים להשתמש במהלך האינטוליזציה, ויכולים להחליף בין מודלים שונים של LoRA במהלך זמן הריצה.const genai = await FilesetResolver.forGenAiTasks(
// path/to/wasm/root
"https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm"
);
const llmInference = await LlmInference.createFromOptions(genai, {
// options for the base model
...
// LoRA ranks to be used by the LoRA models during runtime
loraRanks: [4, 8, 16]
});
במהלך זמן הריצה, אחרי שמפעילים את מודל הבסיס, אפשר לטעון את מודלי ה-LoRa לשימוש. בנוסף, מפעילים את מודל LoRA על ידי העברת ההפניה למודל LoRA בזמן יצירת התשובה של LLM.
// Load several LoRA models. The returned LoRA model reference is used to specify
// which LoRA model to be used for inference.
loraModelRank4 = await llmInference.loadLoraModel(loraModelRank4Url);
loraModelRank8 = await llmInference.loadLoraModel(loraModelRank8Url);
// Specify LoRA model to be used during inference
llmInference.generateResponse(
inputPrompt,
loraModelRank4,
(partialResult, done) => {
document.getElementById('output').textContent += partialResult;
});