אופטימיזציה של מודלי ML עבור Core ML למכשירי Apple

המודל עובד בשרת, אך האפליקציה זקוקה לתגובה כאן ומיד — בלי להמתין לרשת. אנו מבצעים המרה של המודל ל-Core ML במסלול מלא: מעבירים את החישובים למכשיר, בודקים את הדיוק ומוסרים גרסה מוכנה. האפליקציה מגיבה מהר יותר באופן ניכר, צריכת הסוללה יורדת, והתנהגות המודל נשארת צפויה בכל מגוון המכשירים.

תחומי פיתוח AI

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1365
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • עיצוב לוגו לחברת B2B Advance
    עיצוב לוגו לחברת B2B Advance
    776
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח לוגו חברת AIDER
    פיתוח לוגו חברת AIDER
    1022
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113

מדוע המרת מודל ל-Core ML נשברת בבדיקה

המרת מודל ל-Core ML נראית כמו קריאה אחת לממיר, אך השגיאה בהעברת המודל כמעט אף פעם לא נוצרת בשלב הזה. המחסום הראשון — פעולות שאינן נתמכות: אב-טיפוס מחקרי מכיל בדרך כלל שכבות שאין להן מקבילה ישירה ב-Apple, והממיר או נעצר, או מציב בשקט תחליף מפושט. המודל נבנה ורץ, אבל מחשב משהו אחר — כאן נפרדות הציפיות מהמציאות.

המחסום השני — פערים בתוצאות. בעת ההעברה משתנים סוגי החישוב: האימון מתבצע ברדיוק מלא, במכשיר מופעל חצי-רדיוק, ואיתו — עיגול שונה וסדר פעולות שונה. הפרש, שבסביבת הבדיקה נראה כמו הספרה השלישית אחרי הנקודה העשרונית, בפלט הופך למחלקה אחרת או למסגרת מוסטת.

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

המחסום השלישי — תנאי הפעלה אמיתיים. המכשיר מוגבל בזיכרון, מתחמם ומפחית תדרים, המצלמה והמיקרופון צורכים משאבים, והאפליקציה ממוזערת לרקע. מודל יציב על סטנד — בשטח נותן השהיות וכשלים; חלק מהפגמים נראים רק בלוגים של גרסאות חיות.

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

מה נותנת האופטימיזציה: מהירות, תגובתיות, משאבי המכשיר

הרצה מקומית של המודל משנה את פרופיל האפליקציה יותר מכפי שנדמה בשלב האב-טיפוס. החישובים מתבצעים על המכשיר עצמו דרך Core ML, ולכן זמן התגובה מפסיק להיות תלוי באיכות הרשת: פריים או טקסט מעובדים בשברירי שנייה, ולא אחרי סבב לשרת וחזרה. המשתמש רואה את תגובת הממשק מיד — ברמה הזו ההבדל בין „עובד" ל„עובד נעים" נעשה ברור.

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

נפח האפליקציה — המדד השלישי, שנראה בדוחות החנות. משקל המודל נכלל בבנייה ומשפיע ישירות על שיעור ההתקנות המבוטלות: ככל שהחבילה גדולה יותר, כך המשתמש מפסיק את ההורדה לעתים קרובות יותר.

כיווץ משקלות וויתור על שכבות שאינן בשימוש מקטינים את תרומת המודל לגודל הבנייה פי כמה, וענפים כבדים ניתן להוריד לפי דרישה — כבר אחרי ההפעלה הראשונה.

חלק מהכשלים נעלם כמחלקה שלמה. נעלמים פסקי זמן, שגיאות רשת ואי-זמינות של השירות בצד השרת: התרחיש עובד אופליין — ברכבת התחתית, במטוס, בערוץ חלש.

נשארים רק כשלים הקשורים לנתונים ולזיכרון המכשיר: קלט לא מתאים, פורמט נדיר, חוסר במשאבים בדגמים ישנים — אותם אנחנו סוגרים בבדיקות ובמסלול עיבוד חלופי.

אפשרויות המרה: במכשיר, בענן או מצב משולב

המרת מודל ל-Core ML נותנת פורמלית ארטיפקט אחד, אך הוא יכול להתבצע בשלושה מצבים שונים — ואלו החלטות ארכיטקטוניות שונות, ולא מתג בהגדרות. המצב קובע היכן נמצאים המשקלות, כיצד המודל מתעדכן לאחר אימון נוסף ואילו דרישות מוצבות לזיכרון ולצריכת החשמל של המכשיר.

מצב מתי מתאים מגבלות
הרצה מקומית נתונים אישיים אינם צריכים לעזוב את המכשיר, יש צורך בתגובה ללא רשת, קהל על הקו העדכני גודל המודל נתקל בזיכרון הזמין; תרחישים כבדים מחממים את המארז ומכלים את הסוללה; עדכון רק יחד עם שחרור גרסת האפליקציה
הרצה בענן חישובים כבדים, פעולות נדירות ויקרות, יש צורך בהחלפת מודל בלי להוציא בנייה חדשה נדרשת רשת, התגובה תלויה בערוץ התקשורת, הנתונים עוברים לשרת
מצב משולב פעולות קלות תכופות — במכשיר, כבדות — בשרת יקר יותר בפיתוח: שני ענפי חישוב, סנכרון גרסאות, סכימה אחידה של עיבוד מקדים של נתונים

בחירת מצב ההרצה מתחילה לא מהמודל, אלא ממגבלות המוצר: רגישות הנתונים, השהיית תגובה מותרת, דרישות פרטיות. לאחר מכן אנחנו מחשבים את תקציב הזיכרון והחימום לקו המכשירים היעד ורק אחרי זה מחליטים מה להוציא לשרת ומה להשאיר מקומית.

שלבי העבודה: אבחון, סכימה, בנייה, בדיקה, מסירה

כל אופטימיזציה מתחילה במדידות, ולא בבנייה מחדש של המודל: בלי מספרים של זמן תגובה, זיכרון וחימום לא ברור היכן צוואר הבקבוק — בגרף החישוב, במשקלות או באופן שבו האפליקציה פונה למודל. לכן העבודה מתנהלת בשלבים קבועים, ובכל שלב נשאר ארטיפקט שניתן לבדוק.

איך נראית העבודה שלב אחר שלב

  1. אבחון הפתרון הנוכחי — מנתחים כיצד המודל אומן ובאיזה פורמט הצוות מוסר אותו, אילו שכבות אינן מועברות ישירות והיכן ייתכן אובדן דיוק.
  2. פרופיילינג על מכשירי היעד — מודדים זמן תגובה, צריכת זיכרון וחימום על טלפונים וטאבלטים אמיתיים, ולא על סטנד בדיקה.
  3. סכימת ההמרה — קובעים אילו פעולות מחליפים בגרף, היכן מכמתים משקלות ואיזה מרווח דיוק נחשב מותר.
  4. המרת המודל ל-Core ML — בונים את החבילה, בודקים תמיכה בפעולות ומשווים את הפלטים למודל המקורי על סט דוגמאות בקרה.
  5. בנייה למכשיר — מרכיבים את המודל עם האפליקציה, בוחרים מצב האצה ובודקים הפעלה קרה.
  6. בדיקה בתרחישים אמיתיים — מריצים קלט נדיר ורועש, בודקים התנהגות בעת חוסר זיכרון ובמעבר בין אפליקציות.
  7. קבלת התוצאה — משווים מדדים לפני ואחרי לפי מתודולוגיה אחת, מוסרים קונפיגורציות, הוראות בנייה ודוח, ובמקרה של פער חוזרים לבנייה הקודמת.

ארטיפקטים של הפרויקט: קונפיגורציות, סכימות, נהלים, תיעוד

המרת מודל ל-Core ML — רק השכבה העליונה של העבודה. בלי תיאור של אופן שחזור הבנייה, העדכון הבא הופך להתכתבות עם הקבלן, ולכן אחרי המסירה נשאר אצל הלקוח כל קווי המתאר: קונפיגורציות בנייה, סכימות, כללי ניהול גרסאות ונוהל עדכון.

  • קונפיגורציות בנייה — כיצד המודל והמעטפת נבנים לגרסת המערכת הנדרשת ולרוחב הסיביות של המכשיר, עם תלויות מקובעות: בנייה חוזרת נותנת את אותה תוצאה.
  • סכימות עיבוד נתונים — עיבוד מקדים, נרמול ועיבוד לאחר של פלטים, עם ציון נקודות הקריאה למודל באפליקציה.
  • כללי ניהול גרסאות — כיצד ממוספרים המשקלות והקונפיגורציות, מה נחשב לשינוי לא תואם וכיצד גרסת המודל נקשרת לגרסת האפליקציה.
  • נוהל עדכון — הוצאה שלב-אחר-שלב של גרסה חדשה: הרצה על סט בקרה, בדיקת מדדים, תנאי חזרה לבנייה הקודמת.
  • תיעוד המודל — כניסות ויציאות, מגבלות גודל וזמן תגובה, נקודות תורפה ידועות ומדדי קבלה.
  • סט בקרה ובדיקות — דוגמאות קלט מקובעות עם תוצאות צפויות, כדי לראות פער לפני העלייה לאוויר.
  • סכימת אינטגרציה — נקודות קריאה, טיפול בשגיאות והתנהגות בעת כשל של המודל באפליקציה.

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

דוגמה מהפרקטיקה: האצת האפליקציה לאחר אופטימיזציה

הפרויקט — שירות נייד לזיהוי אובייקטים בתמונה: המשתמש מצלם פריים וממתין לתוצאה. בתחילה המודל חושב בצד השרת — הפריים נשלח לעיבוד וחזר דרך הרשת. על סטנד הבדיקה הסכימה נראתה עובדת, אך אצל משתמשים אמיתיים היא נתקלה בשני מקומות: השהיית התגובה ואובדנים בקישור לא יציב.

היכן בדיוק איבדנו

כל בקשה עברה סבב מלא: כיווץ הפריים, שליחה, תור לעיבוד, דרך חזרה. בשעות שיא התור גדל, והתגובה התארכה מ-0.8 ל-2.5 שניות — המשתמש הספיק לסגור את האפליקציה. ברשת סלולרית חלק מהבקשות נקטעו באמצע: כ-6.5% מהפעולות הסתיימו בכישלון. זו מחלקה של כשלים שלא נרפאה בצד השרת — הסיבה הייתה בערוץ, ולא במודל עצמו.

מה שינינו

הסקת המודל הועברה למכשיר עצמו: המרת הרשת ל-Core ML, כיווץ המשקלות, הפחתת דיוק החישוב היכן שלא השפיע על הזיהוי, והעברת העיבוד המקדים של הפריים לתהליכון נפרד. הפריים כבר לא עוזב את המכשיר — נעלמו גם התור וגם הסבב ברשת.

זמן התגובה הצטמצם פי 8-9, מ-0.8 ל-0.09 שניות. שיעור הפעולות הכושלות ירד ל-0.4%, גודל המודל במכשיר קטן מ-240 ל-70 MB, והעומס על קו השרת ירד עד כדי כך שהפסיקו להרחיב את כושרו עם גידול הקהל. איכות הזיהוי על מדגם הבקרה לא ירדה — זה נבדק בהרצה נפרדת לפני העלייה לאוויר.

מה לעשות אם האפליקציה כבר משתמשת בסביבת הרצה אחרת?

אין צורך לכתוב את האפליקציה מחדש כולה: סביבת ההרצה היא שכבת הסקת המודל, ולא הלוגיקה העסקית. המסכים, העבודה עם המצלמה ואחסון הנתונים נשארים כשהיו, משתנה רק מה שעומד מאחורי הקריאה „לקבל חיזוי". היקף העבודה תלוי במידה שבה המודל המקורי נשען על יכולות הסביבה הקודמת.

בנייה מחדש של מודל קיים — התרחיש הבסיסי. אם הארכיטקטורה מורכבת משכבות סטנדרטיות, המשקלות מועברים כפי שהם, והפלטים תואמים לקודמים בגבולות הפער המותר. המעבר בלי כתיבה מחדש נשען על מתאם קריאה: טנסורי הכניסה והיציאה מותאמים לסוגים הקודמים, ואת שאר הקוד לא נוגעים.

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

אימון מחדש ובדיקה מחודשת של הארכיטקטורה — עבור מודלים שתלויים במאפיינים של השרת: צורות כניסה דינמיות, טרנספורמציות מאפיינים לא סטנדרטיות.

אפשרות מתי מתאים מגבלות
בנייה מחדש של מודל קיים שכבות סטנדרטיות, משקלות ללא שינוי אופרטורים נדירים אינם עוברים
אימון נוסף חלק מהפעולות הוחלפו בשקולים נדרש מדגם אימון והרצת בדיקה
אימון מחדש הארכיטקטורה תלויה בסביבת השרת ארוך יותר, דורש השוואת מדדים עם הגרסה הנוכחית
בחינה מחודשת של הארכיטקטורה המודל עובר כולו למכשיר משתנות הדרישות לזיכרון ולגודל הבנייה

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

מגבלות, תאימות ודרישות לנתונים

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

את הדרישות לנתונים בודקים לפני ההתחלה: פורמט התיוג, איזון מחלקות, שיעור החסרים, התאמת ההתפלגויות במדגם האימון ובמדגם הבדיקה. אם המדגמים נאספו בדרכים שונות, הירידה לאחר ההמרה ל-Core ML תתגלה כתוצאה של הנתונים, ולא של האופטימיזציה — זה נראה בניתוח, ולא אחרי השחרור.

אילו פעולות אינן מועברות למכשיר?

צורות דינמיות של טנסורים, שכבות קשב לא סטנדרטיות, אופרטורים מותאמים אישית. אותם או מבטאים דרך נתמכים, או משאירים בצד השרת — ההחלטה מתקבלת לפי מדידת האיכות וזמן התגובה.

כיצד נבדקת האיכות לאחר האופטימיזציה?

מכינים סט כניסות ייחוס, קובעים את תשובות המודל המקורי ומשווים לתשובות המודל המומר: פער במדד היעד, שיעור התשובות שאינן תואמות, התנהגות בדוגמאות קצה. בנפרד מריצים על מכשירים אמיתיים בפארק היעד.

מה עם מכשירים מדורות קודמים?

בונים מטריצת תאימות: על אילו דורות וגרסאות מערכת המודל עובד, והיכן מופעל מסלול חלופי. עבור מכשירים חלשים מכינים מראש ענף מוקל, כדי שהאפליקציה לא תאבד פונקציונליות.

נדון במשימה: מה נדרש להערכת לוחות זמנים

זמן ההערכה להעברת המודל למכשיר נקבע לא לפי גודלו, אלא לפי מספר השכבות שאין להן מיפוי תקני ב-Core ML, ולהיקף העיבוד המקדים של נתוני הכניסה. ככל שנראה את הארכיטקטורה ואת הדוגמאות החיות מוקדם יותר, כך יהיה פחות מרווח באי-ודאות בתוכנית. להלן — מה מספיק לשלוח כדי שנחזור עם תוכנית עבודה, ולא עם טווח רחב.

  • ארכיטקטורה ומשקלות של המודל המאומן: סטק האימון, סקריפט בניית הגרף, צ'קפוינט, רשימת אופרטורים לא סטנדרטיים.
  • סט של נתוני כניסה אמיתיים עם תשובות צפויות — 100–300 דוגמאות מספיקות כדי לתפוס פער בתוצאות המספריות לאחר ההמרה.
  • מדדי קבלה: שיעור התשובות הנכונות, פער מותר מול המודל המקורי, דרישות לזמן תגובה ולצריכת סוללה.
  • תרחיש העבודה במכשיר: הסקה מקומית לחלוטין, הורדה של משקלות מעודכנים או היברידי עם פנייה לשרת.
  • מגבלות: גרסאות מערכת נתמכות, פארק המכשירים, גודל האפליקציה, עבודה ללא רשת.
  • גישות: מאגר, סביבת בנייה, פארק מכשירים לבדיקה, חשבונות לפרסום.
  • דרישות פרטיות: אילו נתונים אינם צריכים לעזוב את המכשיר.

אנחנו חוזרים עם תוכנית עבודה: שלבים, התוכן של כל אחד, נקודות קבלה ומה שאנחנו רואים כתוצאה. השלב הראשון — פיילוט: מעבירים מודל אחד, מודדים איכות ומהירות על מכשירים חיים, קובעים פערים. אחריו רואים אם הגישה ניתנת לשכפול על שאר המודלים ובאיזה קצב, — הערכת לוחות הזמנים נעשית עניינית.