작동 방식

Qualcomm® AI Hub 는 비전, 오디오 및 음성 사용 사례를 위해 디바이스에서 머신 러닝 모델을 최적화, 검증 및 배포하는 데 도움을 줍니다.

Qualcomm® AI Hub 는 무엇을 측정합니까?

Qualcomm® AI Hub 에서 프로파일 작업은 최적화된 모델을 다양한 물리적 디바이스에서 실행하는 데 필요한 리소스를 측정합니다. 수집된 메트릭은 모델이 시간과 메모리 예산 내에 맞는지 여부를 결정하는 데 도움이 되도록 설계되었습니다.

개요

프로파일은 사용자의 디바이스에서 타겟 모델을 실행하는 데 필요한 네 가지 단계로 수집됩니다.

  1. 컴파일 – 디바이스에서 컴파일을 지원하는 플랫폼에서는 시스템이 충분히 안정적이고 리소스를 존중하는 툴체인을 제공할 때 관련 메트릭을 보고합니다.

  2. 첫 번째 앱 로드 – 모델이 처음 로드될 때 운영 체제는 모델을 실행 중인 디바이스에 맞게 추가로 최적화할 수 있습니다. 예를 들어, Qualcomm® Hexagon™ 프로세서와 같은 신경 처리 장치(NPU)가 사용 가능한 경우 모델은 해당 하드웨어에서 실행되도록 준비됩니다. 결과는 일반적으로 캐시되어 이후 로드 속도를 빠르게 합니다.

  3. 후속 앱 로드 – 모델이 두 번째로 로드될 때부터는 비용이 많이 드는 디바이스별 최적화를 피할 수 있습니다.

  4. 추론 – 모델이 로드된 후, Hub는 추론을 수행합니다. 프로파일링 작업은 무작위 데이터를 준비하고 모델을 여러 번 반복 실행합니다.

아래 설명된 시간과 메모리 수치는 각 단계별로 수집이 됩니다.

시간

많은 단계는 한 번만 실행할 수 있습니다. 예를 들어, 첫 번째 앱 로드 후 모든 프레임워크 및 OS 캐시를 지우는 것은 종종 불가능합니다. 따라서 추론만 여러 번 측정됩니다.

여러 반복에 걸쳐 Hub는 모델을 평가하는 데 필요한 시간을 측정합니다. 비용에는 추론 프레임워크 호출 비용과 약간의 오버헤드만 포함됩니다.

추론 시간 측정은 모델을 다른 노이즈로부터 격리하여 원자 단위로 최적화할 수 있도록 하는 마이크로벤치마크입니다. 입력은 배치당 한 번만 생성되고 여러 반복에 재사용됩니다. Hub는 모델 최적화로 줄어들지 않는 노이즈를 제외한 최소 관찰 시간을 보고합니다.

메모리

앱의 메모리 사용량을 특성화하는 방법은 여러 가지가 있습니다. 그러나 대부분의 개발자는 운영 체제의 관점에서 앱의 메모리 사용량을 알고 싶어합니다. 결국, 이는 앱이 종료되거나 메모리를 정리하도록 요청받는지 여부를 결정합니다. 아래에서 설명하듯이, 이것조차 예측하기 어려울 수 있습니다. 명확하고 포괄적인 메모리 메트릭을 제공하기 위해 Hub는 단일 숫자 메트릭보다 더 정확한 범위를 보고합니다.

가상 메모리

현대 운영 체제는 사용자 프로세스와 물리적 메모리 사이에 가상 메모리 라고 불리는 추상화 계층을 제공합니다. 프로세스가 메모리를 요청할 때, 몇 개의 주소만 물리적 메모리에 즉시 매핑됩니다. 대신, OS는 일부 주소 범위가 약속되었고 그것들이 깨끗한 상태임을 기록하는 내부 기록을 수행합니다.

깨끗한 상태의 메모리는 쓰여지지 않았기 때문에 시스템이 메모리가 부족할 때 내용을 보존할 필요가 없습니다. 프로세스가 메모리에 쓰면, 그것은 더러워져서 OS가 데이터 손실 없이 독립적으로 내용을 삭제할 수 없습니다. 일정 기간 동안 액세스되지 않은 더러운 메모리 조각은 디스크에 데이터를 쓰거나(스왑) 메모리를 압축하여 더 작게 만들지만 일시적으로 사용할 수 없게 하여 관련 물리적 메모리를 해제할 수 있습니다. 앱의 메모리 풋프린트 는 더럽고, 스왑되고, 압축된 메모리의 합계입니다.

대부분의 Unix 계열 운영 체제, Android 및 Linux를 포함하여, 가상 메모리가 물리적 저장소에 매핑될 수 있음을 보장하지 않습니다. 글로벌 사용량이 높으면, 수요가 사용 가능한 물리적 메모리와 디스크 스왑을 초과할 수 있습니다. 그럴 경우, 시스템은 메모리를 많이 사용하는 프로세스를 종료하여 안정성을 유지하려고 시도합니다. Windows는 다른 접근 방식을 취합니다: 프로세스가 가상 메모리를 할당할 때, 시스템은 물리적 메모리 및/또는 페이지 파일에 내용을 저장할 것을 약속 하여 글로벌 수요가 시스템 용량을 초과하지 않도록 보장합니다. 시스템이 메모리가 부족해지지 않기 때문에, 과도하게 할당된 프로세스를 종료할 필요가 없습니다.

OS는 현대 디바이스에서 상상할 수 없을 정도로 큰 가상 주소 공간을 관리해야 합니다. 가상 주소를 임의의 작은 할당에 매핑하는 데 필요한 메타데이터는 커널에 부담이 됩니다. 따라서 시스템에는 최소 할당 크기인 페이지 가 있으며, 이는 일반적으로 4-16 KB 범위입니다. 물론, 프로그램은 일반적으로 단일 페이지보다 훨씬 작은 객체를 생성합니다. 메모리를 효율적으로 사용하기 위해, malloc 은 여러 프로그램 객체를 하나 이상의 OS 페이지에 패킹하는 인터페이스로 사용됩니다.

../_images/Malloc-In-Context.png

그림 1: 가상 메모리는 운영 체제에 의해 페이지 단위로 할당되며, 이는 깨끗하거나(녹색으로 표시됨) 깨끗하지 않을 수 있습니다. Malloc은 이러한 큰 페이지에 작은 객체를 효율적으로 패킹하는 인터페이스입니다. 이 예제에서는 256 바이트의 사용자 데이터가 단일 4,096 바이트 페이지에 패킹되어 있으며, 3,840 바이트는 향후 malloc 호출을 위해 사용 가능합니다.

그림 1은 단순화된 가상 메모리 주소 공간을 보여줍니다. 깨끗한 영역은 OS가 사용자 코드를 실행하지 않고 재생성할 수 있는 영역입니다. 이는 일반적으로 이러한 페이지가 변경되지 않는 파일에 의해 지원되거나 단순히 쓰여지지 않았기 때문입니다. 일부 운영 체제의 관점에서, 깨끗하지 않은 페이지는 애플리케이션의 메모리 풋프린트를 구성합니다: 앱에 너무 많은 더럽고, 스왑되고, 압축된 페이지가 있으면, 시스템이 메모리가 부족할 때 종료될 위험이 있습니다.

대부분의 런타임 데이터는 malloc에 의해 관리되며, 그 더러운 페이지는 부분적으로만 사용될 수 있습니다. 이 예제에서는 256 바이트의 사용자 데이터가 4 KB 페이지에 보관되어 있지만, 3,840 바이트는 사용되지 않습니다. 실제 애플리케이션에서는 모델 컴파일 및 로드와 같은 메모리를 많이 사용하는 작업이 malloc 관리 페이지에 상당한 양의 사용되지 않은 공간을 남길 수 있습니다. 이 메모리는 일반적으로 후속 단계에서 재사용될 수 있습니다.

메모리 풋프린트를 계산할 때, OS 제공 도구 및 API는 malloc 관리 페이지의 사용되지 않은 메모리 양을 인식하지 못합니다. 이 사용되지 않은 메모리의 일부 또는 전부가 재사용될 수 있기 때문에, Android에서는 Hub가 최상의 경우 완전 재사용을 가정하고 최악의 경우 재사용하지 않는 범위로 메모리 사용량을 보고합니다.

위에서 언급했듯이, 상황은 Windows에서 다릅니다. 시스템이 예기치 않게 메모리가 부족해지는 것이 불가능하기 때문에, 사용자의 프로세스를 종료할 수 있는 메모리 모니터가 없습니다. 따라서, Windows에서는 Hub의 메모리 사용량 메트릭이 이미 할당된 힙 공간이 후속 요구에 의해 재사용되지 않을 것을 가정합니다. 보고된 범위의 양 끝은 가상 메모리 할당의 합계인 프로세스 커밋 차지입니다. 작업 집합 크기와 같은 추가 메트릭은 런타임 로그 파일에서 찾을 수 있습니다.

피크 대 증가

작업을 완료하는 데 사용되는 메모리는 일반적으로 결과의 크기를 초과합니다. 모델을 컴파일하는 시나리오를 고려해 보십시오; 컴파일러에 메모리 누수가 없다고 가정하면, 디바이스 모델을 컴파일된 모델로 변환하는 데 일정량의 메모리가 필요하며, 디스크에 아티팩트를 남기고 메모리에 객체가 없습니다. 컴파일러가 40 MB를 사용했다면, 우리는 그것의 피크 사용량이 40 MB였지만, 메모리 사용량의 안정 상태 증가 는 0 바이트였다고 말할 것입니다.

특정 메모리 메트릭

모든 것을 종합하면, 프로파일링 작업은 표 1에 표시된 것과 유사한 메모리 메트릭을 반환합니다. 예제의 CNN 모델 소스는 54 MB이며, 디바이스에서 컴파일하는 동안 약 163 MB가 사용되었지만, 컴파일된 모델이 디스크에 유지된 후에는 메모리가 사용되지 않았다는 것은 놀라운 일이 아닙니다. 증가 의 상한은 최악의 시나리오를 보고하며, 컴파일 후 남은 0.7 MB의 사용되지 않은 malloc 관리 메모리가 앱에 의해 재사용되지 않을 것이라고 가정합니다. 마찬가지로, 모델을 로드한 후 앱에 의해 보유된 데이터 양은 초기 로드 후 더 많은 사용되지 않은 malloc 관리 메모리를 남겼지만, 첫 번째 및 후속 로드 간에 실제로 다르지 않을 가능성이 높습니다. 초기 로드가 더 많은 작업을 수행했기 때문에 더 많은 할당이 있었을 가능성이 높습니다.

표 1: 대형 CNN 모델의 메모리 메트릭.

단계

피크

증가

컴파일

162.7 - 163.4 MB

0.0 - 0.7 MB

첫 앱 로드

1.7 - 2.8 MB

0.6 - 1.7 MB

후속 앱 로드

1.8 - 2.5 MB

0.8 - 1.6 MB

추론

629.6 - 630.6 MB

378.7 - 379.6 MB

Hub에서는 메모리 압박에 가장 중요한 기여를 강조하는 피크 범위를 제공합니다. 이는 OS가 앱을 종료할 수 있습니다. 이러한 메트릭 및 기타 모든 메트릭은 Python 클라이언트 라이브러리에서 사용할 수 있습니다. 메모리 및 시간 메트릭의 전체 세트는 표 2에 나와 있습니다.

표2: ProfileJob.download_profile 의 결과로 반환된 execution_summary 의 메트릭.

유형

단위

compile_memory_increase_range

(int, int)

Bytes

compile_memory_peak_range

(int, int)

Bytes

first_load_memory_increase_range

(int, int)

Bytes

first_load_memory_peak_range

(int, int)

Bytes

warm_load_memory_increase_range

(int, int)

Bytes

warm_load_memory_peak_range

(int, int)

Bytes

inference_memory_increase_range

(int, int)

Bytes

inference_memory_peak_range

(int, int)

Bytes

compile_time

int

Microseconds

first_load_time

int

Microseconds

warm_load_time

int

Microseconds

estimated_inference_time

int

Microseconds