درایورهای API شبکه های عصبی

این صفحه یک نمای کلی از نحوه پیاده سازی یک درایور API شبکه های عصبی (NNAPI) ارائه می دهد. برای جزئیات بیشتر، به مستندات موجود در فایل های تعریف HAL ​​در hardware/interfaces/neuralnetworks مراجعه کنید. اجرای درایور نمونه در frameworks/ml/nn/driver/sample است.

برای اطلاعات بیشتر در مورد API شبکه های عصبی، به API شبکه های عصبی مراجعه کنید.

شبکه های عصبی HAL

شبکه‌های عصبی (NN) HAL انتزاعی از دستگاه‌های مختلف مانند واحدهای پردازش گرافیکی (GPU) و پردازنده‌های سیگنال دیجیتال (DSP) را که در یک محصول (مثلاً تلفن یا تبلت) هستند، تعریف می‌کند. درایورهای این دستگاه ها باید با NN HAL مطابقت داشته باشند. رابط در فایل های تعریف HAL ​​در hardware/interfaces/neuralnetworks مشخص شده است.

جریان کلی رابط بین چارچوب و درایور در شکل 1 نشان داده شده است.

شبکه های عصبی جریان دارند

شکل 1. جریان شبکه های عصبی

مقداردهی اولیه

در زمان اولیه سازی، فریم ورک با استفاده از IDevice::getCapabilities_1_3 از درایور قابلیت های خود را جستجو می کند. ساختار @1.3::Capabilities شامل تمام انواع داده‌ها است و عملکرد غیرآرامش را با استفاده از یک بردار نشان می‌دهد.

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

برای تعیین مقادیری که درایور در پاسخ به IDevice::getCapabilities_1_3 برمی‌گرداند، از برنامه معیار NNAPI برای اندازه‌گیری عملکرد انواع داده‌های مربوطه استفاده کنید. مدل‌های MobileNet v1 و v2، asr_float و tts_float برای اندازه‌گیری عملکرد برای مقادیر ممیز شناور 32 بیتی و مدل‌های کوانتیزه MobileNet v1 و v2 برای مقادیر کوانتیزه‌شده 8 بیتی توصیه می‌شوند. برای اطلاعات بیشتر، مجموعه تست یادگیری ماشین اندروید را ببینید.

در اندروید 9 و پایین‌تر، ساختار Capabilities شامل اطلاعات عملکرد درایور فقط برای ممیز شناور و تانسورهای کوانتیزه می‌شود و انواع داده‌های اسکالر را شامل نمی‌شود.

به عنوان بخشی از فرآیند اولیه سازی، چارچوب ممکن است با استفاده از IDevice::getType ، IDevice::getVersionString ، IDevice:getSupportedExtensions و IDevice::getNumberOfCacheFilesNeeded ، اطلاعات بیشتری را درخواست کند.

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

تلفیقی

این فریم ورک تعیین می کند که هنگام دریافت درخواست از یک برنامه از چه دستگاه هایی استفاده کند. در Android 10، برنامه‌ها می‌توانند دستگاه‌هایی را که فریم‌ورک از آن‌ها انتخاب می‌کند، پیدا کرده و مشخص کنند. برای اطلاعات بیشتر، Device Discovery and Assignment را ببینید.

در زمان کامپایل مدل، چارچوب با فراخوانی IDevice::getSupportedOperations_1_3 مدل را برای هر راننده کاندید ارسال می کند. هر درایور آرایه ای از بولی ها را برمی گرداند که نشان می دهد کدام عملیات از مدل پشتیبانی می شود. یک درایور می تواند تشخیص دهد که به دلایلی نمی تواند یک عملیات معین را پشتیبانی کند. مثلا:

  • درایور از نوع داده پشتیبانی نمی کند.
  • درایور فقط از عملیات با پارامترهای ورودی خاص پشتیبانی می کند. به عنوان مثال، یک درایور ممکن است از 3x3 و 5x5 پشتیبانی کند، اما از عملیات پیچشی 7x7 پشتیبانی نمی کند.
  • درایور دارای محدودیت‌های حافظه است که از مدیریت نمودارها یا ورودی‌های بزرگ جلوگیری می‌کند.

در طول کامپایل، ورودی، خروجی و عملوندهای داخلی مدل، همانطور که در OperandLifeTime توضیح داده شده است، می توانند ابعاد یا رتبه ناشناخته داشته باشند. برای اطلاعات بیشتر، شکل خروجی را ببینید.

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

در صورت موفقیت، درایور یک دسته @1.3::IPreparedModel را برمی گرداند. اگر درایور هنگام تهیه زیرمجموعه مدل خود، کد خرابی را برگرداند، فریم ورک کل مدل را روی CPU اجرا می کند.

برای کاهش زمان استفاده از کامپایل هنگام شروع یک برنامه، یک درایور می تواند مصنوعات کامپایل را در حافظه پنهان نگه دارد. برای اطلاعات بیشتر، به ذخیره سازی کامپایل مراجعه کنید.

اجرا

هنگامی که یک برنامه از فریم ورک می‌خواهد تا یک درخواست را اجرا کند، فریم‌ورک به‌طور پیش‌فرض متد IPreparedModel::executeSynchronously_1_3 HAL را فراخوانی می‌کند تا یک اجرای همزمان روی یک مدل آماده‌شده انجام شود. یک درخواست همچنین می تواند به صورت ناهمزمان با استفاده از متد execute_1_3 ، متد executeFenced (به اجرای Fenced مراجعه کنید) یا با استفاده از یک اجرای پشت سر هم اجرا شود.

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

با متد execute_1_3 ناهمزمان، پس از شروع اجرا، کنترل به فرآیند برنامه برمی‌گردد و راننده باید با استفاده از @1.3::IExecutionCallback ، چارچوب را پس از اتمام اجرا مطلع کند.

پارامتر Request که به متد execute ارسال می شود، عملوندهای ورودی و خروجی مورد استفاده برای اجرا را فهرست می کند. حافظه‌ای که داده‌های عملوند را ذخیره می‌کند باید از ترتیب ردیف اصلی استفاده کند که بُعد اول کندترین تکرار را داشته باشد و در انتهای هر سطر فاقد بالشتک باشد. برای اطلاعات بیشتر در مورد انواع عملوندها، به عملوندها مراجعه کنید.

برای درایورهای NN HAL 1.2 یا بالاتر، هنگامی که یک درخواست تکمیل می‌شود، وضعیت خطا، شکل خروجی و اطلاعات زمان‌بندی به چارچوب بازگردانده می‌شود. در حین اجرا، خروجی یا عملوندهای داخلی مدل می توانند یک یا چند بعد مجهول یا رتبه ناشناخته داشته باشند. هنگامی که حداقل یک عملوند خروجی دارای بعد یا رتبه ناشناخته است، درایور باید اطلاعات خروجی با اندازه پویا را برگرداند.

برای درایورهایی با NN HAL 1.1 یا پایین تر، تنها زمانی که یک درخواست تکمیل می شود، وضعیت خطا برگردانده می شود. ابعاد عملوندهای ورودی و خروجی باید به طور کامل مشخص شود تا اجرا با موفقیت انجام شود. عملوندهای داخلی می توانند یک یا چند بعد مجهول داشته باشند، اما باید دارای رتبه مشخصی باشند.

برای درخواست‌های کاربر که شامل چندین درایور می‌شوند، فریم‌ورک مسئول ذخیره حافظه میانی و ترتیب دادن تماس‌ها به هر راننده است.

چندین درخواست را می توان به صورت موازی در همان @1.3::IPreparedModel آغاز کرد. درایور می تواند درخواست ها را به صورت موازی اجرا کند یا اجراها را سریالی کند.

چارچوب می تواند از راننده بخواهد که بیش از یک مدل آماده را نگه دارد. به عنوان مثال، مدل m1 را آماده کنید، m2 آماده کنید، درخواست r1 روی m1 اجرا کنید، r2 روی m2 اجرا کنید، r3 روی m1 اجرا کنید، r4 روی m2 اجرا کنید، رها کنید (شرح شده در Cleanup ) m1 ، و m2 آزاد کنید.

برای جلوگیری از اجرای آهسته اول که می تواند منجر به تجربه کاربری ضعیف شود (به عنوان مثال، اولین لکنت فریم)، ​​درایور باید بیشترین مقداردهی اولیه را در مرحله کامپایل انجام دهد. راه‌اندازی در اولین اجرا باید به اقداماتی محدود شود که در زمان انجام زودهنگام بر سلامت سیستم تأثیر منفی می‌گذارند، مانند رزرو بافرهای موقت بزرگ یا افزایش نرخ ساعت یک دستگاه. درایورهایی که می‌توانند تنها تعداد محدودی از مدل‌های همزمان را آماده کنند، ممکن است مجبور باشند در اولین اجرا، مقداردهی اولیه خود را انجام دهند.

در Android 10 یا بالاتر، در مواردی که چندین اجرا با یک مدل آماده شده به صورت متوالی اجرا می‌شوند، مشتری ممکن است استفاده از یک شیء انفجاری اجرا را برای برقراری ارتباط بین فرآیندهای برنامه و درایور انتخاب کند. برای اطلاعات بیشتر، به اجراهای انفجاری و صف‌های پیام سریع مراجعه کنید.

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

شکل خروجی

برای درخواست هایی که یک یا چند عملوند خروجی همه ابعاد مشخص شده را ندارند، درایور باید فهرستی از اشکال خروجی حاوی اطلاعات ابعاد برای هر عملوند خروجی پس از اجرا ارائه کند. برای اطلاعات بیشتر در مورد ابعاد، OutputShape را ببینید.

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

زمان سنجی

در اندروید 10، اگر برنامه یک دستگاه واحد را برای استفاده در فرآیند کامپایل تعیین کرده باشد، یک برنامه می‌تواند زمان اجرا را درخواست کند. برای جزئیات، به MeasureTiming و Device Discovery and Assignment مراجعه کنید. در این مورد، یک درایور NN HAL 1.2 باید مدت زمان اجرا را اندازه گیری کند یا UINT64_MAX گزارش کند (برای نشان دادن اینکه مدت زمان در دسترس نیست) هنگام اجرای یک درخواست. راننده باید جریمه عملکرد ناشی از اندازه گیری مدت اجرا را به حداقل برساند.

درایور مدت زمان های زیر را در میکروثانیه در ساختار Timing گزارش می کند:

  • زمان اجرا در دستگاه: زمان اجرا در درایور که روی پردازنده میزبان اجرا می شود را شامل نمی شود.
  • زمان اجرا در درایور: شامل زمان اجرا در دستگاه است.

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

وقتی از راننده خواسته نشده است که مدت زمان اجرا را اندازه‌گیری کند، یا زمانی که خطای اجرا وجود دارد، راننده باید مدت‌ها را به‌عنوان UINT64_MAX گزارش کند. حتی زمانی که از راننده خواسته می‌شود مدت زمان اجرا را اندازه‌گیری کند، در عوض می‌تواند UINT64_MAX برای زمان روی دستگاه، زمان در درایور یا هر دو گزارش دهد. وقتی درایور هر دو مدت زمان را به‌عنوان مقداری غیر از UINT64_MAX گزارش می‌کند، زمان اجرا در درایور باید برابر یا بیشتر از زمان دستگاه باشد.

اعدام محصور شده

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

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

پس از اتمام یک اجرا، دو مقدار زمان بندی زیر که مدت زمان اجرا را اندازه گیری می کنند را می توان از طریق IFencedExecutionCallback::getExecutionInfo جستجو کرد.

  • timingLaunched : مدت زمانی که executeFenced شود به زمانی فراخوانی می شود که executeFenced به syncFence برگشتی سیگنال می دهد.
  • timingFenced : مدت زمانی که تمام حصارهای همگام‌سازی که اجرا در انتظار آن است علامت داده می‌شوند تا زمانی که executeFenced به syncFence برگشتی سیگنال می‌دهد.

جریان را کنترل کنید

برای دستگاه‌های دارای Android 11 یا بالاتر، NNAPI شامل دو عملیات جریان کنترلی، IF و WHILE است که مدل‌های دیگر را به‌عنوان آرگومان می‌گیرد و آنها را به‌صورت مشروط ( IF ) یا مکرر ( WHILE ) اجرا می‌کند. برای اطلاعات بیشتر در مورد نحوه اجرای این، به Control flow مراجعه کنید.

کیفیت خدمات

در اندروید 11، NNAPI شامل بهبود کیفیت خدمات (QoS) با اجازه دادن به برنامه برای نشان دادن اولویت‌های نسبی مدل‌های خود، حداکثر زمان مورد انتظار برای آماده‌سازی یک مدل و حداکثر زمان مورد انتظار برای اجرا است. تکمیل شود. برای اطلاعات بیشتر، کیفیت خدمات را ببینید.

پاک کردن

هنگامی که یک برنامه با استفاده از یک مدل آماده به پایان می رسد، چارچوب مرجع خود را به شی @1.3::IPreparedModel آزاد می کند. هنگامی که شی IPreparedModel دیگر ارجاع داده نمی شود، به طور خودکار در سرویس راننده ای که آن را ایجاد کرده است، از بین می رود. منابع خاص مدل را می توان در این زمان در پیاده سازی ویرانگر توسط راننده بازیابی کرد. اگر سرویس درایور بخواهد که شی IPreparedModel زمانی که دیگر مورد نیاز کلاینت نیست، به طور خودکار از بین برود، پس از بازگشت شیء IPreparedModel از طریق IPreparedModelCallback::notify_1_3 ، نباید هیچ ارجاعی به شی IPreparedeModel داشته باشد.

میزان استفاده از پردازنده

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

این چارچوب یک پیاده سازی CPU را برای تمام عملیات NNAPI به جز عملیات تعریف شده توسط فروشنده ارائه می دهد. برای اطلاعات بیشتر، به برنامه های افزودنی فروشنده مراجعه کنید.

عملیات معرفی شده در Android 10 (سطح API 29) فقط دارای یک پیاده سازی CPU مرجع برای تأیید صحت تست های CTS و VTS هستند. پیاده‌سازی‌های بهینه‌شده موجود در چارچوب‌های یادگیری ماشین سیار بر اجرای CPU NNAPI ترجیح داده می‌شوند.

توابع سودمند

پایگاه کد NNAPI شامل توابع ابزاری است که می توانند توسط خدمات راننده استفاده شوند.

فایل frameworks/ml/nn/common/include/Utils.h شامل توابع مختلف ابزاری است، مانند توابع مورد استفاده برای ورود به سیستم و تبدیل بین نسخه‌های مختلف NN HAL.

  • VLogging: VLOG یک ماکرو بسته بندی در اطراف LOG اندروید است که فقط در صورتی پیام را ثبت می کند که تگ مناسب در ویژگی debug.nn.vlog تنظیم شده باشد. initVLogMask() باید قبل از هر تماسی با VLOG فراخوانی شود. ماکرو VLOG_IS_ON را می‌توان برای بررسی فعال بودن VLOG در حال حاضر استفاده کرد، و در صورت عدم نیاز، امکان حذف کدهای پیچیده گزارش‌گیری وجود دارد. ارزش ملک باید یکی از موارد زیر باشد:

    • یک رشته خالی که نشان می دهد هیچ گزارشی نباید انجام شود.
    • نشانه 1 یا all ، نشان می دهد که تمام ثبت نام باید انجام شود.
    • فهرستی از برچسب‌ها که با فاصله، کاما یا دونقطه مشخص می‌شوند و نشان می‌دهند که کدام گزارش باید انجام شود. تگ ها عبارتند از compilation , cpuexe , driver , execution , manager و model .
  • compliantWithV1_* : اگر یک شی NN HAL را بتوان بدون از دست دادن اطلاعات به همان نوع از نسخه HAL متفاوت تبدیل کرد، true برمی‌گرداند. برای مثال، فراخوانی compliantWithV1_0 در V1_2::Model اگر مدل شامل انواع عملیات معرفی شده در NN HAL 1.1 یا NN HAL 1.2 باشد، false برمی‌گرداند.

  • convertToV1_* : یک شی NN HAL را از یک نسخه به نسخه دیگر تبدیل می کند. اگر تبدیل منجر به از دست رفتن اطلاعات شود (یعنی اگر نسخه جدید از نوع نتواند به طور کامل مقدار را نشان دهد) یک هشدار ثبت می شود.

  • قابلیت ها: از توابع nonExtensionOperandPerformance و update می توان برای کمک به ساخت فیلد Capabilities::operandPerformance استفاده کرد.

  • خصوصیات پرس و جو انواع: isExtensionOperandType ، isExtensionOperationType ، nonExtensionSizeOfData ، nonExtensionOperandSizeOfData ، nonExtensionOperandTypeIsScalar ، tensorHasUnspecifiedDimensions .

فایل frameworks/ml/nn/common/include/ValidateHal.h حاوی توابع کاربردی برای تأیید اعتبار یک شی NN HAL مطابق با مشخصات نسخه HAL آن است.

  • validate* : اگر شی NN HAL مطابق مشخصات نسخه HAL آن معتبر باشد، true برمی‌گرداند. انواع OEM و انواع پسوند تأیید نشده اند. برای مثال، اگر مدل حاوی عملیاتی باشد که به یک شاخص عملوندی که وجود ندارد یا عملیاتی که در آن نسخه HAL پشتیبانی نمی‌شود، ارجاع می‌دهد، validateModel false را برمی‌گرداند.

فایل frameworks/ml/nn/common/include/Tracing.h حاوی ماکروهایی برای ساده‌سازی افزودن اطلاعات سیستراسینگ به کد شبکه‌های عصبی است. برای مثال، فراخوانی های ماکرو NNTRACE_* را در درایور نمونه ببینید.

فایل frameworks/ml/nn/common/include/GraphDump.h حاوی یک تابع کاربردی برای حذف محتوای یک Model به شکل گرافیکی برای اهداف اشکال‌زدایی است.

  • graphDump : نمایشی از مدل را در قالب Graphviz ( .dot ) در جریان مشخص شده (در صورت ارائه) یا در logcat (اگر جریانی ارائه نشده است) می نویسد.

اعتبار سنجی

برای آزمایش اجرای NNAPI، از تست‌های VTS و CTS موجود در چارچوب Android استفاده کنید. VTS رانندگان شما را مستقیماً (بدون استفاده از چارچوب) تمرین می دهد، در حالی که CTS آنها را به طور غیر مستقیم از طریق چارچوب تمرین می کند. این روش‌ها هر روش API را آزمایش می‌کنند و تأیید می‌کنند که تمام عملیات پشتیبانی شده توسط درایورها به درستی کار می‌کنند و نتایجی را ارائه می‌دهند که الزامات دقت را برآورده می‌کنند.

الزامات دقت در CTS و VTS برای NNAPI به شرح زیر است:

  • نقطه شناور: abs(مورد انتظار - واقعی) <= atol + rtol * abs(expected); جایی که:

    • برای fp32، atol = 1e-5f، rtol = 5.0f * 1.1920928955078125e-7
    • برای fp16، atol = rtol = 5.0f * 0.0009765625f
  • Quantized: off-by-one (به جز mobilenet_quantized که به صورت off-by-3 است)

  • بولی: مطابقت دقیق

یکی از روش‌هایی که CTS NNAPI را آزمایش می‌کند، تولید نمودارهای شبه تصادفی ثابت است که برای آزمایش و مقایسه نتایج اجرای هر درایور با پیاده‌سازی مرجع NNAPI استفاده می‌شود. برای درایورهایی با NN HAL 1.2 یا بالاتر، اگر نتایج معیارهای دقیق را برآورده نکنند، CTS یک خطا گزارش می‌کند و یک فایل مشخصات مدل ناموفق را در زیر /data/local/tmp برای اشکال‌زدایی می‌گذارد. برای جزئیات بیشتر در مورد معیارهای دقت، به TestRandomGraph.cpp و TestHarness.h مراجعه کنید.

تست فاز

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

برای انجام تست فازی برای تأیید اجرای درایور خود، frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp در ابزار آزمایشی libneuralnetworks_driver_fuzzer موجود در AOSP تغییر دهید تا کد درایور شما را نیز در بر گیرد. برای اطلاعات بیشتر در مورد تست فاز NNAPI، frameworks/ml/nn/runtime/test/android_fuzzing/README.md را ببینید.

امنیت

از آنجا که فرآیندهای برنامه مستقیماً با فرآیند راننده ارتباط برقرار می کنند، رانندگان باید آرگومان های تماس هایی را که دریافت می کنند تأیید کنند. این اعتبار توسط VTS تأیید شده است. کد اعتبارسنجی در frameworks/ml/nn/common/include/ValidateHal.h است.

رانندگان همچنین باید اطمینان حاصل کنند که برنامه‌ها نمی‌توانند هنگام استفاده از یک دستگاه با سایر برنامه‌ها تداخل داشته باشند.

مجموعه تست یادگیری ماشین اندروید

مجموعه تست یادگیری ماشین اندروید (MLTS) یک معیار NNAPI است که در CTS و VTS برای اعتبارسنجی دقت مدل‌های واقعی در دستگاه‌های فروشنده گنجانده شده است. این معیار تأخیر و دقت را ارزیابی می‌کند و نتایج درایورها را با نتایج با استفاده از TF Lite در حال اجرا بر روی CPU برای مدل و مجموعه داده‌های مشابه مقایسه می‌کند. این تضمین می کند که دقت درایور بدتر از اجرای مرجع CPU نیست.

توسعه دهندگان پلتفرم اندروید نیز از MLTS برای ارزیابی تأخیر و دقت درایورها استفاده می کنند.

معیار NNAPI را می توان در دو پروژه در AOSP یافت:

مدل ها و مجموعه داده ها

معیار NNAPI از مدل ها و مجموعه داده های زیر استفاده می کند.

  • MobileNetV1 شناور و u8 در اندازه‌های مختلف کوانتیزه می‌شوند، در برابر یک زیر مجموعه کوچک (1500 تصویر) از Open Images Dataset v4 اجرا می‌شوند.
  • MobileNetV2 float و u8 در اندازه‌های مختلف کوانتیزه می‌شوند، در مقابل یک زیر مجموعه کوچک (1500 تصویر) از Open Images Dataset v4 اجرا می‌شوند.
  • مدل آکوستیک مبتنی بر حافظه کوتاه مدت بلند مدت (LSTM) برای تبدیل متن به گفتار، در برابر زیرمجموعه کوچکی از مجموعه CMU قطب شمال اجرا می شود.
  • مدل آکوستیک مبتنی بر LSTM برای تشخیص خودکار گفتار، در برابر زیرمجموعه کوچکی از مجموعه داده LibriSpeech اجرا می‌شود.

برای اطلاعات بیشتر، به platform/test/mlts/models مراجعه کنید.

تست استرس

مجموعه تست یادگیری ماشین اندروید شامل مجموعه‌ای از تست‌های تصادف برای تایید انعطاف‌پذیری رانندگان در شرایط استفاده سنگین یا در موارد گوشه‌ای از رفتار مشتریان است.

تمام تست های تصادف ویژگی های زیر را ارائه می دهند:

  • تشخیص هنگ: اگر کلاینت NNAPI در حین آزمایش هنگ کند، آزمایش با دلیل شکست HANG شکست می‌خورد و مجموعه آزمایشی به آزمایش بعدی منتقل می‌شود.
  • تشخیص خرابی کلاینت NNAPI: تست‌ها از خرابی کلاینت جان سالم به در می‌برند و آزمایش‌ها با دلیل شکست CRASH شکست می‌خورند.
  • تشخیص تصادف راننده: آزمایش‌ها می‌توانند تصادف راننده‌ای را که باعث شکست در تماس NNAPI می‌شود، تشخیص دهند. توجه داشته باشید که ممکن است در فرآیندهای درایور خرابی هایی وجود داشته باشد که باعث خرابی NNAPI نشود و باعث شکست تست نشود. برای پوشش این نوع خرابی، توصیه می شود برای خطاها یا خرابی های مربوط به راننده، دستور tail را در گزارش سیستم اجرا کنید.
  • هدف‌گیری تمام شتاب‌دهنده‌های موجود: آزمایش‌ها علیه همه درایورهای موجود انجام می‌شود.

تمام تست های تصادف چهار نتیجه احتمالی زیر را دارند:

  • SUCCESS : اجرا بدون خطا انجام شد.
  • FAILURE : اجرا ناموفق بود. معمولاً به دلیل خرابی هنگام آزمایش یک مدل ایجاد می شود، که نشان می دهد درایور در کامپایل یا اجرای مدل شکست خورده است.
  • HANG : فرآیند تست پاسخگو نبود.
  • CRASH : فرآیند آزمایش از کار افتاد.

برای اطلاعات بیشتر در مورد تست استرس و لیست کامل تست‌های تصادف، به platform/test/mlts/benchmark/README.txt مراجعه کنید.

از MLTS استفاده کنید

برای استفاده از MLTS:

  1. دستگاه مورد نظر را به ایستگاه کاری خود وصل کنید و مطمئن شوید که از طریق adb قابل دسترسی است. اگر بیش از یک دستگاه متصل است، متغیر محیطی ANDROID_SERIAL دستگاه مورد نظر را صادر کنید.
  2. cd وارد فهرست منبع سطح بالای اندروید کنید.

    source build/envsetup.sh
    lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available.
    ./test/mlts/benchmark/build_and_run_benchmark.sh
    

    در پایان اجرای بنچمارک، نتایج به صورت یک صفحه HTML ارائه شده و به xdg-open ارسال می‌شود.

برای اطلاعات بیشتر، به platform/test/mlts/benchmark/README.txt مراجعه کنید.

شبکه های عصبی نسخه های HAL

در این بخش تغییرات ایجاد شده در نسخه های اندروید و شبکه های عصبی HAL توضیح داده شده است.

اندروید 11

اندروید 11 NN HAL 1.3 را معرفی می کند که شامل تغییرات قابل توجه زیر است.

  • پشتیبانی از کوانتیزاسیون 8 بیتی امضا شده در NNAPI. نوع عملوند TENSOR_QUANT8_ASYMM_SIGNED را اضافه می کند. درایورهای دارای NN HAL 1.3 که از عملیات با کوانتیزاسیون بدون علامت پشتیبانی می کنند، باید از انواع امضا شده آن عملیات نیز پشتیبانی کنند. هنگام اجرای نسخه‌های امضا شده و بدون علامت اکثر عملیات‌های کوانتیزه‌شده، درایورها باید نتایج یکسانی را تا انحراف 128 تولید کنند. پنج استثنا برای این شرط وجود دارد: CAST ، HASHTABLE_LOOKUP ، LSH_PROJECTION ، PAD_V2 ، و QUANTIZED_16BIT_LSTM . عملیات QUANTIZED_16BIT_LSTM از عملوندهای امضا شده پشتیبانی نمی کند و چهار عملیات دیگر از کوانتیزاسیون امضا شده پشتیبانی می کنند اما نیازی به یکسان بودن نتایج ندارند.
  • پشتیبانی از اجراهای حصاردار که در آن چارچوب روش IPreparedModel::executeFenced را فراخوانی می‌کند تا اجرای محصور شده و ناهمزمان را روی یک مدل آماده با بردار حصارهای همگام‌سازی راه‌اندازی کند. برای اطلاعات بیشتر، اجرای حصاردار را ببینید.
  • پشتیبانی از جریان کنترل عملیات IF و WHILE را اضافه می کند، که مدل های دیگر را به عنوان آرگومان می گیرند و آنها را به صورت شرطی ( IF ) یا مکرر ( WHILE ) اجرا می کنند. برای اطلاعات بیشتر، به کنترل جریان مراجعه کنید.
  • بهبود کیفیت خدمات (QoS) به‌عنوان برنامه‌ها می‌تواند اولویت‌های نسبی مدل‌های آن، حداکثر زمان مورد انتظار برای آماده‌سازی یک مدل و حداکثر زمان مورد انتظار برای تکمیل یک اجرا را نشان دهد. برای اطلاعات بیشتر، کیفیت خدمات را ببینید.
  • پشتیبانی از دامنه های حافظه که رابط های تخصیص دهنده را برای بافرهای مدیریت شده توسط راننده فراهم می کنند. این اجازه می دهد تا حافظه های بومی دستگاه را در بین اجراها منتقل کنید، کپی داده های غیر ضروری و تغییر شکل بین اجرای متوالی در همان درایور را متوقف کنید. برای اطلاعات بیشتر، دامنه‌های حافظه را ببینید.

اندروید 10

اندروید 10 NN HAL 1.2 را معرفی می کند که شامل تغییرات قابل توجه زیر است.

  • ساختار Capabilities شامل همه انواع داده‌ها از جمله انواع داده‌های اسکالر است و عملکرد غیرآرامش را با استفاده از یک برداری به جای فیلدهای نام‌گذاری شده نشان می‌دهد.
  • متدهای getVersionString و getType به فریم ورک اجازه می‌دهند تا نوع دستگاه ( DeviceType ) و اطلاعات نسخه را بازیابی کند. به کشف و تخصیص دستگاه مراجعه کنید.
  • متد executeSynchronously به طور پیش فرض برای انجام یک اجرا به صورت همزمان فراخوانی می شود. متد execute_1_2 به فریم ورک می گوید که یک اجرا را به صورت ناهمزمان انجام دهد. اجرا را ببینید.
  • پارامتر MeasureTiming برای executeSynchronously ، execute_1_2 و burst execution مشخص می کند که آیا درایور باید مدت زمان اجرا را اندازه گیری کند یا خیر. نتایج در ساختار Timing گزارش شده است. زمان بندی را ببینید.
  • پشتیبانی از اجراهایی که یک یا چند عملوند خروجی دارای بعد یا رتبه ناشناخته هستند. شکل خروجی را ببینید.
  • پشتیبانی از افزونه های فروشنده، که مجموعه ای از عملیات ها و انواع داده های تعریف شده توسط فروشنده هستند. درایور برنامه های افزودنی پشتیبانی شده را از طریق روش IDevice::getSupportedExtensions گزارش می دهد. به افزونه های فروشنده مراجعه کنید.
  • توانایی یک شی انفجاری برای کنترل مجموعه‌ای از اجرای پشت سر هم با استفاده از صف‌های پیام سریع (FMQ) برای برقراری ارتباط بین فرآیندهای برنامه و درایور و کاهش تأخیر. به اعدام های انفجاری و صف های پیام سریع مراجعه کنید.
  • پشتیبانی از AHardwareBuffer به درایور اجازه می دهد تا بدون کپی کردن داده ها را اجرا کند. AHardwareBuffer را ببینید.
  • پشتیبانی بهبود یافته برای ذخیره سازی مصنوعات کامپایل برای کاهش زمان استفاده برای کامپایل هنگام شروع یک برنامه. به ذخیره سازی کامپایل مراجعه کنید.

اندروید 10 انواع عملوند و عملیات زیر را معرفی می کند.

  • انواع عملوند

    • ANEURALNETWORKS_BOOL
    • ANEURALNETWORKS_FLOAT16
    • ANEURALNETWORKS_TENSOR_BOOL8
    • ANEURALNETWORKS_TENSOR_FLOAT16
    • ANEURALNETWORKS_TENSOR_QUANT16_ASYMM
    • ANEURALNETWORKS_TENSOR_QUANT16_SYMM
    • ANEURALNETWORKS_TENSOR_QUANT8_SYMM
    • ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL
  • عملیات

    • ANEURALNETWORKS_ABS
    • ANEURALNETWORKS_ARGMAX
    • ANEURALNETWORKS_ARGMIN
    • ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM
    • ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM
    • ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN
    • ANEURALNETWORKS_BOX_WITH_NMS_LIMIT
    • ANEURALNETWORKS_CAST
    • ANEURALNETWORKS_CHANNEL_SHUFFLE
    • ANEURALNETWORKS_DETECTION_POSTPROCESSING
    • ANEURALNETWORKS_EQUAL
    • ANEURALNETWORKS_EXP
    • ANEURALNETWORKS_EXPAND_DIMS
    • ANEURALNETWORKS_GATHER
    • ANEURALNETWORKS_GENERATE_PROPOSALS
    • ANEURALNETWORKS_GREATER
    • ANEURALNETWORKS_GREATER_EQUAL
    • ANEURALNETWORKS_GROUPED_CONV_2D
    • ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT
    • ANEURALNETWORKS_INSTANCE_NORMALIZATION
    • ANEURALNETWORKS_LESS
    • ANEURALNETWORKS_LESS_EQUAL
    • ANEURALNETWORKS_LOG
    • ANEURALNETWORKS_LOGICAL_AND
    • ANEURALNETWORKS_LOGICAL_NOT
    • ANEURALNETWORKS_LOGICAL_OR
    • ANEURALNETWORKS_LOG_SOFTMAX
    • ANEURALNETWORKS_MAXIMUM
    • ANEURALNETWORKS_MINIMUM
    • ANEURALNETWORKS_NEG
    • ANEURALNETWORKS_NOT_EQUAL
    • ANEURALNETWORKS_PAD_V2
    • ANEURALNETWORKS_POW
    • ANEURALNETWORKS_PRELU
    • ANEURALNETWORKS_QUANTIZE
    • ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
    • ANEURALNETWORKS_RANDOM_MULTINOMIAL
    • ANEURALNETWORKS_REDUCE_ALL
    • ANEURALNETWORKS_REDUCE_ANY
    • ANEURALNETWORKS_REDUCE_MAX
    • ANEURALNETWORKS_REDUCE_MIN
    • ANEURALNETWORKS_REDUCE_PROD
    • ANEURALNETWORKS_REDUCE_SUM
    • ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
    • ANEURALNETWORKS_ROI_ALIGN
    • ANEURALNETWORKS_ROI_POOLING
    • ANEURALNETWORKS_RSQRT
    • ANEURALNETWORKS_SELECT
    • ANEURALNETWORKS_SIN
    • ANEURALNETWORKS_SLICE
    • ANEURALNETWORKS_SPLIT
    • ANEURALNETWORKS_SQRT
    • ANEURALNETWORKS_TILE
    • ANEURALNETWORKS_TOPK_V2
    • ANEURALNETWORKS_TRANSPOSE_CONV_2D
    • ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
    • ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN

اندروید 10 به‌روزرسانی‌هایی را برای بسیاری از عملیات‌های موجود معرفی می‌کند. به روز رسانی ها عمدتا مربوط به موارد زیر است:

  • پشتیبانی از طرح حافظه NCHW
  • پشتیبانی از تانسورهای با رتبه متفاوت از 4 در عملیات سافت مکس و نرمال سازی
  • پشتیبانی از پیچش های گشاد شده
  • پشتیبانی از ورودی های با کوانتیزه مختلط در ANEURALNETWORKS_CONCATENATION

لیست زیر عملیات‌هایی را نشان می‌دهد که در Android 10 اصلاح شده‌اند. برای جزئیات کامل تغییرات، OperationCode را در مستندات مرجع NNAPI ببینید.

  • ANEURALNETWORKS_ADD
  • ANEURALNETWORKS_AVERAGE_POOL_2D
  • ANEURALNETWORKS_BATCH_TO_SPACE_ND
  • ANEURALNETWORKS_CONCATENATION
  • ANEURALNETWORKS_CONV_2D
  • ANEURALNETWORKS_DEPTHWISE_CONV_2D
  • ANEURALNETWORKS_DEPTH_TO_SPACE
  • ANEURALNETWORKS_DEQUANTIZE
  • ANEURALNETWORKS_DIV
  • ANEURALNETWORKS_FLOOR
  • ANEURALNETWORKS_FULLY_CONNECTED
  • ANEURALNETWORKS_L2_NORMALIZATION
  • ANEURALNETWORKS_L2_POOL_2D
  • ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
  • ANEURALNETWORKS_LOGISTIC
  • ANEURALNETWORKS_LSH_PROJECTION
  • ANEURALNETWORKS_LSTM
  • ANEURALNETWORKS_MAX_POOL_2D
  • ANEURALNETWORKS_MEAN
  • ANEURALNETWORKS_MUL
  • ANEURALNETWORKS_PAD
  • ANEURALNETWORKS_RELU
  • ANEURALNETWORKS_RELU1
  • ANEURALNETWORKS_RELU6
  • ANEURALNETWORKS_RESHAPE
  • ANEURALNETWORKS_RESIZE_BILINEAR
  • ANEURALNETWORKS_RNN
  • ANEURALNETWORKS_ROI_ALIGN
  • ANEURALNETWORKS_SOFTMAX
  • ANEURALNETWORKS_SPACE_TO_BATCH_ND
  • ANEURALNETWORKS_SPACE_TO_DEPTH
  • ANEURALNETWORKS_SQUEEZE
  • ANEURALNETWORKS_STRIDED_SLICE
  • ANEURALNETWORKS_SUB
  • ANEURALNETWORKS_SVDF
  • ANEURALNETWORKS_TANH
  • ANEURALNETWORKS_TRANSPOSE

اندروید 9

NN HAL 1.1 در اندروید 9 معرفی شده است و شامل تغییرات قابل توجه زیر است.

  • IDevice::prepareModel_1_1 شامل یک پارامتر ExecutionPreference است. یک راننده می تواند از این برای تنظیم آماده سازی خود استفاده کند، زیرا بداند که برنامه ترجیح می دهد باتری را ذخیره کند یا در تماس های متوالی سریع مدل را اجرا می کند.
  • نه عملیات جدید اضافه شده است: BATCH_TO_SPACE_ND , DIV , MEAN , PAD , SPACE_TO_BATCH_ND , SQUEEZE , STRIDED_SLICE , SUB , TRANSPOSE .
  • با تنظیم Model.relaxComputationFloat32toFloat16 روی true ، یک برنامه می تواند تعیین کند که محاسبات شناور 32 بیتی را می توان با استفاده از محدوده شناور 16 بیتی و/یا دقت اجرا کرد. ساختار Capabilities دارای یک میدان اضافی است relaxedFloat32toFloat16Performance تا راننده بتواند عملکرد آرام خود را به چارچوب گزارش دهد.

اندروید 8.1

شبکه های عصبی اولیه HAL (1.0) در اندروید 8.1 منتشر شد. برای اطلاعات بیشتر، به /neuralnetworks/1.0/ مراجعه کنید.