Derlemeyi önbelleğe alma

Neural Networks API (NNAPI), Android 10'dan itibaren derleme yapılarının önbelleğe alınmasını destekleyen işlevler sağlar. Bu da uygulama başlatıldığında derleme için harcanan süreyi kısaltır. Sürücü, bu önbelleğe alma işlevini kullandığında önbelleğe alınan dosyaları yönetmesi veya temizlemesi gerekmez. Bu, NN HAL 1.2 ile uygulanabilen isteğe bağlı bir özelliktir. Bu işlev hakkında daha fazla bilgi için ANeuralNetworksCompilation_setCaching bölümüne bakın.

Sürücü, NNAPI'den bağımsız olarak derleme önbelleğe almayı da uygulayabilir. Bu, NNAPI NDK ve HAL önbelleğe alma özellikleri kullanılsın veya kullanılmasın uygulanabilir. AOSP, alt düzey bir yardımcı program kitaplığı (önbellek motoru) sağlar. Daha fazla bilgi için Önbelleğe alma motoru uygulama başlıklı makaleyi inceleyin.

İş akışına genel bakış

Bu bölümde, derleme önbelleğe alma özelliğinin uygulandığı genel iş akışları açıklanmaktadır.

Önbellek bilgileri sağlanıyor ve önbellek isabeti

  1. Uygulama, bir önbelleğe alma dizini ve modele özgü bir sağlama toplamı iletmelidir.
  2. NNAPI çalışma zamanı; sağlama toplamına, yürütme tercihine ve bölümlendirme sonucuna göre önbellek dosyalarını arar ve dosyaları bulur.
  3. NNAPI, önbellek dosyalarını açar ve herkese açık kullanıcı adlarını prepareModelFromCache ile sürücüye iletir.
  4. Sürücü, modeli doğrudan önbellek dosyalarından hazırlar ve hazırlanan modeli geri gönderir.

Sağlanan önbellek bilgileri ve önbelleğe alma hatası

  1. Uygulama, modele özel bir sağlama toplamı ve bir önbelleğe alma dizini iletir.
  2. NNAPI çalışma zamanı; sağlama toplamına, yürütme tercihine ve bölümlendirme sonucuna göre önbelleğe alma dosyalarını arar ve önbellek dosyalarını bulmaz.
  3. NNAPI; denetim toplamına, yürütme tercihine ve bölümlendirmeye göre boş önbellek dosyaları oluşturur, önbellek dosyalarını açar ve işleyiciler ile modeli prepareModel_1_2 kullanarak sürücüye iletir.
  4. Sürücü modeli derleyip önbelleğe alma bilgilerini önbelleğe dosyalarına yazar ve hazırlanan modeli döndürür.

Önbellek bilgileri sağlanmadı

  1. Uygulama, herhangi bir önbelleğe alma bilgisi sağlamadan derlemeyi çağırıyor.
  2. Uygulama, önbelleğe alma ile ilgili hiçbir şey iletmiyor.
  3. NNAPI çalışma zamanı, modeli prepareModel_1_2 ile sürücüye iletir.
  4. Sürücü, modeli derler ve hazırlanan modeli döndürür.

Önbellek bilgileri

Sürücüye sağlanan önbelleğe alma bilgileri, bir jeton ve önbelleğe alma dosyası tutamaçlarından oluşur.

Jeton

Jeton, hazırlanmış modeli tanımlayan Constant::BYTE_SIZE_OF_CACHE_TOKEN uzunluğunda bir önbelleğe alma jetonudur. Önbellek dosyalarını prepareModel_1_2 ile kaydederken ve hazırlanan modeli prepareModelFromCache ile alırken de aynı jeton sağlanır. Sürücünün istemcisi düşük çakışma oranına sahip bir jeton seçmelidir. Sürücü, jeton çakışmasını algılayamaz. Çakışma, başarısız bir yürütme veya yanlış çıkış değerleri üreten başarılı bir yürütmeyle sonuçlanır.

Önbelleğe alınmış dosya tutamaçları (iki tür önbelleğe alınmış dosya)

İki tür önbellek dosyası, veri önbelleği ve model önbellek'tir.

  • Veri önbelleği: Önceden işlenmiş ve dönüştürülmüş tenör arabellekleri dahil olmak üzere sabit verileri önbelleğe almak için kullanın. Veri önbelleğinde yapılan bir değişiklik, yürütme sırasında kötü çıkış değerleri oluşturmaktan daha kötü bir etkiye yol açmamalıdır.
  • Model önbellek: Derlenmiş yürütülebilir makine kodu gibi güvenlik açısından hassas verileri cihazın yerel ikili program biçiminde önbelleğe almak için kullanın. Model önbelleğinde yapılan bir değişiklik, sürücünün yürütme davranışını etkileyebilir ve kötü amaçlı bir istemci, verilen iznin ötesinde çalışmak için bunu kullanabilir. Bu nedenle sürücü, modeli önbellekten hazırlamadan önce model önbelleğinin bozuk olup olmadığını kontrol etmelidir. Daha fazla bilgi için Güvenlik başlıklı makaleyi inceleyin.

Sürücü, önbellek bilgilerinin iki tür önbellek dosyası arasında nasıl dağıtılacağına karar vermelidir ve her tür için kaç önbellek dosyasına ihtiyaç duyduğunu getNumberOfCacheFilesNeeded ile bildirmelidir.

NNAPI çalışma zamanı, önbellek dosya tutamaçlarını her zaman hem okuma hem de yazma izniyle açar.

Güvenlik

Derleme önbelleğe alma işleminde model önbelleği, cihazın yerel ikili program biçiminde derlenmiş yürütülebilir makine kodu gibi güvenlik açısından hassas veriler içerebilir. Doğru şekilde korunmazsa model önbelleğiyle ilgili bir değişiklik, sürücünün yürütme davranışını etkileyebilir. Önbellek içerikleri uygulama dizininde depolandığından, önbellek dosyaları istemci tarafından değiştirilebilir. Hatalı bir istemci, önbelleği yanlışlıkla bozabilir ve kötü amaçlı bir istemci, cihazda doğrulanmamış kod yürütmek için kasıtlı olarak bundan yararlanabilir. Cihazın özelliklerine bağlı olarak bu bir güvenlik sorunu olabilir. Bu nedenle, sürücü, modeli önbellekten hazırlamadan önce olası model önbelleği bozulmasını algılayabilmelidir.

Bunu yapmanın bir yolu, sürücünün jetondan model önbelleğinin kriptografik karmasına kadar bir haritayı muhafaza etmesidir. Sürücü, derlemeyi önbelleğe kaydederken jetonu ve model önbelleğinizin karmasını saklayabilir. Sürücü, derlemeyi önbellekten alırken model önbelleğini yeni karmasını kaydedilen jeton ve karma çiftiyle kontrol eder. Bu eşleme, sistem yeniden başlatma işlemleri boyunca kalıcı olmalıdır. Sürücü, Android anahtar deposu hizmetini, framework/ml/nn/driver/cache'daki yardımcı program kitaplığını veya eşleme yöneticisi uygulamak için uygun başka bir mekanizmayı kullanabilir. Sürücü güncellemesinin ardından, önbellek dosyalarının önceki bir sürümden hazırlanmasını önlemek için bu eşleme yöneticisinin yeniden başlatılması gerekir.

Kontrol zamanı ile kullanım zamanı (TOCTOU) saldırılarını önlemek için sürücünün, dosyaya kaydetmeden önce kaydedilen karma oluşturma işlemini ve dosya içeriğini dahili bir arabelleğe kopyaladıktan sonra yeni karma oluşturma işlemini yapması gerekir.

Bu örnek kodda bu mantığın nasıl uygulanacağı gösterilmektedir.

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;
    }
}

Gelişmiş kullanım alanları

Bazı gelişmiş kullanım alanlarında, sürücülerin derleme çağrısından sonra önbellek içeriğine erişmesi (okuma veya yazma) gerekir. Kullanım alanlarına şunlar örnek verilebilir:

  • Tam zamanında derleme: Derleme, ilk yürütmeye kadar ertelenir.
  • Çok aşamalı derleme: Başlangıçta hızlı bir derleme gerçekleştirilir. Daha sonra kullanım sıklığına bağlı olarak isteğe bağlı olarak optimize edilmiş bir derleme gerçekleştirilir.

Derleme çağrısından sonra önbellek içeriğine (okuma veya yazma) erişmek için sürücünün aşağıdakileri sağladığından emin olun:

  • prepareModel_1_2 veya prepareModelFromCache çağrılırken dosya işlemelerini kopyalar ve önbellek içeriğini daha sonra okur/günceller.
  • Bir okuma veya başka bir yazma işlemiyle eş zamanlı olarak bir yazma işleminin gerçekleşmesini önlemek için normal derleme çağrısının dışında dosya kilitleme mantığını uygular.

Önbelleğe alma motoru uygulama

frameworks/ml/nn/driver/cache dizininde NN HAL 1.2 derleme önbelleğe alma arayüzüne ek olarak bir önbelleğe alma yardımcı programı kitaplığı da bulunur. nnCache alt dizini, sürücünün NNAPI önbelleğe alma özelliklerini kullanmadan derleme önbelleğe alma uygulaması için kalıcı depolama alanı kodu içerir. Bu derleme önbelleğe alma biçimi, NN HAL'nin herhangi bir sürümüyle uygulanabilir. Sürücü, HAL arayüzüyle bağlantısı kesilen önbelleğe almayı uygulamayı seçerse sürücü, artık ihtiyaç duyulmadığında önbelleğe alınan yapıları serbest bırakmaktan sorumludur.