מדריך להסקת מסקנות LLM לאתרים

בעזרת LLM Inference API אפשר להריץ מודלים גדולים של שפה (LLM) לגמרי בדפדפן לאפליקציות אינטרנט. אפשר להשתמש בהם כדי לבצע מגוון רחב של משימות כמו יצירת טקסט, אחזור מידע בפורמט שפה טבעית (LLM) וסיכום מסמכים. המשימה כוללת תמיכה מובנית בכמה מודלים של שפה גדולה (LLM) של טקסט לטקסט, כדי שתוכלו להחיל על אפליקציות האינטרנט שלכם את המודלים העדכניים ביותר של הבינה המלאכותית הגנרטיבית במכשיר.

ניתן לראות את המשימה הזו בפעולה בהדגמה של 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: חלק ממשפחה של מודלים פתוחים קלילים וחדשניים שנוצרו על סמך אותם מחקר וטכנולוגיה ששימשו ליצירת הדגמים של Gemini. מתאימה למגוון רחב של משימות של יצירת טקסט, כולל מענה על שאלות, תמצות והבנת תשובות. צריך להוריד את וריאנט הדגם של Gemma 2B או Gemma 7B.
  • Phi-2: מודל טרנספורמר של 2.7 מיליארד פרמטרים, המתאים ביותר לפורמט Question-Answer, צ'אט וקוד.
  • Falcon-RW-1B: מיליארד פרמטרים של מפענח סיבתי בלבד, מודל שאומן על 350 מיליארד אסימונים של RefinedWeb.
  • StableLM-3B: מודל שפה של 3 מיליארד פרמטרים בלבד, שעבר אימון על טריליון אסימונים ממגוון מערכי נתונים של אנגלית וקוד.

מומלץ להשתמש ב-Gemma 2B או ב-Gemma 7B, שזמינים במודלים של Kaggle בפורמט שכבר תואם ל-LLM Inference API. אם אתם משתמשים ב-LLM אחר, תצטרכו להמיר את המודל לפורמט ידידותי ל-MediaPipe. מידע נוסף על Gemma זמין באתר Gemma. למידע נוסף על שאר המודלים הזמינים, עיינו בסקירה הכללית על המשימות קטע על מודלים.

המרת המודל לפורמט MediaPipe

המרה למודל מקורי

אם אתם משתמשים ב-LLM חיצוני (Phi-2, Falcon או StableLM) או בגרסה שאינה של Gemma, השתמשו בסקריפטים של ההמרות כדי לעצב את המודל כך שיתאים ל-MediaPipe.

תהליך המרת המודל מחייב חבילת MediaPipe PyPI. סקריפט ההמרה זמין בכל חבילות MediaPipe אחרי 0.10.11.

מתקינים ומייבאים את יחסי התלות באמצעות הפעולות הבאות:

$ python3 -m pip install mediapipe

משתמשים בספרייה genai.converter כדי להמיר את המודל:

import mediapipe as mp
from mediapipe.tasks.python.genai import converter

config = converter.ConversionConfig(
  input_ckpt=INPUT_CKPT,
  ckpt_format=CKPT_FORMAT,
  model_type=MODEL_TYPE,
  backend=BACKEND,
  output_dir=OUTPUT_DIR,
  combine_file_only=False,
  vocab_model_file=VOCAB_MODEL_FILE,
  output_tflite_file=OUTPUT_TFLITE_FILE,
)

converter.convert_checkpoint(config)

כדי להמיר את מודל LoRA, יש לציין ב-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)

הממיר יפיק שני קובצי TFLite למאגר אחסון שטוח, אחד למודל הבסיסי והשני למודל LoRA.

פרמטר תיאור ערכים מותרים
input_ckpt הנתיב לקובץ model.safetensors או pytorch.bin. חשוב לשים לב שלפעמים הפורמט של פריטי ה-safetensors מחולקים למספר קבצים, למשל model-00001-of-00003.safetensors, model-00001-of-00003.safetensors. אפשר לציין תבנית של קובץ, כמו model*.safetensors. PATH
ckpt_format פורמט הקובץ של המודל. {"safetensors", "pytorch"}
model_type ה-LLM עובר המרה. {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B"}
backend המעבד (הגישה) ששימש להפעלת המודל. {"cpu", "gpu"}
output_dir הנתיב לספריית הפלט שמארחת את קובצי המשקל לכל שכבה. PATH
output_tflite_file הנתיב לקובץ הפלט. לדוגמה, "model_cpu.bin" או "model_gpu.bin". הקובץ הזה תואם רק ל-LLM Inference API, ואי אפשר להשתמש בו כקובץ 'tflite' כללי. PATH
vocab_model_file הנתיב לספרייה שמאחסנת את הקבצים tokenizer.json ו-tokenizer_config.json. עבור Gemma, מצביעים על הקובץ tokenizer.model היחיד. PATH
lora_ckpt הנתיב לקובץ Safetensors של LoRA ששומר את משקל המתאם של LoRA. PATH
lora_rank מספר שלם שמייצג את הדירוג של LoRA ckpt. נדרש כדי להמיר את משקולות הלורה. אם לא מציינים את הפרמטר הזה, הממיר מניח שאין משקלי LoRA. הערה: רק הקצה העורפי של ה-GPU תומך ב-LoRA. מספר שלם
lora_output_tflite_file שם קובץ tflite של הפלט של המשקולות של LoRA. PATH

המרה של מודל AI Edge

אם אתם משתמשים ב-LLM שממופה למודל TFLite באמצעות AI Edge, תוכלו להשתמש בסקריפט הקיבוץ כדי ליצור חבילת משימות. תהליך הקיבוץ כולל את המודל הממופה עם מטא-נתונים נוספים (למשל, פרמטרים של אסימון) שנדרשים כדי להריץ הסקת מסקנות מקצה לקצה.

תהליך קיבוץ המודלים מחייב חבילת MediaPipe PyPI. סקריפט ההמרה זמין בכל חבילות MediaPipe אחרי 0.10.14.

מתקינים ומייבאים את יחסי התלות באמצעות הפעולות הבאות:

$ python3 -m pip install mediapipe

אפשר להשתמש בספרייה genai.bundler כדי לקבץ את המודל:

import mediapipe as mp
from mediapipe.tasks.python.genai import bundler

config = bundler.BundleConfig(
    tflite_model=TFLITE_MODEL,
    tokenizer_model=TOKENIZER_MODEL,
    start_token=START_TOKEN,
    stop_tokens=STOP_TOKENS,
    output_filename=OUTPUT_FILENAME,
    enable_bytes_to_unicode_mapping=ENABLE_BYTES_TO_UNICODE_MAPPING,
)
bundler.create_bundle(config)
פרמטר תיאור ערכים מותרים
tflite_model הנתיב למודל TFLite שיוצא באמצעות AI Edge. PATH
tokenizer_model הנתיב למודל האסימונים של SentencePiece. PATH
start_token אסימון התחלה ספציפי לדגם. אסימון ההתחלה חייב להיות קיים במודל ההמרה לאסימונים. מחרוזת
stop_tokens הדגמה של אסימוני עצירה ספציפיים. אסימוני העצירה חייבים להיות קיימים במודל ההמרה לאסימונים. רשימה[STRING]
output_filename שם קובץ חבילת משימות הפלט. PATH

הוספת מודל לספריית הפרויקט

אחסן את המודל בספריית הפרויקט שלך:

<dev-project-root>/assets/gemma-2b-it-gpu-int4.bin

מציינים את הנתיב של המודל באמצעות הפרמטר baseOptions של האובייקט modelAssetPath:

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 האסימונים בעלי הסבירות הגבוהה ביותר. כשמגדירים את topK, צריך להגדיר גם ערך עבור randomSeed. מספר שלם 40
temperature כמות הרנדומיזציה שהוכנסה במהלך היצירה. טמפרטורה גבוהה יותר מובילה ליצירתיות רבה יותר בטקסט שנוצר, וטמפרטורה נמוכה יוצרת יצירה צפויה יותר. כשמגדירים את temperature, צריך להגדיר גם ערך עבור randomSeed. Float 0.8
randomSeed המקור האקראי שנעשה בו שימוש במהלך יצירת הטקסט. מספר שלם 0
loraRanks הדירוג של LoRA במודלים של LoRA לשימוש במהלך זמן ריצה. הערה: האפשרות הזו תואמת רק לדגמים של GPU. מערך של מספרים שלמים לא רלוונטי

הכנת הנתונים

LLM Inference API מקבל נתוני טקסט (string). המשימה מטפלת בעיבוד מראש של קלט הנתונים, כולל המרה לאסימונים ועיבוד מראש של tensor.

כל העיבודים מראש מטופלים בפונקציה 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

אפשר להגדיר את ה-API להסקת ה-LLM של Mediapipe כך שיתמוך באדפטציה נמוכה (LoRA) במודלים גדולים של שפה (LLM). מפתחים יכולים להשתמש במודלים משופרים של LoRA כדי להתאים אישית את ההתנהגות של מודלים גדולים של שפה, באמצעות תהליך אימון חסכוני.

התמיכה של LoRA ב-LLM Inference API פועלת במודלים מסוג Gemma-2B ו-Pi-2 בקצה העורפי של ה-GPU, עם משקלי LoRA שרלוונטיים לשכבות תשומת לב בלבד. ההטמעה הראשונית הזו משמשת כ-API ניסיוני לפיתוחים עתידיים, עם תוכניות לתמוך במודלים נוספים ובסוגים שונים של שכבות בעדכונים הקרובים.

הכנת מודלים של LoRA

פועלים לפי ההוראות ב-HugingFace כדי לאמן מודל LoRA שעבר כוונון עדין במערך נתונים משלכם עם סוגי מודלים נתמכים, Gemma-2B או Phi-2. הדגמים Gemma-2B ו-Pi-2 זמינים ב-HugingFace בפורמט Safetensors. מכיוון ש-LLM Inference API תומך רק ב-LoRA בשכבות תשומת לב, צריך לציין רק שכבות תשומת לב כשיוצרים את LoraConfig באופן הבא:

# For Gemma-2B
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, שזמינים ב-HugingFace. לדוגמה: monsterapi/gemma-2b-lora-maths-orca-200k עבור Gemma-2B, ו-lole25/phi-2-sft-ultrachat-lora עבור Phi-2.

אחרי אימון על מערך הנתונים המוכן ושמירת המודל, מתקבל קובץ adapter_model.safetensors שמכיל את המשקלים המדויקים של מודל LoRA. קובץ Safetensors הוא נקודת הביקורת של LoRA שמשמשת בהמרת המודל.

בשלב הבא, צריך להמיר את משקלי המודל ל-TensorFlow Lite Flatbuffer באמצעות חבילת MediaPipe Python. השדה 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)

הממיר יפיק שני קובצי TFLite למאגר אחסון שטוח, אחד למודל הבסיסי והשני למודל LoRA.

הסקת מודל LoRA

ה-LLM Inference API של האינטרנט, ה-Android ו-iOS מתעדכנות כדי לתמוך בהסקה של מודל LoRA. האינטרנט תומך ב-LoRA דינמי, שיכול להחליף מודלים שונים של LoRA במהלך זמן הריצה. ב-Android וב-iOS יש תמיכה ב-LoRA הסטטי, שמשתמש באותם משקלים של 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;
});