איך WebGPU משתמש ביכולות של ה-GPU כדי לשפר את הביצועים של למידת מכונה ורינדור גרפיקה טוב יותר.
ה-WebGPU API החדש מאפשר שיפורים משמעותיים בביצועים בעומסי עבודה (workloads) של גרפיקה ולמידת מכונה. במאמר הזה מתואר איך WebGPU פועל לשיפור הפתרון הנוכחי של WebGL, כולל הצצה לפיתוחים עתידיים. אבל קודם כל, בואו נספק הקשר לגבי הסיבה לפיתוח של WebGPU.
הקשר ב-WebGPU
WebGL הגיע ל-Chrome ב-2011. WebGL מאפשר לאפליקציות אינטרנט לנצל את היתרונות של מעבדי GPU מאפשר חוויות מדהימות באינטרנט – מ-Google Earth, דרך סרטוני מוזיקה אינטראקטיביים, דרך הדרכות מפורטות בתלת-ממד בעולם האמיתי ועוד. WebGL התבסס על משפחת ממשקי ה-API OpenGL שפותחה לראשונה בשנת 1992. מזמן לא שמענו ממך... ואפשר לדמיין שחומרת ה-GPU התפתחה באופן משמעותי מאז.
כדי לעמוד בהתפתחות הזו, פותחו זן חדש של ממשקי API שמאפשרים אינטראקציה יעילה יותר עם חומרת GPU מודרנית. ממשקי API כמו Direct3D 12, Metal ו-Vulkan. ממשקי ה-API החדשים האלה תומכים בתרחישים לדוגמה חדשים ותובעניים לתכנות GPU, כמו פיצוץ בלמידת מכונה והתקדמות באלגוריתמים של עיבוד. WebGPU הוא התחליף ל-WebGL שמביא את הפיתוחים של הסוג החדש הזה של ממשקי API מודרניים לאינטרנט.
WebGPU פותחת בדפדפן הרבה אפשרויות לתכנות GPU. הוא משקף טוב יותר את האופן שבו חומרת GPU מודרנית פועלת, וגם מניח את היסודות ליכולות GPU מתקדמות יותר בעתיד. ה-API נמצא בקבוצת GPU for the Web של W3C מאז 2017. זהו שיתוף פעולה בין חברות רבות כמו Apple, Google, Mozilla, Microsoft ו-Intel. ועכשיו, לאחר 6 שנים של עבודה, אנחנו שמחים להכריז שאחת התוספות הגדולות ביותר לפלטפורמת האינטרנט זמינה סוף סוף!
WebGPU זמין היום ב-Chrome 113 ב-ChromeOS, ב-macOS וב-Windows. בקרוב נוסיף עוד פלטפורמות. תודה רבה לתורמים אחרים ל-Chromium ול-Intel שעזרו לנו לגרום לזה.
עכשיו נבחן כמה תרחישי שימוש מרגשים שמאפשרים ל-WebGPU.
קבלת גישה לעומסי עבודה (workloads) חדשים של GPU לעיבוד
תכונות של WebGPU כמו תוכנות הצללה (shader) למחשוב מאפשרות לנייד סוגים חדשים של אלגוריתמים ב-GPU. לדוגמה, אלגוריתמים שיכולים להוסיף עוד פרטים דינמיים לסצנות, לדמות תופעות פיזיקליות ועוד. יש אפילו עומסי עבודה שבעבר ניתן היה לבצע רק ב-JavaScript, ועכשיו אפשר להעביר אותם ל-GPU.
בסרטון הבא מוצג אלגוריתם של קוביות הצעדות, שבו משתמשים באלגוריתם של קוביות ההליכה כדי לבצע טרינגל פני השטח של הכדורים האלה. ב-20 השניות הראשונות של הסרטון, כשהאלגוריתם פועל ב-JavaScript, האלגוריתם מתקשה לעמוד בקצב של 8 FPS, וכתוצאה מכך נוצרת אנימציה מוזרה. כדי לשמור על ביצועיו ב-JavaScript, עלינו להוריד באופן משמעותי את רמת הפרטים.
כשאנחנו מעבירים את אותו אלגוריתם להצללה של מחשוב, אפשר לראות אותו בסרטון לאחר 20 שניות, וזהו הפרש בין לילה ויום. הביצועים משתפרים באופן משמעותי בכך שהדף פועל עכשיו בקצב חלק של 60 FPS, ועדיין יש מקום לשיפור הביצועים של אפקטים אחרים. בנוסף, לולאת ה-JavaScript הראשית של הדף פנויה לחלוטין למשימות אחרות, מה שמבטיח שהאינטראקציות עם הדף יישארו רספונסיביות.
WebGPU מאפשר גם אפקטים חזותיים מורכבים שקודם לכן לא היו מעשיים. בדוגמה הבאה, שנוצרה בספרייה הפופולרית Babylon.js, מדמה את פני האוקיינוס לגמרי ב-GPU. הדינמיקה הריאליסטית נוצרת מהרבה גלים עצמאיים שנוספים זה לזה. אבל סימולציה של כל גל באופן ישיר תהיה יקרה מדי.
לכן ההדגמה משתמשת באלגוריתם מתקדם שנקרא Fast Forier Transform. במקום לייצג את כל הגלים כנתוני מיקום מורכבים, נעשה שימוש בנתונים הספקטרליים, שהרבה יותר יעילים לבצע חישובים. לאחר מכן, כל מסגרת משתמשת בטרנספורמציה של פורייה כדי להמיר מנתונים ספקטרליים לנתוני המיקום שמייצגים את גובה הגלים.
הסקת מסקנות מהירה יותר מלמידת מכונה
WebGPU שימושי גם להאצת למידת מכונה, שהפכה לשימוש נרחב במעבדי GPU בשנים האחרונות.
במשך תקופה ארוכה, מפתחי קריאייטיב השתמשו ב-API לרינדור של WebGL כדי לבצע פעולות שלא קשורות לעיבוד, כמו חישובי למידת מכונה. עם זאת, לשם כך נדרש ציור הפיקסלים של המשולשים כדרך להתחיל את החישובים, ואריזה ופתיחה קפדנית של נתוני טנזור במרקם במקום גישת זיכרון לשימוש כללי יותר.
שימוש ב-WebGL בצורה הזו מחייב מפתחים להתאים את הקוד שלהם באופן מוזר לציפיות של API שמיועד לשרטוט בלבד. בשילוב עם היעדר תכונות בסיסיות כמו גישה משותפת לזיכרון בין החישובים, התוצאה תהיה כפילות בעבודה וביצועים לא אופטימליים.
תוכנות הצללה למחשוב היא התכונה החדשה העיקרית של WebGPU, והיא מסירה את הבעיות האלה. תוכנות הצללה למחשוב מציעים מודל תכנות גמיש יותר שמנצל את האופי המקביל המדהים של ה-GPU כשהוא לא מוגבל על ידי המבנה המחמיר של פעולות רינדור.
תוכנות הצללה (shader) של מחשוב נותנת יותר הזדמנות לשיתוף נתונים ותוצאות מחשוב בתוך קבוצות של תוכנות הצללה (shader). הדבר עשוי להוביל לשיפורים משמעותיים בהשוואה לניסיונות קודמים להשתמש ב-WebGL לאותה מטרה.
דוגמה לשיפור היעילות יכולה להוביל לכך שיציאה ראשונית של מודל דיפוזיה של תמונה ב-TensorFlow.js מראה שיפור ביצועים פי 3 במגוון חומרה כשעוברים מ-WebGL ל-WebGPU. בחלק מהחומרה, התמונה עברה עיבוד תוך פחות מ-10 שניות בחלק מהחומרה. ובגלל שזו הייתה ניוד מוקדם, אנחנו מאמינים שאפשר לשפר עוד יותר את ה-WebGPU וגם את TensorFlow.js. כדאי לקרוא את המאמר מה חדש ב-Web ML ב-2023? סשן של Google I/O.
אבל WebGPU לא משפיע רק על שימוש בתכונות של GPU באינטרנט.
מותאם ל-JavaScript תחילה
התכונות שמאפשרות תרחישים לדוגמה כאלה זמינים כבר זמן מה למפתחים ספציפיים לפלטפורמה מסוימת במחשב ובנייד, והאתגר שלנו היה לחשוף אותם באופן שנראה כמו חלק טבעי מפלטפורמת האינטרנט.
טכנולוגיית WebGPU פותחה עם היתרונות של מבט לאחור במשך יותר מעשור, של מפתחים שעושים עבודה מדהימה עם WebGL. הצלחנו לקחת את הבעיות שהם נתקלו בהן, את צווארי הבקבוק שבהם הן נתקלו, ואת הבעיות שהם העלו והועברו לכל המשוב הזה לתוך ה-API החדש.
ראינו שמודל המצב הגלובלי של WebGL הפך את היצירה של ספריות ואפליקציות עוצמתיות וקומפוזביליות לקשות ושבריריות. כך, WebGPU מפחית משמעותית את כמות המצב שהמפתחים צריכים לעקוב אחריהם בזמן שליחת פקודות ה-GPU.
שמענו שניפוי באגים באפליקציות WebGL היה מאוד קשה, ולכן WebGPU כולל מנגנונים גמישים יותר של טיפול בשגיאות שלא פוגעים בביצועים. השקענו מאמצים רבים כדי להבטיח שכל הודעה שתתקבל מה-API תהיה קלה להבנה ופעולה.
ראינו גם שלעיתים קרובות התקורה של ביצוע יותר מדי קריאות JavaScript הייתה צוואר בקבוק באפליקציות מורכבות של WebGL. כתוצאה מכך, ה-WebGPU API פחות עמוס בצ'אט, ואתם יכולים להספיק יותר בפחות הפעלות של פונקציות. אנחנו מתמקדים בביצוע תיקוף של נתונים כבדים מראש, כדי לשמור על לולאת משיכה קריטית קלה ככל האפשר. כמו כן, אנחנו מציעים ממשקי API חדשים כמו Render Bundles, שמאפשרים להקליט מראש מספר גדול של פקודות שרטוט ולהפעיל אותן מחדש באמצעות קריאה אחת.
כדי להמחיש את ההבדל הדרמטי שיכולה לעשות תכונה כמו חבילות רינדור, הנה הדגמה נוספת של Babylon.js. כלי הרינדור WebGL 2 שלהם יכול לבצע את כל קריאות ה-JavaScript כדי לעבד את הסצנה הזו של גלריית האומנות בערך 500 פעמים בשנייה. זה די טוב!
עם זאת, כלי הרינדור של WebGPU מאפשר תכונה שנקראת 'עיבוד תמונת מצב'. התכונה הזו, שמובנית על חבילות עיבוד של WebGPU, מאפשרת לשלוח את אותה סצנה מהר יותר מפי 10. התקורה הזו שמצמצמת במידה משמעותית מאפשרת ל-WebGPU לעבד סצנות מורכבות יותר, ובמקביל לאפשר לאפליקציות לעשות יותר עם JavaScript במקביל.
לממשקי API גרפיים מודרניים יש מוניטין של מורכבות, מסחר בפשטות להשגת הזדמנויות קיצוניות של אופטימיזציה. לעומת זאת, WebGPU מתמקד בתאימות לפלטפורמות שונות, ומטפל באופן אוטומטי בנושאים מסורתיים כמו סנכרון משאבים, ברוב המקרים.
כתוצאה מכך, קל ללמוד ולהשתמש ב-WebGPU. הוא מסתמך על תכונות קיימות של פלטפורמת האינטרנט לפעולות כמו טעינת תמונות וסרטונים, ומתבסס על תבניות JavaScript מוכרות כמו Promises לפעולות אסינכרוניות. כך כדאי לשמור על הכמות המינימלית של הקוד הסטנדרטי. אפשר להציג את המשולש הראשון במסך שמכיל פחות מ-50 שורות קוד.
<canvas id="canvas" width="512" height="512"></canvas>
<script type="module">
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
const context = canvas.getContext("webgpu");
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format });
const code = `
@vertex fn vertexMain(@builtin(vertex_index) i : u32) ->
@builtin(position) vec4f {
const pos = array(vec2f(0, 1), vec2f(-1, -1), vec2f(1, -1));
return vec4f(pos[i], 0, 1);
}
@fragment fn fragmentMain() -> @location(0) vec4f {
return vec4f(1, 0, 0, 1);
}`;
const shaderModule = device.createShaderModule({ code });
const pipeline = device.createRenderPipeline({
layout: "auto",
vertex: {
module: shaderModule,
entryPoint: "vertexMain",
},
fragment: {
module: shaderModule,
entryPoint: "fragmentMain",
targets: [{ format }],
},
});
const commandEncoder = device.createCommandEncoder();
const colorAttachments = [
{
view: context.getCurrentTexture().createView(),
loadOp: "clear",
storeOp: "store",
},
];
const passEncoder = commandEncoder.beginRenderPass({ colorAttachments });
passEncoder.setPipeline(pipeline);
passEncoder.draw(3);
passEncoder.end();
device.queue.submit([commandEncoder.finish()]);
</script>
סיכום
מרגש לראות את כל האפשרויות החדשות ש-WebGPU מציע לפלטפורמת האינטרנט, ואנחנו מצפים לראות את כל תרחישי השימוש החדשים והמגניבים שתמצאו ב-WebGPU!
סביבה עסקית תוססת של ספריות ומסגרות נבנתה סביב WebGL, ואותה סביבה עסקית רוצה לאמץ את WebGPU. התמיכה ב-WebGPU נמצאת כבר בתהליך או כבר הושלמה בספריות פופולריות רבות של JavaScript WebGL, ובמקרים מסוימים ניצול היתרונות של WebGPU עשוי להיות פשוט כמו שינוי דגל אחד!
הגרסה הראשונה הזו ב-Chrome 113 היא רק התחלה. הגרסה הראשונית שלנו מיועדת ל-Windows, ל-ChromeOS ול-MacOS, אבל אנחנו מתכננים להוסיף את WebGPU לפלטפורמות האחרות כמו Android ו-Linux בעתיד הקרוב.
ולא רק צוות Chrome שעובד על השקת WebGPU. ההטמעה מתבצעת גם ב-Firefox וב-WebKit.
בנוסף, תכונות חדשות כבר מתוכננות ב-W3C וניתן לחשוף אותן כאשר הן זמינות בחומרה. לדוגמה: ב-Chrome אנחנו מתכננים להפעיל בקרוב תמיכה במספרים של נקודות צפות של 16 ביט בכלי להצללה ואת סיווג ההוראות של DP4a כדי לשפר עוד יותר את הביצועים של למידת מכונה.
WebGPU הוא ממשק API מקיף שמעניק ביצועים מדהימים אם משקיעים בו. היום נוכל לתאר את היתרונות של המוצר ברמה גבוהה בלבד, אבל אם אתם רוצים להתחיל להשתמש ב-WebGPU, כדאי לכם לבדוק את ההיכרות שלנו עם Codelab, אפליקציית WebGPU הראשונה שלך. ב-Codelab הזה תבנה גרסת GPU של משחק החיים הקלאסי של קונוויי. ב-Codelab הזה תעברו את התהליך שלב אחרי שלב, כך שתוכלו לנסות אותו גם אם זו הפעם הראשונה שאתם מפתחים GPU.
גם הדוגמאות של WebGPU מספקות לכם הצצה ל-API. הם נעים בין 'משולש הלוך' המסורתי לצינורות עיבוד נתונים ומחשוב מלאים יותר, תוך הדגמה של מגוון שיטות. לסיום, תוכלו להיעזר במקורות המידע האחרים שלנו.