تصور کنید به جای گشتن در تپههای زبالهی تبلیغات شرکتی، مستقیماً به وبسایتهای هنرمندان، برنامهنویسان و شاعران دسترسی داشته باشید. این دقیقاً همان چیزی است که الکس مورلی فینچ (Alex Morley Finch) با صرف ۱۰ دلار و یک آخر هفته به دست آورد.
به نقل از گزارش منتشر شده در ۱۳ اوت ۲۰۲۶، فینچ توانست ۵۶۰,۱۸۳ صفحه اصلی را در یک موتور جستوجوی شخصی فهرست کند. او برای عبور از لایههای مزاحم سئو (SEO) و یافتن «کسانی که واقعاً چیزی میسازند» — از هنرمندان و کدنویسان گرفته تا شاعران — از یک خط لوله بهینه شامل مدلهای محلی و یک ایستگاه کاری اجارهای استفاده کرد.
بیشتر موتورهای جستوجوی مدرن توسط مستندات شرکتی و صفحات بهینهشده برای گوگل اشغال شدهاند. برای یک سازنده مستقل، یافتن یک «زین» (zine) یا یک پروژه نرمافزاری تکنفره، اغلب شبیه حفاری در یک لندفیل بازاریابی شرکتی است. این پروژه در زمانی رخ میدهد که مدلهای زبانی کوچک (SLM) به اندازه کافی کارآمد شدهاند تا به جای چتبات ساده، به عنوان کیوریتورهای خودکار عمل کنند.
همانطور که در تحلیلهای قبلی ما دربارهی بهینهسازی استنتاج در مدلهای بازمتن اشاره کردیم، کاهش اندازه مدلها امکان اجرای عملیات سنگین روی سختافزارهای ارزان فراهم کرده است.
انگیزه و محدوده پروژه
این پروژه ساعت ۲ بامداد یک یکشنبه آغاز شد؛ زمانی که فینچ از غرق شدن نتایج جستوجوی پورتفولیوها و پروژههای هنری عجیب در میان مستندات شرکتی به ستوه آمده بود. هدف او فهرست کردن کل وب در تمام ابعادش نبود، بلکه ساخت ابزاری شخصی و تککاربره بود که هیچ نیازی به ساخت حساب کاربری نداشته باشد.
او روی زیباییشناسی خاصی تمرکز کرد: افرادی که در حال ساخت سختافزار، نوشتن شعر، اداره تئاترهای کوچک یا کدنویسی هستند. برای اینکه پروژه قابل مدیریت باقی بماند، او صراحتاً تصمیم گرفت چه چیزهایی را «نسازد». او از پیچیدگیهایی مثل اسکن IP، استفاده از Redis، ذخیره کامل HTML صفحات، زمانبندهای بازخزش (recrawl schedulers) و معماریهای چندکاربره (multi-tenant) پرهیز کرد. هدف، یک خزندهی ساده بود که فقط صفحات اصلی را میدید و از یک مدل محلی برای استخراج نام، چند جمله توصیفی، یک دستهبندی و تگها استفاده میکرد. در این راستا، ابزارهای پیشرفتهتری مانند پلتفرم Apify با هزاران اسکرپر آماده میتوانند فرآیند استخراج داده را برای پروژههای صنعتیتر اتوماتیک کنند.
محاسبات اولیه و محدودیت دادهها
فینچ با یک محاسبه ساده روی کاغذ شروع کرد: حدود ۴۰ میلیون دامنه وجود دارد. اگر برای هر کدام تنها ۱ کیلوبایت متاداده ذخیره شود، مجموعاً ۴۰ گیگابایت فضا لازم است. او به این نتیجه رسید که این حجم برای یک دیتابیس استاندارد Postgres کاملاً قابل انجام و مدیریت است.
نکته کلیدی این بود که متن خودِ صفحات هرگز قرار نبود به عنوان یک مجموعه داده دائمی (corpus) ذخیره شود. در عوض، متنها فقط در یک بافر موقت (scratch buffer) قرار میگرفتند و به محض اینکه مدل خواندن آنها را تمام میکرد، پاک میشدند. این استراتژی مانع از متورم شدن دیتابیس به اندازهای شد که غیرقابل مدیریت شود.
معماری یک ایندکس آخر هفته
فینچ سیستم را در چهار فرآیند مجزا ساخت تا اطمینان حاصل کند که منابع محاسباتی گرانقیمت در زمان انتظار برای پاسخهای کند شبکه، بیکار نمیمانند:
- واکشیکننده (Fetcher): یک دامنه در انتظار را میگیرد، ابتدا HTTPS و سپس HTTP را امتحان میکند و عنوان، متن بدنه و لینکهای خروجی را با یک پارسر ساده HTML استخراج میکند. برای حفظ سرعت بالا و کاهش هزینه، این بخش صراحتاً از اجرای جاوااسکریپت پرهیز میکند. پس از اتمام کار، وضعیت ردیف دیتابیس را به «آماده» تغییر میدهد.
- کارگر (Worker): این فرآیند متن خام را به یک مدل Gemma (با ۴ میلیارد پارامتر) میفرستد. مدل یک نام، خلاصه دو جملهای، یک دستهبندی و تگها را تولید میکند. اگر صفحه خالی باشد، پارک شده باشد یا توسط دیوارهای تشخیص بات مسدود شده باشد، مدل کاملاً نادیده گرفته میشود. پس از پردازش، متن موقت پاک شده و لینکهای خروجی بر اساس اولویت در صف قرار میگیرند.
- ناظر (Steward): یک فرآیند کنترل کیفیت خودکار است که به صف اصلی دست نمیزند. این بخش دامنههایی را از میزبانهایی که تعداد مشکوکی صفحه تولید میکنند نمونهبرداری کرده و از مدل میپرسد که آیا این دامنه باید «مسدود شود، حفظ شود یا نامشخص است». این فرآیند یک لیست سیاه (blocklist) را نگه میدارد تا از بلعیده شدن ایندکس توسط «مارپیچهای» بیپایان وب جلوگیری کند.
- رابط کاربری/API: یک رابط سبک برای تطبیق تقریبی (fuzzy matching) و فیلتر کردن دستهها. این بخش شامل صفحهای برای فعال/غیرفعال کردن دستههای پنهان و یک داشبورد برای نظارت لحظهای بر «کارخانه» است تا کاربر مجبور نباشد به لاگهای متنی خیره شود.

برای جلوگیری از متورم شدن دیتابیس، فینچ استراتژی «بافر موقت» را پیاده کرد. متن خام صفحه تنها زمانی که وضعیت دامنه «در حال پردازش» است، مستقیماً در ردیف دیتابیس ذخیره میشود. به محض اتمام کار مدل، آن متن پاک میشود. این موضوع حیاتی است زیرا ۴۰ میلیون ردیف ضرب در چند کیلوبایت، سریعاً حجم عظیمی میشد. این استراتژی باعث شد ایندکس نهایی با وجود فهرست کردن بیش از نیم میلیون سایت، زیر یک گیگابایت روی دیسک باقی بماند.
حل مشکل «وب شرکتی»
در ابتدای خزش، فینچ متوجه شد بیش از ۹۰٪ سایتهای فهرست شده، مستندات شرکتی هستند. لیست بذر (seed list) او دارای سوگیری بود و خزنده در ابتدا هیچ نظری درباره اینکه بعداً به دنبال چه چیزی باشد نداشت. او به جای مسدود کردن سخت این سایتها — که ممکن بود حاوی لینکهایی به وبلاگهای شخصی باشند — یک صف وزنی با استفاده از فایلی به نام category-priority.txt به عنوان فرمان هدایت ایجاد کرد.
وزندهی به صف و فیلترینگ
- اولویت بالا: صفحاتی که به عنوان «پورتفولیو»، «زین» یا «نرمافزار» طبقهبندی میشدند، لینکهای خروجیشان را به ابتدای لیست اولویتها میبردند.
- اولویت پایین: صفحاتی که «شرکتی» یا «مستندات» تشخیص داده میشدند، لینکهایشان به انتهای صف رانده میشدند.
- نتیجه: این روش به خزنده اجازه داد تا از صفحات شرکتی به عنوان پلی برای یافتن سایتهای مستقل استفاده کند، بدون اینکه ایندکس را با زبالههای تبلیغاتی پر کند.

او همچنین با «توهمات» مدل مواجه شد؛ جایی که مدل برای دامنههای پارکشده، محتوا اختراع میکرد. برای مثال، یک صفحه پارکشده در GoDaddy به عنوان سایت «جامعه فوریا» خلاصه شد، چون کلمه furry در نام دامنه بود، هرچند بدنه صفحه خالی بود. همچنین مواردی یافت که مدل برچسب دستهبندی را در فیلد خلاصه قرار میداد (مثلاً خلاصهای که فقط میگفت «academic-profile»).
راه حل او ایجاد یک سلسلهمراتب سختگیرانه از اعتماد بود: اول متن قابل مشاهده، سپس عنوان و در نهایت نام دامنه. او همچنین قانونی وضع کرد که خلاصههای مشکوک کوتاه را به عنوان شکست در نظر بگیرد و یک بار دیگر با پرامپتی سختگیرانهتر تلاش کند.
نبرد با حجم پلتفرمها
تا شب یکشنبه، وبلاگهای Tumblr و Neocities با چنان حجمی ظاهر شدند که تهدید میکردند کل ایندکس را تصاحب کنند. در حالی که Neocities با زیباییشناسی مورد نظر او سازگار بود، اما حجم آن غیرقابل تحمل بود.
فینچ یک سقف (cap) تعیین کرد: دامنه اصلی همیشه مجاز است، اما به محض اینکه یک دامنه ریشه بیش از ۱۰۰ زیردامنه تولید کند، سیستم از اضافه کردن موارد جدید از آن دامنه دست میکشد. این تک قانون فوراً بیش از ۴۵,۰۰۰ صفحه در صف را حذف کرد. با این حال، Tumblr همچنان بیش از ۹,۰۰۰ صفحه در ایندکس نهایی داشت.
برای پالایش بیشتر نتایج، او خزش را با ۱۰ «درگاه» (doors) بازنشانی کرد، از جمله جوامع tilde، پلتفرمهای وبلاگنویسی مستقل کوچک و وبرینگها. تقریباً تمام ایندکس نهایی به این ۱۰ بذر بازمیگردد. او همچنین مجبور شد دستهبندی «فروم» را تنزل دهد و یک لیست سیاه صریح برای اجتناب از «مزارع فروم» و میکروسایتهای فروشندگان B2B چینی نگه دارد.
اقتصاد اجاره GPU
اجرای این خط لوله روی یک GPU مصرفی تنها اجازه تولید یک خلاصه در ثانیه را میداد. برای مقیاسپذیری، فینچ یک GPU ابری اجاره کرد و متوجه شد که رقابت برای CPU (CPU contention) گلوگاه بزرگتری نسبت به خود GPU است. اولین اجاره او از یک کتابخانه Wrapper استفاده میکرد که یک چارچوب محاسباتی توزیعشده را بالا میآورد و این چارچوب با ماشین میزبان برای زمان CPU میجنگید. او متوجه شد در حالی که استفاده از CPU روی ۹۰٪ است، GPU تنها ۳۰ تا ۵۰٪ درگیر است.
با تغییر به یک سرور استنتاج بازمتن ساده (vLLM) روی یک GPU ایستگاه کاری میانرده با یک برش اختصاصی از CPU، او به نرخ پایدار ۶۰۰ خلاصه در دقیقه رسید. او همچنین مجبور شد همزمانی (concurrency) را به تدریج افزایش دهد تا از جهشهای حافظه در زمان شروعهای سرد (cold starts) جلوگیری کند.

با هزینه اجاره حدود ۳۵ سنت در ساعت، هزینه فهرست کردن ۱۰۰,۰۰۰ سایت تقریباً ۱ دلار است. هزینه کل به صورت خطی با تعداد سایتها افزایش مییابد، به شرطی که GPU همیشه با داده تغذیه شود. این رویکرد اقتصادی در تضاد با بسیاری از مدلهای تجاری است؛ برای درک بهتر تفاوت هزینهها، میتوانیم به تحلیل هزینه میزبانی شخصی در برابر APIهای مدیریتشده نگاه کنیم تا متوجه شویم در چه مقیاسی میزبانی شخصی به صرفه است.
- ۱۰ هزار سایت: حدود ۰.۱۰ دلار (۱۷ دقیقه با ۱ GPU / ۸ دقیقه با ۲ GPU / ۶ دقیقه با ۳ GPU)
- ۱۰۰ هزار سایت: حدود ۱ دلار (۳ ساعت با ۱ GPU / ۱.۵ ساعت با ۲ GPU / ۱ ساعت با ۳ GPU)
- ۱ میلیون سایت: حدود ۱۰ دلار (۱.۲ روز با ۱ GPU / ۱۴ ساعت با ۲ GPU / ۹ ساعت با ۳ GPU)
- ۱۰ میلیون سایت: حدود ۱۰۰ دلار (۱۲ روز با ۱ GPU / ۶ روز با ۲ GPU / ۴ روز با ۳ GPU)

دردهای مقیاسپذیری و هرجومرج دستهبندی
در حالی که محاسبات ارزان بود، سازماندهی دادهها آشفته بود. با اجازه دادن به مدل برای تولید «آزادانه» دستهها و تگها، فینچ در نهایت با ۶۷۱ دسته متمایز و ۱۲۱,۰۰۰ تگ مواجه شد. بیش از نیمی از این تگها فقط یک بار استفاده شده بودند، زیرا مدل در هر بار فراخوانی، کلمات را متفاوت هجی میکرد. این موضوع یک بار پاکسازی دستی ایجاد کرد که فراتر از یک پروژه سرگرمی، مقیاسپذیر نبود.


ترکیب نهایی ایندکس
مشاهده تکامل ایندکس در طول چهار روز، چشماندازی در حال تغییر را نشان داد. در ابتدا، وبلاگها و سایتهای شخصی (عمدتاً Tumblr و Neocities) بیش از نیمی از ایندکس را تشکیل میدادند. در پایان، این سهم به ۱۲٪ کاهش یافت و ترکیب گستردهتری شکل گرفت:
- سازمانهای غیرانتفاعی: نزدیک به ۲۷,۰۰۰ سازمان، از جمله بانکهای غذا، خیریههای حیات وحش و گروههای مدنی.
- سایر دستهها: سایتهای اجتماعی، پروژههای نرمافزاری، مجلات، موزهها و پادکستها.
- باکت «خالی»: تقریباً ۱۵٪ از کل موارد خزش شده به دلیل اینکه صفحات تنها پوستههای خالی جاوااسکریپت یا دیوارهای تشخیص بات بودند، «خالی» علامت شدند. فینچ برای اجتناب از هزینههای بالا، تصمیم گرفت رندرکننده کامل مرورگر را پیاده نکند.
- باقیمانده صف: هنگامی که دستههای اولویتدار تمام شدند، خزنده به صف پشتیبان با اولویت صفر رسید که منجر به موجی از سایتهای بزرگسالان شد.
در نهایت، این پروژه ثابت میکند که برای یک حوزه خاص، یک وب «کیوریت شده» بسیار ارزشمندتر از یک وب «کامل» است. موفقترین بخش این فرآیند، حلقه تکرار بود: نگاه کردن به خروجی واقعی، تغییر چند عدد در یک فایل متنی و تماشای تغییر نتایج.
اگر میخواهید سیستم خودتان را بسازید، کد این پروژه با نام Marlin به صورت متنباز منتشر میشود. اکنون میتوانید خزش خود را به سمت هر جامعه یا علاقه خاصی که میخواهید نقشهبرداری کنید، هدایت کنید.
گام بعدی شما
- اگر به دنبال یافتن منابع مستقل هستید، از ابزارهای مشابه Marlin برای خزش در وبرینگهای تخصصی استفاده کنید.
- برای کاهش هزینه استنتاج در پروژههای خود، به جای مدلهای غولپیکر، روی مدلهای ۴ میلیاردی مثل Gemma تمرکز کنید.
- استراتژی «بافر موقت» را برای مدیریت دادههای حجیم در دیتابیسهای SQL به کار ببرید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو