یک بررسی ساده از هزینههای سرور مدل زبانی شما میتواند یک دروغ باشد. در یک تست عملی، توسعهدهندهای دریافت که هزینههای سرور او بین دو اجرای مشابه، علیرغم عدم تغییر در مدل، پرامپتها یا تنظیمات سختافزاری، ۲۷.۱٪ جهش کرده است. دادهها نشان داد که در اجرای اول هزینه ۸.۷۷ دلار به ازای هر میلیون توکن خروجی بود، در اجرای دوم به ۸.۸۶ دلار (۱٪+) رسید، در اجرای سوم به ۱۱.۲۶ دلار (۲۷.۱٪+) جهش کرد و در اجرای چهارم دوباره به ۱۰.۰۲ دلار (۱۱٪-) کاهش یافت.
این نوسان به این دلیل رخ میدهد که اندازهگیری هزینه در واقع همان اندازهگیری زمان است. وقتی شما دلار به ازای هر میلیون توکن را محاسبه میکنید، در حقیقت میسنجید که سختافزار چند ثانیه زمان میبرد تا آن توکنها را پردازش کند. اگر ماشین کند شود، قیمت بالا میرود، حتی اگر پیکربندی دقیقاً همان باشد. اگر توسعهدهندهای بین اجرای دوم و سوم یک فلگ (Flag) را تغییر داده بود، قطعاً مقصر را آن فلگ میدانست؛ و اگر تغییری بین اجرای سوم و چهارم میداد، یک صرفهجویی ۱۱ درصدی را گزارش میکرد. هر دو نتیجه غلط بودند، اما هر دو شبیه به «دادههای واقعی» به نظر میرسیدند.
همانطور که در تحلیل قبلی ما دربارهی بهینهسازی خط لولههای مدلهای زبانی توسط شرکتهایی مثل Oxlo اشاره کردیم، مشخص است که هوش مصنوعی در مقیاس تولیدی به چیزی فراتر از یک مدل خوب نیاز دارد؛ این حوزه نیازمند رویکردی سختگیرانه در اندازهگیری است. برای اکثر توسعهدهندگان، تست سادهی «قبل و بعد» استاندارد است، اما این روش اغلب نویز پسزمینهی سیستم را با تغییر واقعی در عملکرد اشتباه میگیرد.
کالبدشکافی یک نوسان هزینه
این آزمایش روی یک مکبوک با استفاده از Ollama و مدل llama3.2:3b انجام شد. توسعهدهنده از ابزار خط فرمان Throttle (یک ابزار متنباز CLI) برای اجرای چهار بررسی یکسان استفاده کرد. جزئیات این ساختار به شرح زیر بود:
- ساختار درخواست: ۳ بلوک شامل ۴ درخواست در هر بررسی.
- همزمانی (Concurrency): روی عدد ۲ تنظیم شد.
- محدودیتها: سقف ۶۴ توکن خروجی با دمای (Temperature) صفر.
- پرامپتها: ۸ پرامپت داخلی به همراه یک درخواست گرمکن (Warm-up).
- زمانبندی: هر چهار بررسی در بازهی زمانی حدود ۷۰ ثانیهای نسبت به یکدیگر به پایان رسیدند.
برای محاسبه هزینه، از آنجایی که لپتاپ فاکتور هزینه GPU ندارد، نرخ ساعتی فرضی ۱.۵۰ دلار برای GPU در نظر گرفته شد. فرمول ریاضی ساده بود: هزینه هر میلیون توکن = (نرخ ساعتی × ساعت ساعت-دیواری) تقسیم بر (تعداد توکنها × ۱,۰۰۰۰۰۰).
در هر چهار اجرا، هر بلوک دقیقاً ۲۵۶ توکن خروجی تولید کرد (۴ درخواست × ۶۴ توکن). تنها متغیری که تغییر کرد، زمان واقعی (Wall-clock time) بود. در اجرای اول، بلوکها ۵.۵۳، ۵.۲۴ و ۵.۴۰ ثانیه زمان بردند. اما در اجرای سوم، همین بلوکها ۷.۰۹، ۷.۰۲ و ۶.۶۵ ثانیه طول کشیدند. این افزایش حدود ۳۰ درصدی در زمان، مستقیماً به افزایش ۲۷ درصدی هزینه به ازای هر توکن تبدیل شد.

چرا سرورها «لرزش» دارند؟
بر اساس بررسیهای فنی، چندین عامل نامرئی میتوانند این نوسانات زمانی را در یک ماشین محلی ایجاد کنند:
- وضعیت حرارتی: با گرم شدن لپتاپ، CPU یا GPU برای جلوگیری از گرم شدن بیش از حد، سرعت کلاک را کاهش میدهند (Thermal Throttling).
- زمانبندی سیستمعامل: فرآیندهای پسزمینه مانند ایندکسگذاری یا سایر پردازشهای فعال برای استفاده از چرخه محاسباتی رقابت میکنند.
- فشار حافظه: استفاده زیاد از RAM میتواند سرعت انتقال داده به پردازنده را کاهش دهد.
- وضعیت سختافزاری: نوسانات کلی سرعت کلاک و سربار مدیریت زمانبندی سیستمعامل.
در گرههای ابری مشترک، مشکل بدتر است. «همسایههای پرسرصدا» (Noisy Neighbors) — یعنی مستاجران دیگر روی همان میزبان فیزیکی یا شبکه — میتوانند پهنای باند شبکه یا حافظه را اشغال کنند و باعث جهش هزینههای شما شوند، بدون اینکه تغییری در نمونهی (Instance) خاص شما رخ داده باشد. چون این عوامل اغلب نامرئی هستند، یک جفت تست «قبل و بعد» نمیتواند بار سیستم را از تغییر واقعی پیکربندی تشخیص دهد.
تلهی بازهی اطمینان
بسیاری از توسعهدهندگان برای تأیید نتایج خود به بازههای اطمینان (Confidence Intervals) ۹۵٪ تکیه میکنند. اگر دو بازه با هم همپوشانی نداشته باشند، فرض میکنند تفاوت «واقعی» است. اما تست Throttle ثابت کرد این یک باور غلط است.
در این آزمایش، اجرای اول (۸.۱۹ تا ۹.۳۵ دلار) و اجرای سوم (۱۰.۳۱ تا ۱۲.۲۱ دلار) همپوشانی نداشتند. طبق قاعدهی رایج، اجرای سوم یک پسرفت (Regression) واقعی ۲۷ درصدی بود. اما بازهی اطمینان فقط به یک سؤال محدود پاسخ میدهد: «لرزش» بلوکها در درون یک اجرا (در بازهی حدود ۲۰ ثانیه) چقدر است؟ این معیار نمیتواند «رانش» (Drift) بین دو اجرای مجزا را تشخیص دهد، چون تمام بلوکهای یک اجرا شرایط یکسانی دارند. اگر کل ماشین برای یک دقیقه ۳۰٪ کند شود، تمام بلوکها با هم کند میشوند و بازهی اطمینان همچنان دور یک عدد غلط، تنگ و دقیق باقی میماند.
کالیبره کردن کفِ نویز
برای حل این مشکل، نویسنده پیشنهاد میکند «نویز بین-اجرایی» (Run-to-run noise) مستقیماً اندازهگیری شود. بهجای مقایسهی دو اجرا، باید یک پیکربندی بدون تغییر را حداقل سه بار اجرا کنید تا خط مبنای واریانس (Variance) — یعنی میزان پراکندگی دادهها — تعیین شود.
ریاضیات نویز
برای محاسبه دقیق، مراحل زیر طی میشود:
- انحراف معیار نسبی (Relative SD): محاسبه انحراف معیار نسبی بین بررسیهای تکراری یک پیکربندی واحد.
- نویز ترکیبی: تفاوت بین دو بررسی تکمرحلهای دارای انحراف معیاری برابر با √2 × SD است.
- توزیع t-Student: در تکرارهای کم، بهجای عدد ۱.۹۶ از توزیع t برای در نظر گرفتن درجات آزادی (df) استفاده میشود.
- فرمول حد نویز: حد نویز = t(0.975, df) × √2 × SD.
در تست مکبوک، اجراهای ۱ تا ۳ (۸.۷۷، ۸.۸۶ و ۱۱.۲۶ دلار) انحراف معیار نسبی ۱۴.۶٪ با ۲ درجه آزادی داشتند (t = 4.303). محاسبه نهایی (4.303 × 1.414 × 14.6%) منجر به «حد نویز» ۸۹.۱٪ شد. این یعنی هر تغییر هزینهای کمتر از ۸۹.۱٪، از نظر آماری با نویز تصادفی سیستم غیرقابل تشخیص است. بنابراین، کاهش ۱۱ درصدی در اجرای چهارم کاملاً درون این حد بود و نتیجه نهایی «بدون برنده» (NO WINNER) اعلام شد.
پروتکل جدید برای بهینهسازی
برای جلوگیری از گزارش «بردها» یا «باختهای» جعلی در محیطهای کاری (مانند Slack)، نویسنده یک قانون سختگیرانه سه مرحلهای را پیشنهاد میکند:
۱. تعیین خط مبنا: پیکربندی بدون تغییر را حداقل سه بار در بازهی ۲۴ ساعت اجرا کنید تا کف نویز اندازهگیری شود.
۲. جداسازی متغیر: دقیقاً یک مورد را تغییر دهید (مثلاً یک فلگ در vLLM).
۳. اعتبارسنجی: نتیجه را تنها زمانی باور کنید که مقدار تغییر بزرگتر از «حد نویز بین-اجرایی» باشد و همزمان بازههای اطمینان ۹۵٪ همپوشانی نداشته باشند.
برای تصمیمات حساس در محیط تولید (Production)، نویسنده توصیه میکند اجراها را به صورت متناوب انجام دهید (مبنا، کاندید، مبنا، کاندید، مبنا، کاندید). این کار باعث میشود هرگونه رانش سیستم بر هر دو پیکربندی اثر یکسانی بگذارد و از این احتمال که کند شدن سیستم در نیمهی دوم تست به اشتباه به عنوان پسرفت در پیکربندی کاندید تفسیر شود، جلوگیری کند.
پیادهسازی و ملاحظات
این متدولوژی با استفاده از نسخه 0.4.0 ابزار Throttle تست شد. از آنجایی که پرامپتهای یکسانی تکرار شدند، کش پرامپت (Prompt Cache) در تمام اجراها «گرم» بود و این موضوع باعث شد کش به عنوان علت نوسانات حذف شود. نسخههای جدیدتر (0.4.1+) درخواستها را تگ میکنند تا از این موضوع که کشهای پیشوند (Prefix Caches) باعث ارزانتر به نظر رسیدن بررسیهای بعدی شوند، جلوگیری کنند؛ همچنین فلگ --warm-cache برای اندازهگیریهای عمدی اضافه شده است.
باید توجه داشت که حد ۸۹ درصدی در این مثال، مختص به یک لپتاپ و مدل 3B است. سرورهای شما پروفایلهای نویز منحصر به فرد خود را خواهند داشت. برای تنگتر کردن این بازهها و افزایش دقت میتوانید:
- تکرارها را افزایش دهید: مقدار t با افزایش درجات آزادی به سرعت کاهش مییابد (۴.۳۰ در ۲ درجه آزادی، ۲.۵۷ در ۵ درجه آزادی و ۲.۲۳ در ۱۰ درجه آزادی).
- نویز محیطی را کاهش دهید: برنامههای پسزمینه را ببندید، از بلوکهای طولانیتر استفاده کنید و همزمانی (Concurrency) را با محیط تولید مطابقت دهید.
اگر در حال حاضر در حال بهینهسازی استک استنتاج (Inference Stack) خود هستید، اعتماد به بنچمارکهای تک-اجرایی را متوقف کنید. با اجرای سه بارهی تنظیمات فعلی خود شروع کنید تا ببینید سرور «پایدار» شما در واقع چقدر نوسان دارد.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو