সংকলন ক্যাশিং

অ্যান্ড্রয়েড 10 থেকে, নিউরাল নেটওয়ার্ক এপিআই (এনএনএপিআই) কম্পাইলেশন আর্টিফ্যাক্টের ক্যাশিং সমর্থন করার জন্য ফাংশন সরবরাহ করে, যা একটি অ্যাপ শুরু হলে সংকলনের জন্য ব্যবহৃত সময়কে কমিয়ে দেয়। এই ক্যাশিং কার্যকারিতা ব্যবহার করে, ড্রাইভারকে ক্যাশে করা ফাইলগুলি পরিচালনা বা পরিষ্কার করার দরকার নেই। এটি একটি ঐচ্ছিক বৈশিষ্ট্য যা NN HAL 1.2 এর সাথে প্রয়োগ করা যেতে পারে। এই ফাংশন সম্পর্কে আরও তথ্যের জন্য, ANeuralNetworksCompilation_setCaching দেখুন।

ড্রাইভার এনএনএপিআই-এর থেকে স্বাধীন কম্পাইলেশন ক্যাশিং বাস্তবায়ন করতে পারে। এনএনএপিআই এনডিকে এবং এইচএএল ক্যাশিং বৈশিষ্ট্যগুলি ব্যবহার করা হোক বা না হোক এটি প্রয়োগ করা যেতে পারে। 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 এর একটি ক্যাশিং টোকেন যা প্রস্তুতকৃত মডেলটিকে চিহ্নিত করে৷ prepareModelFromCache prepareModel_1_2 এর সাথে ক্যাশে ফাইলগুলি সংরক্ষণ করার সময় এবং প্রস্তুত মডেলটি প্রস্তুত মডেলটি পুনরুদ্ধার করার সময় একই টোকেন প্রদান করা হয়। ড্রাইভারের ক্লায়েন্টকে একটি টোকেন বেছে নেওয়া উচিত যাতে সংঘর্ষের হার কম থাকে। ড্রাইভার একটি টোকেন সংঘর্ষ সনাক্ত করতে পারে না। একটি সংঘর্ষের ফলে একটি ব্যর্থ মৃত্যুদন্ড বা একটি সফল মৃত্যুদন্ড যা ভুল আউটপুট মান তৈরি করে।

ক্যাশে ফাইল হ্যান্ডেল (দুই ধরনের ক্যাশে ফাইল)

দুই ধরনের ক্যাশে ফাইল হল ডেটা ক্যাশে এবং মডেল ক্যাশে

  • ডেটা ক্যাশে: প্রিপ্রসেসড এবং ট্রান্সফর্মড টেনসর বাফার সহ ধ্রুবক ডেটা ক্যাশ করার জন্য ব্যবহার করুন। ডাটা ক্যাশে পরিবর্তনের ফলে এক্সিকিউশনের সময় খারাপ আউটপুট মান জেনারেট করার চেয়ে খারাপ কোনো প্রভাব হওয়া উচিত নয়।
  • মডেল ক্যাশে: ডিভাইসের নেটিভ বাইনারি ফর্ম্যাটে কম্পাইল করা এক্সিকিউটেবল মেশিন কোডের মতো নিরাপত্তা-সংবেদনশীল ডেটা ক্যাশ করার জন্য ব্যবহার করুন। মডেল ক্যাশে একটি পরিবর্তন ড্রাইভারের মৃত্যুদন্ড আচরণ প্রভাবিত করতে পারে, এবং একটি দূষিত ক্লায়েন্ট মঞ্জুর করা অনুমতির বাইরে চালানোর জন্য এটি ব্যবহার করতে পারে। এইভাবে, ক্যাশে থেকে মডেল প্রস্তুত করার আগে ড্রাইভারকে অবশ্যই মডেল ক্যাশে নষ্ট হয়েছে কিনা তা পরীক্ষা করতে হবে। আরও তথ্যের জন্য, নিরাপত্তা দেখুন।

দুই ধরনের ক্যাশে ফাইলের মধ্যে ক্যাশে তথ্য কীভাবে বিতরণ করা হবে তা ড্রাইভারকে অবশ্যই সিদ্ধান্ত নিতে হবে এবং প্রতিটি প্রকারের জন্য কতগুলি ক্যাশে ফাইল প্রয়োজন getNumberOfCacheFilesNeeded এর সাথে রিপোর্ট করতে হবে।

NNAPI রানটাইম সর্বদা ক্যাশে ফাইল হ্যান্ডেলগুলি পড়া এবং লেখার উভয় অনুমতির সাথে খোলে।

নিরাপত্তা

কম্পাইলেশন ক্যাশে, মডেল ক্যাশে ডিভাইসের নেটিভ বাইনারি ফর্ম্যাটে কম্পাইল করা এক্সিকিউটেবল মেশিন কোডের মতো নিরাপত্তা-সংবেদনশীল ডেটা থাকতে পারে। সঠিকভাবে সুরক্ষিত না হলে, মডেল ক্যাশে একটি পরিবর্তন ড্রাইভারের কার্যকর আচরণ প্রভাবিত করতে পারে। যেহেতু ক্যাশে বিষয়বস্তু অ্যাপ ডিরেক্টরিতে সংরক্ষণ করা হয়, ক্যাশে ফাইলগুলি ক্লায়েন্ট দ্বারা পরিবর্তনযোগ্য। একটি বগি ক্লায়েন্ট ঘটনাক্রমে ক্যাশে দূষিত করতে পারে, এবং একটি দূষিত ক্লায়েন্ট ইচ্ছাকৃতভাবে ডিভাইসে অযাচাইকৃত কোড চালানোর জন্য এটি ব্যবহার করতে পারে। ডিভাইসের বৈশিষ্ট্যের উপর নির্ভর করে, এটি একটি নিরাপত্তা সমস্যা হতে পারে। এইভাবে, ড্রাইভার ক্যাশে থেকে মডেল প্রস্তুত করার আগে সম্ভাব্য মডেল ক্যাশে দুর্নীতি সনাক্ত করতে সক্ষম হতে হবে।

এটি করার একটি উপায় হল ড্রাইভারের জন্য টোকেন থেকে মডেল ক্যাশের একটি ক্রিপ্টোগ্রাফিক হ্যাশে একটি মানচিত্র বজায় রাখা। কম্পাইলেশন ক্যাশে সংরক্ষণ করার সময় ড্রাইভার তার মডেল ক্যাশের টোকেন এবং হ্যাশ সংরক্ষণ করতে পারে। ড্রাইভার ক্যাশে থেকে সংকলন পুনরুদ্ধার করার সময় রেকর্ড করা টোকেন এবং হ্যাশ জোড়া দিয়ে মডেল ক্যাশের নতুন হ্যাশ পরীক্ষা করে। এই ম্যাপিং সিস্টেম রিবুট জুড়ে স্থায়ী হওয়া উচিত। ড্রাইভার অ্যান্ড্রয়েড কীস্টোর পরিষেবা , 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 ডিরেক্টরিতে একটি ক্যাশিং ইউটিলিটি লাইব্রেরিও খুঁজে পেতে পারেন। NNAPI ক্যাশিং বৈশিষ্ট্যগুলি ব্যবহার না করেই কম্পাইলেশন ক্যাশিং বাস্তবায়নের জন্য nnCache সাবডিরেক্টরিতে ড্রাইভারের জন্য স্থায়ী স্টোরেজ কোড রয়েছে। কম্পাইলেশন ক্যাশিংয়ের এই ফর্মটি NN HAL-এর যেকোনো সংস্করণের সাথে প্রয়োগ করা যেতে পারে। ড্রাইভার যদি HAL ইন্টারফেস থেকে সংযোগ বিচ্ছিন্ন করা ক্যাশিং প্রয়োগ করতে বেছে নেয়, ড্রাইভার ক্যাশে করা আর্টিফ্যাক্টগুলিকে মুক্ত করার জন্য দায়ী যখন সেগুলির আর প্রয়োজন নেই।