Derleme önbelleğe alma

Android 10'dan itibaren Neural Networks API (NNAPI), derleme yapıtlarının önbelleğe alınmasını destekleyen işlevler sunar. Bu işlevler, bir uygulama başlatıldığında derleme için kullanılan süreyi kısaltır. Bu önbelleğe alma işlevini kullanan sürücünün, ö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 sayfasına 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 ya da kullanılmasın uygulanabilir. AOSP, alt düzey bir yardımcı program kitaplığı (önbelleğe alma 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ğiyle ilgili genel iş akışları açıklanmaktadır.

Önbellek bilgileri sağlandı ve önbellek isabeti gerçekleşti

  1. Uygulama, modele özgü bir önbelleğe alma dizininden ve sağlama toplamından geçmelidir.
  2. NNAPI çalışma zamanı, sağlama toplamına, yürütme tercihine ve bölümleme sonucuna göre önbellek dosyalarını arar ve dosyaları bulur.
  3. NNAPI, önbellek dosyalarını açar ve tutma yerlerini prepareModelFromCache ile sürücüye iletir.
  4. Sürücü, modeli doğrudan önbellek dosyalarından hazırlar ve hazırlanan modeli döndürür.

Önbellek bilgisi sağlandı ve önbellekte yok

  1. Uygulama, modele özgü bir sağlama toplaması ve bir önbelleğe alma dizininden geçer.
  2. NNAPI çalışma zamanı, önbelleğe alma dosyalarını sağlama toplamı, yürütme tercihi ve bölümleme sonucuna göre arar ancak önbellek dosyalarını bulamaz.
  3. NNAPI, sağlama toplamına, yürütme tercihine ve bölümlendirmeye göre boş önbellek dosyaları oluşturur, önbellek dosyalarını açar ve tutamaçları ile modeli prepareModel_1_2 ile sürücüye iletir.
  4. Sürücü, modeli derler, önbelleğe alma bilgilerini önbellek dosyalarına yazar ve hazırlanan modeli döndürür.

Önbellek bilgisi 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 önbellek 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ı prepareModel_1_2 ile kaydedilirken ve hazırlanmış model prepareModelFromCache ile alınırken aynı jeton sağlanır. Sürücünün istemcisi, düşük çarpışma oranına sahip bir jeton seçmelidir. Sürücü, jeton çarpışmasını algılayamıyor. Çakışma, yürütmenin başarısız olmasına veya yanlış çıkış değerleri üreten başarılı bir yürütmeye neden olur.

Önbellek dosyası tutma yerleri (iki tür önbellek dosyası)

İki tür önbellek dosyası vardır: veri önbelleği ve model önbelleği.

  • Veri önbelleği: Önceden işlenmiş ve dönüştürülmüş tensör arabellekleri de dahil olmak üzere sabit verileri önbelleğe almak için kullanılır. 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 neden olmamalıdır.
  • Model önbelleği: Cihazın yerel ikili biçiminde derlenmiş yürütülebilir makine kodu gibi güvenliğe duyarlı verileri önbelleğe almak için kullanılır. 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 yürütme yapmak için bundan yararlanabilir. Bu nedenle, sürücü modeli önbellekten hazırlamadan önce model önbelleğinin bozulup bozulmadığı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 vermeli ve her tür için kaç önbellek dosyasına ihtiyacı olduğunu getNumberOfCacheFilesNeeded ile bildirmelidir.

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

Güvenlik

Derleme önbelleğe alma işleminde, model önbelleği güvenlik açısından hassas veriler içerebilir. Örneğin, cihazın yerel ikili biçiminde derlenmiş yürütülebilir makine kodu. Model önbelleği uygun şekilde korunmazsa model önbelleğinde yapılan 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. Kötü amaçlı bir istemci ise cihazda doğrulanmamış kod yürütmek için bunu kasıtlı olarak kullanabilir. Cihazın özelliklerine bağlı olarak bu durum 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 bir harita oluşturmasını sağlamaktır. Sürücü, derlemeyi önbelleğe kaydederken jetonu ve model önbelleğinin karma değerini saklayabilir. Sürücü, derlemeyi önbellekten alırken model önbelleğinin yeni karmasını kayıtlı jeton ve karma çiftiyle karşılaştırır. Bu eşleme, sistem yeniden başlatıldığında da geçerli olmalıdır. Sürücü, eşleme yöneticisi uygulamak için Android anahtar deposu hizmetini, framework/ml/nn/driver/cache içindeki yardımcı kitaplığı veya uygun başka bir mekanizmayı kullanabilir. Sürücü güncellendikten sonra, önceki bir sürümden önbellek dosyalarının hazırlanmasını önlemek için bu eşleme yöneticisi yeniden başlatılmalıdır.

Kontrol zamanından kullanım zamanına (TOCTOU) saldırılarını önlemek için sürücünün, dosyaya kaydetmeden önce kaydedilen karma değerini hesaplaması ve dosya içeriğini dahili bir arabelleğe kopyaladıktan sonra yeni karma değerini hesaplaması gerekir.

Bu örnek kod, bu mantığın nasıl uygulanacağını gösterir.

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ı

Belirli gelişmiş kullanım alanlarında, derleme çağrısından sonra sürücünün önbellek içeriğine erişmesi (okuma veya yazma) gerekir. Kullanım alanı örnekleri:

  • 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. Kullanım sıklığına bağlı olarak daha sonra isteğe bağlı optimize edilmiş bir derleme gerçekleştirilir.

Derleme çağrısından sonra önbelleğe alınmış içeriğe erişmek (okuma veya yazma) için sürücünün aşağıdakileri yaptığından emin olun:

  • prepareModel_1_2 veya prepareModelFromCache çağrılırken dosya tutamaçlarını kopyalar ve daha sonra önbellek içeriğini okur/günceller.
  • Okuma veya başka bir yazma işlemiyle eşzamanlı olarak 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

NN HAL 1.2 derleme önbelleğe alma arayüzüne ek olarak, frameworks/ml/nn/driver/cache dizininde bir önbelleğe alma yardımcı programı kitaplığı da bulabilirsiniz. nnCache alt dizini, sürücünün NNAPI önbelleğe alma özelliklerini kullanmadan derleme önbelleğe almayı uygulaması için kalıcı depolama 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ünden bağımsız olarak önbelleğe almayı uygulamayı seçerse önbelleğe alınan yapıtlar artık gerekli olmadığında bunları serbest bırakmak sürücünün sorumluluğundadır.