קימפול קטע קוד לתוך טרנספורמר!

אנחנו מאמנים היום טרנספורמרים לממש כל מיני אלגוריתמים פשוטים כמו מיון, ספירה, איזון סוגריים..
מפה לשם דיפמיינד שחררו מאמר שעושה את הכיוון ההפוך:
קימפול קטע קוד לתוך טרנספורמר!
לצורך הקסם, המחברים השתמשו ב"שפת תכנות" "עילית" שאותה אפשר "לקמפל" לתוך הרשת.
כשמסתכלים על המשקולות עצמן לצד הקוד עצמו (בתמונה המצורפת) הקסם מתבהר ונראה שהסוד הוא בהגדרת "שפת התכנות" אותה אפשר "לקמפל" לתוך הרשת.
אנחנו עדיין רחוקים מהיום בו נוכל "לקמפל" כל קטע קוד לתוך רשת נוירונים אבל זו בהחלט עבודה מקורית שיש לה פוטנציאל להיות מאד משמעותית אם ימשיכו בכיוון הזה.
כרגע, המטרה העיקרית כנראה היא לחקור שיטות הסבר לרשתות נוירונים על רשתות שאנחנו יודעים ב-ד-י-ו-ק מה הן עושות. שזה גם מגניב!
השפה אותה דיפמיינד קימפלו לתוך טרנספורמר היא השפה RASP והיא הוגדרה במאמר שכל המחברים שלו נמצאים כאן איתנו בקבוצה!
המאמר: https://arxiv.org/pdf/2106.06981.pdf – נשמח לשמוע ממכם!
סיכום מאמר זריז: לחשוב כמו טרנספורמר
טרנספורמרים נמצאים בכל מקום היום, וכמו כל שאר רשתות הנוירונים: אנחנו בקושי יודעים איך הם עובדים (ולמה הם עובדים). על מנתלהשיג הבנה טובה יותר של אופן פעולתם של טרנספורמרים, הוצעה במאמר Thinking like Transformers סביבת חישוב בדיד כדי לדמות חישובי טרנספורמרים שפותחה לשפת תכנות שלמה הנקראת RASP, בשפה זו כל תוכנית מתקמפלת לטרנספורמר ספציפי.
הכותבים מימשו גרסה של RASP בפייתון, אם בא לכם לשחק: https://github.com/srush/RASPy
שפה זו תואמת בערך לגרסה המקורית במאמר אך יש בה כמה שינויים תחביריים שהופכים אותה ליותר ידידותית. בבלוג הזה: https://srush.github.io/raspy/ המחברים סיפקו סדרה של תרגילים כדי לעזור לנו להבין איך השפה עובדת.
הרעיון בשפה הוא שפעולות מבוצעות על רצף לפי שכבות המודל, כל הפעולות הופכות רצף לרצף אחר באותו אורך. כמו טרנספורמרים.
והפעולות אותן אנו יכולים לעשות הן רק הפעולות הקיימות ברשתות טרנספורמרים, למשל: אין לנו גישה ישירה למיקום הטוקנים אבל יש לנו Positional Encoding שהוא רצף נוסף של אינדקסים איתו אנחנו יכולים לבצע פעולות.
קוד בשכבות Feed Forward:
לאחר שכבת הקלט אנחנו מגיעים לבלוק Feed Forward, בבלוק זה יש לנו את האפשרות להפעיל פעולות על כל אחד מהטוקנים (סתם לדוגמה: tokens == l – שימו לב שזו פעולה על רצף, tokens הוא מערך).
שוב: כל הפעולות מבוצעות על רצפים אז למשל כדי לבצע ifים: אפשר להשתמש בwhere על הרצף.
קוד בשכבות אטנשן:
כאן יש לנו גישה לתנאים היכולים לבחור בשבילנו קלט איתו נבצע פעולות, אנחנו יכולים להגדיר key ו query ולהתחיל להשתמש בהם לצורך בחירה של טוקנים מתוך הרצף לביצוע פעולות בטרנספורמר למשל לדוגמה:
הקוד eq = (key(tokens) == query(tokens))
יבחר לנו לכל טוקן רק את הטוקנים הזהים אליו ברשת.
או:
הקוד offset = (key(indices) == query(indices – 1))
יבחר לכל טוקן את הטוקנים שלידו.
בצורה כזו ניתן (דרך מלא טריקים) לבצע חישובים גדולים ומסובכים שמובילים לתוכניות מורכבות. ככל הנראה מודל זה מבצע חישובים בדומה לטרנספורמר ויכול לספק מודל חישובי המדמה את פעולות הרשת.
באופן כללי: די מגניב לראות את החישובים של טרנספורמרים בצורה כזו ורק תצוגת החישוב בצורה זו נותנת הרבה רעיונות לשיפור הרשת.