تشخیص چهره در دروازه ورود اکثر خط لوله‌های (pipelines) بینایی ماشین قرار دارد. هر تماس تصویری، گالری عکس و فید امنیتی، پیش از هر اتفاق دیگری، به شناسایی چهره‌های انسانی وابسته است. با این حال، انتخاب مدل معمولاً منجر به یک سبک‌سنگین کردن (trade-off) ناخوشایند می‌شود. شبکه‌های سنگین دقت بالایی دارند اما به GPUهای گران‌قیمت و سیستم‌های خنک‌کننده رکمونت (rack-mounted) نیاز دارند. مدل‌های کوچک‌تر روی سخت‌افزارهای معمولی اجرا می‌شوند، اما اغلب در مواجهه با چهره‌های کوچک یا فیدهای با رزولوشن بالا دچار مشکل می‌شوند. مدل YuNet از OpenCV Zoo این الگو را می‌شکند. من زمان خود را صرف بنچمارک گرفتن از آن در مقیاس‌های مختلف کردم تا ببینم آیا جایگاهی در پروژه‌های واقعی دارد یا صرفاً روی کاغذ خوب به نظر می‌رسد.

چرا YuNet ارزش بررسی دقیق‌تر را دارد

YuNet صرفاً یک کنجکاوی پژوهشی نیست. این مدل در OpenCV Zoo قرار دارد، مجموعه‌ای از مدل‌های پیش‌آموزش‌دیده که برای ماژول OpenCV DNN بهینه‌سازی شده‌اند. نسخه خاصی که من تست کردم از کوانتیزاسیون (quantization) INT8 استفاده می‌کند، به این معنی که وزن‌ها و فعال‌سازهای (activations) آن به جای اعداد ممیز شناور ۳۲ بیتی معمول، به اعداد صحیح ۸ بیتی فشرده می‌شوند. این یک نکته فنی جزئی نیست. INT8 پهنای باند حافظه را کاهش می‌دهد، فشار روی کش (cache) را کم می‌کند و به CPUهای مدرن اجازه می‌دهد بدون فشار زیاد، فرآیند استنتاج (inference) را انجام دهند. برای هر کسی که روی لپ‌تاپ، یک دستگاه لبه (edge device) یا سروری بدون کارت گرافیک اختصاصی کار می‌کند، این کارایی تفاوت بین یک خط لوله روان و یک نمایش اسلاید (slideshow) است.

معماری آن ذاتاً سبک طراحی شده است. این مدل از بار اضافیِ ستون‌های فقرات (backbones) عظیم عبور کرده و بر وظیفه واحدِ مکان‌یابی چهره‌ها تمرکز می‌کند. این انضباط زمانی نتیجه می‌دهد که بخواهید تشخیص را در یک اپلیکیشن بزرگتر ادغام کنید، جایی که بودجه CPU و باتری با وظایفی مثل ردیابی (tracking)، تشخیص (recognition) یا کدگذاری ویدئو به اشتراک گذاشته می‌شود.

تنظیمات (The Setup)

تمام تست‌ها روی یک Mac Studio با تراشه Apple M4 Max انجام شد. فایل مدل، نسخه ONNX کوانتیزه شده‌ی YuNet INT8 از مخزن OpenCV Zoo بود. ابتدا سرعت استنتاج را روی یک تصویر ۱۲۸۰x۷۲۰ اندازه‌گیری کردم، سپس تعداد تشخیص‌ها را در چهار رزولوشن مختلف مقایسه کردم تا بفهمم مقیاس چگونه بر نتایج تأثیر می‌گذارد.

اگر می‌خواهید این اعداد را روی دستگاه خودتان تأیید کنید، فرآیند کاملاً قابل بازتولید است. دستورات زیر را برای دریافت مخزن sparse و اجرای بنچمارک اجرا کنید:

git clone --depth 1 --filter=blob:none --sparse https://github.com/kiarina/labs.git
cd labs
git sparse-checkout set .gitignore .mise/tasks Makefile mise.toml 2026/07/08/yunet-face-detection
mise -C 2026/07/08/yunet-face-detection run

عملیات sparse checkout حجم دانلود را کم نگه می‌دارد و ابزار مدیریت وظیفه mise وابستگی‌ها را در پشت صحنه مدیریت می‌کند. نیازی نیست با محیط‌های پایتون یا نصب دستی پکیج‌ها دست‌وپنجه نرم کنید.

سرعتی که ثابت می‌ماند

روی یک تصویر ۱۲۸۰x۷۲۰، مدل INT8 YuNet به طور متوسط ۹.۲۱ میلی‌ثانیه برای هر استنتاج زمان نیاز داشت. سریع‌ترین مرحله ۸.۰۳ میلی‌ثانیه و کندترین مرحله ۱۰.۴۷ میلی‌ثانیه ثبت شد. این یک بازه بسیار محدود و دقیق است. کمتر از دو و نیم میلی‌ثانیه بین بهترین و بدترین زمان فاصله وجود دارد.

در عمل، این ثبات بیشتر از خودنمایی اهمیت دارد. اپلیکیشن‌های بلادرنگ (real-time) فقط به تأخیر (latency) میانگین پایین نیاز ندارند؛ آن‌ها به تأخیر قابل پیش‌بینی نیاز دارند. مدلی که گاهی ۵۰ میلی‌ثانیه طول می‌کشد، باعث پرش (stutter) قابل مشاهده در فید وب‌کم می‌شود. YuNet ثابت می‌ماند. می‌توانید روی آن حساب کنید تا قبل از رسیدن فریم بعدی، فریم فعلی را تمام کند، که این امر زمان‌بندی بقیه خط لوله شما را بسیار ساده‌تر می‌کند.

تغییر مقیاس، داستان واقعی را فاش می‌کند

سرعت خام معنای چندانی ندارد اگر مدل نیمی از چهره‌های موجود در صحنه را از دست بدهد. برای تست این موضوع، همان تصاویر منبع را در چهار رزولوشن مختلف از طریق YuNet عبور دادم. آمارها داستان واضحی را روایت می‌کنند:

  • ۳۲۰ x ۱۸۰: ۶ چهره تشخیص داده شد
  • ۶۴۰ x ۳۶۰: ۲۶ چهره تشخیص داده شد
  • ۱۲۸۰ x ۷۲۰: ۳۸ چهره تشخیص داده شد
  • ۲۵۶۰ x ۱۴۴۰: ۵۲ چهره تشخیص داده شد

این جهش چشمگیر است. در رزولوشن ۳۲۰x۱۸۰، فقط بزرگ‌ترین و نزدیک‌ترین چهره‌ها ثبت می‌شوند. با بالا بردن آن به ۶۴۰x۳۶۰، تعداد تشخیص‌ها چهار برابر می‌شود. در رزولوشن کامل 1440p، YuNet بیش از هشت برابرِ رزولوشن پایین‌ترین، چهره پیدا می‌کند.

این اتفاق به این دلیل می‌افتد که کاهش نمونه‌برداری (downsampling) جزئیات را سریع‌تر از آنچه تصور می‌شود از بین می‌برد. چهره‌ای که در یک فریم 1440p بخش کوچکی را می‌پوشاند، می‌تواند در رزولوشن 360p به لکه‌ای ۵ در ۵ پیکسلی تبدیل شود. زمانی که ویژگی‌های صورت به زیر میدان پذیرش (receptive field) مدل سقوط کنند، به نویز نامرئی تبدیل می‌شوند. چشم‌ها با ابروها ادغام می‌شوند. بینی‌ها ناپدید می‌شوند. YuNet چیزی برای چسبیدن به آن ندارد.

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

استراتژی تغییر اندازه که واقعاً به آن نیاز دارید

YuNet آن‌قدر سریع است که نیازی نیست از روی عادت، ورودی خود را به ۳۲۰ در ۲۴۰ محدود کنید. در M4 Max، حتی رزولوشن ۲۵۶۰ در ۱۴۴۰ نیز بدون نیاز به یک GPU مجزا اجرا می‌شود. این موضوع نحوه معماری خط لوله (pipeline) شما را تغییر می‌دهد.

به‌جای اینکه هر فریم را مجبور کنید از یک اندازه ثابت و کوچک عبور کند، رزولوشن ورودی را بر اساس آنچه به دنبال یافتن آن هستید، انتخاب کنید. اگر فقط به فردی که مستقیماً مقابل دوربین است اهمیت می‌دهید، رزولوشن 720p یا حتی 640p کافی است. اگر نیاز دارید تمام شرکت‌کنندگان در یک سالن بزرگ را فهرست کنید، یک برش (crop) با رزولوشن بالاتر یا کل فریم اصلی را به مدل بدهید. از آنجایی که YuNet سبک است، فضای کافی برای انجام این انتخاب را دارید. شما برای جلوگیری از تأخیر ۲۰۰ میلی‌ثانیه‌ای، محدود به یک تنظیم پیش‌فرض واحد نیستید.

با این حال، یک نکته قابل توجه باقی می‌ماند. مدل همچنان به اندازه صورت نسبت به تنسور (tensor) ورودی وابسته است. در اینجا خبری از تغییرناپذیری مقیاس (scale invariance) جادویی نیست. صورت‌های کوچک تا زمانی که پیکسل‌های کافی اشغال نکنند، نامرئی باقی می‌مانند. راه حل مکانیکی است: هنگام جستجوی سوژه‌های دوردست، تصویر منبع را قبل از استنتاج (inference) بزرگ‌نمایی کنید، سپس جعبه‌های محصورکننده (bounding boxes) حاصل را به مختصات اصلی نگاشت کنید. YuNet به شما بودجه زمانی (از نظر سرعت) لازم برای انجام این مرحله را می‌دهد.

جایگاه این ابزار در پشته (Stack) شما

YuNet برای هر نوع وظیفه مربوط به تشخیص چهره، راهکار نیست. انسداد شدید (occlusion)، زوایای بسیار جانبی یا استخراج مش ۳بعدی (3D mesh) خارج از محدوده آن است. اما برای کارهای اصلی و معمول مانند مکان‌یابی چهره‌ها در عکس‌ها و جریان‌های ویدئویی، در جایگاه ایده‌آلی قرار دارد. اپلیکیشن‌های وب‌کم بلادرنگ، ابزارهای خودکار انتخاب عکس و سیستم‌های نهفته (embedded) معمولی، همگی از آشکارسازی که روی CPUهای استاندارد سریع اجرا می‌شود، بهره می‌برند.

فرمت INT8 ONNX نیز استقرار (deployment) را بدون دردسر می‌کند. نیازی به نصب PyTorch یا TensorFlow روی دستگاه مقصد ندارید. ماژول DNN در OpenCV مدل را مستقیماً بارگذاری می‌کند که باعث می‌شود فایل باینری شما کوچک و درخت وابستگی‌هایتان کوتاه باقی بماند.

خلاصه کلام

YuNet ثابت می‌کند که تشخیص چهره نیازی به سخت‌افزار صنعتی یا فریم‌ورک‌های سنگین ندارد. اعداد به وضوح صحبت می‌کنند: کمتر از ده میلی‌ثانیه برای یک فریم 720p، و افزایشی مستقیم و قابل پیش‌بینی در تعداد تشخیص‌ها با افزایش رزولوشن. شما می‌توانید انتخاب کنید که آیا سرعت حداکثری در رزولوشن متوسط را می‌خواهید یا پوشش گسترده‌تر در مقیاس بالاتر، و مدل شما را بابت این انتخاب جریمه نخواهد کرد.

اگر در حال ساخت چیزی هستید که با تصاویر دنیای واقعی سر و کار دارد، مراحل بازتولید (reproduction) بالا را روی سخت‌افزار خود اجرا کنید. آن را با ویدئوهای خود آزمایش کنید. سپس منطق تغییر اندازه خود را برای مطابقت با چهره‌هایی که واقعاً نیاز به یافتن آن‌ها دارید، تنظیم کنید. سرعت تنها زمانی مفید است که بتوانید آن را هدایت کنید. YuNet هم سرعت و هم کنترل را به شما می‌دهد.