WebGPU: باز کردن قفل دسترسی به GPU مدرن در مرورگر

بیاموزید که چگونه WebGPU قدرت GPU را برای عملکرد سریعتر یادگیری ماشینی و رندر گرافیکی بهتر باز می کند.

WebGPU API جدید دستاوردهای عملکردی عظیمی را در بارهای کاری گرافیکی و یادگیری ماشین باز می کند. این مقاله بررسی می‌کند که چگونه WebGPU نسبت به راه‌حل فعلی WebGL، با نگاهی گذرا به پیشرفت‌های آینده، بهبود یافته است. اما ابتدا، بیایید زمینه ای برای چرایی توسعه WebGPU ارائه کنیم.

زمینه در WebGPU

WebGL در سال 2011 وارد کروم شد . WebGL با اجازه دادن به برنامه‌های کاربردی وب برای استفاده از GPUها، تجربه‌های شگفت‌انگیزی را در وب فراهم می‌کند - از Google Earth گرفته تا نماهنگ‌های تعاملی، تا مراحل سه‌بعدی املاک و غیره. WebGL مبتنی بر خانواده OpenGL از APIها بود که برای اولین بار در سال 1992 توسعه یافت. این مدت زمان زیادی است! و شما می توانید تصور کنید که سخت افزار GPU از آن زمان به طور قابل توجهی تکامل یافته است.

برای همگام شدن با این تکامل، نسل جدیدی از APIها برای تعامل موثرتر با سخت افزار GPU مدرن توسعه یافتند. APIهایی مانند Direct3D 12 ، Metal و Vulkan . این APIهای جدید از موارد استفاده جدید و درخواستی برای برنامه نویسی GPU مانند انفجار در یادگیری ماشین و پیشرفت در الگوریتم های رندر پشتیبانی می کنند. WebGPU جانشین WebGL است که پیشرفت های این کلاس جدید از API های مدرن را به وب می آورد.

WebGPU بسیاری از امکانات جدید برنامه نویسی GPU را در مرورگر باز می کند. این بهتر نحوه عملکرد سخت افزار GPU مدرن را نشان می دهد، در حالی که پایه ای برای قابلیت های پیشرفته تر GPU در آینده ایجاد می کند. API از سال 2017 در گروه "GPU برای وب" W3C ساخته شده است و همکاری بین بسیاری از شرکت ها مانند اپل، گوگل، موزیلا، مایکروسافت و اینتل است. و اکنون پس از 6 سال کار، ما مشتاقیم اعلام کنیم که یکی از بزرگترین موارد اضافه شده به پلتفرم وب بالاخره در دسترس است!

WebGPU امروز در Chrome 113 در ChromeOS، macOS و Windows در دسترس است و پلتفرم‌های دیگر به زودی عرضه می‌شوند. از دیگر مشارکت‌کنندگان Chromium و به‌ویژه اینتل که به تحقق این امر کمک کردند بسیار سپاسگزاریم.

حال بیایید نگاهی به برخی از موارد استفاده هیجان انگیزی که WebGPU فعال می کند بیاندازیم.

بارهای کاری جدید GPU را برای رندر باز کنید

ویژگی‌های WebGPU مانند شیدرهای محاسباتی ، کلاس‌های جدیدی از الگوریتم‌ها را قادر می‌سازد تا بر روی GPU منتقل شوند. به عنوان مثال، الگوریتم هایی که می توانند جزئیات دینامیکی بیشتری به صحنه ها اضافه کنند، پدیده های فیزیکی را شبیه سازی کنند و موارد دیگر! حتی بارهای کاری وجود دارد که قبلاً فقط در جاوا اسکریپت قابل انجام بودند و اکنون می توان آنها را به GPU منتقل کرد.

ویدیوی زیر الگوریتم مکعب های رژه را نشان می دهد که برای مثلث بندی سطح این متابولاها استفاده می شود. در 20 ثانیه اول ویدیو، الگوریتم زمانی که در جاوا اسکریپت اجرا می‌شود، تلاش می‌کند تا با صفحه‌ای که تنها با سرعت 8 فریم در ثانیه اجرا می‌شود، هماهنگی داشته باشد و در نتیجه انیمیشن‌های عجیب و غریب ایجاد می‌شود. برای حفظ عملکرد آن در جاوا اسکریپت، باید سطح جزئیات را بسیار پایین بیاوریم.

زمانی که همان الگوریتم را به یک شیدر محاسباتی منتقل می کنیم، تفاوت شب و روز است که پس از 20 ثانیه در ویدیو دیده می شود. عملکرد صفحه به طور چشمگیری بهبود می یابد و صفحه اکنون با سرعت 60 فریم در ثانیه کار می کند و هنوز فضای زیادی برای عملکرد برای جلوه های دیگر وجود دارد. علاوه بر این، حلقه اصلی جاوا اسکریپت صفحه برای سایر وظایف کاملاً آزاد می شود و اطمینان حاصل می کند که تعاملات با صفحه پاسخگو باقی می مانند.

نسخه ی نمایشی متابولز

WebGPU همچنین جلوه های بصری پیچیده ای را فعال می کند که قبلاً عملی نبودند. در مثال زیر که در کتابخانه محبوب Babylon.js ایجاد شده است، سطح اقیانوس به طور کامل بر روی GPU شبیه سازی شده است. دینامیک واقعی از بسیاری از امواج مستقل که به یکدیگر اضافه می شوند ایجاد می شود. اما شبیه سازی مستقیم هر موج بسیار پرهزینه خواهد بود.

دمو اقیانوس

به همین دلیل است که نسخه آزمایشی از یک الگوریتم پیشرفته به نام تبدیل فوریه سریع استفاده می کند. به جای نمایش همه امواج به عنوان داده های موقعیتی پیچیده، از داده های طیفی استفاده می کند که برای انجام محاسبات بسیار کارآمدتر است. سپس هر فریم از تبدیل فوریه برای تبدیل داده های طیفی به داده های موقعیتی که ارتفاع امواج را نشان می دهد استفاده می کند.

استنتاج ML سریعتر

WebGPU همچنین برای سرعت بخشیدن به یادگیری ماشینی مفید است که در سال های اخیر به یکی از کاربردهای اصلی پردازنده های گرافیکی تبدیل شده است.

برای مدت طولانی، توسعه‌دهندگان خلاق، API رندر WebGL را برای انجام عملیات غیر رندر مانند محاسبات یادگیری ماشین تغییر داده‌اند. با این حال، این امر مستلزم ترسیم پیکسل‌های مثلث به عنوان راهی برای شروع محاسبات، و بسته‌بندی و بازکردن دقیق داده‌های تانسور در بافت به‌جای دسترسی‌های کلی به حافظه است.

تصویری از ناکارآمدی‌ها در اجرای یک اپراتور ML با WebGL، از جمله بارهای حافظه اضافی، محاسبات اضافی، و مقادیر کمی نوشته شده در هر رشته.
اجرای تک اپراتور ML با WebGL.

استفاده از WebGL در این راه مستلزم آن است که توسعه دهندگان به طرز عجیبی کد خود را با انتظارات یک API طراحی شده فقط برای طراحی مطابقت دهند. همراه با فقدان ویژگی‌های اساسی مانند دسترسی به حافظه مشترک بین محاسبات، این امر منجر به کار تکراری و عملکرد غیربهینه می‌شود.

شیدرهای محاسبه ویژگی جدید اصلی WebGPU هستند و این نقاط دردناک را حذف می کنند. شیدرهای محاسباتی مدل برنامه نویسی انعطاف پذیرتری را ارائه می دهند که از ماهیت موازی انبوه GPU بهره می برد در حالی که توسط ساختار دقیق عملیات رندر محدود نمی شود.

بهره وری مختلف در سایه زن های محاسباتی WebGPU، از جمله بارهای حافظه مشترک، محاسبات مشترک، و نوشتن انعطاف پذیر در حافظه.
WebGPU محاسبه کارایی سایه زن.

شیدرهای محاسباتی فرصت بیشتری برای به اشتراک گذاری داده ها و نتایج محاسباتی در گروه های کار سایه زن برای کارایی بهتر می دهد. این می تواند منجر به دستاوردهای قابل توجهی نسبت به تلاش های قبلی برای استفاده از WebGL برای همان هدف شود.

به عنوان نمونه ای از افزایش بهره وری که می تواند به ارمغان بیاورد، یک پورت اولیه یک مدل انتشار تصویر در TensorFlow.js زمانی که از WebGL به WebGPU منتقل می شود، افزایش عملکرد 3 برابری را بر روی انواع سخت افزار نشان می دهد. در برخی از سخت افزارهای آزمایش شده، تصویر در کمتر از 10 ثانیه رندر شده است. و از آنجایی که این یک پورت اولیه بود، ما معتقدیم که حتی در WebGPU و TensorFlow.js بهبودهای بیشتری ممکن است! بررسی کنید Web ML در سال 2023 چه خبر است؟ جلسه Google I/O.

اما WebGPU تنها در مورد آوردن ویژگی های GPU به وب نیست.

ابتدا برای جاوا اسکریپت طراحی شده است

ویژگی‌هایی که این موارد استفاده را فعال می‌کنند برای مدتی برای توسعه‌دهندگان دسکتاپ و موبایل مخصوص پلتفرم در دسترس بوده‌اند، و این چالش ما بوده است که آنها را به گونه‌ای که به نظر می‌رسد بخشی طبیعی از پلتفرم وب به نظر می‌رسد، در معرض نمایش بگذاریم.

WebGPU با بهره مندی از آینده نگری بیش از یک دهه از توسعه دهندگانی که کارهای شگفت انگیزی را با WebGL انجام می دهند، توسعه یافته است. ما توانستیم مشکلاتی را که با آن‌ها مواجه می‌شدند، گلوگاه‌هایی که به آن‌ها برخورد کردند، و مسائلی که مطرح کردند و همه این بازخوردها را به این API جدید انتقال دادیم.

ما دیدیم که مدل حالت جهانی WebGL ایجاد کتابخانه ها و برنامه های کاربردی قوی و قابل ترکیب را دشوار و شکننده می کند. بنابراین WebGPU به طور چشمگیری میزان وضعیتی را که توسعه دهندگان باید هنگام ارسال دستورات GPU پیگیری کنند، کاهش می دهد.

شنیده‌ایم که اشکال‌زدایی برنامه‌های WebGL یک دردسر است، بنابراین WebGPU دارای مکانیسم‌های انعطاف‌پذیرتر رسیدگی به خطا است که عملکرد شما را مختل نمی‌کند. و ما تمام تلاش خود را انجام داده ایم تا اطمینان حاصل کنیم که هر پیامی که از API دریافت می کنید به راحتی قابل درک و عملی است.

ما همچنین دیدیم که اغلب هزینه های سربار برقراری تماس های بیش از حد جاوا اسکریپت یک گلوگاه برای برنامه های پیچیده WebGL بود. در نتیجه، WebGPU API کمتر چت است، بنابراین می توانید با فراخوانی عملکرد کمتر کارهای بیشتری انجام دهید. ما روی انجام اعتبارسنجی سنگین وزن در جلو تمرکز می‌کنیم، و تا جایی که ممکن است حلقه قرعه‌کشی حیاتی را نازک نگه می‌داریم. و ما API های جدیدی مانند Render Bundles را ارائه می دهیم که به شما امکان می دهد تعداد زیادی از دستورات ترسیم را از قبل ضبط کنید و آنها را با یک تماس دوباره پخش کنید.

برای نشان دادن تفاوت چشمگیر یک ویژگی مانند بسته‌های رندر، در اینجا نسخه‌ی نمایشی دیگری از Babylon.js وجود دارد. رندر WebGL 2 آنها می تواند تمام فراخوان های جاوا اسکریپت را برای رندر کردن این صحنه گالری هنری حدود 500 بار در ثانیه اجرا کند. که خیلی خوبه!

گالری هنر

با این حال، رندر WebGPU آنها قابلیتی را فعال می کند که آن را Snapshot Rendering می نامند. این ویژگی که بر روی بسته‌های رندر WebGPU ساخته شده است، به همان صحنه اجازه می‌دهد تا بیش از ۱۰ برابر سریع‌تر ارسال شود. این کاهش قابل توجه سربار به WebGPU اجازه می دهد تا صحنه های پیچیده تری را ارائه دهد، در حالی که به برنامه ها اجازه می دهد کارهای بیشتری را با جاوا اسکریپت به صورت موازی انجام دهند.

APIهای گرافیکی مدرن به پیچیدگی شهرت دارند و سادگی را برای فرصت‌های بهینه‌سازی شدید معامله می‌کنند. از سوی دیگر، WebGPU بر سازگاری بین پلتفرم متمرکز است و در اغلب موارد موضوعات دشوار سنتی مانند همگام سازی منابع را به طور خودکار مدیریت می کند.

این یک عارضه جانبی خوشحال کننده دارد که یادگیری و استفاده از WebGPU آسان است. برای مواردی مانند بارگذاری تصویر و ویدئو به ویژگی‌های موجود پلتفرم وب متکی است و به الگوهای معروف جاوا اسکریپت مانند 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 ممکن است به سادگی تغییر یک پرچم باشد!

Babylon.js، Construct 3، Google Earth، Google Meet، PlayCanvas، Sketchfab، Three.JS، TensorFlow.js و Unity.
چارچوب‌ها، برنامه‌ها و کتابخانه‌ها با پورت‌های WebGPU تمام‌شده یا در حال انجام.

و این اولین نسخه در کروم 113 فقط یک شروع است. در حالی که نسخه اولیه ما برای Windows، ChromeOS و MacOS است، ما قصد داریم در آینده نزدیک WebGPU را به پلتفرم های باقی مانده مانند Android و Linux بیاوریم.

و این فقط تیم Chrome نیست که روی راه‌اندازی WebGPU کار می‌کند. پیاده سازی ها در فایرفاکس و WebKit نیز در حال پیشرفت هستند.

علاوه بر این، ویژگی‌های جدیدی از قبل در W3C طراحی شده‌اند که در صورت وجود سخت‌افزار می‌توانند در معرض دید قرار گیرند. به عنوان مثال: در کروم قصد داریم به زودی پشتیبانی از اعداد ممیز شناور 16 بیتی در سایه بان ها و دستورالعمل های کلاس DP4a را برای بهبود عملکرد یادگیری ماشین بیشتر فعال کنیم.

WebGPU یک API گسترده است که اگر روی آن سرمایه گذاری کنید، عملکرد شگفت انگیزی را باز می کند. امروز ما فقط می‌توانیم مزایای آن را در سطح بالایی پوشش دهیم، اما اگر می‌خواهید با WebGPU شروع کنید، Codelab مقدماتی ما، اولین برنامه WebGPU شما را بررسی کنید. در این کد لبه، شما یک نسخه GPU از بازی کلاسیک Conway's Game of Life را خواهید ساخت. این لبه کد شما را مرحله به مرحله در طول فرآیند راهنمایی می کند، بنابراین می توانید آن را امتحان کنید حتی اگر اولین بار است که توسعه GPU را انجام می دهید.

نمونه های WebGPU نیز مکان خوبی برای درک API هستند. آنها از "مثلث سلام" سنتی تا رندر کامل تر و خطوط لوله محاسبه می شوند و تکنیک های مختلفی را نشان می دهند. در نهایت، منابع دیگر ما را بررسی کنید.