이 페이지에서는 NNAPI(Neural Networks API) 드라이버를 구현하는 방법에 대한 개요를 제공합니다. 자세한 내용은 hardware/interfaces/neuralnetworks
의 HAL 정의 파일에 있는 문서를 참조하세요. 샘플 드라이버 구현은 frameworks/ml/nn/driver/sample
에 있습니다.
Neural Networks API에 대한 자세한 내용은 Neural Networks API 를 참조하십시오.
신경망 HAL
신경망(NN) HAL은 제품(예: 휴대폰 또는 태블릿)에 있는 그래픽 처리 장치(GPU) 및 디지털 신호 프로세서(DSP)와 같은 다양한 장치 의 추상화를 정의합니다. 이러한 장치의 드라이버는 NN HAL을 준수해야 합니다. 인터페이스는 hardware/interfaces/neuralnetworks
의 HAL 정의 파일에 지정됩니다.
프레임워크와 드라이버 간 인터페이스의 일반적인 흐름은 그림 1에 나와 있습니다.
그림 1. 신경망 흐름
초기화
초기화 시 프레임워크는 IDevice::getCapabilities_1_3
을 사용하여 드라이버의 기능을 쿼리합니다. @1.3::Capabilities
구조는 모든 데이터 유형을 포함하며 벡터를 사용하여 완화되지 않은 성능을 나타냅니다.
사용 가능한 장치에 계산을 할당하는 방법을 결정하기 위해 프레임워크는 기능을 사용하여 각 드라이버가 얼마나 빠르고 에너지 효율적으로 실행을 수행할 수 있는지 이해합니다. 이 정보를 제공하기 위해 드라이버는 참조 워크로드 실행을 기반으로 표준화된 성능 수치를 제공해야 합니다.
드라이버가 IDevice::getCapabilities_1_3
에 대한 응답으로 반환하는 값을 확인하려면 NNAPI 벤치마크 앱을 사용하여 해당 데이터 유형의 성능을 측정하세요. MobileNet v1 및 v2, asr_float
및 tts_float
모델은 32비트 부동 소수점 값에 대한 성능 측정에 권장되며 MobileNet v1 및 v2 양자화 모델은 8비트 양자화 값에 권장됩니다. 자세한 내용은 Android 기계 학습 테스트 도구 모음 을 참조하세요.
Android 9 이하에서 Capabilities
구조에는 부동 소수점 및 양자화 텐서에 대한 드라이버 성능 정보만 포함되며 스칼라 데이터 유형은 포함되지 않습니다.
초기화 프로세스의 일부로 프레임워크는 IDevice::getType
, IDevice::getVersionString
, IDevice:getSupportedExtensions
및 IDevice::getNumberOfCacheFilesNeeded
를 사용하여 추가 정보를 쿼리할 수 있습니다.
제품 재부팅 사이에 프레임워크는 이 섹션에 설명된 모든 쿼리가 지정된 드라이버에 대해 항상 동일한 값을 보고할 것으로 예상합니다. 그렇지 않으면 해당 드라이버를 사용하는 앱의 성능이 저하되거나 잘못된 동작이 나타날 수 있습니다.
편집
프레임워크는 앱에서 요청을 수신할 때 사용할 장치를 결정합니다. Android 10에서 앱은 프레임워크가 선택하는 기기를 검색하고 지정할 수 있습니다. 자세한 내용은 장치 검색 및 할당 을 참조하십시오.
모델 컴파일 시간에 프레임워크는 IDevice::getSupportedOperations_1_3
을 호출하여 모델을 각 후보 드라이버로 보냅니다. 각 드라이버는 지원되는 모델 작업을 나타내는 부울 배열을 반환합니다. 드라이버는 여러 가지 이유로 지정된 작업을 지원할 수 없다고 결정할 수 있습니다. 예를 들어:
- 드라이버가 데이터 유형을 지원하지 않습니다.
- 드라이버는 특정 입력 매개변수를 사용하는 작업만 지원합니다. 예를 들어 드라이버는 3x3 및 5x5를 지원하지만 7x7 컨볼루션 작업은 지원하지 않을 수 있습니다.
- 드라이버에는 큰 그래프나 입력을 처리하지 못하도록 하는 메모리 제약이 있습니다.
컴파일하는 동안 OperandLifeTime
에 설명된 대로 모델의 입력, 출력 및 내부 피연산자는 알 수 없는 차원 또는 순위를 가질 수 있습니다. 자세한 내용은 출력 형태 를 참조하십시오.
프레임워크는 선택한 각 드라이버가 IDevice::prepareModel_1_3
을 호출하여 모델의 하위 집합을 실행할 준비를 하도록 지시합니다. 그런 다음 각 드라이버는 해당 하위 집합을 컴파일합니다. 예를 들어, 드라이버는 코드를 생성하거나 재정렬된 가중치 사본을 생성할 수 있습니다. 모델 컴파일과 요청 실행 사이에는 상당한 시간이 있을 수 있으므로 컴파일 중에 장치 메모리의 큰 청크와 같은 리소스를 할당하면 안 됩니다.
성공하면 드라이버는 @1.3::IPreparedModel
핸들을 반환합니다. 드라이버가 모델의 하위 집합을 준비할 때 실패 코드를 반환하면 프레임워크는 CPU에서 전체 모델을 실행합니다.
앱이 시작될 때 컴파일에 사용되는 시간을 줄이기 위해 드라이버는 컴파일 아티팩트를 캐시할 수 있습니다. 자세한 내용은 컴파일 캐싱 을 참조하십시오.
실행
앱이 프레임워크에 요청 실행을 요청하면 프레임워크는 기본적으로 IPreparedModel::executeSynchronously_1_3
HAL 메서드를 호출하여 준비된 모델에서 동기식 실행을 수행합니다. 요청은 execute_1_3
메서드, executeFenced
메서드( Fenced 실행 참조)를 사용하여 비동기적으로 실행하거나 버스트 실행 을 사용하여 실행할 수도 있습니다.
동기 실행 호출은 실행이 완료된 후에만 제어가 앱 프로세스로 반환되기 때문에 비동기 호출에 비해 성능이 향상되고 스레딩 오버헤드가 줄어듭니다. 이는 드라이버가 실행이 완료되었음을 앱 프로세스에 알리기 위해 별도의 메커니즘이 필요하지 않음을 의미합니다.
비동기 execute_1_3
메서드를 사용하면 실행이 시작된 후 제어가 앱 프로세스로 돌아가고 드라이버는 실행이 완료되면 @1.3::IExecutionCallback
을 사용하여 프레임워크에 알려야 합니다.
실행 메소드에 전달된 Request
매개변수는 실행에 사용된 입력 및 출력 피연산자를 나열합니다. 피연산자 데이터를 저장하는 메모리는 첫 번째 차원이 가장 느린 것을 반복하는 행 주요 순서를 사용해야 하며 행 끝에 패딩이 없어야 합니다. 피연산자 유형에 대한 자세한 내용은 피연산자 를 참조하십시오.
NN HAL 1.2 이상 드라이버의 경우 요청이 완료되면 오류 상태, 출력 형태 및 타이밍 정보 가 프레임워크에 반환됩니다. 실행 중에 모델의 출력 또는 내부 피연산자는 하나 이상의 알 수 없는 차원 또는 알 수 없는 순위를 가질 수 있습니다. 하나 이상의 출력 피연산자에 알 수 없는 차원 또는 순위가 있는 경우 드라이버는 동적으로 크기가 조정된 출력 정보를 반환해야 합니다.
NN HAL 1.1 이하 드라이버의 경우 요청이 완료되면 오류 상태만 반환됩니다. 실행을 성공적으로 완료하려면 입력 및 출력 피연산자에 대한 차원을 완전히 지정해야 합니다. 내부 피연산자는 하나 이상의 알 수 없는 차원을 가질 수 있지만 지정된 순위를 가져야 합니다.
여러 드라이버에 걸쳐 있는 사용자 요청의 경우 프레임워크는 중간 메모리를 예약하고 각 드라이버에 대한 호출 순서를 지정합니다.
동일한 @1.3::IPreparedModel
에서 여러 요청을 병렬로 시작할 수 있습니다. 드라이버는 요청을 병렬로 실행하거나 실행을 직렬화할 수 있습니다.
프레임워크는 운전자에게 둘 이상의 준비된 모델을 유지하도록 요청할 수 있습니다. 예를 들어, 모델 m1
준비, m2
준비, m1
에서 요청 r1
실행, m2
에서 r2
실행, m1
에서 r3
실행, m2
에서 r4
실행, m1
해제( Cleanup 에 설명됨) 및 m2
해제를 수행합니다.
사용자 경험이 저하될 수 있는 느린 첫 번째 실행(예: 첫 번째 프레임 끊김)을 방지하려면 드라이버가 컴파일 단계에서 대부분의 초기화를 수행해야 합니다. 첫 번째 실행 시 초기화는 큰 임시 버퍼를 예약하거나 장치의 클럭 속도를 높이는 것과 같이 초기에 수행할 때 시스템 상태에 부정적인 영향을 미치는 작업으로 제한되어야 합니다. 제한된 수의 동시 모델만 준비할 수 있는 드라이버는 처음 실행 시 초기화를 수행해야 할 수 있습니다.
Android 10 이상에서 동일한 준비된 모델을 사용하여 여러 실행이 빠르게 연속적으로 실행되는 경우 클라이언트는 실행 버스트 개체를 사용하여 앱과 드라이버 프로세스 간에 통신하도록 선택할 수 있습니다. 자세한 내용은 버스트 실행 및 빠른 메시지 큐 단원 을 참조하십시오.
빠르게 연속적으로 여러 번 실행하는 성능을 개선하기 위해 드라이버는 임시 버퍼를 유지하거나 클럭 속도를 높일 수 있습니다. 일정 시간이 지나도 새로운 요청이 생성되지 않으면 감시 스레드를 생성하여 리소스를 해제하는 것이 좋습니다.
출력 형태
하나 이상의 출력 피연산자에 모든 차원이 지정되지 않은 요청의 경우 드라이버는 실행 후 각 출력 피연산자에 대한 차원 정보가 포함된 출력 셰이프 목록을 제공해야 합니다. 치수에 대한 자세한 내용은 OutputShape
를 참조하십시오.
크기가 작은 출력 버퍼로 인해 실행이 실패하는 경우 드라이버는 출력 셰이프 목록에서 버퍼 크기가 부족한 출력 피연산자를 표시해야 하며 알 수 없는 차원에 대해 0을 사용하여 가능한 한 많은 차원 정보를 보고해야 합니다.
타이밍
Android 10에서는 앱이 컴파일 프로세스 중에 사용할 단일 기기를 지정한 경우 앱에서 실행 시간을 요청할 수 있습니다. 자세한 내용은 MeasureTiming
및 장치 검색 및 할당 을 참조하십시오. 이 경우 NN HAL 1.2 드라이버는 요청을 실행할 때 실행 기간을 측정하거나 UINT64_MAX
(기간을 사용할 수 없음을 나타냄)를 보고해야 합니다. 드라이버는 실행 기간 측정으로 인한 성능 저하를 최소화해야 합니다.
드라이버는 Timing
구조에서 다음 기간을 마이크로초 단위로 보고합니다.
- 장치의 실행 시간: 호스트 프로세서에서 실행되는 드라이버의 실행 시간은 포함하지 않습니다.
- 드라이버의 실행 시간: 장치의 실행 시간을 포함합니다.
이러한 기간에는 실행이 일시 중단된 시간(예: 실행이 다른 작업에 의해 선점되었거나 리소스가 사용 가능해질 때까지 대기 중인 시간)이 포함되어야 합니다.
드라이버가 실행 기간을 측정하도록 요청받지 않았거나 실행 오류가 있는 경우 드라이버는 기간을 UINT64_MAX
로 보고해야 합니다. 드라이버가 실행 기간을 측정하도록 요청받은 경우에도 장치의 시간, 드라이버의 시간 또는 둘 다에 대해 UINT64_MAX
를 대신 보고할 수 있습니다. 드라이버가 UINT64_MAX
이외의 값으로 두 기간을 모두 보고하는 경우 드라이버의 실행 시간은 장치의 시간과 같거나 초과해야 합니다.
울타리 실행
Android 11에서 NNAPI는 실행이 sync_fence
핸들 목록을 기다리고 선택적으로 sync_fence
객체를 반환하도록 허용합니다. 이 객체는 실행이 완료될 때 신호를 받습니다. 이렇게 하면 작은 시퀀스 모델 및 스트리밍 사용 사례의 오버헤드가 줄어듭니다. Fenced 실행은 sync_fence
신호를 보내거나 기다릴 수 있는 다른 구성 요소와의 보다 효율적인 상호 운용성을 허용합니다. sync_fence
에 대한 자세한 정보는 동기화 프레임워크 를 참조하십시오.
분리 실행에서 프레임워크는 대기할 동기화 펜스 벡터가 있는 준비된 모델에서 분리된 비동기 실행을 시작하기 위해 IPreparedModel::executeFenced
메서드를 호출합니다. 호출이 반환되기 전에 비동기 작업이 완료되면 sync_fence
에 대해 빈 핸들이 반환될 수 있습니다. 프레임워크가 오류 상태 및 기간 정보를 쿼리할 수 있도록 IFencedExecutionCallback
개체도 반환되어야 합니다.
실행이 완료된 후 IFencedExecutionCallback::getExecutionInfo
를 통해 실행 기간을 측정하는 다음 두 가지 타이밍 값을 쿼리할 수 있습니다.
-
timingLaunched
:executeFenced
가 호출될 때부터syncFence
executeFenced
신호를 보낼 때까지의 기간입니다. -
timingFenced
: executeFenced가 반환된executeFenced
에 신호를 보낼 때 실행이 대기하는 모든 동기화 펜스가 신호를 받는 때부터의syncFence
입니다.
제어 흐름
Android 11 이상을 실행하는 기기의 경우 NNAPI에는 다른 모델을 인수로 사용하여 조건부( IF
) 또는 반복적으로( WHILE
) 실행하는 두 가지 제어 흐름 작업인 IF
및 WHILE
이 포함됩니다. 이를 구현하는 방법에 대한 자세한 내용은 제어 흐름 을 참조하십시오.
서비스 품질
Android 11에서 NNAPI에는 앱이 모델의 상대적 우선순위, 모델 준비에 예상되는 최대 시간, 실행에 예상되는 최대 시간을 표시할 수 있도록 하여 향상된 서비스 품질(QoS)이 포함됩니다. 완료됩니다. 자세한 내용 은 서비스 품질을 참조하십시오.
대청소
앱이 준비된 모델을 사용하여 완료되면 프레임워크는 @1.3::IPreparedModel
개체에 대한 참조를 해제합니다. IPreparedModel
개체가 더 이상 참조되지 않으면 개체를 생성한 드라이버 서비스에서 자동으로 소멸됩니다. 이 시점에서 드라이버의 소멸자 구현에서 모델별 리소스를 회수할 수 있습니다. 드라이버 서비스가 클라이언트에 더 이상 필요하지 않을 때 IPreparedModel
개체가 자동으로 삭제되기를 원하는 경우 IPreparedeModel
개체가 IPreparedModelCallback::notify_1_3
을 통해 반환된 후에는 IPreparedModel
개체에 대한 참조를 보유하지 않아야 합니다.
CPU 사용량
드라이버는 CPU를 사용하여 계산을 설정해야 합니다. 드라이버는 작업을 올바르게 할당하는 프레임워크의 기능을 방해하기 때문에 그래프 계산을 수행하기 위해 CPU를 사용해서는 안 됩니다. 드라이버는 처리할 수 없는 부분을 프레임워크에 보고하고 프레임워크가 나머지를 처리하도록 해야 합니다.
프레임워크는 공급업체 정의 작업을 제외한 모든 NNAPI 작업에 대한 CPU 구현을 제공합니다. 자세한 내용은 공급업체 확장 을 참조하십시오.
Android 10(API 레벨 29)에 도입된 작업 에는 CTS 및 VTS 테스트가 올바른지 확인하기 위한 참조 CPU 구현만 있습니다. 모바일 기계 학습 프레임워크에 포함된 최적화된 구현이 NNAPI CPU 구현보다 선호됩니다.
유틸리티 기능
NNAPI 코드베이스에는 드라이버 서비스에서 사용할 수 있는 유틸리티 기능이 포함되어 있습니다.
frameworks/ml/nn/common/include/Utils.h
파일에는 로깅 및 서로 다른 NN HAL 버전 간의 변환에 사용되는 기능과 같은 다양한 유틸리티 기능이 포함되어 있습니다.
VLogging:
VLOG
는debug.nn.vlog
속성에 적절한 태그가 설정된 경우에만 메시지를 기록하는 Android의LOG
주변 래퍼 매크로입니다.VLOG
를 호출하기 전에initVLogMask()
를 호출해야 합니다.VLOG_IS_ON
매크로는VLOG
가 현재 활성화되어 있는지 확인하는 데 사용할 수 있으므로 필요하지 않은 경우 복잡한 로깅 코드를 건너뛸 수 있습니다. 속성 값은 다음 중 하나여야 합니다.- 로깅이 수행되지 않음을 나타내는 빈 문자열입니다.
- 모든 로깅이 완료됨을 나타내는 토큰
1
또는all
. - 수행할 로깅을 나타내는 공백, 쉼표 또는 콜론으로 구분된 태그 목록입니다. 태그는
compilation
,cpuexe
,driver
,execution
,manager
및model
입니다.
compliantWithV1_*
: NN HAL 개체를 정보 손실 없이 동일한 유형의 다른 HAL 버전으로 변환할 수 있는 경우true
를 반환합니다. 예를 들어V1_2::Model
에서compliantWithV1_0
을 호출하면 모델에 NN HAL 1.1 또는 NN HAL 1.2에 도입된 작업 유형이 포함된 경우false
가 반환됩니다.convertToV1_*
: NN HAL 개체를 한 버전에서 다른 버전으로 변환합니다. 변환으로 인해 정보가 손실되는 경우(즉, 유형의 새 버전이 값을 완전히 표현할 수 없는 경우) 경고가 기록됩니다.기능:
nonExtensionOperandPerformance
및update
기능을 사용하여Capabilities::operandPerformance
필드를 구축할 수 있습니다.유형의 속성 쿼리:
isExtensionOperandType
,isExtensionOperationType
,nonExtensionSizeOfData
,nonExtensionOperandSizeOfData
,nonExtensionOperandTypeIsScalar
,tensorHasUnspecifiedDimensions
.
frameworks/ml/nn/common/include/ValidateHal.h
파일에는 NN HAL 개체가 HAL 버전 사양에 따라 유효한지 확인하는 유틸리티 함수가 포함되어 있습니다.
-
validate*
: NN HAL 객체가 HAL 버전의 사양에 따라 유효한 경우true
를 반환합니다. OEM 유형 및 확장 유형은 검증되지 않습니다. 예를 들어 모델에 존재하지 않는 피연산자 인덱스를 참조하는 작업이 포함되어 있거나 해당 HAL 버전에서 지원되지 않는 작업이 포함된 경우validateModel
은false
를 반환합니다.
frameworks/ml/nn/common/include/Tracing.h
파일에는 Neural Networks 코드에 systracing 정보 추가를 단순화하는 매크로가 포함되어 있습니다. 예제는 샘플 드라이버 의 NNTRACE_*
매크로 호출을 참조하십시오.
frameworks/ml/nn/common/include/GraphDump.h
파일에는 디버깅 목적으로 Model
의 콘텐츠를 그래픽 형식으로 덤프하는 유틸리티 함수가 포함되어 있습니다.
-
graphDump
: Graphviz(.dot
) 형식의 모델 표현을 지정된 스트림(제공된 경우) 또는 logcat(스트림이 제공되지 않은 경우)에 기록합니다.
확인
NNAPI 구현을 테스트하려면 Android 프레임워크에 포함된 VTS 및 CTS 테스트를 사용하세요. VTS는 드라이버를 프레임워크를 사용하지 않고 직접 실행하는 반면 CTS는 프레임워크를 통해 간접적으로 드라이버를 실행합니다. 이들은 각 API 메서드를 테스트하고 드라이버가 지원하는 모든 작업이 올바르게 작동하는지 확인하고 정밀도 요구 사항을 충족하는 결과를 제공합니다.
NNAPI에 대한 CTS 및 VTS의 정밀도 요구 사항은 다음과 같습니다.
부동 소수점: abs(예상 - 실제) <= atol + rtol * abs(예상); 어디:
- fp32의 경우 atol = 1e-5f, rtol = 5.0f * 1.1920928955078125e-7
- fp16의 경우 atol = rtol = 5.0f * 0.0009765625f
Quantized: off-by-one(off-by-one인
mobilenet_quantized
제외)부울: 정확히 일치
CTS가 NNAPI를 테스트하는 한 가지 방법은 NNAPI 참조 구현을 사용하여 각 드라이버의 실행 결과를 테스트하고 비교하는 데 사용되는 고정 의사 난수 그래프를 생성하는 것입니다. NN HAL 1.2 이상이 있는 드라이버의 경우 결과가 정밀도 기준을 충족하지 않으면 CTS는 오류를 보고하고 디버깅을 위해 실패한 모델의 사양 파일을 /data/local/tmp
아래에 덤프합니다. 정밀도 기준에 대한 자세한 내용은 TestRandomGraph.cpp
및 TestHarness.h
를 참조하십시오.
퍼지 테스트
퍼즈 테스트의 목적은 예기치 않은 입력과 같은 요인으로 인해 테스트 중인 코드에서 충돌, 어설션, 메모리 위반 또는 일반적으로 정의되지 않은 동작을 찾는 것입니다. NNAPI 퍼즈 테스트의 경우 Android는 libFuzzer 기반 테스트를 사용합니다. 이 테스트는 이전 테스트 사례의 라인 범위를 사용하여 새로운 무작위 입력을 생성하기 때문에 퍼징에 효율적입니다. 예를 들어 libFuzzer는 새로운 코드 줄에서 실행되는 테스트 사례를 선호합니다. 이렇게 하면 테스트에서 문제가 있는 코드를 찾는 데 걸리는 시간이 크게 줄어듭니다.
퍼즈 테스트를 수행하여 드라이버 구현을 검증하려면 AOSP에 있는 libneuralnetworks_driver_fuzzer
테스트 유틸리티에서 frameworks/ml/nn/runtime/test/android_fuzzing/DriverFuzzTest.cpp
를 수정하여 드라이버 코드를 포함하세요. NNAPI fuzz 테스트에 대한 자세한 내용은 frameworks/ml/nn/runtime/test/android_fuzzing/README.md
를 참조하세요.
보안
앱 프로세스는 드라이버 프로세스와 직접 통신하므로 드라이버는 수신하는 호출의 인수를 확인해야 합니다. 이 유효성 검사는 VTS에서 확인합니다. 검증 코드는 frameworks/ml/nn/common/include/ValidateHal.h
에 있습니다.
또한 드라이버는 동일한 장치를 사용할 때 앱이 다른 앱을 방해할 수 없도록 해야 합니다.
Android 기계 학습 테스트 도구 모음
Android 기계 학습 테스트 도구 모음(MLTS)은 공급업체 기기에서 실제 모델의 정확성을 검증하기 위해 CTS 및 VTS에 포함된 NNAPI 벤치마크입니다. 벤치마크는 대기 시간과 정확도를 평가하고 동일한 모델 및 데이터 세트에 대해 드라이버의 결과를 CPU에서 실행되는 TF Lite 를 사용한 결과와 비교합니다. 이렇게 하면 드라이버의 정확도가 CPU 참조 구현보다 나쁘지 않습니다.
Android 플랫폼 개발자는 또한 MLTS를 사용하여 드라이버의 지연 시간과 정확도를 평가합니다.
NNAPI 벤치마크는 AOSP의 두 프로젝트에서 찾을 수 있습니다.
-
platform/test/mlts/benchmark
(벤치마크 앱) -
platform/test/mlts/models
(모델 및 데이터 세트)
모델 및 데이터 세트
NNAPI 벤치마크는 다음 모델과 데이터 세트를 사용합니다.
- 서로 다른 크기로 양자화된 MobileNetV1 float 및 u8은 Open Images Dataset v4의 작은 하위 집합(1500개 이미지)에 대해 실행됩니다.
- 서로 다른 크기로 양자화된 MobileNetV2 float 및 u8은 Open Images Dataset v4의 작은 하위 집합(1500개 이미지)에 대해 실행됩니다.
- 텍스트 음성 변환을 위한 LSTM(Long Short-Term Memory) 기반 음향 모델은 CMU Arctic 집합의 작은 하위 집합에 대해 실행됩니다.
- 자동 음성 인식을 위한 LSTM 기반 음향 모델은 LibriSpeech 데이터 세트의 작은 하위 집합에 대해 실행됩니다.
자세한 내용은 platform/test/mlts/models
를 참조하십시오.
스트레스 테스트
Android Machine Learning Test Suite에는 사용량이 많은 조건이나 클라이언트 동작의 코너 케이스에서 드라이버의 복원력을 검증하기 위한 일련의 충돌 테스트가 포함되어 있습니다.
모든 충돌 테스트는 다음 기능을 제공합니다.
- 중단 감지: 테스트 중에 NNAPI 클라이언트가 중단되면 실패 이유
HANG
과 함께 테스트가 실패하고 테스트 스위트가 다음 테스트로 이동합니다. - NNAPI 클라이언트 크래시 감지: 테스트는 클라이언트 크래시 후에도 유지되고 테스트는 실패 이유
CRASH
로 실패합니다. - 드라이버 충돌 감지: 테스트는 NNAPI 호출 실패를 유발하는 드라이버 충돌을 감지할 수 있습니다. NNAPI 오류를 일으키지 않고 테스트 실패를 일으키지 않는 드라이버 프로세스에 충돌이 있을 수 있습니다. 이러한 종류의 실패를 처리하려면 드라이버 관련 오류 또는 충돌에 대한 시스템 로그에서
tail
명령을 실행하는 것이 좋습니다. - 사용 가능한 모든 가속기 대상 지정: 테스트는 사용 가능한 모든 드라이버에 대해 실행됩니다.
모든 충돌 테스트에는 다음과 같은 네 가지 가능한 결과가 있습니다.
-
SUCCESS
: 오류 없이 실행이 완료되었습니다. -
FAILURE
: 실행에 실패했습니다. 일반적으로 모델을 테스트할 때 오류가 발생하여 드라이버가 모델을 컴파일하거나 실행하지 못했음을 나타냅니다. -
HANG
: 테스트 프로세스가 응답하지 않게 되었습니다. -
CRASH
: 테스트 프로세스가 충돌했습니다.
스트레스 테스트 및 전체 충돌 테스트 목록에 대한 자세한 내용은 platform/test/mlts/benchmark/README.txt
를 참조하세요.
MLTS 사용
MLTS를 사용하려면:
- 대상 장치를 워크스테이션에 연결하고 adb 를 통해 연결할 수 있는지 확인합니다. 둘 이상의 장치가 연결된 경우 대상 장치
ANDROID_SERIAL
환경 변수를 내보냅니다. cd
를 통해 Android 최상위 소스 디렉토리로 이동합니다.source build/envsetup.sh lunch aosp_arm-userdebug # Or aosp_arm64-userdebug if available. ./test/mlts/benchmark/build_and_run_benchmark.sh
벤치마크 실행이 끝나면 결과가 HTML 페이지로 표시되고
xdg-open
으로 전달됩니다.
자세한 내용은 platform/test/mlts/benchmark/README.txt
를 참조하세요.
신경망 HAL 버전
이 섹션에서는 Android 및 Neural Networks HAL 버전에 도입된 변경 사항에 대해 설명합니다.
안드로이드 11
Android 11에는 다음과 같은 주요 변경사항이 포함된 NN HAL 1.3이 도입되었습니다.
- NNAPI에서 부호 있는 8비트 양자화를 지원합니다.
TENSOR_QUANT8_ASYMM_SIGNED
피연산자 유형을 추가합니다. 부호 없는 양자화 작업을 지원하는 NN HAL 1.3 드라이버는 해당 작업의 서명된 변형도 지원해야 합니다. 대부분의 양자화된 작업의 서명된 버전과 서명되지 않은 버전을 실행할 때 드라이버는 오프셋 128까지 동일한 결과를 생성해야 합니다. 이 요구 사항에는CAST
,HASHTABLE_LOOKUP
,LSH_PROJECTION
,PAD_V2
및QUANTIZED_16BIT_LSTM
의 5가지 예외가 있습니다.QUANTIZED_16BIT_LSTM
연산은 부호 있는 피연산자를 지원하지 않으며 다른 네 개의 연산은 부호 있는 양자화를 지원하지만 결과가 동일할 필요는 없습니다. - 프레임워크가
IPreparedModel::executeFenced
메서드를 호출하여 대기할 동기화 펜스 벡터가 있는 준비된 모델에서 펜스 비동기 실행을 시작하는 펜스 실행을 지원합니다. 자세한 정보는 분리된 실행 을 참조하십시오. - 제어 흐름을 지원합니다. 다른 모델을 인수로 사용하여 조건부(
IF
) 또는 반복적으로(WHILE
) 실행하는IF
및WHILE
연산을 추가합니다. 자세한 내용은 제어 흐름 을 참조하세요. - 앱이 모델의 상대적 우선순위, 모델 준비에 예상되는 최대 시간, 실행 완료에 예상되는 최대 시간을 표시할 수 있으므로 서비스 품질(QoS)이 향상됩니다. 자세한 내용 은 서비스 품질을 참조하십시오.
- 드라이버 관리 버퍼에 대한 할당자 인터페이스를 제공하는 메모리 도메인 지원. 이를 통해 실행 간에 장치 기본 메모리를 전달할 수 있으므로 동일한 드라이버에서 연속 실행 간에 불필요한 데이터 복사 및 변환을 억제할 수 있습니다. 자세한 내용은 메모리 도메인 을 참조하십시오.
안드로이드 10
Android 10에는 다음과 같은 주요 변경사항이 포함된 NN HAL 1.2가 도입되었습니다.
-
Capabilities
구조체는 스칼라 데이터 유형을 포함한 모든 데이터 유형을 포함하며 명명된 필드가 아닌 벡터를 사용하여 완화되지 않은 성능을 나타냅니다. -
getVersionString
및getType
메서드를 사용하면 프레임워크에서 장치 유형(DeviceType
) 및 버전 정보를 검색할 수 있습니다. 장치 검색 및 할당을 참조하십시오. -
executeSynchronously
메서드는 동기적으로 실행을 수행하기 위해 기본적으로 호출됩니다.execute_1_2
메서드는 프레임워크에 비동기적으로 실행을 수행하도록 지시합니다. 실행 을 참조하십시오. -
executeSynchronously
,execute_1_2
및 버스트 실행에 대한MeasureTiming
매개 변수는 드라이버가 실행 기간을 측정할지 여부를 지정합니다. 결과는Timing
구조에 보고됩니다. 타이밍 을 참조하십시오. - 하나 이상의 출력 피연산자가 알 수 없는 차원 또는 순위를 갖는 실행을 지원합니다. 출력 형태 를 참조하십시오.
- 공급업체 정의 작업 및 데이터 유형의 모음인 공급업체 확장 지원. 드라이버는
IDevice::getSupportedExtensions
메서드를 통해 지원되는 확장을 보고합니다. 공급업체 확장 을 참조하십시오. - 앱과 드라이버 프로세스 간에 통신하기 위해 FMQ(빠른 메시지 대기열)를 사용하여 일련의 버스트 실행을 제어하는 버스트 객체의 기능으로 대기 시간을 줄입니다. 버스트 실행 및 빠른 메시지 대기열을 참조하십시오.
- 드라이버가 데이터를 복사하지 않고 실행을 수행할 수 있도록 AHardwareBuffer를 지원합니다. AHardwareBuffer 를 참조하십시오.
- 앱이 시작될 때 컴파일에 사용되는 시간을 줄이기 위해 컴파일 아티팩트 캐싱에 대한 지원이 개선되었습니다. 컴파일 캐싱 을 참조하십시오.
Android 10에는 다음과 같은 피연산자 유형 및 연산이 도입되었습니다.
-
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
-
-
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에서는 많은 기존 작업이 업데이트되었습니다. 업데이트는 주로 다음과 관련이 있습니다.
- NCHW 메모리 레이아웃 지원
- 소프트맥스 및 정규화 작업에서 순위가 4가 아닌 텐서 지원
- 확장된 컨볼루션 지원
-
ANEURALNETWORKS_CONCATENATION
에서 혼합 양자화가 있는 입력 지원
아래 목록은 Android 10에서 수정된 작업을 보여줍니다. 변경사항에 대한 자세한 내용은 NNAPI 참조 문서의 OperationCode 를 참조하세요.
-
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
안드로이드 9
NN HAL 1.1은 Android 9에 도입되었으며 다음과 같은 주요 변경사항을 포함합니다.
-
IDevice::prepareModel_1_1
에는ExecutionPreference
매개변수가 포함되어 있습니다. 운전자는 이를 사용하여 앱이 배터리 절약을 선호하거나 빠른 연속 호출로 모델을 실행할 것임을 알고 준비를 조정할 수 있습니다. - 9개의 새로운 작업이 추가되었습니다:
BATCH_TO_SPACE_ND
,DIV
,MEAN
,PAD
,SPACE_TO_BATCH_ND
,SQUEEZE
,STRIDED_SLICE
,SUB
,TRANSPOSE
. - 앱은
Model.relaxComputationFloat32toFloat16
을true
로 설정하여 16비트 부동 범위 및/또는 정밀도를 사용하여 32비트 부동 계산을 실행할 수 있도록 지정할 수 있습니다.Capabilities
구조체에는 드라이버가 완화된 성능을 프레임워크에 보고할 수 있도록relaxedFloat32toFloat16Performance
라는 추가 필드가 있습니다.
안드로이드 8.1
초기 Neural Networks HAL(1.0)은 Android 8.1에서 출시되었습니다. 자세한 내용은 /neuralnetworks/1.0/
을 참조하십시오.