سخت افزار های یادگیری عمیق : FPGA یا GPU مساله این است!

هنگام استفاده از شبکه عصبی، به غیر از GPU ها ( واحدهای پردازش گرافیک )، گزینه های دیگری، مثل FPGA  ( مخفف Field Programmable Gate Array ) نیز وجود دارد. قبل از پرداختن به FPGA ها و نحوه پیاده سازی شبکه عمیق روی آن ها، بهتر است کمی در مورد معماری GPU و اینکه چرا GPU ها جزء اصلی شبکه های عصبی هستند، بدانیم.

کتابخانه های معروف مانند Tensorflow با استفاده از CUDA ( مخفف Compute Unified Device Architecture ) برای پردازش داده ها در GPU ها ، از قدرت محاسبات موازی آن ها بهره می برند. به این کار، برنامه نویسی GPGPU (مخفف General Purpose GPU ) گفته می شود. این روش با مدل های یادگیری عمیق که حداقل به هزاران عملیات محاسباتی نیاز دارند، سازگار است.

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

Tensorflow می تواند با پشتیبانی CUDA ساخته شود، که کاربر نهایی را از پیاده سازی کد موازی و درک معماری تراشه آن ها خلاص کند. راحتی و بهینه سازی بالا، آن را برای استفاده گسترده مناسب می سازد.

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

بررسی اجمالی

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

  • GPU ، CPU و CUDA
  • مزایا و طراحی FPGA ها
  • HDL به عنوان روشی برای بکار بردن FPGA
  • HLS به عنوان روشی برای بکار بردن FPGA
  • بکار بردن FPGA با استفاده از LeFlow
  • ویژگی های LeFlow برای بهینه سازی

چرا گاهی اوقات GPU ها بهتر از CPU ها هستند؟

CPU ها ( واحدهای پردازش مرکزی ) برای عملیات سریالی و پشتیبانی از منطق پیشرفته، طراحی شده اند. طراحی شان، نشان می دهد که برای دریافت سریع دستورالعمل های پیچیده، دارای هسته های کم تر و حافظه پنهان ( cach ) بیشتری هستند.

مقایسه نحوه کار GPUو CPU ها
مقایسه نحوه کار GPU و CPU . منبع : مقاله Elkaduwe 

با این حال، GPU ها دارای صد ها هسته کوچک تر، برای محاسبات ساده هستند و در نتیجه در مقایسه با CPU ها، توان عملیاتی بالاتری دارند.

cudaMalloc((void**)&dev_bitmap, bitmap.image_size());
dim3 grid(DIM, DIM);
kernel<<<grid, 1 >>>(dev_bitmap);
cudaMemcpy(bitmap.get_ptr(), dev_bitmap, bitmap.image_size(), cudaMemcpyDeviceToHost);

منبع : Github

CUDA، با جدا کردن GPU ها به بلوک ها ، به بسیاری از هسته های GPU دسترسی پیدا می کند. هر بلوک شامل ۵۱۲ رشته ( Thread ) قابل دسترسی است که می توانند ۶۵۵۳۵ بلوک را با هم اجرا کنند. هر رشته یک برنامه کوتاه را اجرا می کند ، و مزیت آن این است که می تواند به صورت موازی در کنار رشته های دیگر اجرا شود. Tensorflow از این الگو برای بهبود قدرت پردازش استفاده می کند، که اغلب صد ها تا هزاران رشته را به طور همزمان اجرا می کند.

برای کسب اطلاعات بیشتر در مورد استفاده از CUDA ، به وبلاگ توسعه دهندگانNvidia  مراجعه کرده یا کتاب CUDA By Example را بررسی کنید.

سخت افزار شبکه عصبی

Tensorflow به دو بخش تقسیم می شود: کتابخانه و Runtime .

کتابخانه، ایجاد یک نمودار محاسباتی ( شبکه عصبی ) است و Runtime ، پیاده سازی آن روی برخی از پلتفرم های سخت افزاری است.

پلتفرم ترجیحی، GPU است ، با این وجود گزینه دیگری نیز وجود دارد: FPGA .

چرا از FPGA استفاده می کنیم؟

FPGA ها می توانند مدار هایی با هزاران واحد حافظه را برای محاسبه تولید کنند ، بنابراین آن ها مشابه GPU ها و رشته هایشان در CUDA کار می کنند. FPGA ها دارای معماری سازگار هستند و بهینه سازی های اضافی را برای افزایش توان عملیاتی در اختیار شما قرار می دهد. بنابراین حجم محاسبات ممکن ، FPGA را به یک جایگزین مناسب برای GPU تبدیل می کند.

در مقایسه، FPGA ها مصرف توان کمتری دارند و می توانند برای کاربرد های تجمیع شده ( Embedded ) بهینه باشند. همچنین آن ها یک استاندارد قابل قبول در عملیات حساس به ایمنی مانند ADAS ( سیستم های پیشرفته کمک به راننده ) در خودرو هستند.

استفاده از FPGA برای یادگیری عمیق در خودرو های خودران
کاربرد FPGA ها در خودرو های خودران برای تشخیص منطقه امن و منطقه خطر. منبع: صفحه فورد موتورز در ویکی پدیا  

علاوه بر این ، FPGA ها می توانند انواع داده های دستی را پیاده سازی کنند در حالی که GPU ها توسط معماری محدود شده اند. با تغییر شبکه های عصبی از جهات مختلف و ارتباط با صنایع بیشتر ، استفاده از FPGA ها بسیار مفید است.

شاید برای شما سوال باشد ، FPGA چیست؟

FPGA ( مخفف Field Programableable Gate Array ) یک دستگاه سخت افزاری قابل تنظیم است. می توان آن را دریایی از دروازه های منطقی شناور دانست. یک طراح، برنامه ای را با استفاده از یک زبان توصیف سخت افزار ( HDL )، مانند Verilog یا VHDL می نویسد. این برنامه تعیین می کند که چه روابطی ایجاد شده و آن ها چگونه با استفاده از مولفه های دیجیتال ، پیاده سازی شدند. اصطلاح دیگر برای HDL زبان RTL ( سطح انتقال بین رجیستری ) است.

FPGA ها به راحتی قابل اجرا هستند ، یک Arduino بزرگ را در نظر بگیرید.

بورد FPGA یادگیری عمیق

شوخی می کنم، FPGA ها شکل و اندازه های مختلفی دارند.

با استفاده از نرم افزاری شبیه به کامپایلر ، HDL سنتز می شود (تعیین کنید از چه گیت هایی باید استفاده کنید) ، سپس مسیریابی شده (قطعات به هم وصل می شود) تا یک مدار دیجیتال بهینه شده را ایجاد کنید. این ابزار ها ( HDL ، سنتز ، مسیریابی ، تحلیل زمان سنجی ، آزمایش ) همگی در یک مجموعه نرم افزاری قرار گرفته اند ، که از این ابزار های طراحی می توان Xilinx و Quartus Prime را نام برد.

در حال حاضر مدل ها با استفاده از یک GPU آموزش می بینند، اما بعدا در یک FPGA برای پردازش بلادرنگ بکار گرفته می شوند.

پس چرا در عوض از FPGA استفاده نمی کنیم؟

برای FPGA ها ، بخش دشوار پیاده سازی چارچوب های یادگیری ماشین است که به زبان های سطح بالاتر مانند پایتون نوشته شده است. HDL ذاتاً یک پلتفرم برنامه نویسی نیست ، بلکه برای تعریف اجزای سخت افزاری مانند رجیستر ها و شمارنده ها، بصورت کد نوشته شده است. برخی از زبان های HDL عبارتند از: Verilog  ،  VHDL.

در زیر قطعه ای از کد مورد استفاده برای ساخت یک آشکار ساز بیت سریالی نشان داده شده است.

اگر با آن آشنا نیستید، سعی کنید حدس بزنید که چه کاری انجام می دهد.

انجام دادید؟ حتی اگر مدت ها به آن خیره شوید ، قابل فهم نمی باشد.

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

دیاگرام FSM FPGA

برگردیم به موضوع : نکته اصلی این است که هیچ انتقال مستقیمی برای تبدیل یک حلقه در پایتون به یک دسته از سیم ها در Verilog ، وجود ندارد.

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

بنابراین آیا باید به GPU ها پایبند باشیم؟

خب نه، FPGA ها بی فایده نیستند.

یکی از راه های حل مشکل برنامه نویسی، استفاده از ابزارهای HLS  ( سنتز سطح بال ا) مانند LegUp ، برای تولید برنامه در Verilog است. ابزار های HLS به طراحان اجازه می دهد از نوشتن HDL از پایه خودداری کنند و به جای آن از یک زبان برنامه نویسی الگوریتمی پویا تر( C )  استفاده کنند.

ابزار HLS طراحی سطح سخت افزاری را به صورت انتزاعی انجام می دهد. شبیه به نحوه راه اندازی خودکار بلوک ها و رشته های همزمان CUDA در هنگام اجرای مدل.

ابزارهای HLS به کد C به عنوان یک ورودی نیاز دارند که به LLVM IR ( نمایش میانی )، نگاشت دهد. از این ابزار ها برای تبدیل توضیحات روش به یک پیاده سازی سخت افزاری استفاده می شود.

نقش آن ها در طراحی FPGA در زیر نشان داده شده است.

اطلاعات بیشتر در مورد LLVM IR ها

LLVM مخفف یک کلمه نیست ، بلکه یک کتابخانه است که دستورالعمل های اسمبلی-مانند ( IR )  را ایجاد می کند. این برنامه ها برای پردازش ابزار های HLS آسان تر هستند و می توان از آن ها برای ایجاد کد ساختاری برای یک FPGA استفاده کرد.

از IR ها برای توصیف کد منبع در یک قالب کلی استفاده می شود که امکان استفاده توسط برنامه های مختلف را دارد.

برای کسب اطلاعات بیشتر در مورد LLVM و IR ها، به اسلایدهای دکتر Chisnall مراجعه کنید.

llvm ir برای استفاده از FPGA

بازگشت به مسائل مربوط به FPGA

مسئله اصلی، تبدیل برنامه ها و انتقال کتابخانه های نوشته شده برای پایتون به C ، برای ابزار های HLS است. در حال حاضر هیچ پشتیبانی از Tensorflow در C وجود ندارد ، بنابراین این راه حل بسیار دشوار است. ظاهرا نیاز به طراحی و ایجاد سخت افزار، یک مانع بزرگ برای استفاده از FPGA ها در یادگیری عمیق است.

LeFlow ناجی ما

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

این نرم افزار توسط محققان بخش ECE ( مهندسی برق و رایانه ) در دانشگاه British Columbia طراحی شده است: Daniel H. Noronha  ، بهار صالح پور و Steven J.E. Wilson.

در بخش های زیر جزئیات چگونگی ادغام LeFlow با Tensorflow و FPGA توضیح داده شده است ، اگر تنها علاقه مند به پیاده سازی برنامه هستید، از آن صرف نظر کنید و به بخش وقت تنظیم کردن بروید.

نحوه کار جعبه ابزار LeFlow با Tensorflow

یک کامپایلر XLA ( جبر خطی تسریع یافته Accelerated Linear Algebra ) برای خروجی های Tensorflow یک IR LLVM ساخته شده است. LeFlow می تواند IR را بازسازی و بهینه کند تا با ابزار های HLS را مورد استفاده قرار گیرد.

بعد از آن، ابزار های HLS برای تبدیل این IR به برنامه مستقر روی FPGA که در بخش آیا باید به GPU ها پایبند باشیم، توضیح داده شد، کار می کنند.

مدل ورودی – خروجی LeFlow

LeFlow ، IR را به عنوان ورودی می گیرد. الگوریتم ۱ ، یک IR از Tensorflow است که دو متغیر float را بارگذاری می کند.

پیاده سازی یادگیری عمیق در FPGA

دنبال کردن این برنامه دشوار است و پیچیده به نظر می رسد. LeFlow آن را ساده می کند و تغییرش می دهد.

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

مدل FPGA یادگیری عمیق

ظاهرا یک رابط سخت افزاری ، به ماژول و سیگنال های اضافی، مانند ساعت، ریست، حافظه و کنترل کننده حافظه نیاز دارد.  LegUp، ساخت این قسمت ها از جمله مشخصات زمان بندی ساعت را بر عهده دارد.

تبدیل IR برای اجرای بهینه

LeFlow بار سبکی را برای رجیستر های FPGA ایجاد می کند. این امر امکان دسترسی متغیر و تغییر مدار اتوماتیک را در زمانی که کد سطح بالا تغییر می کند، می دهد. تغییرات در خطوط ۱ ، ۶ و ۷ به طور عمده قابل مشاهده هستند.

الگوریتم پیاده سازی یادگیری عمیق روی FPGA

LeFlow کار خود را به شکلی که توسطIR  اصلاح شده الگوریتم ۲ نشان داده شده، پایان می دهد، و بقیه توسط یک ابزار HLS اداره می شوند!

وقت تنظیم کردن!

ویژگی جالب LeFlow قابلیت تغییر سخت افزار است. LeFlow ، unrolling  و پارامتر های تقسیم حافظه را ارائه می دهد که در صورت استفاده صحیح، محاسبات توربوشارژ را انجام می دهد. این ترکیب با تاخیر کم در FPGA به آن ها امکان می دهد تا با راندمان استثنایی کار کنند.

نکته جالب این است که می توان این پارامتر ها را در پایتون مشخص کرد و دستورالعمل ها مستقیماً به سطح مدار منتقل می شوند.

با Unroll یا بدون Unroll

Unrolling برای ایجاد حلقه استفاده می شود و یک عمل متعادل سازی دقیق است. ایده این است که در هر تکرار، محاسبات چندگانه (یا مکرر) انجام شود و اقدامات بزرگتری انجام گیرد.

به نظر می رسد مانند یک حلقه معمولی است، اما اجزای بیشتری در سطح سخت افزار اضافه شده اند تا محاسبات بیشتری در هر سیکل ساعت (یا تکرار حلقه) انجام دهند. اطلاعات بیشتر در مورد unrolling در راهنمای کاربر Keil در دسترس است.

int sum = 0;
for(int i = 0; i < 10; i+=2)
     sum += a[i]; sum += a[i+1];

با نگاهی به بالا، می توانیم با یکی از ۲ فاکتور unroll  کنیم، به این معنی که دو تکرار به طور همزمان انجام شده و دو مرحله به حلقه افزوده می شود.

Unrolling Fpga

با این کار مزیت موازی بودنFPGA  برای شباهت بیشتر کار کردن آن به یک GPU استفاده می شود، که ظاهرا در هر سیکل از این مثال ۱۳% کاهش یافته است.

به خاطر داشته باشید که سخت افزار اضافه شده می تواند باعث عدم کارآیی یا محدودیت های اندازه شود.

آن را با پارتیشن های حافظه تقسیم کنید

HLS مورد استفاده در خط لوله LeFlow برای ذخیره مقادیر ، نیاز به حافظه RAM تسهیم شده ( حافظه دسترسی تصادفی ) دارد.

این مسئله بسیار مشکل ساز است زیرا RAM برای ذخیره کردن بسیاری از داده ها ساخته شده ، اما بسیار کند طراحی شده است و می تواند ده برابر سیکل ساعت طول بکشد تا مقادیری از آن بدست آید.

خوشبختانه FPGA ها دارای بسیاری از واحدهای حافظه مستقل دیگر هستند، بنابراین LeFlow می تواند داده های خود را به چندین مکان ذخیره منحصر به فرد تقسیم کند. که به نوعی مشابه با اضافه کردن هسته های بیشتر در یک پردازنده است. این کار سیکل های ساعت را با مجاز کردن دستورالعمل های بیشتری برای اجرای همزمان، کاهش می دهد.

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

FPGA ها می توانند با استفاده از پارتیشن های حافظه به طور موثرتری اجرا شوند. برنامه زیر بیش از هشت سیکل ساعت اجرا شده است.

سیکل زمانی کار FPGA یادگیری عمیق

در (a)، هیچ پارتیشن حافظه ای وجود ندارد، بنابراین یک عنصر از هر آرایه بارگذاری، ضرب و در هر چرخه ذخیره می شود. این فرآیند ادامه دارد و تا تکمیل شدن هشت چرخه طول می کشد.

در (b)، دو حافظه جداگانه تقسیم می شوند. دو عنصر از هر مجموعه بارگیری ، ضرب و در هر سیکل ذخیره می شود. بخش های بزرگتر نشان می دهند که فرآیند ها به طور همزمان در بخش های مختلف سخت افزار اتفاق می افتند. این کار، آن را به شش سیکل کاهش می دهد.

در (c) ، آرایه ها به صورت چرخشی، به چهار حافظه جداگانه تقسیم می شوند و به پنج چرخه کاهش میابند. چهار عنصر از هر مجموعه بارگیری ، ضرب و در هر چرخه ذخیره می شود.

استفاده از LeFlow در پایتون

استفاده از LeFlow در پایتون

وقتی LeFlow درست تنظیم شود، تمام آنچه که برای اجرا بدون پیکربندی اضافی نیاز دارد ( مانند unrolling ) یک خط انتخاب دستگاه است:

with tf.device("device:XLA_CPU:0")

این نشان می دهد که کامپایلر XLA برای تولید LLVM و شروع فرآیند تبدیل LeFlow استفاده خواهد شد.

LeFlow را امتحان کنید!

اکنون شما در درک نحوه کار LeFlow متخصص هستید و شاید FPGA ها برای شما مناسب باشد.

نمونه هایی از LeFlow و نصب خاص آن بر روی Github وجود دارد. Daniel Holanda ( یکی از نویسندگان ) کد منبع را برای تشخیص اعداد MNIST در بین چیزهای دیگر ارائه کرده است، بنابراین یک FPGA بردارید و دست بکار شوید.

بیشتر بخوانید :

منبع Towards Data Science
5/5 (2 نظر)

درباره‌ی احمدرضا جعفری

همچنین ببینید

ویروس Covid-19

استفاده از هوش مصنوعی در دوران کرونا

در دوران بحران و مدیریت آن در سال ۲۰۲۰ ، فناوری های نوآورانه مانند هوش …

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *