التخزين المؤقت للتجميع

اعتبارًا من الإصدار 10 من Android، يوفّر Neural Networks API (NNAPI) وظائف لتمكين تخزين مؤقت لعناصر الترجمة، ما يقلل من الوقت المستغرَق في الترجمة عند بدء أحد التطبيقات. وباستخدام وظيفة التخزين المؤقت هذه، لا إدارة أو مسح الملفات المخزنة مؤقتًا. هذه ميزة اختيارية يمكن تنفيذها باستخدام NN HAL 1.2. لمزيد من المعلومات حول هذه الدالة، الرؤية ANeuralNetworksCompilation_setCaching

يمكن لبرنامج التشغيل أيضًا تنفيذ التخزين المؤقت للتجميع البرمجي بشكل مستقل عن NNAPI. هذا النمط يمكن تنفيذها سواء تم استخدام ميزات التخزين المؤقت لـ NNAPI NDK وHAL أو لا. يوفر AOSP مكتبة من الخدمات منخفضة المستوى (محرك تخزين مؤقت). لمزيد من المعلومات، يُرجى الاطّلاع على تنفيذ محرك تخزين مؤقت.

نظرة عامة على سير العمل

يصف هذا القسم عمليات سير العمل العامة باستخدام ميزة التخزين المؤقت للتجميع تنفيذها.

تم تقديم معلومات ذاكرة التخزين المؤقت ونتيجة ذاكرة التخزين المؤقت

  1. يجتاز التطبيق دليل تخزين مؤقت ومجموع اختباري فريد للنموذج.
  2. يبحث بيئة تشغيل NNAPI عن ملفات ذاكرة التخزين المؤقت بناءً على المجموع الاختباري وتفضيل التنفيذ، ونتيجة التقسيم والعثور على الملفات.
  3. تفتح NNAPI ملفات ذاكرة التخزين المؤقت وتنقل المؤشرات إلى برنامج التشغيل. مع prepareModelFromCache
  4. يُعدّ السائق النموذج مباشرةً من ملفات التخزين المؤقت ويعرض النموذج المعدّ.

معلومات ذاكرة التخزين المؤقت المقدَّمة وعدم توفّر ذاكرة التخزين المؤقت

  1. يجتاز التطبيق مجموعًا اختباريًا فريدًا للنموذج والتخزين المؤقت الدليل.
  2. يبحث وقت تشغيل NNAPI عن ملفات التخزين المؤقت استنادًا إلى المجموع الاختباري وملف ملف التشغيل المفضّل ونتيجة التقسيم، ولا يعثر على ملفات التخزين المؤقت.
  3. ينشئ NNAPI ملفات ذاكرة التخزين المؤقت الفارغة استنادًا إلى القيمة المحصَّلة وإعدادات تنفيذ النموذج المفضّلة وتقسيم الذاكرة، ويفتح ملفات ذاكرة التخزين المؤقت ويُمرِّر المعرّفات والنموذج إلى برنامج التشغيل باستخدام prepareModel_1_2.
  4. يُجمِّع برنامج التشغيل النموذج ويكتب معلومات التخزين المؤقت في ملفات التخزين المؤقت ويُعيد النموذج المُعدّ.

عدم توفّر معلومات حول ذاكرة التخزين المؤقت

  1. يستدعي التطبيق التجميع بدون توفير أي معلومات عن التخزين المؤقت.
  2. لا يعمل التطبيق على تمرير أي شيء مرتبط بالتخزين المؤقت.
  3. يُرسِل وقت تشغيل NNAPI النموذج إلى برنامج التشغيل باستخدام prepareModel_1_2.
  4. يقوم برنامج التشغيل بتجميع النموذج وعرض النموذج المعد.

معلومات ذاكرة التخزين المؤقت

تتكون معلومات التخزين المؤقت التي يتم تقديمها إلى السائق من رمز مؤشرات ملفات ذاكرة التخزين المؤقت.

الرمز المميز

الرمز المميّز هو رمز مميّز لتخزين البيانات مؤقتًا بطول Constant::BYTE_SIZE_OF_CACHE_TOKEN يحدّد النموذج المُعدّ. يتم تقديم الرمز المميّز نفسه عند حفظملف التمهيد باستخدام prepareModel_1_2 واسترداد النموذج المُعدّ باستخدام prepareModelFromCache. على عملاء السائق اختيار رمز مميّز يتسم بمعدل اصطدام منخفض. لا يمكن لبرنامج التشغيل رصد تعارض الرموز المميّزة. تصادم إلى فشل التنفيذ أو إلى عملية تنفيذ ناجحة نتج عنها قيم مخرجات غير صحيحة.

مؤشرات ملفات ذاكرة التخزين المؤقت (نوعان من ملفات ذاكرة التخزين المؤقت)

النوعان من ملفات التخزين المؤقت هما ذاكرة التخزين المؤقت للبيانات وذاكرة التخزين المؤقت للنماذج.

  • ذاكرة التخزين المؤقت للبيانات: تُستخدم للتخزين المؤقت للبيانات الثابتة، بما في ذلك البيانات التي تمت معالجتها مسبقًا والمُحولات الاحتياطية إلى مترابطة. يجب ألا يؤدي تعديل ذاكرة التخزين المؤقت للبيانات إلى أي تأثير أسوأ من إنشاء قيم ناتجة غير صالحة في وقت التنفيذ .
  • ذاكرة التخزين المؤقت للنموذج: تُستخدَم لتخزين البيانات الحسّاسة للأمان، مثل الترميز المُجمَّع القابل للتنفيذ على الآلة بتنسيق الجهاز الثنائي الأصلي. قد يؤدي تعديل على ذاكرة التخزين المؤقت للنموذج إلى التأثير في سلوك تنفيذ برنامج التشغيل، ويمكن لأحد العملاء الضارين الاستفادة من ذلك لتنفيذ إجراءات تتجاوز الإذن الممنوح. وبالتالي، يجب أن يتحقق برنامج التشغيل مما إذا كانت ذاكرة التخزين المؤقت للنموذج قبل إعداد النموذج من ذاكرة التخزين المؤقت. لمزيد من المعلومات راجِع الأمان.

يجب أن يحدد برنامج التشغيل كيفية توزيع معلومات ذاكرة التخزين المؤقت بين الاثنين وأنواع ملفات ذاكرة التخزين المؤقت والإبلاغ عن عدد ملفات ذاكرة التخزين المؤقت اللازمة لكل نوع مع getNumberOfCacheFilesNeeded

يفتح بيئة تشغيل NNAPI دائمًا مؤشرات ملفات ذاكرة التخزين المؤقت التي تتضمّن كلاً من القراءة والكتابة إذن.

الأمان

أثناء التخزين المؤقت للتجميع، قد تحتوي ذاكرة التخزين المؤقت للنموذج على بيانات حساسة للأمان مثل كرمز برمجي جهاز قابل للتنفيذ مجمّع بالتنسيق الثنائي الأصلي للجهاز. إذا لم يكن كذلك محمي بشكل صحيح، فإن تعديل ذاكرة التخزين المؤقت للطراز قد يؤثر على تخزين والتنفيذ. لأنّه يتم تخزين محتوى ذاكرة التخزين المؤقت في التطبيق الدليل، تكون ملفات ذاكرة التخزين المؤقت قابلة للتعديل بواسطة العميل. قد يؤدي عيوب العميل إلى تلف ذاكرة التخزين المؤقت عن طريق الخطأ، ويمكن للعميل الضار استخدام هذا عن قصد لتنفيذ رمز غير تم التحقّق منه على الجهاز. قد يشير ذلك إلى مشكلة أمنية حسب خصائص الجهاز. وبالتالي، يجب أن يكون السائق قادرًا على اكتشاف احتمال تلف في ذاكرة التخزين المؤقت للنموذج قبل إعداد النموذج من ذاكرة التخزين المؤقت.

تتمثل إحدى طرق القيام بذلك في أن يحافظ السائق على خريطة بدءًا من الرمز المميز التجزئة المشفرة لذاكرة التخزين المؤقت للنموذج. يمكن لبرنامج التشغيل تخزين الرمز المميّز والرمز المميّز لملف التخزين المؤقت للنموذج عند حفظ عملية التجميع في ذاكرة التخزين المؤقت. يتحقّق برنامج التشغيل من قيمة التجزئة الجديدة لمخزّن النموذج المؤقت باستخدام الرمز المميّز المسجّل وزوج التجزئة عند استرداد الحِزمة من المخزّن المؤقت. يجب أن يظلّ هذا الربط ثابتًا عند إعادة تشغيل النظام. يمكن للسائق استخدام خدمة ملف تخزين مفاتيح Android، وهي مكتبة الأدوات المساعدة في framework/ml/nn/driver/cache, أو أي آلية أخرى مناسبة لتنفيذ مدير الخرائط. عند السائق يجب إعادة إعداد مدير التعيين هذا لمنع إعداد ذاكرة التخزين المؤقت من إصدار سابق.

لمنع وقت التحقّق من وقت الاستخدام (TOCTOU)، يجب على برنامج التشغيل حساب التجزئة المسجلة قبل الحفظ في وتحسب التجزئة الجديدة بعد نسخ محتوى الملف إلى قسم المورد الاحتياطي.

يوضّح رمز البرنامج النموذجي هذا كيفية تنفيذ هذا المنطق.

bool saveToCache(const sp<V1_2::IPreparedModel> preparedModel,
                 const hidl_vec<hidl_handle>& modelFds, const hidl_vec<hidl_handle>& dataFds,
                 const HidlToken& token) {
    // Serialize the prepared model to internal buffers.
    auto buffers = serialize(preparedModel);

    // This implementation detail is important: the cache hash must be computed from internal
    // buffers instead of cache files to prevent time-of-check to time-of-use (TOCTOU) attacks.
    auto hash = computeHash(buffers);

    // Store the {token, hash} pair to a mapping manager that is persistent across reboots.
    CacheManager::get()->store(token, hash);

    // Write the cache contents from internal buffers to cache files.
    return writeToFds(buffers, modelFds, dataFds);
}

sp<V1_2::IPreparedModel> prepareFromCache(const hidl_vec<hidl_handle>& modelFds,
                                          const hidl_vec<hidl_handle>& dataFds,
                                          const HidlToken& token) {
    // Copy the cache contents from cache files to internal buffers.
    auto buffers = readFromFds(modelFds, dataFds);

    // This implementation detail is important: the cache hash must be computed from internal
    // buffers instead of cache files to prevent time-of-check to time-of-use (TOCTOU) attacks.
    auto hash = computeHash(buffers);

    // Validate the {token, hash} pair by a mapping manager that is persistent across reboots.
    if (CacheManager::get()->validate(token, hash)) {
        // Retrieve the prepared model from internal buffers.
        return deserialize<V1_2::IPreparedModel>(buffers);
    } else {
        return nullptr;
    }
}

حالات الاستخدام المتقدّمة

في بعض حالات الاستخدام المتقدمة، يحتاج السائق إلى الوصول إلى محتوى ذاكرة التخزين المؤقت (قراءة أو كتابة) بعد مكالمة التجميع. تشمل أمثلة حالات الاستخدام ما يلي:

  • تجميع المحتوى في الوقت المناسب: يتأخّر الفيديو التجميعي حتى والتنفيذ الأول.
  • تجميع الفيديو المجمّع من عدة مراحل: يتم في البداية تجميع المحتوى بشكل سريع. ويتم تنفيذ تجميع اختياري محسّن في وقت لاحق اعتمادًا على تكرار الاستخدام.

للوصول إلى محتوى ذاكرة التخزين المؤقت (قراءة أو كتابة) بعد المكالمة التجميعية، تأكد من أن السائق:

  • تكرار عناصر تحكّم الملفات أثناء استدعاء prepareModel_1_2 أو prepareModelFromCache وقراءة/تعديل محتوى ملف التخزين المؤقت في وقت لاحق
  • تُنفِّذ منطق قفل الملف خارج طلب الترجمة العادي لمنع حدوث عملية كتابة بشكل متزامن مع عملية قراءة أو عملية كتابة أخرى.

استخدام محرّك تخزين مؤقت

بالإضافة إلى واجهة التخزين المؤقت للتجميعات NN HAL 1.2، يمكنك أيضًا العثور على للتخزين المؤقت في مكتبة frameworks/ml/nn/driver/cache الدليل. تشير رسالة الأشكال البيانية nnCache يحتوي دليل فرعي على رمز تخزين ثابت لبرنامج التشغيل لينفّذه. التخزين المؤقت للتجميع بدون استخدام ميزات التخزين المؤقت في NNAPI. يمكن تنفيذ هذا النوع من التخزين المؤقت للترجمة مع أي إصدار من NN HAL. إذا اختار العميل تنفيذ ميزة التخزين المؤقت غير المتصلة بواجهة HAL، يتحمّل العميل مسؤولية تحرير العناصر المخزّنة مؤقتًا عندما لا تكون مطلوبة.