הבלוג של ארתיום
בלוג על לינוקס, תוכנה חופשית, מוזיקה, סלסה, ומה לא!
מאמרים בנושא בינה מלאכותית.
התקדמות חשובה בתמיכה ב־OpenCL ב־pytorch.
רקע
היום pytorch היא אחת התשתיות המובילות בעולם למידה עמוקה. יש לה יתרונות רבות, אבל מבחינת המפתח זה קוד איכותי ותיעוד טוב. הקוד כתוב בצורה מאוד מודרנית עם שימוש נכון ביכולות C++ מה שמאוד מקל על הפיתוח. אני עובד בתקופה האחרונה על פיתוח מנוע עבור pytorch מבוסס OpenCL כחלופה ל־cuda.
כבר כתבתי בעבר על חשיבות התמיכה ב־OpenCL.
אבל בכל זאת אזכיר כמה נקודות מבחינת קהילת תוכנה חופשית וקוד פתוח:
- אנחנו זקוקים בתמיכה חוצת פלטפורמה בכרטיסי מסך מיצרנים שונים כמו AMD, Intel וכמובן nVidia.
- אנחנו זקוקים למימוש האלגוריתמים המרכזיים כקוד פתוח הזמין לכל (ולא כקופסה סגורה ש־nVidia נותנת)
- אנחנו רוצים לעבוד עם סטנדרטים פתוחים וזמינים כמו OpenCL ולא מימושים ספציפיים של יצרן (כמו cuda).
אז מה חדש? קלות אינטגרציה!
עם שחרור גרסה 1.13 של pytorch חל שיפור משמעותי ב־out-of-tree-backend. עכשיו הוספת מנוע אימון מבוסס OpenCL היא פשוטה מאוד ולמעשה שאלה של מספר דקות, אפילו בוונידוס העניין יחסית פשוט. המשמעות שאפשר להשתמש במנוע OpenCL בקלות רבה הן בלינוקס והן בווינדוס.
מה עם הביצועים? אם משווים מול גרסת cuda/cudnn על אותו ה־gpu מדובר בין 50 ל־70 אחוז ביצועי cuda באימון ובין כ־60 ל־80 באבלואציה (תלוי ברשת כמובן).
למרות שהמנוע עדיין ניסיוני וחסרים בו לא מעט פעולות הוא נבדק בהצלחה על עשרות רשתות כמו resnet, mobilenet ורבות אחרות.
המנוע עצמו מבוסס על ספריית dlprimitives שאני מפתח במקביל והיא חלופה ל־cuDNN על בסיס OpenCL וגם מנוע חיזוי שעובד עם מודלים בפורמט ONNX - שזה נושא גדול בפני עצמו.
מה המשמעות של זה?
משתמשי AMD יכולים לאמן רשתות. הם לא מוגבלים למספר מצומצם של דגמים ש־rocm תומך בהם או לשימוש בלינוקס בלבד. התמיכה היא גורפת מ־APUים ישנים כמו Stoney Ridge ועד ל־RDNA 2 וגם זה עובד על "חלונות" למי שמעוניין.
זו הייתה משימה כמעט ובלי אפשרית עד היום. עכשיו זה במרחק מספר פקודות
תשתית אימון היא קוד פתוח לגמרי גם אם עובדים עם nVidia (טוב חוץ מהדרייבר שלהם)
- כל מה שצריך זה דרייברי של OpenCL. לא צריך את כל המפלצת של cuda (מי שיצא לו להתקין לשדרג לגלות בעיות תאימות יבין אותי מידי)
מחפש עזרה...
מישהו יודע איך אפשר לבנות ולפרסם whl לפלטפורמות שונות? רצוי איזה שירות ענן שיעשה זאת? כדי שזה יהיה ממש במרחק של pip install :-)
מעשה בשני NaNים
לאחרונה ניסיתי להריץ אימון של GAN על pytorch עם תמיכה ב־dlprimitives. אחד דברים הלא נעימים באימון של GANים באופן כללי זה שהם לא ממש יציבים ומתבדרים בקלות.
שמתי לב שבגרסת cuda הוא רץ ללא דופי ובגרסה שלי הוא נתקע. נתקע על ביצוע backpropogation ב־convolution. אחד ההבדלים העיקריים באגלוריתם בהשוואה לשאר היה שימוש בפעולות אטומיות לחישוב סכום (טריק מאוד נפוץ במימוש קונבולוציה)
אחרי זמן מה הגעתי למסקנה שהחישובים מגיעים ל־NaN באיזהו מקום ואז הכל נתקע. לא הבנתי למה פעולת חיבור אטומית פשוטה נתקעת. בכל מקרה איתרתי באג האחר שהביא לחישוב ה־NaN והכל הסתדר. אבל בכל זאת נושא התקיעה הטריד אותי.
כתבתי שאלה ב־Stackoverflow העתקתי קטע קוד... ואז נפל האסימון
float oldv = *ptr;
for(;;) {
float newv = oldv + v;
float prev = as_float(atomic_cmpxchg((__global volatile int *)(ptr),as_int(oldv),as_int(newv)));
if(prev == oldv)
return;
oldv = prev;
}
קחו לכם כמה דקות.
פעולת comxchg ב־OpenCL עובדת רק על int. לכן הייתי צריך לעשות bit-casting ל־int ובחזרה (as_float
ו־as_int
בדיוק עושים את זה). ואז תנאי הבדיקה prev==old
ביצעתי ב־float במקום בשלמים.
כך שאם הערכים שווים אז ההחלפה הצליחה. אבל מה שכחתי? NaN == NaN תמיד נותן false! ולכן תקעתי בלולאה אינסופית כי התנאי לעולם לא ייתקיים. החלפתי לבדיקה בערכים שלמים (קרי ייצוג בינארי) והכל עבד חלק.
מסקנה NaN הוא טריקי... יש לכבדו
עדכוני dlprimitives
מספר עדכונים:
התקדמות יפה עם pytorch - בוצעה ולידציה של מרבית הרשתות של סיווג הנמצאות ה־torchvision:
alexnet
resnet18
resnet50
vgg16
densenet161
googlenet
squeezenet1_0
inception_v3
shufflenet_v2_x1_0
mobilenet_v2
mobilenet_v3_large
mobilenet_v3_small
resnext50_32x4d
wide_resnet50_2
mnasnet1_0
efficientnet_b0
efficientnet_b4
regnet_y_400mf
מה שאומר שניתן לאמן עכשיו הרבה סוגי רשתות. על הדרך מצאתי לא מעט באגים ותיקנתי אותם
ניסיתי לעשות אינטגרציה עם OneDNN של אינטל (מאין cudnn ל־GPU שלהם) רק כדי לגלות שהביצועים שלהם בפורמט NCHW גרועים. כיוון שרוב התשתיות עובדות עם הפורמט הזה pytorch, caffe, mxnet ועוד אז OneDNN לא ממש רלוונטי בינתיים. אחזור לשם כשיקרה אחד מהשניים:
- אינטל יתקנו את הביצועים עבור הפורמט הנפוץ
- אני אפתח תמיכה ב־NHWC לטובת TensorFlow בו זה פורמט ברירת מחדל
המשך יבוא
התחלתי להתקדם לאימון בקוד פתוח: pytorch עם תמיכה ב־OpenCL
תקציר: הצלחתי לבצע inference של AlexNet ב־pytorch ב־OpenCL. הביצועים זהים לפעלה ישירה של dlprimitives.
הדרך עוד ארוכה אבל פחות קצת יותר ברורה מה לעשות. המאמר המלא באנגלית בבלוג הפיתוח:
http://blog.dlprimitives.org/post/5
מדוע אנחנו זקוקים ל־deep-learning מבוסס OpenCL?
במאמר חדש http://blog.dlprimitives.org/post/2 אני סוקר את הסיבות והצורך בהקמת תשתית למידה חישובית מבוססת OpenCL. אני מתייחס כאן לסיבות שהן לאו דווקא סיבות "אידואולוגיות" כמו שימוש בקוד פתוח אלא גם מתייחס לנושאים טכניים ומהותיים:
- מחקר ואלגוריתמים
- וניהול פרויקטים לטווח רחוק
- שיפור מוצר ע"י תחרותיות