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 işlem, NNAPI NDK ve HAL önbelleğe alma özelliklerinin kullanılıp kullanılmasa da uygulanabilir. AOSP, alt düzey bir yardımcı program kitaplığı (önbellek motoru) sağlar. Daha fazla bilgi için Önbelleğe alma motoru uygulama bölümüne bakın.

İş 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 özel bir sağlama toplamı iletir.
  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.

Önbellek bilgileri sağlandı ve önbellekte yok

  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 derler, önbelleğe alma bilgilerini önbellek 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 almayla ilgili hiçbir şey iletmez.
  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ı işleyicilerinden oluşur.

Jeton

Jeton, hazırlanan modeli tanımlayan Constant::BYTE_SIZE_OF_CACHE_TOKEN uzunluğundaki 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. Bir çakışma, yürütmenin başarısız olmasına veya yanlış çıkış değerleri üreten başarılı bir yürütmeye yol açar.

Önbellek dosyası işleyicileri (iki tür önbellek dosyası)

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

  • Veri önbelleği: Önceden işlenmiş ve dönüştürülmüş tensör arabellekleri dahil 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 bölümüne bakın.

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

NNAPI çalışma zamanı, önbellek dosyası tutma yerlerini 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. Düzgün ş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 ve kötü amaçlı bir istemci, cihazda doğrulanmamış kodu yürütmek için bunu bilinçli olarak kullanabilir. Cihazın özelliklerine bağlı olarak bu bir güvenlik sorunu olabilir. Bu nedenle sürücü, modeli önbellekten hazırlamadan önce olası model önbellek 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ğinin karmasını depolayabilir. Sürücü, derlemeyi önbellekten alırken kayıtlı jeton ve karma çiftiyle model önbelleğinin yeni karmasını 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 bir eşleme yöneticisini 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.

Kullanım zamanına kadar kontrol zamanı (TOCTOU) saldırılarını önlemek için sürücünün dosyaya kaydetmeden önce kaydedilen karmayı hesaplaması ve dosya içeriğini dahili bir arabelleğe kopyaladıktan sonra yeni karmayı 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ı

Bazı gelişmiş kullanım durumlarında sürücünün, derleme çağrısından sonra önbellek içeriğine (okuma veya yazma) erişmesi 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:

  • 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.