LiteRT용 GPU 위임

그래픽 처리 장치 (GPU)를 사용하여 머신러닝 (ML) 모델을 실행하면 모델의 성능과 ML 지원 애플리케이션의 사용자 환경을 크게 개선할 수 있습니다. LiteRT를 사용하면 대리자라는 하드웨어 드라이버를 통해 GPU 및 기타 특수 프로세서를 사용할 수 있습니다. LiteRT ML 애플리케이션에서 GPU를 사용 설정하면 다음과 같은 이점이 있습니다.

  • 속도 - GPU는 대규모 병렬 워크로드의 높은 처리량을 위해 빌드됩니다. 이 설계로 인해 이러한 칩은 병렬로 처리할 수 있는 입력 텐서에서 각각 작동하는 수많은 연산자로 구성된 심층 신경망에 적합하며, 일반적으로 지연 시간이 짧아집니다. 최상의 시나리오에서는 GPU에서 모델을 실행하면 이전에는 불가능했던 실시간 애플리케이션을 지원할 수 있을 만큼 빠르게 실행될 수 있습니다.
  • 전력 효율성 - GPU는 매우 효율적이고 최적화된 방식으로 ML 계산을 실행하며, 일반적으로 CPU에서 동일한 작업을 실행하는 것보다 전력을 적게 소비하고 열을 적게 생성합니다.

이 문서에서는 LiteRT의 GPU 지원과 GPU 프로세서의 고급 사용 사례를 간략하게 설명합니다. 특정 플랫폼에서 GPU 지원을 구현하는 방법에 관한 자세한 내용은 다음 가이드를 참고하세요.

GPU ML 작업 지원

LiteRT GPU 위임으로 가속화할 수 있는 TensorFlow ML 작업(작업)에는 몇 가지 제한사항이 있습니다. 위임자는 16비트 및 32비트 부동 소수점 정밀도로 다음 작업을 지원합니다.

  • ADD
  • AVERAGE_POOL_2D
  • CONCATENATION
  • CONV_2D
  • DEPTHWISE_CONV_2D v1-2
  • EXP
  • FULLY_CONNECTED
  • LOGICAL_AND
  • LOGISTIC
  • LSTM v2 (Basic LSTM only)
  • MAX_POOL_2D
  • MAXIMUM
  • MINIMUM
  • MUL
  • PAD
  • PRELU
  • RELU
  • RELU6
  • RESHAPE
  • RESIZE_BILINEAR v1-3
  • SOFTMAX
  • STRIDED_SLICE
  • SUB
  • TRANSPOSE_CONV

기본적으로 모든 작업은 버전 1에서만 지원됩니다. 양자화 지원을 사용 설정하면 적절한 버전(예: ADD v2)이 사용 설정됩니다.

GPU 지원 문제 해결

일부 작업이 GPU 위임에 의해 지원되지 않으면 프레임워크는 그래프의 일부만 GPU에서 실행하고 나머지는 CPU에서 실행합니다. CPU/GPU 동기화 비용이 높기 때문에 이와 같은 분할 실행 모드는 전체 네트워크가 CPU에서만 실행될 때보다 성능이 느려지는 경우가 많습니다. 이 경우 애플리케이션에서 다음과 같은 경고를 생성합니다.

WARNING: op code #42 cannot be handled by this delegate.

실제 런타임 실패가 아니므로 이러한 유형의 실패에 대한 콜백은 없습니다. GPU 대리자를 사용하여 모델 실행을 테스트할 때는 이러한 경고에 주의해야 합니다. 이러한 경고가 많이 표시되면 모델이 GPU 가속에 적합하지 않다는 의미일 수 있으며 모델을 리팩터링해야 할 수 있습니다.

예시 모델

다음 예시 모델은 LiteRT를 사용하여 GPU 가속을 활용하도록 빌드되었으며 참조 및 테스트용으로 제공됩니다.

GPU에 최적화

다음 기법을 사용하면 LiteRT GPU 대리자를 사용하여 GPU 하드웨어에서 모델을 실행할 때 성능을 개선할 수 있습니다.

  • Reshape 작업 - CPU에서 빠른 일부 작업은 모바일 기기의 GPU에서 비용이 많이 들 수 있습니다. BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH 등을 비롯한 재구성 작업은 실행하는 데 특히 비용이 많이 듭니다. reshape 작업의 사용을 자세히 살펴보고 데이터 탐색이나 모델의 초기 반복에만 적용되었을 수 있음을 고려해야 합니다. 이러한 항목을 삭제하면 성능이 크게 향상될 수 있습니다.

  • 이미지 데이터 채널 - GPU에서 텐서 데이터는 4채널로 슬라이스되므로 [B,H,W,5] 모양의 텐서에 대한 계산은 [B,H,W,8] 모양의 텐서에 대한 계산과 거의 동일하지만 [B,H,W,4]보다는 훨씬 나쁩니다. 사용 중인 카메라 하드웨어가 RGBA의 이미지 프레임을 지원하는 경우 3채널 RGB에서 4채널 RGBX로의 메모리 복사를 방지하므로 4채널 입력을 공급하는 것이 훨씬 빠릅니다.

  • 모바일 최적화 모델 - 최상의 성능을 위해 모바일 최적화 네트워크 아키텍처로 분류기를 재학습하는 것이 좋습니다. 온디바이스 추론을 위한 최적화는 모바일 하드웨어 기능을 활용하여 지연 시간과 전력 소비를 크게 줄일 수 있습니다.

고급 GPU 지원

GPU 처리와 함께 양자화, 직렬화 등 고급 기술을 추가로 사용하여 모델의 성능을 더욱 개선할 수 있습니다. 다음 섹션에서는 이러한 기법을 자세히 설명합니다.

양자화된 모델 사용

이 섹션에서는 GPU 위임이 다음을 비롯한 8비트 양자화 모델을 가속화하는 방법을 설명합니다.

성능을 최적화하려면 부동 소수점 입력 및 출력 텐서가 모두 있는 모델을 사용하세요.

작동 방식

GPU 백엔드는 부동 소수점 실행만 지원하므로 원래 모델의 '부동 소수점 뷰'를 제공하여 양자화된 모델을 실행합니다. 대략적으로 다음 단계를 따릅니다.

  • 상수 텐서 (예: 가중치/편향)는 GPU 메모리로 한 번 역양자화됩니다. 이 작업은 대리자가 LiteRT에 사용 설정된 경우에 발생합니다.

  • 8비트 양자화된 경우 GPU 프로그램의 입력 및 출력은 각 추론에 대해 역양자화되고 양자화됩니다 (각각). 이 작업은 LiteRT의 최적화된 커널을 사용하여 CPU에서 실행됩니다.

  • 양자화 시뮬레이터는 양자화된 동작을 모방하기 위해 작업 사이에 삽입됩니다. 이 접근 방식은 작업에서 활성화가 양자화 중에 학습된 경계를 따를 것으로 예상하는 모델에 필요합니다.

GPU 위임으로 이 기능을 사용 설정하는 방법은 다음을 참고하세요.

직렬화로 초기화 시간 단축

GPU 위임 기능은 이전에 실행된 적이 있는 사전 컴파일된 커널 코드와 직렬화되어 디스크에 저장된 모델 데이터를 로드할 수 있도록 지원합니다. 이 접근 방식은 재컴파일을 방지하고 시작 시간을 최대 90%까지 줄일 수 있습니다. 이 개선사항은 디스크 공간을 시간 절약과 교환하여 달성됩니다. 다음 코드 예와 같이 몇 가지 구성 옵션으로 이 기능을 사용 설정할 수 있습니다.

C++

    TfLiteGpuDelegateOptionsV2 options = TfLiteGpuDelegateOptionsV2Default();
    options.experimental_flags |= TFLITE_GPU_EXPERIMENTAL_FLAGS_ENABLE_SERIALIZATION;
    options.serialization_dir = kTmpDir;
    options.model_token = kModelToken;

    auto* delegate = TfLiteGpuDelegateV2Create(options);
    if (interpreter->ModifyGraphWithDelegate(delegate) != kTfLiteOk) return false;
      

자바

    GpuDelegate delegate = new GpuDelegate(
      new GpuDelegate.Options().setSerializationParams(
        /* serializationDir= */ serializationDir,
        /* modelToken= */ modelToken));

    Interpreter.Options options = (new Interpreter.Options()).addDelegate(delegate);
      

직렬화 기능을 사용할 때는 코드가 다음 구현 규칙을 준수해야 합니다.

  • 다른 앱이 액세스할 수 없는 디렉터리에 직렬화 데이터를 저장합니다. Android 기기에서는 현재 애플리케이션에 비공개인 위치를 가리키는 getCodeCacheDir()를 사용하세요.
  • 모델 토큰은 특정 모델의 기기에 고유해야 합니다. farmhash::Fingerprint64과 같은 라이브러리를 사용하여 모델 데이터에서 지문을 생성하여 모델 토큰을 계산할 수 있습니다.