filmyar

2026/09/11

فیلم‌یار؛ روایتی از یک پروژه کارشناسی: وقتی گراف دانش با هوش مصنوعی مولد ترکیب می‌شود

پروژه پایانی کارشناسی مهندسی کامپیوتر

این پروژه از کجا شروع شد؟

برای پروژه پایانی مقطع کارشناسی مهندسی کامپیوتر، تصمیم گرفتیم سراغ موضوعی برویم که صرفاً یک تمرین درسی نباشد، بلکه یک سیستم واقعی و قابل‌اجرا باشد: یک دستیار پیشنهاد فیلم به نام فیلم‌یار، که پاسخ‌هایش را نه از حدس یک مدل زبانی، بلکه از دل یک گراف دانش واقعی بیرون می‌کشد. رویکردی که این روزها به آن GraphRAG (Retrieval-Augmented Generation مبتنی بر گراف) گفته می‌شود.

ماهیت پروژه در یک نگاه

فیلم‌یار یک چت‌بات تحت وب است که به فارسی و انگلیسی (هر دو، به‌صورت خودکار بر اساس زبان سوال کاربر) به سوالات سینمایی پاسخ می‌دهد: معرفی فیلم بر اساس ژانر، بازیگر، کارگردان یا سال ساخت؛ ارائه امتیاز IMDB؛ و پیشنهاد فیلم‌های مشابه. نکته‌ی متفاوت این پروژه نسبت به بسیاری از چت‌بات‌های مشابه، این است که اطلاعات واقعی فیلم‌ها (بازیگران، کارگردان، ژانر، امتیاز) از یک گراف دانش ساخته‌شده در Neo4j خوانده می‌شود، و مدل زبانی فقط وظیفه دارد این اطلاعات را به‌صورت طبیعی و روان بیان کند — نه این‌که آن‌ها را از حافظه‌ی خودش بسازد.

معماری سیستم: پنج مرحله تا رسیدن به پاسخ

هر پیامی که کاربر می‌فرستد، این مسیر را طی می‌کند:

مرحله شرح
استخراج موجودیت متن آزاد کاربر (بدون دخالت مدل زبانی، صرفاً با منطق برنامه‌نویسی، Regex و تطبیق فازی) تحلیل می‌شود تا نام ژانر، بازیگر، کارگردان یا سال از آن بیرون کشیده شود
پرس‌وجوی گراف دانش با موجودیت‌های استخراج‌شده، یک کوئری Cypher روی گراف Neo4j اجرا می‌شود
بازگشت به جست‌وجوی وب اگر گراف محلی چیزی پیدا نکرد، به‌صورت خودکار سراغ جست‌وجوی وب (DuckDuckGo) می‌رود
تولید پاسخ با مدل زبانی اطلاعات پیداشده در قالب یک پرامپت جای می‌گیرد و به یک مدل زبانی مولد (LLaDA-8B، از خانواده مدل‌های دیفیوژنی) داده می‌شود تا پاسخ نهایی را بنویسد
لایه ارتباطی یک سرور Flask درخواست‌ها را از یک صفحه چت اختصاصی می‌گیرد و از طریق تونل Cloudflare، به‌صورت عمومی در دسترس قرار می‌دهد

جدا نگه‌داشتن مرحله استخراج موجودیت از مدل زبانی یک تصمیم طراحی آگاهانه بود: مدل‌های زبانی، به‌خصوص مدل‌های دیفیوژنی مثل LLaDA، در تولید خروجی دقیق و ساخت‌یافته (مثل کوئری پایگاه داده) عملکرد قابل‌اعتمادی ندارند؛ به همین دلیل این بخش کاملاً با منطق قطعی برنامه انجام می‌شود، و مدل زبانی فقط در آخرین قدم، برای «حرف زدن» به کار گرفته می‌شود.

استفاده از یک مدل زبانی دیفیوژنی به‌جای مدل‌های زنجیره‌ای رایج‌تر (مثل خانواده GPT) هم یکی از جنبه‌های کاوش‌گرانه‌ی این پروژه بود — تجربه‌ای که رفتار و محدودیت‌های متفاوتی نسبت به مدل‌های متداول‌تر نشان داد.

پشته فناوری

حوزه ابزار / فناوری
گراف دانش Neo4j (نسخه Community)
مدل زبانی مولد LLaDA-8B-Instruct، با کوانتیزاسیون ۴-بیتی
پردازش زبان طبیعی spaCy، Regex، تطبیق فازی با rapidfuzz
بک‌اند Python، Flask، Flask-CORS
زیرساخت یادگیری عمیق PyTorch، Transformers، Accelerate، BitsAndBytes
جست‌وجوی وب DuckDuckGo Search، به‌همراه پشتیبانی اختیاری از Tavily API
پردازش داده Pandas
محیط اجرا Google Colab (با GPU رایگان T4)
ذخیره دائمی دیتاست Google Drive
دسترسی عمومی به سرویس Cloudflare Quick Tunnel
رابط کاربری HTML، CSS، JavaScript

ویژگی‌های کلیدی

  • پاسخ‌دهی دوزبانه (فارسی/انگلیسی) با تشخیص خودکار زبان سوال
  • اطلاعات مبتنی بر داده واقعی، نه حدس مدل زبانی
  • مکانیزم بازگشتی به جست‌وجوی وب در نبود داده محلی
  • دیتاست فقط یک‌بار در Google Drive کاربر بارگذاری می‌شود و در اجراهای بعدی نیازی به تکرار آن نیست
  • اجرای کامل روی زیرساخت رایگان Google Colab، بدون نیاز به هیچ سرور اختصاصی
  • رابط کاربری وب مستقل، جدا از محیط نوت‌بوک

چالش‌های فنی در طول توسعه

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

چالش راه‌حل اتخاذشده
جا نشدن مدل ۸ میلیاردی روی GPU رایگان (T4، ۱۵ گیگابایت VRAM) کوانتیزاسیون ۴-بیتی مدل با bitsandbytes
ریسک خطای کمبود حافظه (OOM) به دلیل فرآیند نمونه‌گیری تکراری مدل دیفیوژنی (تا ۴۸ گام برای هر پاسخ) استفاده از torch.inference_mode() و پاک‌سازی صریح کش CUDA بین گام‌ها
نشتِ متن دستورالعمل/زمینه به داخل پاسخ نهایی مدل افزودن نشانگر مشخص («پاسخ نهایی:») در انتهای پرامپت و پاک‌سازی خروجی بر اساس آن
کندی اولین پاسخ به دلیل بارگذاری تنبل مدل، که از مهلت زمانی تونل عمومی عبور می‌کرد بارگذاری فعال مدل بلافاصله پس از بالا آمدن سرور، پیش از دریافت اولین درخواست
ناسازگاری نسخه‌ای bitsandbytes با ساختار به‌روزشده CUDA در Colab ارتقا به نسخه‌هایی از bitsandbytes/accelerate که مکانیزم تشخیص CUDA را بازنویسی کرده بودند
تفاوت نام‌گذاری ستون‌ها در نسخه‌های مختلف دیتاست IMDB نگاشت خودکار و مشروط نام ستون‌ها

محدودیتی که هنوز باقی است

در کمال صداقت باید گفت این پروژه با یک چالش حل‌نشده هم روبه‌روست: دیتاست محلی (TMDB 5000 و IMDB Top 1000) عمدتاً سینمای هالیوود را پوشش می‌دهد. برای بازیگران یا فیلم‌های خارج از این دامنه، هم گراف محلی و هم جست‌وجوی وب رایگان ممکن است نتیجه‌ی ضعیف یا نامرتبطی برگردانند؛ در چنین شرایطی، مدل زبانی دیفیوژنی گاهی به‌جای اعلام صریح «اطلاعاتی پیدا نشد»، ترکیبی نادرست از دانش پیش‌آموخته‌ی خود ارائه می‌دهد. این موضوع یکی از زمینه‌های روشن برای ادامه‌ی کار روی پروژه است: گسترش پوشش دیتاست، و تقویت مکانیزم‌های جلوگیری از پاسخ نادرست.

دیتاست‌های استفاده‌شده

  • TMDB 5000 Movie Dataset: اطلاعات پایه فیلم‌ها شامل ژانر، بازیگران و کارگردان
  • IMDB Top 1000: امتیازهای IMDB برای تکمیل اطلاعات فیلم‌های مشترک

راهنمای اجرا

فیلم‌یار کاملاً روی Google Colab اجرا می‌شود؛ نیازی به نصب چیزی روی سیستم شخصی نیست.

  1. نوت‌بوک پروژه را از مخزن گیت‌هاب دانلود کنید: لینک مخزن گیت‌هاب پروژه
  2. فایل .ipynb را در Google Colab باز کنید.
  3. از منوی Runtime، گزینه Change runtime type را انتخاب و GPU (نوع T4) را فعال کنید.
  4. سلول‌ها را به‌ترتیب از بالا به پایین اجرا کنید.
  5. در سلول بارگذاری دیتاست، درخواست دسترسی به Google Drive نمایش داده می‌شود؛ دسترسی را تأیید کنید.
  6. فایل‌های دیتاست را از این مسیر دانلود و در همان مرحله بارگذاری کنید: لینک دانلود دیتاست‌ها از این پس، دیتاست‌ها در Google Drive شما ذخیره می‌مانند و در اجراهای بعدی نیازی به تکرار این مرحله نیست.
  7. در انتهای اجرا، یک لینک عمومی (Cloudflare Tunnel) دریافت می‌کنید.
  8. صفحه چت (ai.movie.salehaskari.ir) را در مرورگر باز کرده، لینک عمومی را در بخش «اتصال به سرور» وارد کنید و گفت‌وگو را شروع کنید. صفحه چت

توجه: تا زمانی که از دستیار استفاده می‌کنید، سلول آخر نوت‌بوک (سرور و تونل) نباید متوقف شود و تب Colab باید باز و فعال بماند.

جمع‌بندی

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

قدردانی

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

saleh askari
saleh askari

خیلی ممنونم بابت مطالعه این وبلاگ

EN