فاز 4 · درس 15

استقرار مدل‌های بینایی ماشین روی لبه و بهینه‌سازی استنتاج

نوع
مفهومی و ساختنی
زمان
حدود 75 دقیقه
زبان‌ها
Python
یک برد پردازشی الکترونیکی کوچک در کنار تراشه‌ای با نشان‌گرهای سنجش سرعت و فشرده‌سازی دیجیتال داده
فهرست مطالب
  1. اهداف یادگیری
  2. صورت مسئله
  3. مفاهیم کلیدی
  4. سه بودجه‌ی اصلی
  5. اصول سنجش دقیق
  6. FLOPs به‌عنوان یک تخمین‌گر
  7. کوانتیزه‌سازی در یک بند
  8. هرس کردن و تقطیر
  9. محیط‌های اجرای استنتاج
  10. راهنمای انتخاب معماری در لبه
  11. پیاده‌سازی
  12. گام 1: اندازه‌گیری اصولی تاخیر
  13. گام 2: شمارش پارامترها و FLOPs
  14. گام 3: کوانتیزه‌سازی ایستا پس از آموزش
  15. گام 4: خروجی گرفتن به فرمت ONNX
  16. گام 5: بنچ‌مارک و مقایسه‌ی حالت‌های مختلف
  17. استفاده‌ی عملی
  18. تحویل پروژه
  19. تمرین‌ها
  20. اصطلاحات کلیدی
  21. برای مطالعه‌ی بیشتر

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

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

در این بخش، سه ابزار اساسی یعنی انتخاب معماری متناسب (مانند MobileNetV3 یا ConvNeXt)، کوانتیزه‌سازی ایستای INT8 و استفاده از موتورهای اجرایی بهینه‌ساز نظیر ONNX Runtime و TensorRT را به‌صورت عملی پیاده‌سازی و ارزیابی می‌کنید.

استنتاج روی لبه (Edge inference) هنرِ اجرای مدلی با دقت 90% و نرخ 30 فریم بر ثانیه روی دستگاهی با 2 گیگابایت رم است؛ جایی که تک‌تک درصدهای دقت در ازای میلی‌ثانیه‌های تاخیر معامله می‌شوند.

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

  • اندازه‌گیری تاخیر استنتاج، اوج مصرف حافظه و نرخ پردازش (throughput) برای هر مدل PyTorch، و تحلیل مصالحه میان FLOPs، تعداد پارامترها و تاخیر
  • کوانتیزه‌سازی یک مدل بینایی به INT8 با استفاده از کوانتیزه‌سازی پس از آموزش (PTQ) در PyTorch و تایید افت دقت کمتر از 1%
  • خروجی گرفتن به فرمت ONNX و کامپایل با ONNX Runtime یا TensorRT؛ به‌همراه نام بردن از سه خطای رایج خروجی گرفتن و روش رفع آن‌ها
  • توضیح زمان مناسب برای انتخاب MobileNetV3، EfficientNet-Lite، ConvNeXt-Tiny یا MobileViT با توجه به محدودیت‌های لبه

صورت مسئله

مدل بینایی ماشین هنگام آموزش، یک غول ممیز شناور (floating-point) است: 100 میلیون پارامتر، 10 گیگافلاپس (GFLOPs) در هر گذر رو به جلو و 2 گیگابایت حافظه‌ی گرافیکی. هیچ‌کدام از این‌ها روی گوشی، سیستم چندرسانه‌ای خودرو، دوربین صنعتی یا پهپاد جا نمی‌شوند. عملیاتی‌سازی یک سیستم بینایی یعنی گنجاندن همان پیش‌بینی‌ها در بودجه‌ای 100 برابر کوچک‌تر.

بخش عمده‌ی کار روی دوش سه اهرم اصلی است: انتخاب مدل (معماری کوچک‌تر با همان دستورالعمل آموزش)، کوانتیزه‌سازی (INT8 به‌جای FP32) و محیط اجرای استنتاج (ONNX Runtime، TensorRT، Core ML، TFLite). تنظیم درست این‌ها مرز میان دمویی است که روی ورک‌استیشن اجرا می‌شود با محصولی تجاری که روی یک ماژول دوربین 30 دلاری بالا می‌آید.

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

مفاهیم کلیدی

سه بودجه‌ی اصلی

مدلتأخیرms به ازای هر تصویرحافظهحداکثر MBتوان مصرفیmJ به ازای هر استنتاجتصمیم‌گیریانتشار / عدم انتشار
  • تاخیر (Latency): صدک‌های p50، p95 و p99. گزارش صرفاً p50 (یا میانگین)، رفتار انتهای توزیع (tail behaviour) را پنهان می‌کند؛ در حالی که همین رفتار برای سیستم‌های بی‌درنگ (real-time) تعیین‌کننده است.
  • اوج مصرف حافظه (Peak memory): بیشترین مقداری که دستگاه در تمام طول اجرا می‌بیند، نه میانگین حالت پایدار. از این جهت مهم است که خطای کمبود حافظه (OOM) روی سخت‌افزارهای امبدد مرگبار است.
  • توان / مصرف انرژی: میلی‌ژول به ازای هر استنتاج روی دستگاه‌های مبتنی بر باتری. اغلب با حاصل‌ضرب زمان در درصد استفاده از CPU/GPU تقریب زده می‌شود.

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

اصول سنجش دقیق

سه قاعده‌ای که در هر پروفایل‌گیری روی لبه باید رعایت شوند:

  1. گرم کردن (Warm up) مدل با 5 تا 10 گذر رو به جلوی آزمایشی پیش از اندازه‌گیری. کش‌های سرد و کامپایل JIT اعدادی غیرواقعی در دورهای اول تولید می‌کنند.
  2. همگام‌سازی (Synchronise) پردازش‌های GPU با torch.cuda.synchronize() قبل و بعد از بلوک زمان‌گیری. بدون این کار، به‌جای زمان اجرای واقعی کرنل، فقط زمان ارسال دستور به کرنل (dispatch) را اندازه می‌گیرید.
  3. تثبیت ابعاد ورودی مطابق با رزولوشن محیط عملیاتی. تاخیر در ابعاد 224x224 با تاخیر در 512x512 برابر نیست.

FLOPs به‌عنوان یک تخمین‌گر

تعداد کل محاسبات ممیز شناور (FLOPs) به ازای هر استنتاج، معیاری ارزان و مستقل از سخت‌افزار برای تخمین تاخیر است؛ برای مقایسه‌ی معماری‌ها مفید است، اما به‌عنوان زمان واقعی اجرا گمراه‌کننده خواهد بود. مدلی با 10% عملیات ممیز شناور بیشتر، در عمل ممکن است 2 برابر سریع‌تر باشد؛ چون از عملیات‌های سازگارتر با سخت‌افزار استفاده می‌کند (کانولوشن‌های depthwise عالی کامپایل می‌شوند، اما کانولوشن‌های بزرگ 7x7 نه).

قاعده: از FLOPs برای جست‌وجوی معماری و از تاخیر واقعی روی دستگاه برای تصمیم‌گیری نهایی استقرار استفاده کنید.

کوانتیزه‌سازی در یک بند

وزن‌ها و اکتیویشن‌های FP32 را با INT8 جایگزین کنید. حجم مدل 4 برابر کاهش می‌یابد، پهنای باند حافظه 4 برابر آزاد می‌شود و محاسبات روی سخت‌افزارهایی با کرنل‌های INT8 (همه‌ی تراشه‌های موبایل امروزی و همه‌ی کارت‌های گرافیک NVIDIA دارای هسته‌ی تنسور (Tensor Core)) بین 2 تا 4 برابر سریع‌تر می‌شود. افت دقت در تسک‌های بینایی با کوانتیزه‌سازی ایستای پس از آموزش معمولاً بین 0.1 تا 1 درصد است.

انواع:

  • پویا (Dynamic) — وزن‌ها به INT8 تبدیل می‌شوند، اما اکتیویشن‌ها در قالب FP محاسبه می‌شوند. پیاده‌سازی آن ساده است و سرعت را کمی بالا می‌برد.
  • ایستا پس از آموزش (Static PTQ) — وزن‌ها کوانتیزه می‌شوند و بازه‌ی اکتیویشن‌ها روی مجموعه‌ی کوچکی از داده‌های کالیبراسیون تنظیم می‌گردد. بسیار سریع‌تر از حالت پویا است.
  • آموزش آگاه از کوانتیزه‌سازی (QAT) — اثر کوانتیزه‌سازی در حین آموزش شبیه‌سازی می‌شود تا مدل خود را با آن تطبیق دهد. بالاترین دقت را دارد، اما به داده‌های برچسب‌دار نیاز دارد.

در بینایی ماشین، کوانتیزه‌سازی ایستای پس از آموزش 95% مزایا را با 5% زحمت فراهم می‌کند. فقط زمانی سراغ QAT بروید که افت دقت PTQ غیرقابل‌قبول باشد.

هرس کردن و تقطیر

  • هرس کردن (Pruning) — حذف وزن‌های کم‌اهمیت (بر اساس بزرگی مقدار) یا کانال‌ها (هرس ساختاریافته). روی مدل‌های دارای پارامتر مازاد عالی جواب می‌دهد؛ اما روی معماری‌هایی که از پیش فشرده‌اند چندان کارآمد نیست.
  • تقطیر (Distillation) — آموزش مدلی کوچک (دانش‌آموز) برای تقلید از لاجیت‌های یک مدل بزرگ (معلم). معمولاً بخش عمده‌ی دقت از‌دست‌رفته بر اثر کوچک‌سازی مدل را برمی‌گرداند و برای مدل‌های عملیاتی لبه یک استاندارد به حساب می‌آید.

محیط‌های اجرای استنتاج

  • حالت Eager در PyTorch — کند است و به درد استقرار عملیاتی نمی‌خورد. فقط برای توسعه استفاده کنید.
  • TorchScript — قدیمی شده و جای خود را به torch.compile و خروجی ONNX داده است.
  • ONNX Runtime — محیط اجرای بی‌طرف و چندمنظوره. برای سخت‌افزارهای CPU، CUDA، CoreML، TensorRT و OpenVINO پرووایدر دارد. کار را از اینجا شروع کنید.
  • TensorRT — کامپایلر اختصاصی NVIDIA. بهترین تاخیر را روی پردازنده‌های گرافیکی NVIDIA (ورک‌استیشن و Jetson) ارائه می‌دهد. به‌صورت مستقل یا ادغام‌شده در ONNX Runtime کار می‌کند.
  • Core ML — محیط اجرای اختصاصی اپل برای iOS/macOS. به فایل‌های .mlmodel یا .mlpackage نیاز دارد.
  • TFLite — محیط اجرای گوگل برای Android/ARM. به فایل‌های .tflite نیاز دارد.
  • OpenVINO — محیط اجرای اینتل برای CPU و VPU. به فایل‌های .xml و .bin نیاز دارد.

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

راهنمای انتخاب معماری در لبه

بودجه مدل دلیل انتخاب
کمتر از 3M پارامتر MobileNetV3-Small همه‌جا کامپایل می‌شود، بیس‌لاین مناسبی است
3 تا 10M EfficientNet-Lite-B0 بالاترین دقت به ازای هر پارامتر در TFLite
10 تا 20M ConvNeXt-Tiny بهترین بازدهی دقت بر پارامتر، بسیار سازگار با CPU
20 تا 30M MobileViT-S یا EfficientViT ترنسفورمر با دقت هم‌سطح ImageNet
30 تا 80M Swin-V2-Tiny در صورتی که بستر نرم‌افزاری از اتنشن پنجره‌ای پشتیبانی کند

همه‌ی این مدل‌ها را به INT8 کوانتیزه کنید، مگر اینکه دلیل مشخصی برای خلاف آن داشته باشید.

تعداد پارامترهای CNNکانولوشن در برابر متراکم
هزینه‌ی یک لایه‌ی کانولوشن برابر با (K·K·Cin + 1)·Cout وزن است و همان یک کرنل را در تمام موقعیت‌های مکانی بازاستفاده می‌کند. یک لایه‌ی متراکم که همان نقشه‌ی ویژگی را متصل کند، به ازای هر جفت پیکسل ورودی-خروجی به وزنی جداگانه نیاز دارد که با بزرگ شدن تصویر منفجر می‌شود. اشتراک وزن دلیلی است که CNNها به اندازه‌ی کافی کوچک می‌مانند تا اصلاً بتوان آن‌ها را روی تصاویر آموزش داد.

پیاده‌سازی

گام 1: اندازه‌گیری اصولی تاخیر

import time
import torch

def measure_latency(model, input_shape, device="cpu", warmup=10, iters=50):
    model = model.to(device).eval()
    x = torch.randn(input_shape, device=device)
    with torch.no_grad():
        for _ in range(warmup):
            model(x)
        if device == "cuda":
            torch.cuda.synchronize()
        times = []
        for _ in range(iters):
            if device == "cuda":
                torch.cuda.synchronize()
            t0 = time.perf_counter()
            model(x)
            if device == "cuda":
                torch.cuda.synchronize()
            times.append((time.perf_counter() - t0) * 1000)
    times.sort()
    return {
        "p50_ms": times[len(times) // 2],
        "p95_ms": times[int(len(times) * 0.95)],
        "p99_ms": times[int(len(times) * 0.99)],
        "mean_ms": sum(times) / len(times),
    }

مدل را گرم کنید، همگام‌سازی را انجام دهید و از time.perf_counter() استفاده کنید. صدک‌ها را گزارش دهید، نه صرفاً میانگین را.

گام 2: شمارش پارامترها و FLOPs

def parameter_count(model):
    return sum(p.numel() for p in model.parameters())

def flops_estimate(model, input_shape):
    """
    Rough FLOP count for a conv/linear-only model. For production use `fvcore` or `ptflops`.
    """
    total = 0
    def conv_hook(m, inp, out):
        nonlocal total
        c_out, c_in, kh, kw = m.weight.shape
        h, w = out.shape[-2:]
        total += 2 * c_in * c_out * kh * kw * h * w
    def linear_hook(m, inp, out):
        nonlocal total
        total += 2 * m.in_features * m.out_features
    hooks = []
    for m in model.modules():
        if isinstance(m, torch.nn.Conv2d):
            hooks.append(m.register_forward_hook(conv_hook))
        elif isinstance(m, torch.nn.Linear):
            hooks.append(m.register_forward_hook(linear_hook))
    model.eval()
    with torch.no_grad():
        model(torch.randn(input_shape))
    for h in hooks:
        h.remove()
    return total

در پروژه‌های واقعی از fvcore.nn.FlopCountAnalysis یا ptflops استفاده کنید؛ این کتابخانه‌ها انواع ماژول‌ها را به‌درستی پوشش می‌دهند.

گام 3: کوانتیزه‌سازی ایستا پس از آموزش

def quantise_ptq(model, calibration_loader, backend="x86"):
    import torch.ao.quantization as tq
    model = model.eval().cpu()
    model.qconfig = tq.get_default_qconfig(backend)
    tq.prepare(model, inplace=True)
    with torch.no_grad():
        for x, _ in calibration_loader:
            model(x)
    tq.convert(model, inplace=True)
    return model

چهار گام اصلی: پیکربندی، آماده‌سازی (قراردادن observerها)، کالیبراسیون با داده‌های واقعی و در نهایت تبدیل (ادغام لایه‌ها + کوانتیزه کردن). این فرآیند مستلزم ادغام لایه‌هاست (Conv -> BN -> ReLU به ConvBnReLU) که torch.ao.quantization.fuse_modules انجامش می‌دهد.

گام 4: خروجی گرفتن به فرمت ONNX

def export_onnx(model, sample_input, path="model.onnx"):
    model = model.eval()
    torch.onnx.export(
        model,
        sample_input,
        path,
        input_names=["input"],
        output_names=["output"],
        dynamic_axes={"input": {0: "batch"}, "output": {0: "batch"}},
        opset_version=17,
    )
    return path

نسخه‌ی opset_version=17 پیش‌فرض امن در سال 2026 است. پارامتر dynamic_axes امکان اجرای مدل ONNX را با اندازه‌های دلخواه بچ فراهم می‌کند.

گام 5: بنچ‌مارک و مقایسه‌ی حالت‌های مختلف

import torch.nn as nn
from torchvision.models import mobilenet_v3_small

def compare_regimes():
    model = mobilenet_v3_small(weights=None, num_classes=10)
    params = parameter_count(model)
    flops = flops_estimate(model, (1, 3, 224, 224))
    lat_fp32 = measure_latency(model, (1, 3, 224, 224), device="cpu")
    print(f"FP32 MobileNetV3-Small: {params:,} params  {flops/1e9:.2f} GFLOPs  "
          f"p50={lat_fp32['p50_ms']:.2f}ms  p95={lat_fp32['p95_ms']:.2f}ms")

همین تابع را برای resnet50، efficientnet_v2_s و convnext_tiny اجرا کنید تا جدول مقایسه‌ای لازم برای تصمیم‌گیری استقرار را به دست آورید.

استفاده‌ی عملی

فرایندهای عملیاتی معمولاً به یکی از سه مسیر زیر ختم می‌شوند:

  • وب / بدون سرور (Serverless): مدل PyTorch -> خروجی ONNX -> اجرا در ONNX Runtime (با پرووایدر CPU یا CUDA). ساده‌ترین مسیر و برای اکثر نیازها کاملاً مناسب است.
  • پردازش لبه در NVIDIA (بردهای Jetson، سرورهای GPU): مدل PyTorch -> خروجی ONNX -> کامپایل در TensorRT. کمترین تاخیر، بیشترین زحمت مهندسی.
  • موبایل: مدل PyTorch -> خروجی ONNX -> تبدیل به Core ML (در iOS) یا TFLite (در اندروید). حتماً قبل از خروجی گرفتن کوانتیزه‌سازی کنید.

برای تحلیل دقیق‌تر، ابزارهای torch-tb-profiler، nvprof / nsys و Instruments در macOS جزئیات را لایه به لایه نشان می‌دهند. ابزارهای خط فرمانی benchmark_app (در OpenVINO) و trtexec (در TensorRT) هم بدون درگیر شدن با کد، آمارهای مستقلی ارائه می‌کنند.

تحویل پروژه

خروجی‌های این درس:

  • outputs/prompt-edge-deployment-planner.md — پرامپتی که بر اساس سخت‌افزار مقصد و تعهد سطح خدمت (SLA) تاخیر، معماری پایه، استراتژی کوانتیزه‌سازی و محیط اجرا را انتخاب می‌کند.
  • outputs/skill-latency-profiler.md — مهارتی که یک اسکریپت کامل برای بنچ‌مارک تاخیر به‌همراه گرم‌کردن، همگام‌سازی، محاسبه‌ی صدک‌ها و ردیابی حافظه می‌نویسد.

تمرین‌ها

  1. (ساده) تاخیر p50 را برای resnet18، mobilenet_v3_small، efficientnet_v2_s و convnext_tiny در ابعاد 224x224 روی CPU بسنجید. جدول نتایج را آماده کنید و ببینید کدام معماری بهترین نسبت دقت به میلی‌ثانیه را دارد.
  2. (متوسط) کوانتیزه‌سازی ایستای پس از آموزش را روی mobilenet_v3_small پیاده کنید. مقایسه‌ی تاخیر و افت دقت بین FP32 و INT8 را روی زیرمجموعه‌ای از داده‌های آزمون CIFAR-10 (یا دیتاست مشابه) گزارش دهید.
  3. (سخت) از مدل convnext_tiny خروجی ONNX بگیرید، آن را در onnxruntime با CPUExecutionProvider اجرا کنید و تاخیرش را با بیس‌لاین PyTorch eager بسنجید. اولین لایه‌ای را که در آن ONNX Runtime سریع‌تر عمل می‌کند پیدا کنید و دلیلش را توضیح دهید.

اصطلاحات کلیدی

اصطلاح اصطلاح رایج مفهوم واقعی
تاخیر (Latency) «چقدر سریع است» زمان رسیدن ورودی به خروجی؛ بر اساس صدک‌های p50/p95/p99، نه میانگین
محاسبات ممیز شناور (FLOPs) «حجم مدل» عملیات ممیز شناور در هر گذر رو به جلو؛ معیاری تقریبی برای هزینه‌ی محاسباتی
کوانتیزه‌سازی INT8 «8 بیتی» جایگزینی وزن‌ها/اکتیویشن‌های FP32 با اعداد صحیح 8 بیتی؛ حدوداً 4 برابر کوچک‌تر، 2 تا 4 برابر سریع‌تر
PTQ «کوانتیزه‌سازی بعد از آموزش» کوانتیزه کردن مدل آموزش‌دیده بدون بازآموزی؛ ساده و در اغلب موارد کافی
QAT «آموزش آگاه از کوانتیزه‌سازی» شبیه‌سازی اثر کوانتیزه‌سازی حین آموزش؛ بالاترین دقت، نیازمند داده‌های برچسب‌دار
ONNX «فرمت استاندارد و خنثی» فرمت تبادل مدل که تمام محیط‌های اجرای استنتاج رایج از آن پشتیبانی می‌کنند
TensorRT «کامپایلر NVIDIA» ابزاری که مدل ONNX را به یک موتور بهینه‌شده برای پردازنده‌های گرافیکی NVIDIA کامپایل می‌کند
تقطیر (Distillation) «معلم -> دانش‌آموز» آموزش مدلی کوچک برای تقلید از لاجیت‌های مدلی بزرگ؛ جبران‌کننده‌ی بخش عمده‌ی افت دقت

برای مطالعه‌ی بیشتر

خودآزمایی

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

  1. پیش از درسمدلی را بنچمارک می‌کنید و نتیجه را «میانگین 12ms به ازای هر تصویر روی 4090» گزارش می‌دهید. چه چیزی از قلم افتاده است؟
  2. پیش از درستعداد FLOPها و تاخیر روی دستگاه همبستگی کاملی ندارند. چرا؟
  3. پس از درسکوانتیزاسیون ایستا INT8 پس از آموزش (PTQ) معمولاً چقدر از دقت مدل‌های بینایی رده‌ی ImageNet می‌کاهد؟
  4. پس از درسبرنامه‌ی موبایل شما به یک مدل بینایی با حجم کمتر از 10MB و تاخیر زیر 10ms نیاز دارد. کدام شبکه پایه (backbone) را انتخاب می‌کنید؟
  5. پس از درسمدل PyTorch را با opset 17 به ONNX خروجی می‌گیرید و با خطای «Unsupported operator» مواجه می‌شود. محتمل‌ترین دلایل کدامند؟

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

چرا در استنتاج روی لبه نباید فقط به میانگین تاخیر (Mean Latency) اتکا کرد؟

میانگین تاخیر رفتارهای انتهای توزیع (دم یا Tail Latency) مانند صدک‌های p95 و p99 را پنهان می‌کند؛ این کندی‌های ناگهانی در سیستم‌های بی‌درنگ می‌توانند به افت شدید فریم یا کرش منجر شوند.

تفاوت کوانتیزه‌سازی پویا (Dynamic) و ایستا (Static PTQ) چیست؟

در حالت پویا تنها وزن‌ها INT8 می‌شوند و اکتیویشن‌ها در فرمت اعشاری باقی می‌مانند، اما در حالت ایستا وزن‌ها و اکتیویشن‌ها هر دو بر اساس داده‌های کالیبراسیون کوانتیزه می‌شوند که سرعت بسیار بیشتری فراهم می‌کند.

آیا تعداد محاسبات (FLOPs) معیار قطعی سرعت استنتاج است؟

خیر؛ FLOPs معیاری تئوری و مستقل از سخت‌افزار است. مدلی با FLOPs بیشتر ممکن است به دلیل استفاده از عملگرهای بهینه‌تر سخت‌افزاری (مثل depthwise conv) سریع‌تر از مدلی با FLOPs کمتر اجرا شود.

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

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