سرورهای یادگیری ماشین
آموزشآموزش‌های پیشرفته هوش مصنوعیچالش‌های عملیاتیعلوم شناختی

ساخت سرورهای یادگیری ماشین

    0
    مدت زمان مطالعه: ۱۰ دقیقه

    چگونه (API) کاربردی رابط برنامه‌نویسی Application Programming Interface (API) قوی بنویسیم؟

    علاقه من به مهندسی تولید و طراحی سیستم به طور مداوم افزایش می‌یابد. پیش از این مقاله‌ای با موضوع مراحل استقرار یک مدل در کاربرد واقعی نوشتم اما در آن مقاله مراحل ساخت سرور یادگیری ماشین را با جزئیات شرح ندادم. اگر فرایند ساخت مدل‌های یادگیری با نظارت/ بدون‌نظارت را به اتمام رسانده‌اید، اکنون باید یک API برای استفاده از آن مدل (مرحله استنتاج) بسازید. در مقاله پیش‌رو، به مطالعه مبانی سرویس‌دهی به مدل یادگیری ماشین و چگونگی استقرار آن بر  روی واحد پردازش مرکزی (CPU) / و واحد پردازش گرافیکی (GPU) و در مجموع ساخت سرورهای یادگیری ماشین خواهیم پرداخت.

    استقرار CPU

    در این بخش شیوه نوشتن APIها برای استقرار روی CPU را بررسی می‌کنیم.
    در این بخش به مطالعه و بررسی موارد زیر خواهیم پرداخت:

    • صف‌های وظیفه Task queues
    • مفاهیم حافظه کَش
    • مفاهیم کارگر worker

    Framework combo → Fastapi + uvicorn + huey + redis

     

    صف‌های وظیفه

    سرورهای یادگیری ماشین

    چرا صف؟

    سرورهای یادگیری ماشین از قبیل flask و uvicorn از صف فراخوان‌های API پشتیبانی نمی‌کنند و وظایف به صورت پیش‌فرض به صورت هم‌زمان اجرا می‌شوند. این قابلیت به شما کمک می‌کند بهتر از سرور استفاده کنید. اما اگر باید APIها را حذف و یا به‌روز رسانی کنید، ممکن است مجبور شوید حالت سرور را تغییر دهید.

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

    برای حل این مشکل بهتر است وظایفی ایجاد کنید و آن‌ها را به صفی که در اختیار کارگر است ارسال کنید و کارگر به صورت ترتیبی آن‌ها را اجرا می‌کند. اما مشکلی که در اینجا با آن مواجه هستیم این است که اگر صف طولانی شود، پاسخ کند می‌شود. در صورتی‌که پاسخ به فراخوان یک پاسخ ثابت و واحد مثل « x به‌روز رسانی خواهد شد» باشد می‌توانید وظایف را به صورت ناهمزمان درآورید و یک پاسخ ثابت به واحد ارائه دهید.

     

    نظریه صف‌بندی عمومی

    تولیدکنندگان – کدی که وظایف را به صف‌ها ارسال می‌کند.

    تبادل‌کنندگان – تصمیم می‌گیرد که پیام در کدام صف باید ذخیره شود.

    • Direct ( پیامی به همراه جدول مربوطه به صف ارسال می‌کند)
    • Topic ( پیامی به صف ارسال می‌کند که با یک الگوی مسیریابی خاص مطابقت دارد)
    • Fan out ( یک پیام به تمامی صف‌ها ارسال می‌کند)

     

    صف‌ها – مباحثی که تا به اینجا ارائه دادیم، تعریفی از صف بوده است. صف فهرستی از وظایف برای کارگرها/ مصرف‌کنندگان دارد.

    مصرف‌کنندگان – مصرف‌کنندگان (کارگر) که کارگرها هم نامیده‌ می‌شوند، وظیفه اجرای وظایف را بر عهده دارند. در هر زمانی می‌توان کارگرها را پیکربندی کرد تا بر روی یک صف خاص کار کنند. (RabbitMQ/ Redis کارگرهای مخصوص به خود ندارند و در نتیجه به کارگرهای وظیفه همچون Celery متکی هستند.)

    سرورهای یادگیری ماشین

    صف وظیفه Huey

    بسیاری از مردم برای صف وظیفه  از Celery استفاده می‌کنند اما برای استفاده مناسب از Celery باید دانش کافی نسبت به آن داشته باشید علاوه بر آن Celery ویژگی‌هایی دارد که ممکن است شما به آن‌ها نیاز نداشته باشید. به عقیده من huey جایگزین مناسبی برای Celery است.

     

    مقایسه RQ، Celery و huey

    1. Celery از RabbitMQ، Redis و Amazon SQS پشتیبانی می‌کند. RQ فقط با Redis کار می‌کند. huey با Redis و sqlite کار می‌کند.
    2. Celery و huey از وظایف برنامه‌ریزی‌شده پشتیبانی می‌کنند.
    3. Celery از زیروظیفه‌ها پشتیبانی می‌کند اما RQ و huey از آن‌ها پشتیبانی نمی‌کنند.
    4. RQ و huey از صف‌هایی که اولویت بیشتری دارند پشتیبانی می‌کنند. در Celery تنها روش پشتیبانی از صف‌هایی با اولویت بیشتر این است که وظایف را به یک سرور متفاوت مسیریابی کرد.
    5. RQ و huey فقط با زبان پایتون نوشته می‌شود اما Celery را علاوه بر پایتون با go و node هم می‌توان نوشت.

    انواع صف

    تمامی وظایف خود را در core.py بنویسید.

    وظایف مختلف

    وظایفی با اولیت ۱۰ ( ۱۰ اولویت بیشتری نسبت به ۱ دارد)

    وظایف دوره‌ای از قبیل واکشی داده‌ها Fetching data و به‌روز رسانی داده‌ها

    کارگر وظیفه huey

    کارگری که خطاها را ثبت می‌کند آغاز کنید

     

    FastAPI

    • سریع‌ترین – از آنجایی‌که fastapi برای باندهای ورودی خروجی سریع‌ترین است، API را مطابق با این دستورالعمل‌ بنویسید و دلایل آن هم در این مطلب توضیح داده شده است.
    • مستندسازی – نوشتن API در fastapi مستندسازی رایگان و هم‌چنین نقاط انتهایی آزمایش را در اختیار ما قرار می‌دهد که هم‌زمان با این‌که ما کد را تغییر می‌دهیم، fastapi به صورت خودکار آن‌ها را تولید و به‌روز رسانی می‌کند.
    • اعتبارسنجیبا بهره‌گیری از pydantic از اعتبارسنجی نوع‌داده پشتیبانی می‌کند
    • کارگرها – با استفاده از uvicorn، رابط برنامه‌نویسی کاربردی را برای بیش از یک کارگر مستقر می‌کنند.
    • از فراخوان‌های ناهم‌زمان پشتیبانی می‌کند
    • وظایف پس‌زمینه

     

    اسناد رابط برنامه‌نویسی کاربردی Swagger

    این سند توسط fastapi به صورت خودکار در http:url/docs ساخته می‌شود

    سرورهای یادگیری ماشین

    وظایف ناهمزمان

    به هر دلیلی ممکن است بالافاصله به نتایج احتیاج نداشته باشید. در این حالت می‌توانید وظایف را به صورت ناهمزمان درآورید.

    وظایف همگام

    به دلایلی ممکن است بالافاصله به نتایج احتیاج داشته باشید. در این حالت می‌تونید وظایف را همگام کنید.

    مفاهیم حافظه کَش

    اندازه حافظه کَش ← مطابق با نیاز، محاسبه سرور و ذخیره‌سازی بهینه‌سازی می‌شود.

    سیاست پاک‌سازی حافظه کَش ← با توجه به این‌که نمی‌توانیم همه‌چیز را در حافظه کَش ذخیره کنیم، باید آیتم‌هایی که کاربردهای کمتری دارند را حذف کنیم.

    • مدت زمان اعتبار حافظه کَش (TTL) TTL (Time To Love) cache

    حافظه‌ کَش را پس از آن‌که برای آخرین بار استفاده شد تا مدت زمان مشخصی نگه می‌دارد.

    • حافظه کَش دورترین به کار رفته (LRU) LRU (Least Recently Used) cache

    LRU – صف FIFO. در این حالت آیتم‌های قدیمی از صف کَش پاک می‌شوند.

    • حافظه کَش با کمترین فروانی به کار رفته (LFU) LFU (Least Frequently Used) cache

    LFU – آمار آیتم‌هایی که درخواست برای آن‌ها بیشتر است را دارد و آیتم‌هایی که بیشتر مورد استفاده قرار می‌گیرند را نگه می‌دارد.

    اکثر مردم در عمل از LRU استفاده می‌کنند چرا که اندازه حافظه کش و تأخیر را تضمین می‌کند.

     

    مفاهیم کارگر

    در صورتی‌که یک ماشین چندهسته‌ای در اختیار دارید، می‌توانید بیشتر از یک کارگر را آغاز کنید تا توان عملیاتی سرورهای یادگیری ماشین را افزایش دهید. هر کارگر در درون خود شبیه به یکی از سرورهای یادگیری ماشین فعالیت می‌کند. حداکثر تعداد کارگرها را هسته‌ها و RAM مشخص می‌کنند. نمی‌توان کارگرهایی بیشتر از RAM/ اندازه مدل شروع کرد و علاوه بر آن نباید کارگرهایی بیشتر از ۲ هسته + ۱  را شروع کنید.

    ثبت

    به عقیده من به اندازه کافی به ثبت توجه نشده است.

    Uvicorn از فایل‌های ثبت سرور پشتیبانی می‌کنند.

    پیکربندی مقابل را در config/logger.config ذخیره کنید.

    این پیکربندی فایل‌های ثبت ۷ روز گذشته را نگه می‌‍دارد و شما می‌توانید آن‌ها را اشکال‌زدایی کنید.

    سرورهای یادگیری ماشین

     

    سرور را آغاز کنید

     

    استقرار GPU

    در این مرحله نگاهی خواهیم انداخت به مبحث دسته‌سازی Batching و این‌که چگونه می‌توانیم با استفاده از دسته‌ها از مزایای GPUها بهره‌مند شویم.

    Framework combo1 → Fastapi + uvicorn + huey

    Framework combo2 → Tensorflow serving

    دلیل این‌که از GPU استفاده می‌کنیم این است که با استفاده از CUDA موجود در GPUها می‌توانیم به سرعت ماتریس‌ها را ضرب کنیم.  برای دست‌یابی به نتایج قابل‌قبول باید درخواست‌ها را در دسته‌ها پردازش کنیم.

     

    مفاهیم دسته‌سازی

    بدون دسته

    در تصویر مقابل چگونگی پردازش درخواست‌ها بدون دسته نشان داده شده است.

    سرورهای یادگیری ماشین

    با دسته

    در تصویر مقابل چگونگی عملکرد دسته‌سازی نشان داده شده است. درخواست‌‌ها بالافاصله پردازش نمی‌شوند، بلکه پس از مدتی تأخیر در دسته‌ها پردازش می‌شوند.

    سرورهای یادگیری ماشین

    تنها پس از استقرار GPU می‌توان دسته‌سازی را انجام داد و هزینه استقرار GPU  بسیار گران‌تر از هزینه استقرار CPU است.

    فقط زمانی می‌توانید GPU را مستقر کنید که خروجی کافی برای توجیه هزینه و تأخیر داشته باشید.

    همان‌گونه که در تصویر مقابل مشاهده می‌کنید پس از مقدار مشخصی از خروجی، عملکرد دسته‌سازی در مقایسه با بدون دسته‌سازی ارتقا پیدا می‌کند.

    سرورهای یادگیری ماشین

    مفاهیم پیشرفته دسته‌سازی

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

    هدف دسته‌سازی تطبیقی Adaptive batching این است که اندازه مناسب را برای یک دسته مشخص پیدا کند. یکی از روش‌هایی که clipper برای یافتن اندازه مناسب برای یک دسته به کار می‌بندد استفاده از روش « افزایش جمعی/کاهش ضربی Additive increase multiplicative decrease (AIMD)» است.

    به عبارت دیگر clipper به طور مداوم اندازه دسته را افزایش می‌دهند تا زمانی‌که به SLOها دست پیدا کند. همزمان با اتمام تأخیر SLO، اندازه دسته چند برابر افزایش پیدا می‌کند. این روش آسان و کارآمد است و روشی است که clipper به طور پیش‌فرض ارائه می‌دهد. روش دیگری که نویسندگان مورد مطالعه و بررسی قرار دادند استفاده از یک رگرسیون چارکی Quantile regression در صدک ۹۹ام تأخیر است و ماکسیسم ندازه دسته را هم مطابق با همان تنظیم می‌کنند. این روش همانند AIMD عمل می‌کند و به دلیل پیچیدگی‌های محاسباتی رگرسیون چارکی پیاده‌سازی و اجرای آن آسان نیست.

    زمانی که بار‌کاری انفجاری یا متوسط باشد می‌توان از دسته‌سازی تأخیردار Delayed batching استفاده کرد. در برخی موارد ممکن است نتوانیم به اندازه بهینه‌ دسته که برای یک چارچوب خاص انتخاب شده دست پیدا کنیم. در این‌گونه موارد، دسته‌ها می‌توانند چند میلی‌ثانیه تأخیر داشته باشند تا درخواست‌های بیشتری جمع‌آوری شود.

     

    پیاده‌سازی سفارشی دسته‌سازی

     

    ثبت

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

    کنترل

    یک مانیتور برای کنترل و نظارت بر وضعیت API داشته باشد تا زمانی‌که سرویس با مشکل مواجه می‌شود به شما اطلاع دهد. بسیاری مواقع این مورد نادیده گرفته می‌شود.

     

    کدهای وضعیت HTTP

    ما به عنوان متخصصین علوم داده معمولاً دانش کافی در اختیار نداریم و بهتر است خطاهای کد که در مقابل به آن‌ها اشاره شده را به خاطر بسپاریم

    • ۴۰۰ Bad Request – ورودی سمت کلاینت نادرست است.
    • ۴۰۱ Unauthorized – کاربر مجاز به دسترسی به منبع نیست. این خطا معمولاً زمانی‌که اعتبار کاربر اثبات نشده باشد، نشان داده می‌شود.
    • ۴۰۳ Forbidden – اعتبار کاربر اثبات شده اما اجازه دسترسی به یک منبع را ندارد.
    • ۴۰۴ Not Found – منبع پیدا نشد.
    • ۵۰۰ Internal server error – یک خطای عمومی سرور است.
    • ۵۰۲ Bad Gateway – پاسخ مناسبی از  سرور‌های بالادست Upstream server دریافت نشد.
    • ۵۰۳ Service Unavailable – اتفاقی غیرمنتظره در سمت سرور رخ داده است ( این اتفاق می‌تواند هرچیزی از جمله ترافیک زیاد سرور، از کار افتادن بخش‌هایی از سیستم و غیره باشد.)

     

    تست API

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

    •  تست عملکرد Functional testing ( برای مثال خروجی مورد انتظار برای یک ورودی مشخص)
    •  تست آماری Statistical testing ( برای مثال API را بر روی ۱۰۰۰ درخواست کاملاً جدید تست کنید و توزیع کلاس پیش‌بینی‌شده باید با توزیع آموزشی مطابقت داشته باشد)
    • رفع اشکال Error handling ( برای مثال اعتبارسنجی نوع داده درخواستی)
    • تست بار Load testing ( n کاربر به صورت همزمان درخواست x زمان/ دقیقه می‌کنند)
    این مطلب چه میزان برای شما مفید بوده است؟
    [کل: ۰ میانگین: ۰]

    فیلترینگ مشارکتی و دستاوردی جدید ؛ ذهن خوانی با کامپیوتر

    مقاله قبلی

    مدل تشخیص چهره ای که می توانید در کمتر از ۳۰ دقیقه آن را بسازید

    مقاله بعدی

    شما همچنین ممکن است دوست داشته باشید

    بیشتر در آموزش

    نظرات

    پاسخ دهید

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