بسیاری از پروژههای یادگیری ماشین با دقت و معیارهای آماری چشمگیر روی دادههای آموزشی متوقف میشوند و هرگز به بهرهبرداری واقعی نمیرسند. دلیل این شکستها معمولاً الگوریتم ضعیف نیست؛ بلکه طراحی نادرست سیستم پیش از نوشتن حتی یک خط کد مدلسازی است: تصمیمهای بدون اقدام عملی، نادیده گرفتن قواعد سرانگشتی موجود و عدم تطابق زمانبندی محاسبات با نیاز واقعی سیستم.
در این درس میآموزید که چطور یک هدف کسبوکار را به تسک یادگیری ماشین تبدیل کنید، معیارهای آفلاین و آنلاین و معیارهای محافظتی را بسنجید، بین استنتاج دستهای و آنلاین با توجه به بودجه و کهنگی داده دست به انتخاب بزنید و سیستم را با الگوهای استقرار سایه، قناری و پیشفرضهای امن آمادهی محیط پروداکشن کنید.
مدل تنها یک بخش از سیستم است. این طراحی سیستم است که مشخص میکند مدل چه چیزی را پیشبینی کند، چه کسی بر اساس آن دست به اقدام بزند، هزینهاش چقدر باشد و هنگام بروز خطا چه اتفاقی بیفتد.
اهداف یادگیری
- فرمولهکردن یک مسئلهی کسبوکار در قالب یک تسک یادگیری ماشین (Machine learning)، همراه با هدف پیشبینی مشخص، تصمیمی که از آن استفاده میکند و دلیلی بر اینکه چرا قواعد ساده (rules) کافی نیستند
- تفکیک معیارهای آفلاین، آنلاین، کسبوکار و معیارهای محافظتی (guardrail metrics)، و مقایسهی هر مدل با بیسلاینهای بدیهی و هیوریستیک
- برآورد هزینهی روزانه، تأخیر (latency) و کهنگی داده (staleness) در استنتاج دستهای (batch inference) و آنلاین بر اساس آمارهای ترافیک
- انتخاب الگوی انتشار (shadow، canary یا آزمون A/B) و یک حالت پیشفرض امن (safe default) برای هر سناریوی شکست
- شناسایی حلقههای بازخورد (feedback loops) که در آنها تصمیمهای مدل، دادههای آموزشی نسخهی بعدیاش را دستخوش تغییر میکند
- نگارش یک سند طراحی یادگیری ماشین (ML design document) و امتیازدهی به آن بر اساس یک چکلیست ثابت
صورت مسئله
یک شرکت مبتنی بر اشتراک، درخواست «یک مدل پیشبینی ریزش کاربر (churn)» میدهد. دانشمند داده مدلی مبتنی بر تقویت گرادیان (gradient-boosted) آموزش میدهد و AUC معادل 0.91 را گزارش میکند. سه ماه بعد، هیچکس از این مدل استفاده نمیکند.
دلایل این اتفاق اصلاً ربطی به الگوریتم ندارند: هیچکس مشخص نکرده بود این امتیاز قرار است ماشهی کدام اقدام عملی را بکشد. امتیازها هفتهای یک بار آماده میشدند، اما تیم حفظ مشتری هر روز با کاربران تماس میگرفت. برچسبها از جدول لغو اشتراکهایی آمده بودند که علت لغو را هم ذخیره میکرد؛ یعنی یکی از ویژگیها عملاً پاسخ نهایی را درون خود داشت. در نهایت هم هیچکس مدل را با قانونی که تیم پشتیبانی از قبل اجرا میکرد مقایسه نکرد: تماس با هر کاربری که دو هفته غیرفعال بوده است.
همهی این شکستها قبل از شروع مرحلهی آموزش رخ داده بودند. اینها نقص در طراحی سیستم هستند؛ یعنی همان مواردی که یک سند طراحی یکصفحهای دربارهی تکتکشان سؤال میپرسد. در این درس، تصمیمگیریهای لازم برای تدوین چنین سندی را یاد میگیرید. در ادامه ابزاری میسازید که هزینهی سرویسدهی دستهای و آنلاین را برآورد میکند، عملکرد مدل را در برابر بیسلاینهایش میسنجد و سند طراحی را بر اساس یک چکلیست ارزیابی و امتیازدهی میکند.
مفاهیم پایه
تبدیل هدف کسبوکار به تسک یادگیری ماشین
هدف کسبوکار، تسک یادگیری ماشین نیست. با پاسخ به این چهار سؤال، هدف را به تسک تبدیل میکنید:
- مدل دقیقاً چه چیزی را پیشبینی میکند و برای کدام موجودیت (کاربر، پرداخت، فروشگاه، کالا)؟
- کدام تصمیم از این پیشبینی استفاده میکند و چه فرد یا سیستمی آن تصمیم را میگیرد؟
- پیشبینی در چه زمانی لازم است و در همان لحظه چه دادههایی در دسترس هستند؟
- از کجا میفهمید که کیفیت این تصمیمگیری بهتر شده است؟
| هدف کسبوکار | پیشبینی | تصمیمی که از آن استفاده میکند | تسک یادگیری ماشین |
|---|---|---|---|
| کاهش ریزش کاربر | احتمال لغو اشتراک کاربر در 30 روز آینده | ارسال پیشنهاد حفظ مشتری به 5 درصد برتر هر شب | دستهبندی دوتایی (Binary classification) |
| کاهش خسارت ناشی از کلاهبرداری | احتمال کلاهبرداری بودن یک پرداخت | تأیید، بررسی دستی یا مسدودسازی ظرف 100 میلیثانیه | دستهبندی دوتایی |
| پر نگه داشتن قفسهها | تعداد کالای فروختهشده در هر فروشگاه در هر روزِ هفتهی آینده | تعیین حجم سفارش برای هر فروشگاه | پیشبینی سری زمانی (Forecasting) |
| نمایش محتوای مرتبط | امتیاز مرتبط بودن برای زوج (کاربر، کالا) | ترتیب نمایش آیتمها در فید کاربر | رتبهبندی (Ranking) |
ستون دوم به بیشترین وسواس نیاز دارد. عبارت «ریزش را پیشبینی کن»، افق زمانی، موجودیت و اقدام عملی را مبهم باقی میگذارد. در مقابل، عبارت «پیشبینی کن آیا این کاربر در 30 روز آینده لغو میکند یا نه، تا جاب امشب مشخص کند به چه کسانی پیشنهاد تخفیف داده شود»، هر سه مورد را دقیقاً معین میکند.
چه زمانهایی نباید از یادگیری ماشین استفاده کرد؟
قاعدهی اول در راهنمای «قواعد یادگیری ماشین» گوگل میگوید: از ارائهی محصول بدون یادگیری ماشین نترسید. یادگیری ماشین به داده نیاز دارد و یک قاعدهی تجربیِ (heuristic) ساده اغلب بخشی از مسیر را برایتان پیش میبرد. در این شرایط به سراغ یادگیری ماشین نروید:
- یک قاعدهی سرانگشتیِ کوتاه شما را به هدف میرساند و درست هم کار میکند. اجرای یک قاعده، آزمودن و توضیح دادنش بسیار ارزانتر تمام میشود.
- هیچ برچسبی ندارید و روش عملی مناسبی هم برای جمعآوری آن وجود ندارد.
- کسی بر اساس این پیشبینی دست به اقدام نمیزند؛ بنابراین پیشبینی بهتر، هیچ تغییری در وضع موجود ایجاد نمیکند.
- دادهای که در لحظهی پیشبینی در دسترس است، سیگنال لازم را درون خود ندارد.
- حتی یک خطا هم پذیرفتنی نیست و هیچ انسانی هم خروجی را بررسی نمیکند.
- ساخت و اجرای سیستم، از ارزشی که با تصمیمهای بهتر به دست میآید گرانتر تمام میشود.
زمانی که قواعد طولانی، پیچیده و شکننده شدند، استفاده از یادگیری ماشین توجیهپذیر میشود. طبق قاعدهی سوم همان راهنما، مدل یادگیری ماشین بر هیوریستیکهای پیچیده ترجیح داده میشود؛ زیرا بهروزرسانی و نگهداری یک مدلِ آموزشدیده آسانتر است.
سه لایهی معیارها
یک سیستم یادگیری ماشین را در سه لایه ارزیابی میکنید، بهعلاوهی یک مجموعه محدودیت:
| لایه | زمان سنجش | مثال در سناریوی ریزش کاربر |
|---|---|---|
| معیار آفلاین | قبل از انتشار، روی دادههای نگهداشتهشدهی گذشته (held-out) | معیار F1 در آستانهی ارسال پیشنهاد، دقت (precision) در 5 درصد بالای لیست |
| معیار آنلاین | در زمان انتشار، روی ترافیک زنده | نرخ پذیرش پیشنهاد، سهم کاربران امتیازدهیشده، توزیع امتیازها |
| معیار کسبوکار | چند هفته پس از انتشار، از طریق یک آزمایش | نرخ ریزش 30 روزه در گروه هدف در مقایسه با گروه کنترل |
| معیار محافظتی | پیوسته و همیشگی | هزینهی پیشنهادها به ازای هر کاربرِ حفظشده، نرخ لغو عضویت، تأخیر صدک 99 (p99 latency) |
این لایهها اغلب با یکدیگر ناهمخوان هستند. معیار آفلاین روی دادههای گذشته ارزیابی میشود؛ در حالی که گذشته حاوی مدل شما نبوده است. معیار آنلاین به نحوهی واکنش انسانها نسبت به تصمیم بستگی دارد. معیار کسبوکار هم بهکندی تغییر میکند و نویز ناشی از تمام رخدادهای دیگر شرکت روی آن میافتد.
معیار آفلاینی را انتخاب کنید که با تصمیم نهایی همخوانی داشته باشد. اگر جاب قرار است با 5 درصد بالای کاربران تماس بگیرد، دقت را در همان 5 درصد بالا بسنجید. معیار AUC روی تمام آستانهها میانگین میگیرد؛ از جمله آستانههایی که اصلاً در عمل سراغشان نمیروید. قاعدهی دوم راهنمای گوگل تأکید میکند که پیش از تعیین کارکرد سیستم یادگیری ماشین، ابتدا معیارها را طراحی و پیادهسازی کنید.
بیسلاینها
مقدار یک معیار بهتنهایی گویای هیچ چیز نیست. امتیاز F1 برابر با 0.56 در شرایطی که بهترین گزینهی جایگزین به 0.30 میرسد عالی است، اما اگر یک قانون ساده به 0.60 برسد، ضعیف تلقی میشود. هر مدلی را با سه نوع بیسلاین مقایسه کنید:
- بیسلاین بدیهی (Trivial baseline): همیشه کلاس اکثریت را پیشبینی کنید، یا میانگین دادههای آموزشی را برگردانید. از این بررسی در درس ارزیابی مدل استفاده کردیم.
- بیسلاین هیوریستیک (Heuristic baseline): قانونی برآمده از دانش دامنه (domain knowledge)، یا تعیین آستانه روی یک ویژگی خاص که بر اساس دادههای آموزشی برازش شده است.
- سیستم فعلی (Current system): هر سازوکاری که امروز مسئولیت تصمیمگیری را بر عهده دارد، حتی اگر فردی باشد که کارها را با یک فایل اکسل پیش میبرد.
لیفت (lift) برابر است با امتیاز مدل منهای امتیاز قویترین بیسلاین. قبل از مشاهدهی نتایج، یک حداقل لیفت تعیین کنید و آن را به اندازهای در نظر بگیرید که هزینههای سیستم جدید را توجیه کند. بیسلاین بدیهی معمولاً ضعیف است؛ اما بیسلاین هیوریستیک حریفی است که شکست دادنش چالش واقعی محسوب میشود.
الزامات داده و برچسب
قبل از شروع آموزش، به این سؤالات پاسخ دهید:
- منبع برچسب: کدام جدول یا رویداد، برچسب را تعریف میکند و مالک آن کیست؟
- تأخیر برچسب (Label delay): چقدر بعد از لحظهی پیشبینی، نتیجهی واقعی مشخص میشود؟ ثبت گزارش استرداد وجه کلاهبرداری (fraud chargebacks) شاید هفتهها بعد از پرداخت طول بکشد. برچسب ریزش کاربر در انتهای بازهی 30 روزه مشخص میشود.
- کیفیت برچسب: چه کسی برچسب را ثبت میکند و این برچسبها چقدر دچار خطا هستند؟
- دسترسیپذیری در زمان پیشبینی: آیا تمام ویژگیها در لحظهی پیشبینی آمادهاند؟ ویژگیهایی که سیستم بعد از رخ دادن نتیجه ثبت میکند، باعث نشت برچسب به دادههای آموزشی میشوند.
- حجم به ازای هر کلاس: چند نمونهی مثبت وجود دارد؟ داشتن 200 نمونهی مثبت، دست شما را میبندد و شما را به مدلهای ساده محدود میکند.
- تفکیک زمانی (Time split): دادههای جدیدترین بازهی زمانی را برای ارزیابی کنار بگذارید. در درس سریهای زمانی هم دادهها را به همین دلیل بر اساس زمان جدا کردیم.
بودجههای تأخیر، توان عملیاتی و هزینه
سه عدد، مرزهای هر طراحی در سرویسدهی را مشخص میکنند:
- بودجهی تأخیر: تأخیر p99 بیشینهی زمانی است که 99 درخواست از هر 100 درخواست زیر آن پاسخ داده میشوند. بررسی یک تراکنش پرداخت ممکن است به 50 میلیثانیه زمان نیاز داشته باشد، اما یک گزارش شبانه میتواند چند ساعت طول بکشد.
- اوج توان عملیاتی (Peak throughput): ابعاد سیستم را برای شلوغترین دقیقه تنظیم کنید، نه برای میانگین روزانه. اوج درخواست در ثانیه (Peak QPS) اغلب چندین برابر میانگین است.
- بودجهی هزینه: آن را بر حسب دلار در روز یا دلار به ازای هر 1000 پیشبینی بیان کنید تا مقایسهی طرحهای مختلف ممکن شود.
قانون لیتل (Little's law) این دو مؤلفهی اول را به هم پیوند میدهد: تعداد درخواستهای در حال پردازش برابر است با توان عملیاتی ضربدر تأخیر. با 400 درخواست در ثانیه و تأخیر 50 میلیثانیهای، در هر لحظه 20 درخواست در دست پردازش هستند.
استنتاج دستهای در برابر استنتاج آنلاین
دو شیوهی بنیادین برای ارائهی پیشبینیها وجود دارد:
- استنتاج دستهای (Batch inference): یک جاب زمانبندیشده، همهی موجودیتها را امتیازدهی کرده و امتیازها را در یک جدول یا پایگاه دادهی کلید-مقداری (key-value) مینویسد. برنامهی کاربردی در لحظهی درخواست، امتیاز ذخیرهشده را میخواند.
- استنتاج آنلاین (Online inference): برنامهی کاربردی ویژگیها را در زمان درخواست به سرویس مدل میفرستد و منتظر دریافت امتیاز میماند.
| ویژگی | دستهای (Batch) | آنلاین (Online) |
|---|---|---|
| تازگی داده | به قدمت آخرین اجرا بهعلاوهی مدتزمان همان اجرا | استفاده از دادههای لحظهای همان درخواست |
| تأخیر درخواست | یک خواندن ساده از دیتابیس کلید-مقدار، در حد چند میلیثانیه | زمان واکشی ویژگیها بهعلاوهی زمان استنتاج مدل |
| عامل هزینه | تعداد موجودیتها ضربدر دفعات اجرا در روز | تعداد نمونهها (replicas) متناسب با اوج QPS |
| موجودیتهای جدید | تا اجرای بعدی امتیازی ندارند | با همان درخواست اول امتیازدهی میشوند |
| رفتار هنگام خرابی | امتیازهای قبلی همچنان خواندنی هستند | درخواستها با خطا یا تایماوت روبهرو میشوند |
ابزاری که در این درس میسازید، هزینهی هر دو روش را محاسبه میکند. هزینهی پردازش دستهای با تعداد موجودیتها و تعداد دفعات اجرا در روز رشد میکند. هرچه محدودیت کهنگی داده کوتاهتر باشد، جابها باید در فاصلههای نزدیکتری تکرار شوند. هزینهی آنلاین با اوج ترافیک افزایش مییابد؛ زیرا در فاصلهی بین پیکهای ترافیکی نیز باید هزینهی سرورهای بیکار را بپردازید. جاب دستهای که اجرایش یک ساعت زمان میبرد، با هیچ هزینهای نمیتواند نیاز به کهنگی زیر یک ساعت را برآورده کند.
طراحی ترکیبی (hybrid) نیز بسیار رایج است: یک جاب دستهای شبانه کاربران شناختهشده را امتیازدهی میکند و یک مسیر آنلاین، پاسخگوی کاربران جدید و درخواستهایی است که به دادههای کاملاً تازه نیاز دارند.
الگوهای انتشار
مدل جدید در چند مرحله به دست کاربران میرسد:
- استقرار در سایه (Shadow): مدل جدید یک کپی از ترافیک زنده را دریافت میکند. سیستم پیشبینیهای آن را لاگ میکند، اما هرگز از آنها استفاده نمیکند. در این مرحله، تأخیر، نرخ خطا و توزیع پیشبینیها را با مدل فعلی مقایسه میکنید.
- استقرار قناری (Canary): مدل جدید برای سهم کوچکی از ترافیک (معمولاً 1 تا 5 درصد) تصمیمگیری واقعی انجام میدهد. این سهم را پلهپله افزایش میدهید و اگر معیارهای محافظتی افت کردند، بلافاصله مدل را بازگردانی (rollback) میکنید.
- آزمون A/B: ترافیک کاربران بهصورت تصادفی میان مدلها تقسیم میشود. با آزمونهای آماری، تفاوت در معیار کسبوکار را ارزیابی میکنید؛ این کار به ترافیک و زمان کافی نیاز دارد تا اختلاف آماری معناداری دیده شود.
هر مرحله نیازمند سازوکار بازگردانی سریعی است که ظرف چند دقیقه اجرا شود. نسخهی قدیمی مدل را در حالت آمادهباش نگه دارید و انتقال ترافیک را فقط از طریق تنظیمات (configuration) تغییر دهید. همین سه الگو برای مدلهای زبانی بزرگ، در فاز سرویسدهی LLM در درس استقرار سایه و قناری و درس آزمون A/B بررسی شدهاند.
حلقههای بازخورد
حلقهی بازخورد زمانی شکل میگیرد که تصمیمهای مدل، دادههای لازم برای آموزش نسخهی بعدی همان مدل را تغییر دهند. اسکالی و همکاران (Sculley et al.) در مقالهی خود، حلقههای بازخورد مستقیم و پنهان را از دلایل اصلی بدهی فنی در سیستمهای یادگیری ماشین معرفی میکنند. سه حالت رایج عبارتاند از:
- مداخلات، برچسبها را پنهان میکنند: مدل ریزش کاربر پیشنهاد تخفیف میفرستد و این پیشنهادها مانع از رفتن برخی کاربران میشوند. ماه بعد، کاربران پرریسک وفادار به نظر میرسند و مدل بازآموزیشده یاد میگیرد که ویژگیهای آنها نشانهی ریزش نیست.
- اقدامات مسدودکننده، خروجی قطعی ثبت نمیکنند: مدل تقلب، پرداختی را مسدود میکند؛ در نتیجه برای آن پرداخت هرگز برچسب بازپرداخت خسارت ثبت نمیشود. مدل بازآموزیشده، نمونههای تقلب کمتری را از آن ناحیهی مسدودشده مشاهده میکند.
- محدودیت در نمایش، بازخورد را محدود میکند: مدل رتبهبندی، فقط آیتمهای برتر خود را نشان میدهد؛ در نتیجه تنها همان موارد کلیک میخورند.
راهکار این معضلات ریشه در یک ایده دارد: بخشی از دادهها را دستنخورده نگه دارید تا مدل روی آنها اثر نگذارد. یک گروه تصادفی کوچک را بدون هیچ مداخلهای کنار بگذارید (holdout). به بخش کوچکی از ترافیک تصمیمهای تصادفی اختصاص دهید. امتیاز و تصمیم اتخاذشده را در کنار هر نمونه ثبت کنید تا در آموزشهای بعدی بتوان دادههای دستکاریشده را از دادههای خالص تفکیک کرد.
سناریوهای شکست و پیشفرضهای امن
هر بخشی از سیستم دیر یا زود با نقص روبهرو میشود. رفتار پیشفرض برای هر خطا را در مرحلهی طراحی مشخص کنید، نه در بحبوحهی بروز رخداد (incident):
| سناریوی شکست | نتیجه بدون داشتن برنامه | پیشفرض امن |
|---|---|---|
| تایماوت سرویس مدل | درخواست کاربر با خطا مواجه میشود | استفاده از بیسلاین هیوریستیک |
| شکست جاب دستهای شبانه | امتیازها مفقود یا قدیمی میشوند | ارائهی آخرین امتیازهای معتبر تا مدتی مشخص، سپس استفاده از قانون |
| ویژگی ناموجود یا خارج از محدوده | مدل ورودی خراب را امتیازدهی میکند | استفاده از مقدار پیشفرضِ مستندشده و ثبت لاگ رخداد |
| موجودیت جدید فاقد سابقه | هیچ امتیازی وجود ندارد | استفاده از قانون یا میانگین کل جامعه |
| جابهجایی ناگهانی توزیع امتیازها | تصمیمهای نادرست در مقیاس وسیع | توقف اقدامات خودکار و ارسال هشدار به نیروی انسانی |
بیسلاین هیوریستیک که در بخش معیارها معرفی شد، پیشفرض امن برای اکثر خطاها نیز به شمار میرود؛ بنابراین آن را در همان ابتدای کار بسازید.
سند طراحی
سند طراحی تمامی تصمیمهای بالا را قبل از شروع فاز آموزش، یکجا ثبت میکند. اسکریپت اعتبارسنجیِ این درس، نسخهی JSON چنین سندی را ارزیابی میکند. شش مورد وجود دارند که نقص در آنها بررسی را متوقف میکند (blocking)؛ چرا که هر یک از آنها سیستم را ناامن یا ناکارآمد میسازد:
| بخش | سؤالی که پاسخ میدهد | مسدودکننده؟ |
|---|---|---|
| مسئله (Problem) | چه چیزی پیشبینی میشود، چه تصمیمی از آن استفاده میکند و چرا قواعد کافی نیستند؟ | تصمیم نهایی |
| معیارها (Metrics) | کدام معیارهای آفلاین، آنلاین، کسبوکار و محافظتی اعمال میشوند؟ | معیار کسبوکار |
| بیسلاینها (Baselines) | کدام بیسلاینهای بدیهی، هیوریستیک و سیستم فعلی کاربرد دارند؟ | بیسلاین هیوریستیک یا سیستم فعلی |
| دادهها (Data) | برچسبها از کجا میآیند، چقدر تأخیر دارند و آیا همهی ویژگیها در لحظهی پیشبینی موجودند؟ | عدم وجود نشت برچسب |
| بودجه و سرویسدهی (Budgets and serving) | چه محدودیتهایی برای تأخیر، اوج QPS، هزینه و کهنگی وجود دارد و کدام شیوهی سرویسدهی با آنها همخوان است؟ | خیر |
| انتشار (Rollout) | کدام مراحل سایه، قناری و A/B در نظر گرفته شدهاند و فرآیند بازگردانی چگونه است؟ | استقرار سایه یا قناری، بهعلاوهی بازگردانی |
| حلقههای بازخورد (Feedback loops) | مدل چگونه دادههای آیندهی خود را تغییر میدهد و دادههای خالص چگونه حفظ میشوند؟ | خیر |
| سناریوهای شکست (Failure modes) | رفتار پیشفرض در ازای هر خرابی چیست؟ | رفتار پیشفرض برای تکتک خرابیها |
| پایش (Monitoring) | بعد از انتشار چه چیزهایی پایش میشوند؟ | خیر |
پیادهسازی از صفر
کدهای فایل code/main.py تنها از کتابخانهی استاندارد پایتون استفاده میکنند. این ابزار از سه بخش تشکیل شده است: مدل هزینهی سرویسدهی، ابزار مقایسهی بیسلاین و اعتبارسنجِ سند طراحی.
گام 1: تعریف بار کاری و قیمتها
یک بار کاری (workload) آمار ترافیک و بودجهها را نگه میدارد. مدل هزینه، نرخ قیمتها را در خود دارد. قیمتهای اینجا صرفاً اعدادی رُند برای این تمرین هستند، نه پیشفاکتورهای رسمی و شرکتی.
@dataclass(frozen=True)
class Workload:
name: str
entities: int
requests_per_day: int
peak_qps: float
max_staleness_hours: float
latency_budget_ms: float
@dataclass(frozen=True)
class CostModel:
batch_dollars_per_million: float = 0.40
batch_job_hours: float = 1.0
lookup_dollars_per_million: float = 0.25
lookup_latency_ms: float = 4.0
replica_dollars_per_hour: float = 0.50
replica_qps: float = 200.0
min_replicas: int = 2
online_latency_ms: float = 35.0
گام 2: قیمتگذاری سرویسدهی دستهای و آنلاین
جاب دستهای باید قبل از رسیدن به حد کهنگی مجاز تمام شود. فاصلهی بین اجراها برابر است با سقف کهنگی منهای مدتزمان اجرای جاب. در هر بار اجرا، تمام موجودیتها امتیازدهی میشوند؛ چه کسی آن امتیاز را استعلام کند و چه نکند.
def batch_plan(workload: Workload, costs: CostModel) -> ServingPlan:
refresh_hours = workload.max_staleness_hours - costs.batch_job_hours
if refresh_hours <= 0:
return ServingPlan(
"batch", False, math.inf, costs.lookup_latency_ms, math.inf, 0.0,
"staleness limit is shorter than one batch job",
)
runs_per_day = 24.0 / refresh_hours
predictions = workload.entities * runs_per_day
dollars = (
predictions / 1e6 * costs.batch_dollars_per_million
+ workload.requests_per_day / 1e6 * costs.lookup_dollars_per_million
)
...
سرویسدهی آنلاین هزینهی تعداد رپلیکای لازم برای پاسخ به اوج ترافیک را میپردازد، همراه با حداقل دو نسخه برای تضمین دسترسیپذیری (availability):
def online_plan(workload: Workload, costs: CostModel) -> ServingPlan:
replicas = max(costs.min_replicas, math.ceil(workload.peak_qps / costs.replica_qps))
dollars = replicas * costs.replica_dollars_per_hour * 24.0
feasible = costs.online_latency_ms <= workload.latency_budget_ms
...
تابع choose_serving طرحهایی را که محدودیتهای تأخیر و کهنگی را رعایت میکنند نگه میدارد و ارزانترین گزینه را برمیگرداند. اگر هیچ گزینهای با بودجه هماهنگ نباشد، خروجی None خواهد بود که یعنی باید در بودجهبندی تجدیدنظر کنید.
گام 3: مقایسهی مدل با بیسلاینها
ابزار مقایسه، مدل و تمام بیسلاینها را با همان معیار یکسان میسنجد. این ابزار، لیفت را در برابر قویترین بیسلاین محاسبه میکند، نه ضعیفترین آنها.
def compare_to_baselines(
y_true: list,
model_pred: list,
baselines: dict[str, list],
metric,
metric_name: str,
higher_is_better: bool = True,
min_lift: float = 0.02,
) -> BaselineReport:
if not baselines:
raise ValueError("a model needs at least one baseline")
scores = {name: metric(y_true, pred) for name, pred in baselines.items()}
pick = max if higher_is_better else min
best_name = pick(scores, key=scores.get)
model_score = metric(y_true, model_pred)
lift = model_score - scores[best_name] if higher_is_better else scores[best_name] - model_score
return BaselineReport(metric_name, {"model": model_score, **scores}, best_name, lift, min_lift)
بیسلاین هیوریستیک، یک قانون بر پایهی یک ویژگی منفرد است. تابع fit_rule تکتک مقادیر آن ویژگی را به عنوان آستانه روی دادههای آموزشی آزمایش میکند و آستانهای را که بهترین F1 را ارائه میدهد نگه میدارد. در کد نمونه، یک رگرسیون لجستیک ساده روی دادههای ساختگیِ ریزش کاربر آموزش داده شده و با سه بیسلاین مقایسه میشود.
گام 4: امتیازدهی به سند طراحی
هر آیتم چکلیست شامل یک کلید، وزن، پرچمِ مسدودکننده (blocking flag)، پیام راهنما و تابع ارزیابی است. وزن موارد مسدودکننده برابر با 2 در نظر گرفته شده است.
CheckItem("decision", 2, True, "name the action that uses each prediction", lambda d: _text(d, "problem.decision")),
CheckItem("baselines", 2, True, "add a heuristic or current-system baseline", check_baselines),
CheckItem("no_leakage", 2, True, "confirm every feature exists at prediction time",
lambda d: get_path(d, "data.features_available_at_prediction_time") is True),
CheckItem("serving_fit", 1, False, "pick a serving mode that meets the staleness, latency, and cost budgets",
check_serving_fit),
تابع check_serving_fit از همان مدل هزینه استفاده میکند. این تابع آمارهای بار کاری را از سند میخواند و هزینهی حالت انتخابی را تخمین میزند. اگر حالت انتخابی از سقف کهنگی، بودجهی تأخیر یا بودجهی هزینهی روزانه تخطی کند، این ارزیابی رد میشود. سندی که حالت «دستهای» را با محدودیت کهنگی سهدقیقهای پیشنهاد دهد، در این مرحله رد خواهد شد. مدل هزینه فاقد طرح ترکیبی است؛ بنابراین اگر سندی گزینهی «hybrid» را قید کند، رد میشود مگر اینکه در تمرین 1 آن طرح را به کد اضافه کنید.
تابع review_design_doc وزن موارد پذیرفتهشده را با هم جمع کرده و بر مجموع وزنها تقسیم میکند. تنها زمانی وضعیت «آمادهی بازبینی» (ready for review) ثبت میشود که امتیاز به 0.85 برسد و هیچ مورد مسدودکنندهای رد نشده باشد.
گام 5: اجرا
python3 code/main.py
nightly churn scores
ok batch $0.91/day 4 ms 1.0 runs per day over 2,000,000 entities
ok online $24.00/day 35 ms 2 replicas sized for 40 peak QPS
choose: batch
feed ranking, 2-hour freshness
ok batch $48.50/day 4 ms 24.0 runs per day over 5,000,000 entities
ok online $24.00/day 35 ms 2 replicas sized for 120 peak QPS
choose: online
=== Model versus baselines (churn, metric F1) ===
model 0.564
days_idle > 12.8688 0.500
random at base rate 0.232
majority class 0.000
model beats the strongest baseline (days_idle > 12.8688) by +0.064
بیسلاین اکثریت امتیاز F1 برابر با 0 میگیرد؛ چون هیچوقت ریزش را پیشبینی نمیکند. قاعدهی برازششده بر پایهی آستانه، رقیب اصلی است. مدل به میزان 0.064 بهتر از آن عمل کرده و شایستگیاش را اثبات میکند. با ویژگیهای ضعیفتر ممکن است قانون ساده برنده شود؛ در آن صورت همان قانون، گزینهی مناسب برای استقرار خواهد بود.
ارزیابی سند طراحی، ابتدا سند ضعیف را همراه با شش خطای مسدودکننده چاپ میکند و سپس سند کامل را با امتیاز 1.00 نشان میدهد. برای بررسی سند خودتان میتوانید مسیر فایل آن را به برنامه بدهید:
python3 code/main.py my_design_doc.json
استفاده در عمل
هر بخش از این جعبهابزار، متناظر با ابزارهایی است که تیمها در محیط پروداکشن به کار میگیرند.
بیسلاینها: کتابخانهی scikit-learn بیسلاینهای بدیهی را در قالب تخمینگر (estimator) ارائه میدهد تا بتوانید آنها را مستقیماً در خط لولهی مدل بنشانید:
from sklearn.dummy import DummyClassifier, DummyRegressor
from sklearn.metrics import f1_score
majority = DummyClassifier(strategy="most_frequent").fit(X_train, y_train)
base_rate = DummyClassifier(strategy="stratified", random_state=0).fit(X_train, y_train)
mean_value = DummyRegressor(strategy="mean").fit(X_train, y_reg_train)
print(f1_score(y_test, majority.predict(X_test)))
گزینهی most_frequent با majority_baseline و گزینهی stratified با base_rate_baseline همارز است. در scikit-learn بیسلاین هیوریستیک وجود ندارد؛ زیرا این قاعده از دامنهی تخصصی کار شما میآید.
سرویسدهی دستهای: ابزارهای زمانبندی گردش کار مانند Apache Airflow یا Dagster جابهای امتیازدهی را اجرا میکنند. این جابها دادهها را در جداول انبار داده یا دیتابیسهای کلید-مقدار نظیر Redis یا DynamoDB ذخیره میکنند.
سرویسدهی آنلاین: سرورهای مدل مانند KServe، BentoML، NVIDIA Triton و TorchServe مدل را پشت یک اندپوینت HTTP یا gRPC قرار میدهند. برای مدلهای کوچک، یک وبسرویس ساده هم کار را راه میاندازد.
انتشار: ابزارهای اکوسیستم Kubernetes مانند Argo Rollouts هدایت ترافیک را برای نسخههای قناری انجام میدهند. پلتفرمهای آزمایش مانند GrowthBook و Statsig وظیفهی تخصیص کاربران به گروههای A/B و انجام محاسبات آماری را بر عهده دارند.
بررسی طراحی: برک و همکاران (Breck et al.) چارچوب ML Test Score را منتشر کردند که شامل 28 آزمون و نیازمندی پایش برای سیستمهای یادگیری ماشین در سطح پروداکشن است. ابزار ارزیاب ما جمعوجورتر است و پرسشهای طراحی را قبل از رسیدن به آن تستها پیش پای شما میگذارد.
کاربرد اجرایی
خروجی این درس فایل outputs/skill-ml-design-review.md است. این مهارت، سند طراحی یادگیری ماشین را بخشبهبخش بررسی میکند و کمبودهای مسدودکننده را همان ابتدا نشان میدهد. علاوه بر این، صحت گزینهی انتخابی برای سرویسدهی را با استفاده از محاسبات ریاضی هزینهی دستهای و آنلاین در این درس اعتبارسنجی میکند.
تمرینها
- طرح ترکیبی (hybrid) را به تابع
choose_servingاضافه کنید: کاربران شناختهشده را بهصورت دستهای و کاربران جدید را بهصورت آنلاین امتیازدهی کنید. هزینهی روزانهی آن را مقایسه کنید. - دادههای ریزش کاربر را طوری تغییر دهید که مدل دیگر نتواند قانون ساده را شکست دهد. کمترین تغییر در ضرایب را که موجب حذف لیفت مدل میشود، گزارش کنید.
- آیتم
budgets.max_dollars_per_1k_predictionsرا به چکلیست اضافه کنید. آزمونی بنویسید که بدون وجود این پارامتر رد شود. - یک سند طراحی در قالب JSON برای بررسی کلاهبرداری پرداخت بنویسید. اسکریپت ارزیاب را اجرا کنید و تمام موارد مسدودکننده را برطرف سازید.
- حلقهی بازخورد ریزش کاربر را شبیهسازی کنید: برچسب کاربرانی را که پیشنهاد دریافت کردهاند حذف کنید، مدل را دوباره آموزش دهید و میزان تغییر در معیار F1 را بسنجید.
اصطلاحات کلیدی
| اصطلاح | اصطلاح عامیانه | معنای فنی |
|---|---|---|
| تسک یادگیری ماشین (ML task) | «یه مدل ریزش بزن» | تعریف هدف پیشبینی، موجودیت، افق زمانی و تصمیمی که از خروجی پیشبینی استفاده میکند |
| معیار آفلاین (Offline metric) | «امتیاز مدل» | معیاری که پیش از انتشار، روی دادههای نگهداشتهشدهی گذشته محاسبه میشود |
| معیار آنلاین (Online metric) | «آمارهای زنده» | معیاری که روی ترافیک واقعی و همزمان با اجرای مدل سنجیده میشود |
| معیار کسبوکار (Business metric) | «هدف اصلی» | برآیند عملکرد شرکت که تصمیم باید آن را تغییر دهد؛ سنجش از طریق آزمایش |
| معیار محافظتی (Guardrail metric) | «صدمه نزدن به سیستم» | معیاری که با راهاندازی مدل جدید هرگز نباید افت کند |
| بیسلاین (Baseline) | «مدل سرانگشتی» | پیشبینیکنندهای بدیهی، هیوریستیک یا سیستم فعلی که مدل جدید باید با اختلافی معین آن را شکست دهد |
| استنتاج دستهای (Batch inference) | «امتیازهای از پیش محاسبهشده» | یک جاب زمانبندیشده همهی موجودیتها را امتیازدهی کرده و برای استعلام ذخیره میکند |
| استنتاج آنلاین (Online inference) | «مدل بلادرنگ» | مدل، هر درخواست را بهمحض دریافت امتیازدهی میکند |
| استقرار در سایه (Shadow deployment) | «لانچ بیصدا» | مدل جدید ترافیک زنده را پردازش میکند، اما هیچ بخشی از سیستم از خروجیاش استفاده نمیکند |
| انتشار قناری (Canary release) | «رولاوت تدریجی» | مدل جدید برای سهمی کوچک و روبهرشد از ترافیک تصمیم میگیرد، در حالی که راهکار بازگردانی آماده است |
| حلقهی بازخورد (Feedback loop) | «مدل از کار خودش یاد میگیره» | تصمیمهای مدل دادههایی را که در آینده نسخهی بعدیاش را آموزش میدهند دستخوش تغییر میکند |
برای مطالعهی بیشتر
- اسکالی و همکاران، بدهی فنی پنهان در سیستمهای یادگیری ماشین (NeurIPS 2015): حلقههای بازخورد، درهمتنیدگی اجزا و هزینههای سیستمی پیرامون یک مدل
- گوگل، قواعد یادگیری ماشین: دستورالعملهای عملی برای اولین مدل، معیارها و هماهنگی دادههای آموزش با سرویسدهی
- برک و همکاران، امتیاز آزمون یادگیری ماشین (IEEE Big Data 2017): 28 آزمون برای سنجش آمادگی مدل در محیط پروداکشن
- کهاوی، تانگ و شو، آزمایشهای کنترلشدهی آنلاین قابلاعتماد (Cambridge University Press, 2020): روش اجرای آزمونهای A/B دقیق و مطمئن
- ساتو، ویدر و ویندهویزر، تحویل مداوم برای یادگیری ماشین (2019): مدیریت نسخههای داده، مدلها و پایپلاینهای استقرار
- گوگل کلود، MLOps: پایپلاینهای تحویل مداوم و اتوماسیون در یادگیری ماشین: سه سطح بلوغ برای خودکارسازی فرآیندهای آموزش و سرویسدهی مدل
