<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های امیرحسین غنی‌پور</title><link>https://virgool.ir/feed/@d3v1ll3n</link><description></description><language>fa</language><pubDate>2026-11-11 00:52:24</pubDate><image><url>https://files.virgool.ir/upload/users/4910421/avatar/8Mw1Hg.jpg</url><title>امیرحسین غنی‌پور</title><link>https://virgool.ir/@d3v1ll3n</link></image><item><title>مدل‌های هوش مصنوعی وقتی توی جیب کاربر زندگی می‌کنن</title><link>https://virgool.ir/@d3v1ll3n/مدل-های-هوش-مصنوعی-وقتی-توی-جیب-کاربر-زندگی-می-کنن-wcklcwmusp3n</link><description>سیستم‌های توصیه‌گر روی موبایل یه جور مساله‌ست که چه توسعه‌دهنده بک‌اند و چه توسعه‌دهنده AI رو مجبور می‌کنه از قلمروی امن خودشون بیرون بیان. بذارید از جایی شروع کنم که معمولاً کسی راجع بهش صحبت نمی‌کنه. خود مدل embedding، وقتی از نوت‌بوک بیرون میاد، دیگه یه آبجکت ریاضی نیست، بلکه یه قطعه‌ی زنده از سیستمه که باید توی چرخه‌ی حیات محصول، اینجا شما بگو اپ، جا بگیره. یعنی باید یه جایی decide بشه که این embedding کِی لود میشه، کجا cache میشه، کِی invalidate میشه، و از همه مهم‌تر، چه زمانی باید recompute بشه که UI فریز نکنه!برای کسی که از دنیای بک‌اند میاد، اولین چیزی که باید جا بیفته اینه که مدل یک state داره که مثل دیتابیس رفتار نمی‌کنه. توی بک‌اند عادت داریم فکر کنیم هر query یک نتیجه‌ی deterministic و قابل‌پیش‌بینی داره. اما embedding یک بردار پیوسته‌ست که با هر بار fine-tune یا update جزئی، shift می‌کنه و این shift می‌تونه باعث بشه فاصله‌ی کسینوسی بین دو آیتم که قبلاً نزدیک بودن، عوض بشه. این یعنی caching عادی (مثلاً یک TTL ساده روی Redis) این‌جا معنا نداره. یه جور دیگه بگم، نباید invalidation براساس زمان، بلکه باید بر اساس drift مدل طراحی بشه.از طرف دیگه، توسعه‌دهنده AI که میاد سراغ دیپلویمنت، باید یاد بگیره که مدل دیگه توی یک محیط کنترل‌شده زندگی نمی‌کنه. مدل روی گوشیه، حافظه‌ای که محدوده، thread اصلی UI که نباید بلاک بشه و باتری که یک constraint واقعیه که هیچ loss functionی بهش اهمیت نمی‌ده. این یعنی مدلی که آفلاین ۹۲ درصد accuracy داشته، وقتی quantize بشه به int8 برای اجرا روی TFLite، ممکنه اون عدد افت کنه و این افت باید از قبل توی طراحی لحاظ بشه.بریم سراغ خود پایپ‌لاین. توی فلاتر، معمول‌ترین الگو استفاده از tflite_flutter یا onnxruntime برای اجرای inference محلیه. اما نکته‌ای که خیلیا ازش رد می‌شن اینه که این پلاگین‌ها inference رو روی native thread اجرا می‌کنن، نه Dart isolate. یعنی اگه بخوای موازی چند embedding رو همزمان محاسبه کنی، مثلاً برای چند آیتم توی یک لیست اسکرول، باید خودت batching رو دستی مدیریت کنی، وگرنه هر فریم اسکرول یک inference جدا trigger می‌کنه و جنک میشه.حالا سراغ online learning بریم که شاید سخت‌ترین بخش کل قضیه‌ست. ایده اینه که embedding کاربر بدون این‌که نیاز به اتصال به سرور باشه، بر اساس رفتار real-time (کلیک، دوئل، اسکرول‌رفتار، dwell time) آپدیت بشه. این یعنی یک نسخه‌ی سبک از gradient update باید روی خود دستگاه اجرا بشه. اما این‌جا یه ریسک جدی هست که اونم catastrophic forgettingه. اگه مدل محلی صرفاً بر مبنای رفتار همین یک کاربر آپدیت بشه، به مرور، دانش عمومی که از ترین سراسری اومده رو فراموش می‌کنه و overfit میشه روی یک pattern محلی محدود. راه‌حل معمول ترکیبیه از elastic weight consolidation یا حداقل یک regularization ساده که فاصله‌ی weight جدید از weight اولیه رو محدود کنه، به‌علاوه یک learning rate خیلی کوچیک برای آپدیت‌های on-device.نکته‌ی بعدی sync استراتژیه. مدل نباید هر بار که کاربر یک اکشن انجام میده به سرور وصل بشه چون هم هزینه‌ی شبکه داره هم battery drain. الگوی رایج اینه که delta تغییرات embedding محلی توی یک buffer جمع بشه و فقط وقتی وای‌فای و شارژ کافی هست، این delta به سرور push بشه. این دقیقاً همون جاییه که تفکر بک‌اندی لازمه. باید یه API طراحی بشه که idempotent باشه، یعنی اگه یه sync دو بار اتفاق بیفته که توی شبکه‌های موبایل خیلی عادیه، مدل مرکزی دوبار همون delta رو اعمال نکنه.یه بحث دیگه که کمتر بهش پرداخته میشه، cold start مدله. کاربر جدید که هیچ رفتار قبلی نداره، embedding معناداری هم نداره. این‌جا معمولاً از یک embedding میانگین (population average) یا clustering اولیه بر اساس metadata (سن، زبان، دستگاه) استفاده میشه تا حداقل یک نقطه‌ی شروع معقول داشته باشیم و بعد به مرور با رفتار واقعی جایگزینش کنیم. این تصمیم باید توی هر دو سمت طراحی بشه. سمت سرور باید این embedding پیش‌فرض رو تولید و push کنه، و سمت اپ باید بلد باشه که چه زمانی از embedding پیش‌فرض به embedding شخصی‌شده سوییچ کنه بدون این‌که کاربر یهو یک تغییر عجیب توی توصیه‌ها ببینه (که راستش من جایی چنین موردی رو دیدم که باعث شد انگیزه نوشتن و به اشتراک گذاشتن این پست رو پیدا کنم که هر چند کمکی کرده باشم).یه چیز دیگه که باید در نظر گرفت، versioning مدله. وقتی مدل embedding سمت سرور آپدیت میشه مثلاً dimensionality عوض میشه یا architecture تغییر می‌کنه، همه‌ی embedding های قدیمی که روی دستگاه ذخیره شدن باید invalidate بشن، وگرنه فاصله‌ی کسینوسی بین embedding قدیم و جدید دیگه معنا نداره. این یعنی باید یک version tag همراه هر embedding ذخیره بشه، هم سمت سرور هم سمت local storage، و منطق sync باید چک کنه که آیا نسخه‌ی local با نسخه‌ی سرور سازگاره یا نه.از منظر قدرت پردازشی، مدل‌های two-tower (یکی برای کاربر، یکی برای آیتم) این مزیت رو دارن که فقط تاور کاربر نیاز به اجرا روی دستگاه داره و تاور آیتم می‌تونه سمت سرور precompute بشه و صرفاً به صورت یک لوکاپ‌تیبل (مثلاً یک فایل باینری embedded توی اپ یا دانلودی) در دسترس باشه. این معماری بار محاسباتی روی دستگاه رو به شدت کم می‌کنه چون فقط و فقط یک forward pass سبک لازمه (embedding کاربر).همینطور، مساله‌ی evaluation هم عوض میشه. توی سرور، معیارهایی مثل NDCG یا recall@k روی یک دیتاست offline اندازه‌گیری میشن. اما روی دستگاه، باید معیارهای online مثل click-through rate واقعی یا session length رو جمع کرد و به سرور فرستاد تا بشه فهمید آیا آپدیت‌های محلی واقعاً باعث بهبود تجربه شدن یا نه. یعنی باید یک لایه‌ی لاگ‌گیری سبک، privacy-aware و batch-friendly هم توی اپ طراحی بشه که خودش یک مساله‌ی جداست (که شاید بعدا بهش بپردازم) چون نباید داده‌ی خام رفتار کاربر رو مستقیم بفرسته، بلکه باید aggregate یا حداقل anonymized بفرسته.این همه گفتم جمع‌بندی این بشه که این نوع سیستم یک پروژه‌ست که هیچ‌کدوم از دو تخصص به تنهایی جوابگو نیست. باید بلد باشی مدل رو طراحی کنی، بلد باشی محدودیت‌های edge رو در نظر بگیری، بلد باشی sync و API idempotent طراحی کنی و بلد باشی lifecycle مدیریت حافظه و thread توی فلاتر رو بشناسی. هر کدوم از این لایه‌ها اگه از نگاه فقط یک تخصص دیده بشه، یه جای کار لنگ می‌مونه.</description><category>امیرحسین غنی‌پور</category><author>امیرحسین غنی‌پور</author><pubDate>Tue, 14 Jul 2026 06:21:49 +0330</pubDate></item></channel></rss>