فاز 19 · درس 57

پیاده‌سازی سرتاسری حلقه‌ی پژوهش خودکار در پایتون

نوع
ساختنی
زمان
حدود 90 دقیقه
زبان‌ها
Python
اتصال زنجیروار چرخ‌دنده‌ها و ماژول‌های مکانیکی روی یک میز کار مهندسی با خروجی یک سند نهایی
فهرست مطالب
  1. اهداف یادگیری
  2. چه چیزهایی در اینجا با هم ترکیب می‌شوند
  3. چرا ایمپورت، نه کپی؟
  4. تضمین‌های قطعیت
  5. ساختار گزارش دمو
  6. مدیریت حالت‌های خطا
  7. انتخاب‌گر بهترین نتیجه
  8. سیم‌کشی حلقه‌ی ناقد
  9. سیم‌کشی نویسنده‌ی مقاله
  10. راهنمای خواندن کد
  11. گام‌های بعدی

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

در این درس یاد می‌گیرید چطور یک حلقه‌ی کامل پژوهش خودکار (auto-research loop) را به‌صورت سرتاسری پیاده کنید. هدف این است که تمام خروجی‌ها قطعی و قابل تست بمانند، هر مرحله در صورت دریافت داده‌ی نامعتبر با خطای صریح متوقف شود و سیستم گزارش نهایی شفافی از عملکرد تمام مراحل ارائه دهد.

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

اهداف یادگیری

  • سیم‌کشی حلقه‌ی پژوهش خودکار (auto-research loop) به‌صورت سرتاسری: فرضیه‌ی اولیه (seed hypothesis)، مجری آزمایش (experiment runner)، اسکژولر، حلقه‌ی ناقد، و نویسنده‌ی مقاله (paper writer).
  • ترکیب اجزای سازنده‌ی چهار درس قبلی مسیر D تنها با ایمپورت‌های ساده‌ی Python، بدون استفاده از هیچ فریم‌ورکی.
  • اجرای حلقه تا رسیدن به پایان خودکار و ارائه‌ی یک گزارش دموی یکپارچه شامل خروجی همه‌ی مراحل.
  • حفظ قطعیت (deterministic بودن) دمو تا مجموعه‌ی تست‌ها بتوانند ساختار خروجی نهایی را اعتبارسنجی (assert) کنند.
  • نمایش شفاف حالت‌های خطا (failure modes) در صورت نقض قرارداد هر مرحله، تا مرحله‌ی بعد با ورودی نامعتبر اجرا نشود.
دموی پژوهشیپنج قرارداد باید ترکیب شوند
RESEARCH DEMOThe demo threads one run through every stage built in the earlier Track D lessons: seed hypotheses, the UCB scheduler, the experiment runner, the critic loop, the paper writer. Each hand-off passes a contract gate that validates the shape before the next stage runs, and the loop self-terminates into a single demo report. If any contract leaks, this is the lesson that catches it.seedاسکژولراجراکنندهناقدنویسندهگیت‌های کنترلی: ورودی نامعتبر اجرا را متوقف می‌کندگزارشایمپورت‌های ساده‌ی پایتون، بدون فریم‌ورک
این دمو یک اجرای واحد را از تمام مراحل ساخته‌شده در درس‌های قبلی بخش D عبور می‌دهد: فرضیه‌های اولیه، اسکژولر UCB، اجراکننده‌ی آزمایش، حلقه‌ی ناقد و نویسنده‌ی مقاله. هر مرحله انتقال داده از یک گیت کنترلی عبور می‌کند که ساختار را پیش از اجرای مرحله‌ی بعدی اعتبارسنجی می‌کند و حلقه با رسیدن به یک گزارش دموی واحد به پایان می‌رسد. اگر در هر قراردادی نشتی رخ دهد، این درس آن را شناسایی می‌کند.

چه چیزهایی در اینجا با هم ترکیب می‌شوند

فرضیه‌های اولیهاسکژولر تکراراجراکننده آزمایشگذرگاه نتایجمحرک مقالهانتخاب‌کننده بهترین نتیجهحلقه ناقدنویسنده مقالهگزارش دمو

شش مرحله داریم. نقطه‌ی آغاز، فهرستی از سه فرضیه است. اسکژولر، شش آزمایش را روی آن‌ها در سه اسلات موازی اجرا می‌کند. باس ارتباطی، یک یا چند تریگر مقاله (paper trigger) را گزارش می‌دهد. بخش انتخاب‌گر (picker)، تک‌نتیجه‌ی بهینه را گلچین می‌کند. حلقه‌ی ناقد روی پیش‌نویسی که بر اساس همان نتیجه ساخته شده بازبینی انجام می‌دهد. در نهایت، نویسنده‌ی مقاله خروجی‌های LaTeX، BibTeX و مانیفست را تولید می‌کند.

چرا ایمپورت، نه کپی؟

هر کدام از درس‌های قبلی یک main.py دارند که شامل دیتاکلاس‌ها و توابع عمومی است. دمو با تنظیم sys.path روی دایرکتوری والد هر درس، آن‌ها را ایمپورت می‌کند. این کار اتصال فریم‌ورکی نیست؛ دقیقاً همان شیوه‌ی ایمپورتی است که فایل‌های تست درس‌های قبل هم استفاده می‌کردند.

57: دموی سرتاسری54: PaperWriter55: CriticLoop56: IterationSchedulerStub درون‌خطی: فرضیه اولیه و اجراکننده

استاب (stub) درون‌کدی، نقش درس‌های 50 تا 53 را ایفا می‌کند: یک مولد کوچک فرضیه‌های اولیه و یک تابع پاداش (reward function) همگام. می‌توانید این استاب را صرفاً با تغییر دو ایمپورت، با اجزای سازنده‌ی واقعی همان درس‌ها جایگزین کنید.

تضمین‌های قطعیت

دمو از پایه و در ذات خود قطعی است. مجری آزمایش با seed مشخص در numpy اجرا می‌شود. بخش بازبین (reviser) در حلقه‌ی ناقد، ابعاد ثابت را با ترتیبی ثابت بررسی می‌کند. تولیدکننده‌ی متن در بخش نگارش مقاله، همان نسخه‌ی شبیه‌سازی‌شده‌ی (mocked) درس 54 است. انتخاب‌گر UCB در اسکژولر نیز هنگام تساوی، انتخاب را بر اساس ترتیب پیمایش انجام می‌دهد، نه تصادفی.

با seed یکسان، دمو گزارش یکسانی ارائه می‌دهد. تست‌های ما هم این ویژگی را با دو بار اجرای دمو و مقایسه‌ی مانیفست بررسی می‌کنند.

ساختار گزارش دمو

DemoReportscheduler_reportbest_branch و best_rewardcritic_resultpaper_manifeststop_reason

هر فیلد عیناً از مرحله‌ی بالادستی خود می‌آید. دمو خروجی‌ها را دستکاری نمی‌کند؛ فقط آن‌ها را کنار هم می‌نشاند. در واقع آزمون اصلی دمو در همین ترکیب نهفته است.

مدیریت حالت‌های خطا

هر مرحله یا با موفقیت به پایان می‌رسد یا یک خطای تایپ‌شده (typed error) صادر می‌کند.

Scheduler ........ returns SchedulerReport with stop_reason
                   in {queue_empty, max_experiments, deadline}
Best-result pick . raises NoTriggerError if no paper trigger fired
Critic loop ...... returns LoopResult with status converged or stopped
Paper writer ..... raises PaperValidationError on contract break

رخ دادن خطا در هر کدام از مراحل، اجرای دمو را بلافاصله با یک خطای مشخص متوقف می‌کند (short-circuit). تست‌ها هم این قرارداد را کاملاً تثبیت کرده‌اند: تست‌های test_no_triggers_raises_typed_error و test_best_picker_raises_when_no_triggers بررسی می‌کنند که اگر در هیچ branchای تریگری فعال نشود، انتخاب‌گر خطای NoTriggerError یا BestResultError صادر کند و بخش نویسنده‌ی مقاله اصلاً فراخوانی نشود.

انتخاب‌گر بهترین نتیجه

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

سیم‌کشی حلقه‌ی ناقد

حلقه‌ی ناقد در درس 55 روی یک MiniPaper کار می‌کند. دمو با قرار دادن شناسه‌ی branch انتخاب‌شده در چکیده، ایجاد دو بخش اولیه (مقدمه و نتایج) و تعیین برچسب اصالت (originality_tag) بر اساس میانگین پاداش branch (مقدار high اگر >= 0.8، مقدار medium اگر >= 0.6، و در غیر این صورت low)، یک MiniPaper می‌سازد.

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

سیم‌کشی نویسنده‌ی مقاله

نویسنده‌ی مقاله در درس 54 روی ساختار کامل Paper همراه با تصاویر و کتاب‌شناسی کار می‌کند. دمو پیش‌نویس همگراشده‌ی MiniPaper را از طریق تابع mini_to_full_paper ارتقا می‌دهد؛ این تابع یک تصویر مربوط به branch انتخاب‌شده و یک کتاب‌شناسی ساختگیِ کوچک برگرفته از اجتماع کلیدهای ارجاعی (cite keys) پیشنهادیِ ناقد را به آن ضمیمه می‌کند. هر ارجاعی که دمو اضافه می‌کند در فهرست کتاب‌شناسی هم می‌آید تا اعتبارسنجی با موفقیت پاس شود.

راهنمای خواندن کد

فایل code/main.py این موارد را تعریف می‌کند: BestResultError، NoTriggerError، DemoReport، pick_best_branch، build_mini_paper، mini_to_full_paper و run_demo. ایمپورت‌های بالای فایل یک بار sys.path را تنظیم کرده و PaperWriter، CriticLoop و IterationScheduler را از درس‌های مربوطه‌شان لود می‌کنند.

فایل code/tests/test_e2e.py این موارد را پوشش می‌دهد: اجرای سرتاسری دمو و تولید گزارش با پر شدن هر پنج فیلد، قطعیت خروجی در دو بار اجرا، صدور NoTriggerError وقتی هیچ branchای از آستانه عبور نمی‌کند، رخ دادن PaperValidationError هنگام نقض قرارداد نویسنده، وجود تصویر branch انتخاب‌شده در مانیفست مقاله، و قرار داشتن دلیل توقف اسکژولر در میان مقادیر مورد انتظار.

گام‌های بعدی

وقتی تست‌های دمو همگی سبز شدند، پیاده‌سازی این سه مورد ارزش ادامه دادن دارد: اول، ماندگارسازی وضعیت (persistent state): ذخیره‌ی نتیجه‌ی هر مرحله در یک فایل JSON کوچک تا در صورت اجرای مجدد، سیستم بدون تکرار مراحل کم‌هزینه از همان‌جا ادامه یابد. دوم، داشبورد: نمایش رویدادهای ردگیری محاسبات (trace events) ثبت‌شده در اسکژولر و حلقه‌ی ناقد در قالب یک خط زمانی واحد. سوم، فراخوانی مدل‌های واقعی: جایگزین کردن تولیدکننده‌ی متنِ شبیه‌سازی‌شده و ناقد قطعی با مدل‌های زبانی واقعی؛ منطق سیم‌کشی سیستم کوچک‌ترین تغییری نخواهد کرد.

رسالت این دمو اثبات این نکته است که خودِ ترکیب، معماری اصلی است. پنج درس، چهار ایمپورت، یک گزارش. دفعات بعد با افزودن هر مرحله‌ی تازه، سیم‌کشی کد دقیقاً یک خط بیشتر می‌شود.

خودآزمایی

به سؤال‌ها جواب بدهید تا ببینید چقدر از درس در ذهنتان مانده است.

  1. پیش از درسوظیفه‌ی دمو در این درس چیست؟
  2. پیش از درسچرا این درس به جای ایمپورت معمولی پکیج، درس‌های قبلی را از طریق importlib بارگذاری می‌کند؟
  3. حین درسهنگامی که بیش از یک branch ماشه‌ی نگارش مقاله را فعال کرده باشد، انتخاب‌کننده‌ی بهترین نتیجه چگونه میان آن‌ها تصمیم می‌گیرد؟
  4. حین درسوقتی اسکژولر صفر ماشه‌ی نگارش مقاله را گزارش می‌دهد، انتخاب‌کننده چه خطایی صادر می‌کند؟
  5. پس از درسچرا دمو در تست قطعیت، دو بار با یک seed یکسان اجرا می‌شود؟
  6. پس از درسگزارش دمو پس از یک اجرای موفق شامل چه مواردی است؟

سؤالات متداول

چگونه قطعیت (determinism) در اجرای سرتاسری دمو تضمین می‌شود؟

با مقداردهی ثابت seed در کتابخانه‌ی numpy، پیمایش ابعاد با ترتیب معین در بازبین، استفاده از متن‌ساز شبیه‌سازی‌شده و شکستن تساوی‌ها بر اساس ترتیب الفبایی.

اگر هیچ شاخه‌ای به آستانه مورد نظر نرسد سیستم چه واکنشی نشان می‌دهد؟

انتخاب‌گر بلافاصله خطای صریح NoTriggerError یا BestResultError صادر می‌کند و مرحله‌ی نگارش مقاله اجرا نمی‌شود.

چرا به جای کپی کردن کدها از ایمپورت مستقیم استفاده شده است؟

برای پایبندی به قراردادهای واقعی کد، پیشگیری از افزونگی و اثبات اینکه ماژول‌های مستقل بدون فریم‌ورک‌های اضافه قابلیت ترکیب دارند.

ما رو توی گوگل بیشتر ببین

با افزودن نکست ادمین به «منابع ترجیحی» گوگل، درس‌ها و مطالب ما را در بخش اخبار برتر جستجو بیشتر می‌بینید.