TensorFlow Lite용 GPU 위임

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

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

이 문서에서는 TensorFlow Lite의 GPU 지원 개요와 GPU 프로세서의 고급 용도를 설명합니다. 특정 플랫폼에서 GPU 지원을 구현하는 방법에 관한 자세한 내용은 다음 가이드를 참고하세요.

GPU ML 작업 지원

TensorFlow Lite GPU 위임을 통해 TensorFlow ML 작업(ops)을 가속화할 수 있는 항목에는 몇 가지 제한사항이 있습니다. 위임은 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 가속에 사용하기에 적합하지 않음을 나타낼 수 있으며 모델 리팩터링이 필요할 수 있습니다.

예시 모델

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

GPU 최적화

다음 기법은 TensorFlow Lite GPU 대리자를 사용하여 GPU 하드웨어에서 모델을 실행할 때 더 나은 성능을 얻는 데 도움이 될 수 있습니다.

  • 작업의 형태 변경 - CPU에서 빠른 일부 작업은 휴대기기의 GPU 비용이 높을 수 있습니다. 형태 변경 작업은 특히 BATCH_TO_SPACE, SPACE_TO_BATCH, SPACE_TO_DEPTH 등을 포함하여 실행 비용이 많이 듭니다. 형태 변경 작업의 사용을 면밀히 검토해야 하며 데이터 탐색 또는 모델의 초기 반복에만 적용되었을 수 있다는 점을 고려해야 합니다. 이러한 필드를 삭제하면 성능이 크게 향상될 수 있습니다.

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

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

고급 GPU 지원

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

양자화 모델 사용

이 섹션에서는 GPU 대리자가 다음을 포함하여 8비트 양자화 모델을 가속화하는 방법을 설명합니다.

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

어떤 방식으로 작동하나요?

GPU 백엔드는 부동 소수점 실행만 지원하므로 원래 모델의 '부동 소수점 뷰'를 제공하여 양자화 모델을 실행합니다. 이를 개략적으로 설명하면 다음과 같은 단계가 포함됩니다.

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

  • GPU 프로그램에 대한 입력 및 출력은 8비트가 양자화되는 경우 각 추론에 대해 각각 양자화되지 않고 양자화됩니다. 이 작업은 TensorFlow Lite의 최적화된 커널을 사용하여 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;
      

Java

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

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

직렬화 기능을 사용할 때는 코드가 다음 구현 규칙을 준수하는지 확인하세요.

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