מדריך להסקת מודלים של LLM ל-iOS

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

המשימה תומכת באפשרויות הבאות של Gemma: Gemma-2 2B,‏ Gemma 2B ו-Gemma 7B. Gemma היא משפחה של מודלים פתוחים וקלים לשימוש, שנוצרו על סמך אותו מחקר וטכנולוגיה ששימשו ליצירת המודלים של Gemini. הוא תומך גם בדגמים החיצוניים הבאים: Phi-2,‏ Falcon-RW-1B ו-StableLM-3B.

בנוסף למודלים הנתמכים, המשתמשים יכולים להשתמש ב-AI Edge Torch של Google כדי לייצא מודלים של PyTorch למודלים של LiteRT (tflite) עם חתימות מרובות, שמצורפים לפרמטרים של ה-tokenizer כדי ליצור חבילות משימות שתואמות ל-LLM Inference API.

אתם יכולים לראות את המשימה הזו בפעולה בהדגמה של MediaPipe Studio. מידע נוסף על היכולות, המודלים והאפשרויות להגדרה של המשימה הזו זמין בסקירה הכללית.

קוד לדוגמה

קוד הדוגמה של MediaPipe Tasks הוא הטמעה בסיסית של אפליקציית LLM Inference API ל-iOS. אפשר להשתמש באפליקציה כנקודת התחלה לאפליקציית iOS משלכם, או להיעזר בה כשמשנים אפליקציה קיימת. קוד הדוגמה של LLM Inference API מתארח ב-GitHub.

מורידים את הקוד

בהוראות הבאות מוסבר איך ליצור עותק מקומי של קוד הדוגמה באמצעות כלי שורת הפקודה git.

כדי להוריד את הקוד לדוגמה:

  1. משכפלים את מאגר ה-git באמצעות הפקודה הבאה:

    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. אפשר גם להגדיר את מכונה של git כך שתשתמש ב-sparse checkout, כך שיישארו רק הקבצים של אפליקציית הדוגמה של LLM Inference API:

    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/llm_inference/ios/
    

אחרי שיוצרים גרסה מקומית של קוד הדוגמה, אפשר להתקין את ספריית המשימות של MediaPipe, לפתוח את הפרויקט באמצעות Xcode ולהפעיל את האפליקציה. להוראות, אפשר לעיין במדריך ההגדרה ל-iOS.

הגדרה

בקטע הזה מתוארים השלבים העיקריים להגדרת סביבת הפיתוח ופרויקטי הקוד כך שישתמשו ב-LLM Inference API. מידע כללי על הגדרת סביבת הפיתוח לשימוש במשימות של MediaPipe, כולל דרישות לגבי גרסת הפלטפורמה, זמין במדריך ההגדרה ל-iOS.

יחסי תלות

ב-LLM Inference API נעשה שימוש בספרייה MediaPipeTasksGenai, שצריך להתקין באמצעות CocoaPods. הספרייה תואמת לאפליקציות Swift וגם לאפליקציות Objective-C, ולא נדרשת הגדרה נוספת ספציפית לשפה.

הוראות להתקנת CocoaPods ב-macOS מפורטות במדריך להתקנת CocoaPods. הוראות ליצירת Podfile עם ה-pods הנדרשים לאפליקציה מפורטות במאמר שימוש ב-CocoaPods.

מוסיפים את ה-pod של MediaPipeTasksGenai ב-Podfile באמצעות הקוד הבא:

target 'MyLlmInferenceApp' do
  use_frameworks!
  pod 'MediaPipeTasksGenAI'
  pod 'MediaPipeTasksGenAIC'
end

אם האפליקציה כוללת יעדי בדיקת יחידה, תוכלו לעיין במדריך ההגדרה ל-iOS כדי לקבל מידע נוסף על הגדרת Podfile.

דגם

כדי לבצע את המשימה של MediaPipe LLM Inference API נדרש מודל מאומן שתואם למשימה הזו. מידע נוסף על המודלים המאומנים הזמינים ל-LLM Inference API זמין בקטע 'מודלים' בסקירה הכללית של המשימה.

הורדת מודל

מורידים מודל ומוסיפים אותו לספריית הפרויקט באמצעות Xcode. להוראות להוספת קבצים לפרויקט ב-Xcode, קראו את המאמר ניהול קבצים ותיקיות בפרויקט ב-Xcode.

לפני שמפעילים את 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. בקטע המרת מודלים מוסבר איך ממירים מודלים אחרים.

יצירת המשימה

אפשר ליצור את המשימה של LLM Inference API על ידי קריאה לאחד מהמפעילים שלה. ה-initializer של LlmInference(options:) מגדיר ערכים לאפשרויות התצורה.

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

הקוד הבא ממחיש איך ליצור ולהגדיר את המשימה הזו.

import MediaPipeTasksGenai

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "bin")

let options = LlmInferenceOptions()
options.baseOptions.modelPath = modelPath
options.maxTokens = 1000
options.topk = 40
options.temperature = 0.8
options.randomSeed = 101

let llmInference = try LlmInference(options: options)

אפשרויות הגדרה

למשימה הזו יש את אפשרויות התצורה הבאות לאפליקציות ל-iOS:

שם האפשרות תיאור טווח ערכים ערך ברירת מחדל
modelPath הנתיב שבו המודל מאוחסן בתוך ספריית הפרויקט. PATH לא רלוונטי
maxTokens המספר המקסימלי של אסימונים (אסימוני קלט + אסימוני פלט) שהמודל מטפל בהם. מספר שלם 512
topk מספר האסימונים שהמודל מתייחס אליהם בכל שלב של היצירה. הגבלת התחזיות ל-k האסימונים האפשריים הטובים ביותר. מספר שלם 40
temperature מידת האקראיות שמתווספת במהלך היצירה. טמפרטורה גבוהה יותר מובילה ליצירת טקסט יצירתי יותר, ואילו טמפרטורה נמוכה יותר מובילה ליצירת טקסט צפוי יותר. מספר ממשי (float) 0.8
randomSeed הזרע האקראי שמשמש ליצירת הטקסט. מספר שלם 0
loraPath הנתיב המוחלט למודל LoRA באופן מקומי במכשיר. הערה: האפשרות הזו תואמת רק לדגמי GPU. PATH לא רלוונטי

הכנת הנתונים

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

כל העיבוד המקדים מתבצע בתוך הפונקציה generateResponse(inputText:). אין צורך בעיבוד מקדים נוסף של טקסט הקלט מראש.

let inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."

הרצת המשימה

כדי להריץ את LLM Inference API, משתמשים ב-method‏ generateResponse(inputText:). LLM Inference API מחזיר את הקטגוריות האפשריות לטקסט הקלט.

let result = try LlmInference.generateResponse(inputText: inputPrompt)

כדי להעביר את התגובה בסטרימינג, משתמשים בשיטה generateResponseAsync(inputText:).

let resultStream =  LlmInference.generateResponseAsync(inputText: inputPrompt)

do {
  for try await partialResult in resultStream {
    print("\(partialResult)")
  }
  print("Done")
}
catch {
  print("Response error: '\(error)")
}

טיפול בתוצאות והצגתן

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.

iOS תומך ב-LoRa סטטי במהלך האתחול. כדי לטעון מודל LoRA, המשתמשים מציינים את הנתיב של מודל LoRA ואת ה-LLM הבסיסי.

import MediaPipeTasksGenai

let modelPath = Bundle.main.path(forResource: "model",
                                      ofType: "bin")
let loraPath= Bundle.main.path(forResource: "lora_model",
                                      ofType: "bin")
let options = LlmInferenceOptions()
options.modelPath = modelPath
options.maxTokens = 1000
options.topk = 40
options.temperature = 0.8
options.randomSeed = 101
options.loraPath = loraPath

let llmInference = try LlmInference(options: options)

כדי להריץ את ההסקה של LLM באמצעות LoRA, משתמשים באותן שיטות generateResponse() או generateResponseAsync() כמו במודל הבסיס.