اگر امروز از مدلهای بینایی-زبانی (VLM) برای تحلیل سریع تصاویر استفاده میکنید، گلوگاه اصلی شما دیگر سختافزار نیست، بلکه مدیریت جریان دادههاست. موتور Photon اکنون میتواند عملکرد این مدلها را به نزدیکی زمانواقعی برساند و در پردازشگر NVIDIA B200 تأخیری تنها ۳۳ میلیثانیه ثبت کند.
به نقل از گزارش فنی تیم مهندسی Moondream در تاریخ ۴ ژوئن ۲۰۲۶، رمز این موفقیت در «رمزگشایی خط لولهای» (Pipelined Decoding) نهفته است؛ روشی که به واحد پردازش گرافیکی (GPU) اجازه میدهد در حالی که واحد پردازش مرکزی (CPU) هنوز در حال پردازش توکن قبلی است، روی توکن بعدی کار کند. این بهینهسازی با تغییر بنیادین تعامل بین CPU و GPU، توان عملیاتی رمزگشایی را تا ۳۵٪ بالا برده است. تلاشها برای کاهش تأخیر در استنتاج تنها محدود به زمان اجرا نیست، بلکه بهینهسازی زمان Cold Start مدلها با سامانههایی نظیر Dynamo Snapshot نیز گامی حیاتی در جهت دسترسپذیری سریعتر مدلهای زبانی است.
برای درک اهمیت این موضوع، تصور کنید در یک مسابقه دو امدادی هستید که در آن دونده (GPU) — شبیه ورزشکاری با سرعت فوقالعاده اما نیازمند دستور — باید بعد از هر قدم کاملاً متوقف شود تا مربی (CPU) تختهشمار خود را چک کند. در تولید متن استاندارد هوش مصنوعی، این فرآیند باعث ایجاد «حباب GPU» میشود. GPU محاسبات سنگین یک توکن (Token) — تکههای کوچکی از متن (تقریباً چند نویسه) که به توکنهای پیش از خود وابسته هستند — را انجام میدهد و سپس بیکار میماند تا CPU کارهای اداری مانند انتخاب درخواستها، مدیریت متادیتا و ثبت توکن خروجی را به پایان برساند تا GPU بتواند دوباره شروع به کار کند.
همانطور که در تحلیلهای پیشین ما دربارهی بهینهسازی حافظه در مدلهای بازمتن اشاره کردیم، مدیریت بهینه ارتباط میان حافظهها کلید افزایش سرعت است. طبق گزارش مهندسی Moondream، این شکاف به دلیل ماهیت خودبازگشتی (Autoregressive) تولید توکن است؛ یعنی شما نمیتوانید توکن سوم را محاسبه کنید تا زمانی که توکن دوم نهایی شده باشد. در گذشته، این روند نیازمند یک رفتوبرگشت سختگیرانه بود: CPU برنامهریزی و یک گذر پیشرو (Forward Pass) را اجرا میکرد، GPU آن را اجرا مینمود و سپس CPU همگامسازی میکرد، منتظر نتایج میماند و آنها را ثبت مینمود.
مشکل: حباب GPU
GPU میلیاردها عملیات ریاضی مورد نیاز برای استنتاج (Inference) — لحظهای که مدل واقعاً جواب تولید میکند، مثل خودِ آشپزی و نه دورهی آموزش آشپز — را مدیریت میکند، اما سازماندهی بر عهده CPU است. این سازماندهی یک هزینه ثابت است که در هر بار رفتوبرگشت پرداخت میشود. وقتی حجم کار GPU برای تولید یک توکن کوچک باشد، کارهای اداری CPU به یک گلوگاه قابل توجه تبدیل میشود. اگر GPU مجبور باشد منتظر CPU بماند تا یک ثبت (Commit) را نهایی کرده و حرکت بعدی را برنامهریزی کند، در بخشی از هر چرخه بیکار میماند. این همان «حباب» است.
Photon این چرخه را با همپوشانی (Overlap) این دو نوع کار میشکند و بهطور مؤثر کارهای اداری CPU را زیر سایه محاسبات GPU پنهان میکند. نکته کلیدی این است که توکن نمونهبرداری شده توسط GPU نیازی ندارد برای شروع گام بعدی حتماً از GPU خارج شود؛ گذر پیشرو بعدی میتواند مستقیماً آن را از حافظه GPU بخواند. در این حین، یک کپی همچنان برای عملیات رمزگشایی (Detokenization) و استریم کردن به CPU فرستاده میشود، اما این مدیریت اداری در پسزمینه رخ میدهد.
سازوکار اول: سیستم اسلاتهای پینگ-پونگ
برای جلوگیری از بازنویسی دادههای مشترک توسط CPU و GPU، Photon از تکنیکی به نام اسلاتهای پینگ-پونگ استفاده میکند. برای اجرای یک گام رمزگشایی، GPU به مجموعهای از بافرهای کاری خاص نیاز دارد: جایی برای استقرار ورودی (آخرین توکن تولید شده و موقعیت آن در توالی)، جایی برای نوشتن لاجیتها (Logits - یک امتیاز برای هر کلمه در واژگان)، جایی برای قرارگیری توکن نمونهبرداری شده، و مدیریت اداری برای اینکه کرنل توجه (Attention Kernel) بتواند کلیدها و مقادیر حافظه کش شده توالی (KV cache) را بیابد.
Photon از «DecodeSlots» استفاده میکند که از بافرهای میزبان پینشده (Page-locked) بهره میبرند. این ساختار اجازه میدهد کپیها به صورت انتقالهای پسزمینه DMA (دسترسی مستقیم به حافظه) اجرا شوند و از مسدود کردن CPU جلوگیری شود.
- جلوگیری از تخصیص زمان-اجرا: Photon برای جلوگیری از همگامسازی دستگاه و ایجاد حبابی جدید، از تخصیص حافظه GPU در زمان اجرا (Runtime Allocation) پرهیز میکند.
- گرافهای CUDA: آدرسهای ثابت بافر اجازه میدهند موتور گام رمزگشایی را به صورت یک گراف CUDA ثبت و سپس بازپخش (Replay) کند، که این امر سربار اجرای کرنل (Kernel Launch Overhead) را کاهش میدهد.
- تناوب اسلاتها: چون بافرها تا زمان تکمیل یک گام در استفاده باقی میماند، اسلات A ممکن است خروجی و کارهای اداری گام فعلی را مدیریت کند، در حالی که اسلات B ورودی گام بعدی را آماده میکند.
این اسلاتها برای موازیسازی GPU نیستند، زیرا تمام گذرهای پیشرو در یک جریان محاسباتی واحد صفبندی شده و به صورت متوالی اجرا میشوند. در عوض، آنها تضمین میکنند CPU بتواند نتایج یک اسلات را پردازش کند در حالی که GPU روی اسلات دیگر کار میکند.
برای بهینهسازی بیشتر، کپیهای دستگاه-به-میزبان (Device-to-Host) که توکنهای نمونهبرداری شده را برای ثبت اداری بازمیگردانند، در یک جریان کپی (Copy Stream) مجزا قرار میگیرند. این امر اجازه میدهد کپیها همزمان با مشغول بودن GPU در گذر پیشرو بعدی اجرا شوند. Photon این کپی را به یک رویداد (Event) متصل میکند که دقیقاً در لحظه نوشتن خروجیهای گام ثبت شده است؛ این کار تضمین میکند که کپی فقط منتظر کار همان گام خاص بماند و نه منتظر کارهای صفبندی شده پشت آن.
برای جلوگیری از باگهای مربوط به فساد دادهها، یک اسلات تنها زمانی آزاد میشود که کپی بافر میزبان پینشدهاش بهطور کامل توسط CPU خوانده شده باشد، نه فقط زمانی که GPU کارش را تمام کرده است. تحویل زودهنگام اسلات به یک گام جدید باعث بازنویسی کپی در میانه انتقال میشد.
سازوکار دوم: ابتدا پیشراند، سپس نمونهبرداری
در رمزگشایی محدود (Constrained Decoding) — جایی که مدل باید فرمت خاصی مثل مختصات برای درخواست «نقطه»، باکسها برای «تشخیص» یا طرح کلی برای «قطعهبندی» را خروجی دهد — سرعت استنتاج معمولاً کاهش مییابد. دلیل این است که توکنهای مجاز (The Mask) برای گام t+1 به توکنی که در گام t نمونهبرداری شده بستگی دارد. برای دستیابی به این هدف، سیستم مجبور است امتیازات (Logits) توکنهای غیرمجاز را قبل از نمونهبرداری به منفی بینهایت تغییر دهد.
اگر مدل در حال طی کردن یک چرخه x, y, size باشد، ماسک برای t+1 به آنچه در t تولید شده وابسته است. Photon این مشکل را با ترتیب «ثبت قبل از نهاییسازی» حل میکند و فرآیند را به سه فاز تقسیم مینماید:
- راهاندازی (Launch): موتور فوراً گذر پیشرو برای توکن t+1 را اجرا میکند. از آنجایی که گذر پیشرو به ماسک وابسته نیست، میتواند جلوتر حرکت کند.
- ثبت (Commit): منتظر میماند تا کپی در حال انتقال توکن t برسد و وضعیت رمزگشایی درخواست را پیش ببرد. این گام حیاتی برای تصمیمگیری درباره ماسک صحیح برای t+1 است.
- نهاییسازی (Finalize): با بهروز شدن وضعیت، موتور ماسک را میسازد و نتیجه را برای t+1 نمونهبرداری میکند.
از آنجا که گذر پیشرو — زمانبرترین بخش — در پسزمینه و طی فازهای ثبت و نهاییسازی اجرا میشود، تأخیر تولید ماسک از مسیر بحرانی (Critical Path) حذف میشود. برای متنهای ساده که نیازی به ماسک ندارند، هر دو مرحله پیشراند و نمونهبرداری میتوانند یک گام کامل جلوتر اجرا شوند. یک چرخه واحد هر دو سناریو را بدون نیاز به موارد خاص مدیریت میکند.
سازوکار سوم: مدیریت «زامبیها»
وقتی یک گام جلوتر اجرا میکنیم، با یک مشکل منطقی در همروندی (Concurrency) مواجه میشویم: اگر یک توالی در گام t به توکن پایان-جمله (EOS) یا سقف طول برسد، اما GPU قبلاً گذر پیشرو برای گام t+1 را اجرا کرده باشد چه رخ میدهد؟
از آنجا که نمیتوان اجرای GPU را لغو کرد (Un-launch)، Photon اجازه میدهد این درخواستها به «زامبی» تبدیل شوند. به جای استفاده از منطق پیچیده لغو برای حذف یک ردیف در میانه مسیر، Photon از دو فیلد برای هر توالی استفاده میکند:
- finalized: به محض اینکه توالی به EOS یا سقف طول برسد، True میشود. نتیجه فوراً ارسال میشود اما توالی هنوز تخریب نمیشود.
- inflight_refs: شمارندهای از گامهای در جریان (۰، ۱ یا ۲) که هنوز به این توالی ارجاع میدهند.
وقتی گام t ثبت میشود و EOS را تشخیص میدهد، توالی علامتگذاری شده به عنوان Finalized. اما چون inflight_refs هنوز غیرصفر است (گام t+1 هنوز به آن ارجاع میدهد)، تخریب نمیشود. در زمان ثبت گام t+1، موتور میبیند که توالی قبلاً نهایی شده و صرفاً از مرحله ثبت عبور میکند (Skip)؛ هیچ توکنی اضافه نمیشود و وضعیتی تغییر نمیکند.
این زامبی اساساً یک گام اضافی را همراه خود میبرد، اسلات خود را اشغال میکند و دادههای KV را مینویسد که هرگز خوانده نخواهند شد. این رقص «نهاییسازی زود، آزادسازی دیر»، جایگزین منطقهای پیچیده لغو شده است. تنها زمانی که inflight_refs به صفر برسد، صفحات KV و اسلات LoRA آزاد میشوند.
یکپارچهسازی پیشپُرکردن و رمزگشایی
Photon هر دو عملیات پیشپُرکردن (Prefill) — پردازش اولیه پرامپت و تصویر که یک گذر پیشرو سنگین روی بسیاری از توکنهاست — و رمزگشایی (Decode) را به عنوان یک خط لوله واحد در نظر میگیرد. پیشپُرکردن صرفاً یک اجرا با kind="prefill" در سیستم دو-اسلاتی است.
به دلیل اینکه خط لوله فقط به یک اسلات آزاد نیاز دارد، موتور میتواند یک پیشراند Prefill را در یک اسلات اجرا کند در حالی که گام رمزگشایی در اسلات دیگر هنوز در حال ثبت (Commit) است. این موضوع بهویژه برای بارهای کاری با درخواستهای کوتاه حیاتی است. درخواستی که فقط سه توکن تولید میکند، تقریباً تمام زمان خود را در مرحله پیشپُرکردن و پذیرش میگذراند؛ به اشتراک گذاشتن یک خط لوله اجازه میدهد این جریان با کارهای اداری CPU همپوشانی داشته باشد، به جای اینکه Prefill را بهصورت متوالی پشت Decode قرار دهد.
همین ترتیب ثبت و حسابداری inflight_refs صحت عملیات را در هر دو نوع حفظ میکند. این کار نیاز به منطقهای خاص برای حالتی که یک Prefill در جریان است و یک Decode در حال ثبت است را از بین میبرد.
ریاضیات عملکرد و «مالیات زامبی»
یک گام رمزگشایی شامل سه بخش است:
۱. پیشراند (Forward): ضربهای ماتریسی سنگین GPU. این بخش محدود به پهنای باند حافظه (Memory-bandwidth bound) است، زیرا هر توکن کل مجموعه وزنها را از طریق هستهها استریم میکند. کف زمانی آن تقریباً weight_bytes / memory_bandwidth است.
۲. نمونهبرداری (Sampling): تبدیل امتیازات به یک توکن ثبت شده، شامل ماسک رمزگشایی محدود، argmax/sample، رمزگشایی مکانیابی فضایی (Spatial Grounding) و کپی دستگاه-به-میزبان.
۳. کارهای اداری (Bookkeeping): کارهای CPU شامل برنامهریزی Batch بعدی، اجرای گراف و ثبت گام قبلی.
یک چرخه مسدودکننده (Blocking) اینها را بهصورت متوالی اجرا میکند و حباب را میسازد. خط لولهگذاری، کارهای اداری یک گام را زیر پیشراند و نمونهبرداری گام بعدی میلغزاند.
Moondream مدل هزینهای برای پیشبینی سرعتبخشی ایجاد کرد: speedup = T_block / T_pipe × (1 − z) که در آن T_block زمان مسدودکننده، T_pipe زمان خط لولهای و z همان «مالیات زامبی» (هزینه پیشراندهای تلف شده برای توالیهای تمامشده) است.
دوره ثبت شده GPU (میانه حالت پایدار، moondream2، میلیثانیه):
| سختافزار | جریانها | پیشراند | نمونهبرداری | دوره |
|---|---|---|---|---|
| 3090 | ۱ | ۴.۸ | ۰.۲۰ | ۵.۱۰ |
| 3090 | ۸ | ۶.۶ | ۰.۲۷ | ۶.۹۷ |
| 3090 | ۳۲ | ۱۰.۲ | ۰.۲۶ | ۱۰.۵۲ |
| B200 | ۱ | ۲.۴۵ | ۰.۱۴ | ۲.۶۳ |
| B200 | ۸ | ۳.۱۲ | ۰.۱۴ | ۳.۳۰ |
| B200 | ۳۲ | ۳.۸۰ | ۰.۱۴ | ۳.۹۸ |
در این تستها، مجموع پیشراند و نمونهبرداری تقریباً با کل دوره برابر است، به این معنی که بیکاری باقیمانده GPU کمتر از ۰.۰۵ میلیثانیه است.
سرعتبخشی مشاهده شده در برابر پیشبینی شده:
| تنظیمات | مسدودکننده | خط لولهای | طول توالی (L) | پیشبینی | مشاهده شده |
|---|---|---|---|---|---|
| 3090 (۱ جریان) | ۵.۴۴ میلیثانیه | ۵.۱۰ میلیثانیه | ۱۰۴ | +۵.۷٪ | +۶.۵٪ |
| 3090 (۸ جریان) | ۷.۵۲ میلیثانیه | ۶.۹۷ میلیثانیه | ۱۱۳ | +۷.۶٪ | +۷.۸٪ |
| 3090 (۳۲ جریان) | ۱۱.۷۴ میلیثانیه | ۱۰.۵۲ میلیثانیه | ۱۱۳ | +۱۱.۱٪ | +۱۱.۶٪ |
| B200 (۱ جریان) | ۳.۱۱ میلیثانیه | ۲.۶۳ میلیثانیه | ۱۱۵ | +۱۷.۲٪ | +۱۷.۶٪ |
| B200 (۸ جریان) | ۴.۰۴ میلیثانیه | ۳.۳۰ میلیثانیه | ۱۱۵ | +۲۲.۲٪ | +۲۱.۹٪ |
| B200 (۳۲ جریان) | ۵.۵۵ میلیثانیه | ۳.۹۸ میلیثانیه | ۱۰۴ | +۳۹.۱٪ | +۳۵.۴٪ |
سه نتیجه کلیدی از این دادهها استخراج میشود:
۱. رشد مزیت با سرعت GPU: خط لولهگذاری در 3090 باعث بهبود ۱۲ درصدی شد، اما در B200 با ۳۲ جریان، این رقم به ۳۵٪ رسید. هرچه پیشراند به دلیل حافظه سریعتر یا مدلهای کوچکتر کوتاهتر شود، حباب CPU سهم نسبتاً بزرگتری از هر گام را میگیرد. خط لولهگذاری به عنوان بیمهای در برابر سریعتر شدن GPUها عمل میکند.
۲. مالیات زامبی مستهلک میشود: در یک جریان واحد، زامبی یعنی یک پیشراند کامل تلف شده — حدود ۱٪ ضرر در طول توالی ۱۱۰. اما در دستههای بزرگ (Batch)، زامبی فقط یک ردیف اضافی در یک عملیات محدود به حافظه است و تقریباً رایگان تمام میشود. این مالیات در جریانهای تکه فعال است و در جایی که توان عملیاتی (Throughput) قرار دارد، محو میشود.
۳. حیاتی بودن جریان کپی: Moondream متوجه باگی شد که در آن یک کپی همگام (Synchronous) تصادفی هنگام ساخت ماسک، سرعت خط لولهای را به سرعت مسدودکننده کاهش میداد. انتقال این بخش به جریان کپی، ۱۱٪ سرعت را در 3090 و ۳۴٪ سرعت را در B200 بازگرداند.
این کارایی حاصل یک ترفند تکبعدی نیست. سرعت Photon از اثر تجمیعی تایلبندی تصاویر، نحوه تغییر اندازه تصاویر در ورودی، کرنلهای بهینه شده، ترتیببندی زمانبند (Scheduler) و حذف نقاط همگامسازی در کل پشته سرویسدهی است. برای توسعهدهندگان، این تغییر به معنای آن است که گلوگاه استنتاج VLM از سختافزار GPU دور شده و به لایه منطق سازماندهی (Orchestration) منتقل شده است.
منتظر انتشار Photon 2.0 باشید که Moondream اشاره کرده است تغییرات معماری بنیادیتری را در بهرهوری استنتاج معرفی خواهد کرد.
گام بعدی شما
- اگر از مدلهای VLM در مقیاس صنعتی استفاده میکنید، بررسی کنید آیا سیستم شما از جریانهای کپی مجزا برای عملیات Bookkeeping استفاده میکند یا خیر.
- برای پیادهسازیهای جدید، به جای لغو پیچیده درخواستها در میانه مسیر، استراتژی «نهاییسازی زود، آزادسازی دیر» (Zombie approach) را امتحان کنید.
- منتظر انتشار Photon 2.0 باشید که تغییرات معماری بنیادیتری را در بهرهوری استنتاج معرفی خواهد کرد.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو