Driver API per reti neurali

Questa pagina fornisce una panoramica su come implementare un driver Neural Networks API (NNAPI). Per ulteriori dettagli, vedere la documentazione trova nei file di definizione HAL in hardware/interfaces/neuralnetworks . Un'implementazione driver di esempio è in frameworks/ml/nn/driver/sample .

Per ulteriori informazioni sul API Reti Neurali, vedere Reti Neurali API .

Reti neurali HAL

Il Neural Networks (NN) HAL definisce un'astrazione dei vari dispositivi, come unità di elaborazione grafica (GPU) e processori di segnali digitali (DSP), pari a un prodotto (ad esempio, un telefono o tablet). I driver per questi dispositivi devono essere conformi a NN HAL. L'interfaccia è specificata nel file di definizione HAL in hardware/interfaces/neuralnetworks .

Il flusso generale dell'interfaccia tra il framework e un driver è illustrato nella figura 1.

Flusso di reti neurali

Flusso Figura 1. Reti Neurali

Inizializzazione

Al di inizializzazione, il quadro interroga il driver per le sue capacità utilizzando IDevice::getCapabilities_1_3 . Il @1.3::Capabilities struttura include tutti i tipi di dati e rappresenta prestazioni nonrelaxed utilizzando un vettore.

Per determinare come allocare i calcoli ai dispositivi disponibili, il framework utilizza le capacità per comprendere la velocità e l'efficienza energetica con cui ciascun driver può eseguire un'esecuzione. Per fornire queste informazioni, il driver deve fornire numeri di prestazioni standardizzati basati sull'esecuzione dei carichi di lavoro di riferimento.

Per determinare i valori che il driver restituisce in risposta a IDevice::getCapabilities_1_3 , utilizzare l'applicazione di riferimento NNAPI per misurare le prestazioni per i corrispondenti tipi di dati. Il MobileNet v1 e v2, asr_float e tts_float modelli sono raccomandati per la misurazione delle prestazioni per i valori in virgola mobile a 32 bit e la MobileNet v1 e v2 quantizzati modelli sono raccomandati per 8 bit valori quantizzati. Per ulteriori informazioni, consultare Macchina Android Learning Test Suite .

In Android 9 e inferiore, la Capabilities struttura comprende informazioni sulle prestazioni del driver solo per punto e tensori quantizzati galleggianti e non comprende i tipi di dati scalari.

Come parte del processo di inizializzazione, il quadro può interrogare ulteriori informazioni, utilizzando IDevice::getType , IDevice::getVersionString , IDevice:getSupportedExtensions , e IDevice::getNumberOfCacheFilesNeeded .

Tra i riavvii del prodotto, il framework prevede che tutte le query descritte in questa sezione riportino sempre gli stessi valori per un determinato driver. In caso contrario, un'app che utilizza quel driver potrebbe mostrare prestazioni ridotte o comportamenti non corretti.

Compilazione

Il framework determina quali dispositivi usare quando riceve una richiesta da un'app. In Android 10, le app possono rilevare e specificare i dispositivi da cui il framework sceglie. Per ulteriori informazioni, vedere dispositivo Scoperta e assegnazione .

Al momento della compilazione del modello, il quadro invia il modello per ogni driver candidato chiamando IDevice::getSupportedOperations_1_3 . Ogni driver restituisce un array di booleani che indica quali operazioni del modello sono supportate. Un driver può determinare che non può supportare una determinata operazione per una serie di motivi. Per esempio:

  • Il driver non supporta il tipo di dati.
  • Il driver supporta solo operazioni con parametri di input specifici. Ad esempio, un driver potrebbe supportare operazioni di convoluzione 3x3 e 5x5, ma non 7x7.
  • Il driver ha vincoli di memoria che gli impediscono di gestire grafici o input di grandi dimensioni.

Durante la compilazione, l'ingresso, uscita e operandi interne del modello, come descritto in OperandLifeTime , possono avere dimensioni sconosciute o rango. Per ulteriori informazioni, vedere la forma di uscita .

Il quadro istruisce ogni driver selezionato per prepararsi ad eseguire un sottoinsieme del modello chiamando IDevice::prepareModel_1_3 . Ogni driver quindi compila il suo sottoinsieme. Ad esempio, un conducente potrebbe generare codice o creare una copia riordinata dei pesi. Poiché può trascorrere una quantità significativa di tempo tra la compilazione del modello e l'esecuzione delle richieste, durante la compilazione non dovrebbero essere assegnate risorse come grandi blocchi di memoria del dispositivo.

In caso di successo, il driver restituisce un @1.3::IPreparedModel maniglia. Se il driver restituisce un codice di errore durante la preparazione del suo sottoinsieme del modello, il framework esegue l'intero modello sulla CPU.

Per ridurre il tempo utilizzato per la compilazione all'avvio di un'app, un driver può memorizzare nella cache gli artefatti di compilazione. Per ulteriori informazioni, vedere Compilazione Caching .

Esecuzione

Quando un'applicazione chiede al quadro per eseguire una richiesta, il framework chiama IPreparedModel::executeSynchronously_1_3 metodo HAL predefinita per eseguire un'esecuzione sincrona su un modello preparato. Una richiesta può anche essere eseguita in modo asincrono con execute_1_3 metodo, il executeFenced metodo (vedi esecuzione Recintato ), oppure eseguita utilizzando un'esecuzione scoppio .

Le chiamate di esecuzione sincrone migliorano le prestazioni e riducono l'overhead di threading rispetto alle chiamate asincrone perché il controllo viene restituito al processo dell'app solo al termine dell'esecuzione. Ciò significa che il driver non ha bisogno di un meccanismo separato per notificare al processo dell'app che un'esecuzione è stata completata.

Con la asincrono execute_1_3 metodo, il controllo ritorna al processo di applicazione dopo l'esecuzione è iniziata, e il conducente deve notificare al quadro quando l'esecuzione viene completata, utilizzando il @1.3::IExecutionCallback .

La Request parametro passato agli elenchi Esegui metodo gli operandi di ingresso e di uscita utilizzati per l'esecuzione. La memoria che memorizza i dati dell'operando deve utilizzare l'ordine maggiore di riga con la prima dimensione che itera più lentamente e senza riempimento alla fine di ogni riga. Per ulteriori informazioni sui tipi di operandi, vedere Operandi .

Per NN HAL 1.2 o superiore driver, quando una richiesta è completato, lo stato di errore, la forma di uscita e informazioni di temporizzazione vengono restituiti al quadro. Durante l'esecuzione, l'output o gli operandi interni del modello possono avere una o più dimensioni o ranghi sconosciuti. Quando almeno un operando di output ha una dimensione o un rango sconosciuto, il driver deve restituire informazioni di output dimensionate dinamicamente.

Per i driver con NN HAL 1.1 o inferiore, viene restituito solo lo stato di errore al completamento di una richiesta. Le dimensioni per gli operandi di input e output devono essere specificate completamente affinché l'esecuzione venga completata correttamente. Gli operandi interni possono avere una o più dimensioni sconosciute, ma devono avere un rango specificato.

Per le richieste dell'utente che si estendono su più driver, il framework è responsabile della prenotazione della memoria intermedia e della sequenza delle chiamate a ciascun driver.

Richieste multiple possono essere avviate in parallelo sullo stesso @1.3::IPreparedModel . Il driver può eseguire richieste in parallelo o serializzare le esecuzioni.

Il framework può chiedere a un driver di mantenere più di un modello preparato. Ad esempio, preparare modello m1 , preparare m2 , eseguire la richiesta r1 sulla m1 , eseguire r2 su m2 , eseguire r3 su m1 , eseguire r4 su m2 , rilascio (descritto nella pulitura ) m1 , e il rilascio m2 .

Per evitare una prima esecuzione lenta che potrebbe comportare un'esperienza utente scadente (ad esempio, un primo frame stutter), il driver dovrebbe eseguire la maggior parte delle inizializzazioni nella fase di compilazione. L'inizializzazione alla prima esecuzione dovrebbe essere limitata alle azioni che influiscono negativamente sull'integrità del sistema se eseguite in anticipo, come la prenotazione di buffer temporanei di grandi dimensioni o l'aumento della frequenza di clock di un dispositivo. I driver che possono preparare solo un numero limitato di modelli simultanei potrebbero dover eseguire la loro inizializzazione alla prima esecuzione.

In Android 10 o versioni successive, nei casi in cui vengono eseguite più esecuzioni con lo stesso modello preparato in rapida successione, il client può scegliere di utilizzare un oggetto burst di esecuzione per comunicare tra i processi dell'app e del driver. Per ulteriori informazioni, vedere le esecuzioni e rapido dei messaggi code Burst .

Per migliorare le prestazioni per più esecuzioni in rapida successione, il driver può mantenere buffer temporanei o aumentare le frequenze di clock. Si consiglia di creare un thread watchdog per rilasciare risorse se non vengono create nuove richieste dopo un periodo di tempo fisso.

Forma di uscita

Per le richieste in cui uno o più operandi di output non hanno tutte le dimensioni specificate, il driver deve fornire un elenco di forme di output contenente le informazioni sulla dimensione per ogni operando di output dopo l'esecuzione. Per ulteriori informazioni sulle dimensioni, vedere OutputShape .

Se un'esecuzione non riesce a causa di un buffer di output sottodimensionato, il driver deve indicare quali operandi di output hanno una dimensione del buffer insufficiente nell'elenco delle forme di output e deve riportare quante più informazioni dimensionali possibili, utilizzando zero per le dimensioni sconosciute.

tempi

In Android 10, un'app può richiedere il tempo di esecuzione se l'app ha specificato un singolo dispositivo da utilizzare durante il processo di compilazione. Per i dettagli, consultare MeasureTiming e periferiche Scoperta e assegnazione . In questo caso, un driver NN HAL 1.2 deve misurare la durata di esecuzione o segnalare UINT64_MAX (ad indicare che la durata non è disponibile) durante l'esecuzione di una richiesta. Il conducente dovrebbe ridurre al minimo qualsiasi penalizzazione delle prestazioni derivante dalla misurazione della durata dell'esecuzione.

Il driver riporta le seguenti durate in microsecondi nella Timing struttura:

  • Tempo di esecuzione sul dispositivo: non include il tempo di esecuzione nel driver, che gira sul processore host.
  • Tempo di esecuzione nel driver: Include tempo di esecuzione sul dispositivo.

Queste durate devono includere il momento in cui l'esecuzione viene sospesa, ad esempio, quando l'esecuzione è stata anticipata da altre attività o quando è in attesa che una risorsa diventi disponibile.

Quando il driver non è stato chiesto di misurare la durata di esecuzione, o quando c'è un errore di esecuzione, il conducente deve riferire durate come UINT64_MAX . Anche quando il driver è stato chiesto di misurare la durata di esecuzione, può invece segnalare UINT64_MAX per volta sul dispositivo, il tempo nel driver, o entrambi. Quando il driver riporta entrambe durate come un valore diverso da UINT64_MAX , il tempo di esecuzione nel driver deve essere uguale o superiore al tempo del dispositivo.

Esecuzione recintata

In Android 11, NNAPI permette esecuzioni di attendere per un elenco di sync_fence maniglie e opzionalmente restituiscono uno sync_fence oggetto, che viene segnalata quando l'esecuzione viene completata. Ciò riduce il sovraccarico per i modelli di piccole sequenze e i casi d'uso di streaming. Esecuzione recintato consente anche di interoperabilità più efficiente con altri componenti che possono segnalare o attendere sync_fence . Per ulteriori informazioni su sync_fence , vedere Sincronizzazione Framework .

In un'esecuzione recintato, il framework chiama IPreparedModel::executeFenced metodo per lanciare una recintato, esecuzione asincrona su un modello preparato con un vettore di recinzioni di sincronizzazione da attendere. Se l'attività asincrona è terminato prima che la chiamata restituisce un manico vuoto può essere restituito per sync_fence . Un IFencedExecutionCallback oggetto deve essere restituito anche per consentire il quadro per lo stato di errore di query e le informazioni di durata.

Dopo l'esecuzione è completata, i seguenti due temporizzazione valori di misurazione della durata dell'esecuzione possono essere interrogati attraverso IFencedExecutionCallback::getExecutionInfo .

  • timingLaunched : Durata da quando executeFenced è chiamata a quando executeFenced segnala l'restituita syncFence .
  • timingFenced : Durata dal momento in cui tutte le recinzioni la sincronizzazione che le attese di esecuzione per vengono segnalate quando executeFenced segnala l'restituita syncFence .

Flusso di controllo

Per i dispositivi con Android 11 o superiore, il NNAPI comprende due operazioni del flusso di controllo, IF e WHILE , che prendono altri modelli come argomenti e li eseguono condizionale ( IF ) o più volte ( WHILE ). Per ulteriori informazioni su come implementare questo, vedere il flusso di controllo .

Qualità del servizio

In Android 11, NNAPI include una migliore qualità del servizio (QoS) consentendo a un'app di indicare le priorità relative dei suoi modelli, il tempo massimo previsto per la preparazione di un modello e il tempo massimo previsto per l'esecuzione essere completato. Per ulteriori informazioni, vedere la qualità del servizio .

Ripulire

Quando un'applicazione è finito utilizzando un modello preparato, il quadro rilascia il suo riferimento al @1.3::IPreparedModel oggetto. Quando l' IPreparedModel oggetto non viene fatto riferimento, viene automaticamente distrutta nel servizio di autista che lo ha creato. Le risorse specifiche del modello possono essere recuperate in questo momento nell'implementazione del distruttore da parte del driver. Se il servizio guidatore vuole che IPreparedModel oggetto da distruggere automaticamente quando non è più necessario da parte del cliente, non deve contenere alcun riferimento al IPreparedModel dell'oggetto dopo l' IPreparedeModel oggetto è stato restituito attraverso IPreparedModelCallback::notify_1_3 .

uso della CPU

Ci si aspetta che i driver utilizzino la CPU per impostare i calcoli. I driver non dovrebbero utilizzare la CPU per eseguire calcoli grafici perché ciò interferisce con la capacità del framework di allocare correttamente il lavoro. Il driver dovrebbe segnalare le parti che non può gestire al framework e lasciare che il framework gestisca il resto.

Il framework fornisce un'implementazione della CPU per tutte le operazioni NNAPI ad eccezione delle operazioni definite dal fornitore. Per ulteriori informazioni, vedere fornitore estensioni .

Le operazioni introdotte in Android 10 (API di livello 29) hanno solo un'implementazione CPU riferimento per verificare che i test TA e TV siano corrette. Le implementazioni ottimizzate incluse nei framework di machine learning per dispositivi mobili sono preferite rispetto all'implementazione della CPU NNAPI.

Funzioni di utilità

La codebase NNAPI include funzioni di utilità che possono essere utilizzate dai servizi driver.

Il frameworks/ml/nn/common/include/Utils.h file contiene funzioni di utilità assortiti, come quelli utilizzati per la registrazione e per la conversione tra le diverse versioni NN HAL.

  • Vlogging: VLOG è una macro wrapper di Android LOG che registra solo il messaggio se il tag appropriato si trova nel debug.nn.vlog proprietà. initVLogMask() deve essere chiamato prima delle chiamate al VLOG . Il VLOG_IS_ON macro può essere utilizzata per controllare se VLOG è attualmente abilitato, consentendo codice di registrazione complicato da saltare se non è necessario. Il valore dell'immobile deve essere uno dei seguenti:

    • Una stringa vuota, che indica che non deve essere eseguita alcuna registrazione.
    • Il token 1 o all , che indica che tutta la registrazione che deve essere fatto.
    • Un elenco di tag, delimitato da spazi, virgole o due punti, che indica quale registrazione deve essere eseguita. I tag sono compilation , cpuexe , driver , execution , manager , e model .
  • compliantWithV1_* : restituisce true se un oggetto NN HAL può essere convertita allo stesso tipo di una versione HAL diverso senza perdere informazioni. Ad esempio, la chiamata compliantWithV1_0 su un V1_2::Model restituisce false se il modello include i tipi di funzionamento introdotte NN HAL 1.1 o NN HAL 1.2.

  • convertToV1_* : Converte un oggetto NN HAL da una versione all'altra. Viene registrato un avviso se la conversione comporta una perdita di informazioni (ovvero, se la nuova versione del tipo non può rappresentare completamente il valore).

  • Funzionalità: Il nonExtensionOperandPerformance e update funzioni possono essere utilizzate per aiutare a costruire le Capabilities::operandPerformance campo.

  • Interrogazione di proprietà dei tipi: isExtensionOperandType , isExtensionOperationType , nonExtensionSizeOfData , nonExtensionOperandSizeOfData , nonExtensionOperandTypeIsScalar , tensorHasUnspecifiedDimensions .

Il frameworks/ml/nn/common/include/ValidateHal.h file contiene funzioni di utilità per la convalida che un oggetto NN HAL è valido in base alle specifiche della sua versione HAL.

  • validate* : Restituisce true se l'oggetto NN HAL è valido in base alle specifiche della sua versione HAL. I tipi OEM e i tipi di estensione non vengono convalidati. Ad esempio, validateModel restituisce false se il modello contiene un'operazione che fa riferimento a un indice operando che non esiste, o un'operazione non supportata in questa versione HAL.

Il frameworks/ml/nn/common/include/Tracing.h file contiene le macro per semplificare l'aggiunta systracing informazioni al codice di Reti Neurali. Per un esempio, vedere le NNTRACE_* macro invocazioni nel driver di esempio .

Il frameworks/ml/nn/common/include/GraphDump.h file contiene una funzione di utilità per eseguire il dump il contenuto di un Model in forma grafica a scopo di debug.

  • graphDump : scrive una rappresentazione del modello Graphviz ( .dot formato) nel flusso specificato (se previsto) o per l'logcat (se non viene fornito alcun flusso).

Convalida

Per testare la tua implementazione di NNAPI, usa i test VTS e CTS inclusi nel framework Android. VTS esercita i tuoi driver direttamente (senza utilizzare il framework), mentre CTS li esercita indirettamente attraverso il framework. Questi testano ogni metodo API e verificano che tutte le operazioni supportate dai driver funzionino correttamente e forniscano risultati che soddisfino i requisiti di precisione.

I requisiti di precisione in CTS e VTS per NNAPI sono i seguenti:

  • Floating-point: abs (previsto - attuale) <= atol + rtol * abs (expected); dove:

    • Per fp32, atol = 1e-5f, rtol = 5,0f * 1.1920928955078125e-7
    • Per fp16, atol = rtol = 5,0f * 0,0009765625f
  • Quantizzata: off-by-one (eccetto mobilenet_quantized , che è off-by-tre)

  • Booleano: corrispondenza esatta

Un modo in cui CTS verifica NNAPI consiste nella generazione di grafici pseudocasuali fissi utilizzati per testare e confrontare i risultati dell'esecuzione di ciascun driver con l'implementazione di riferimento NNAPI. Per i conducenti con NN HAL 1.2 o superiore, se i risultati non soddisfano i criteri di precisione, CTS segnala un errore e ne mostra un file di specifica per il modello fallito sotto /data/local/tmp per il debug. Per maggiori dettagli sui criteri di precisione, vedere TestRandomGraph.cpp e TestHarness.h .

Test fuzz

Lo scopo del test fuzz è trovare arresti anomali, asserzioni, violazioni della memoria o comportamenti generici non definiti nel codice sottoposto a test a causa di fattori quali input imprevisti. Per il test fuzz NNAPI, Android utilizza test basati sulla libFuzzer , che sono efficienti a fuzzing perché usano copertura linea di precedenti casi di test per generare nuovi ingressi casuali. Ad esempio, libFuzzer favorisce i casi di test eseguiti su nuove righe di codice. Ciò riduce notevolmente il tempo impiegato dai test per trovare il codice problematico.

Per eseguire il test fuzz per convalidare l'implementazione del driver, Modifica frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp nel libneuralnetworks_driver_fuzzer utility di test trovato in AOSP per includere il codice del driver. Per ulteriori informazioni sui test fuzz NNAPI, vedere frameworks/ml/nn/runtime/test/android_fuzzing/README.md .

Sicurezza

Poiché i processi dell'app comunicano direttamente con il processo di un driver, i driver devono convalidare gli argomenti delle chiamate che ricevono. Questa convalida è verificata da VTS. Il codice di convalida è in frameworks/ml/nn/common/include/ValidateHal.h .

I conducenti dovrebbero anche assicurarsi che le app non possano interferire con altre app quando si utilizza lo stesso dispositivo.

Suite di test per l'apprendimento automatico di Android

Android Machine Learning Test Suite (MLTS) è un benchmark NNAPI incluso in CTS e VTS per convalidare l'accuratezza dei modelli reali sui dispositivi dei fornitori. I Esamina benchmark latenza e la precisione, e mette a confronto i risultati dei piloti con i risultati utilizzando TF Lite in esecuzione sulla CPU, per lo stesso modello e serie di dati. Ciò garantisce che la precisione di un driver non sia peggiore dell'implementazione di riferimento della CPU.

Gli sviluppatori di piattaforme Android utilizzano anche MLTS per valutare la latenza e l'accuratezza dei driver.

Il benchmark NNAPI può essere trovato in due progetti in AOSP:

Modelli e set di dati

Il benchmark NNAPI utilizza i seguenti modelli e set di dati.

  • MobileNetV1 float e u8 quantizzati in diverse dimensioni, eseguiti su un piccolo sottoinsieme (1500 immagini) di Open Images Dataset v4.
  • MobileNetV2 float e u8 quantizzati in diverse dimensioni, eseguiti su un piccolo sottoinsieme (1500 immagini) di Open Images Dataset v4.
  • Modello acustico basato sulla memoria a breve termine (LSTM) per la sintesi vocale, eseguito su un piccolo sottoinsieme del set CMU Arctic.
  • Modello acustico basato su LSTM per il riconoscimento vocale automatico, eseguito su un piccolo sottoinsieme del set di dati di LibriSpeech.

Per ulteriori informazioni, vedere platform/test/mlts/models .

Test da sforzo

La suite di test di Android Machine Learning include una serie di crash test per convalidare la resilienza dei conducenti in condizioni di utilizzo intenso o in casi estremi di comportamento dei clienti.

Tutti i crash test forniscono le seguenti caratteristiche:

  • Rilevamento Hang: Se si blocca client NNAPI durante un test, il test ha esito negativo con il motivo fallimento HANG e la suite di test si sposta al prossimo test.
  • NNAPI rilevamento crash del client: Test sopravvivono crash del client e le prove falliscono con la causa del disturbo CRASH .
  • Rilevamento delle collisioni driver: I test in grado di rilevare un incidente driver che causa un errore su una chiamata NNAPI. Si noti che potrebbero verificarsi arresti anomali nei processi del driver che non causano un errore NNAPI e non causano il fallimento del test. Per coprire questo tipo di guasto, si consiglia di eseguire il tail comando sul registro di sistema per errori relativi ai driver o crash.
  • Targeting di tutti gli acceleratori disponibili: I test sono eseguiti nei confronti di tutti i driver disponibili.

Tutti i crash test hanno i seguenti quattro possibili esiti:

  • SUCCESS : L'esecuzione completata senza errori.
  • FAILURE : esecuzione fallita. In genere causato da un errore durante il test di un modello, che indica che il driver non è riuscito a compilare o eseguire il modello.
  • HANG : processo di test è diventato insensibile.
  • CRASH : processo di test si è schiantato.

Per ulteriori informazioni sui test di stress e un elenco completo di crash test, vedere platform/test/mlts/benchmark/README.txt .

Utilizzo di MLTS

Per utilizzare l'MLTS:

  1. Collegare un dispositivo di destinazione alla workstation e assicurarsi che sia raggiungibile attraverso adb . Esportare il dispositivo di destinazione ANDROID_SERIAL variabile ambiente se è collegato più di un dispositivo.
  2. cd nella directory source Android di livello superiore.

    source build/envsetup.sh
    lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available.
    ./test/mlts/benchmark/build_and_run_benchmark.sh
    

    Al termine di una corsa di riferimento, i risultati sono presentati come una pagina HTML e passati al xdg-open .

Per ulteriori informazioni, vedere platform/test/mlts/benchmark/README.txt .

Reti neurali versioni HAL

Questa sezione descrive le modifiche introdotte nelle versioni HAL di Android e Neural Networks.

Android 11

Android 11 introduce NN HAL 1.3, che include le seguenti notevoli modifiche.

  • Supporto per la quantizzazione a 8 bit con segno in NNAPI. Aggiunge il TENSOR_QUANT8_ASYMM_SIGNED tipo di operando. I driver con NN HAL 1.3 che supportano operazioni con quantizzazione senza segno devono supportare anche le varianti con segno di tali operazioni. Quando si esegue le versioni con e senza segno di maggior parte delle operazioni quantizzati, il macchinista deve produrre gli stessi risultati fino a un offset di 128. Ci sono cinque eccezioni a questo requisito: CAST , HASHTABLE_LOOKUP , LSH_PROJECTION , PAD_V2 e QUANTIZED_16BIT_LSTM . Il QUANTIZED_16BIT_LSTM operazione non supporta operandi firmate e le altre quattro operazioni supporta quantizzazione firmato ma non richiedono risultati essere lo stesso.
  • Il supporto per le esecuzioni recintato in cui il quadro chiama IPreparedModel::executeFenced metodo per lanciare un recintato, esecuzione asincrona su un modello preparato con un vettore di recinzioni di sincronizzazione da attendere. Per ulteriori informazioni, vedere l'esecuzione recintato .
  • Supporto per il controllo del flusso. Aggiunge le IF e WHILE operazioni, che prendono altri modelli come argomenti e li eseguono condizionale ( IF ) o più volte ( WHILE ). Per ulteriori informazioni, vedere il flusso di controllo .
  • Miglioramento della qualità del servizio (QoS) in quanto le app possono indicare le priorità relative dei suoi modelli, il tempo massimo previsto per la preparazione di un modello e il tempo massimo previsto per il completamento di un'esecuzione. Per ulteriori informazioni, vedere la qualità del servizio .
  • Supporto per domini di memoria che forniscono interfacce di allocazione per buffer gestiti dal driver. Ciò consente di passare le memorie native del dispositivo tra le esecuzioni, sopprimendo la copia e la trasformazione dei dati non necessari tra esecuzioni consecutive sullo stesso driver. Per ulteriori informazioni, vedere i domini di memoria .

Android 10

Android 10 introduce NN HAL 1.2, che include le seguenti notevoli modifiche.

  • La Capabilities struct comprende tutti i tipi di dati tra cui i tipi di dati scalari, e rappresenta le prestazioni nonrelaxed utilizzando un vettore piuttosto che campi denominati.
  • I getVersionString e getType metodi consentono il quadro per recuperare tipo di dispositivo ( DeviceType ) e le informazioni sulla versione. Vedere Dispositivo Scoperta e assegnazione .
  • executeSynchronously metodo viene chiamato da predefinito per eseguire un'esecuzione sincrono. execute_1_2 metodo indica il quadro per eseguire un'esecuzione in modo asincrono. Vedere Esecuzione .
  • Il MeasureTiming parametro executeSynchronously , execute_1_2 specifica, ed esecuzione di scoppio se il pilota sta per misurare la durata di esecuzione. I risultati sono riportati nella Timing struttura. Vedere Timing .
  • Supporto per esecuzioni in cui uno o più operandi di output hanno una dimensione o un rango sconosciuti. Vedere la forma di uscita .
  • Supporto per le estensioni del fornitore, che sono raccolte di operazioni e tipi di dati definiti dal fornitore. Le relazioni del driver estensioni supportate attraverso IDevice::getSupportedExtensions metodo. Vedere fornitore Estensioni .
  • Possibilità per un oggetto burst di controllare una serie di esecuzioni burst utilizzando code di messaggi veloci (FMQ) per comunicare tra app e processi driver, riducendo la latenza. Vedere esecuzioni Burst e code di messaggi veloci .
  • Supporto per AHardwareBuffer per consentire al driver di eseguire esecuzioni senza copiare i dati. Vedere AHardwareBuffer .
  • Supporto migliorato per la memorizzazione nella cache degli artefatti di compilazione per ridurre il tempo utilizzato per la compilazione all'avvio di un'app. Vedere Compilazione Caching .

Android 10 introduce i seguenti tipi di operandi e operazioni.

  • Tipi di operandi

    • ANEURALNETWORKS_BOOL
    • ANEURALNETWORKS_FLOAT16
    • ANEURALNETWORKS_TENSOR_BOOL8
    • ANEURALNETWORKS_TENSOR_FLOAT16
    • ANEURALNETWORKS_TENSOR_QUANT16_ASYMM
    • ANEURALNETWORKS_TENSOR_QUANT16_SYMM
    • ANEURALNETWORKS_TENSOR_QUANT8_SYMM
    • ANEURALNETWORKS_TENSOR_QUANT8_SYMM_PER_CHANNEL
  • operazioni

    • ANEURALNETWORKS_ABS
    • ANEURALNETWORKS_ARGMAX
    • ANEURALNETWORKS_ARGMIN
    • ANEURALNETWORKS_AXIS_ALIGNED_BBOX_TRANSFORM
    • ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_LSTM
    • ANEURALNETWORKS_BIDIRECTIONAL_SEQUENCE_RNN
    • ANEURALNETWORKS_BOX_WITH_NMS_LIMIT
    • ANEURALNETWORKS_CAST
    • ANEURALNETWORKS_CHANNEL_SHUFFLE
    • ANEURALNETWORKS_DETECTION_POSTPROCESSING
    • ANEURALNETWORKS_EQUAL
    • ANEURALNETWORKS_EXP
    • ANEURALNETWORKS_EXPAND_DIMS
    • ANEURALNETWORKS_GATHER
    • ANEURALNETWORKS_GENERATE_PROPOSALS
    • ANEURALNETWORKS_GREATER
    • ANEURALNETWORKS_GREATER_EQUAL
    • ANEURALNETWORKS_GROUPED_CONV_2D
    • ANEURALNETWORKS_HEATMAP_MAX_KEYPOINT
    • ANEURALNETWORKS_INSTANCE_NORMALIZATION
    • ANEURALNETWORKS_LESS
    • ANEURALNETWORKS_LESS_EQUAL
    • ANEURALNETWORKS_LOG
    • ANEURALNETWORKS_LOGICAL_AND
    • ANEURALNETWORKS_LOGICAL_NOT
    • ANEURALNETWORKS_LOGICAL_OR
    • ANEURALNETWORKS_LOG_SOFTMAX
    • ANEURALNETWORKS_MAXIMUM
    • ANEURALNETWORKS_MINIMUM
    • ANEURALNETWORKS_NEG
    • ANEURALNETWORKS_NOT_EQUAL
    • ANEURALNETWORKS_PAD_V2
    • ANEURALNETWORKS_POW
    • ANEURALNETWORKS_PRELU
    • ANEURALNETWORKS_QUANTIZE
    • ANEURALNETWORKS_QUANTIZED_16BIT_LSTM
    • ANEURALNETWORKS_RANDOM_MULTINOMIAL
    • ANEURALNETWORKS_REDUCE_ALL
    • ANEURALNETWORKS_REDUCE_ANY
    • ANEURALNETWORKS_REDUCE_MAX
    • ANEURALNETWORKS_REDUCE_MIN
    • ANEURALNETWORKS_REDUCE_PROD
    • ANEURALNETWORKS_REDUCE_SUM
    • ANEURALNETWORKS_RESIZE_NEAREST_NEIGHBOR
    • ANEURALNETWORKS_ROI_ALIGN
    • ANEURALNETWORKS_ROI_POOLING
    • ANEURALNETWORKS_RSQRT
    • ANEURALNETWORKS_SELECT
    • ANEURALNETWORKS_SIN
    • ANEURALNETWORKS_SLICE
    • ANEURALNETWORKS_SPLIT
    • ANEURALNETWORKS_SQRT
    • ANEURALNETWORKS_TILE
    • ANEURALNETWORKS_TOPK_V2
    • ANEURALNETWORKS_TRANSPOSE_CONV_2D
    • ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_LSTM
    • ANEURALNETWORKS_UNIDIRECTIONAL_SEQUENCE_RNN

Android 10 introduce aggiornamenti a molte delle operazioni esistenti. Gli aggiornamenti riguardano principalmente quanto segue:

  • Supporto per il layout di memoria NCHW
  • Supporto per tensori con rango diverso da 4 nelle operazioni di softmax e normalizzazione
  • Supporto per circonvoluzioni dilatate
  • Il supporto per ingressi con quantizzazione misto in ANEURALNETWORKS_CONCATENATION

Il seguente elenco mostra le operazioni che sono modificati in Android 10. Per tutti i dettagli delle modifiche, vedere OperationCode nella documentazione di riferimento NNAPI.

  • ANEURALNETWORKS_ADD
  • ANEURALNETWORKS_AVERAGE_POOL_2D
  • ANEURALNETWORKS_BATCH_TO_SPACE_ND
  • ANEURALNETWORKS_CONCATENATION
  • ANEURALNETWORKS_CONV_2D
  • ANEURALNETWORKS_DEPTHWISE_CONV_2D
  • ANEURALNETWORKS_DEPTH_TO_SPACE
  • ANEURALNETWORKS_DEQUANTIZE
  • ANEURALNETWORKS_DIV
  • ANEURALNETWORKS_FLOOR
  • ANEURALNETWORKS_FULLY_CONNECTED
  • ANEURALNETWORKS_L2_NORMALIZATION
  • ANEURALNETWORKS_L2_POOL_2D
  • ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION
  • ANEURALNETWORKS_LOGISTIC
  • ANEURALNETWORKS_LSH_PROJECTION
  • ANEURALNETWORKS_LSTM
  • ANEURALNETWORKS_MAX_POOL_2D
  • ANEURALNETWORKS_MEAN
  • ANEURALNETWORKS_MUL
  • ANEURALNETWORKS_PAD
  • ANEURALNETWORKS_RELU
  • ANEURALNETWORKS_RELU1
  • ANEURALNETWORKS_RELU6
  • ANEURALNETWORKS_RESHAPE
  • ANEURALNETWORKS_RESIZE_BILINEAR
  • ANEURALNETWORKS_RNN
  • ANEURALNETWORKS_ROI_ALIGN
  • ANEURALNETWORKS_SOFTMAX
  • ANEURALNETWORKS_SPACE_TO_BATCH_ND
  • ANEURALNETWORKS_SPACE_TO_DEPTH
  • ANEURALNETWORKS_SQUEEZE
  • ANEURALNETWORKS_STRIDED_SLICE
  • ANEURALNETWORKS_SUB
  • ANEURALNETWORKS_SVDF
  • ANEURALNETWORKS_TANH
  • ANEURALNETWORKS_TRANSPOSE

Android 9

NN HAL 1.1 è stato introdotto in Android 9 e include le seguenti importanti modifiche.

  • IDevice::prepareModel_1_1 include un ExecutionPreference parametro. Un guidatore può usarlo per regolare la sua preparazione, sapendo che l'app preferisce risparmiare la batteria o eseguirà il modello in rapide chiamate successive.
  • Sono state aggiunte nove nuove operazioni: BATCH_TO_SPACE_ND , DIV , MEAN , PAD , SPACE_TO_BATCH_ND , SQUEEZE , STRIDED_SLICE , SUB , TRANSPOSE .
  • Un'applicazione può specificare che i calcoli float a 32 bit può essere eseguito utilizzando gamma float a 16 bit e / o la precisione impostando Model.relaxComputationFloat32toFloat16 al true . La Capabilities struct ha il campo aggiuntivo relaxedFloat32toFloat16Performance in modo che il conducente possa riferire le sue prestazioni rilassata al quadro.

Android 8.1

Il primo Neural Networks HAL (1.0) è stato rilasciato in Android 8.1. Per ulteriori informazioni, vedere /neuralnetworks/1.0/ .