GenAI Image Description API

ML Kit의 GenAI Image Description API를 사용하면 이미지에 대한 짧은 콘텐츠 설명을 생성할 수 있습니다. 이는 다음과 같은 사용 사례에서 유용할 수 있습니다.

  • 이미지 제목 생성
  • 시각 장애 사용자가 이미지의 콘텐츠를 더 잘 이해할 수 있도록 대체 텍스트 (alt 텍스트) 생성
  • 생성된 설명을 메타데이터로 사용하여 사용자가 이미지를 검색하거나 정리할 수 있도록 지원
  • 사용자가 화면을 볼 수 없는 경우(예: 운전 중 또는 팟캐스트 듣기 중) 이미지에 대한 짧은 설명을 활용합니다.

주요 기능

  • 입력 이미지에 대한 간단한 설명을 반환합니다.

결과 예시

입력 출력
선인장 같은 디자인의 초록색 소형 Android 로봇이 검은색 표면에 놓여 있습니다. 선인장 같은 디자인의 초록색 소형 Android 로봇이 검은색 표면에 놓여 있습니다.
검은색 코와 분홍색 혀를 가진 작은 흰색 강아지가 배경에 다리가 있는 풀밭을 가로질러 달립니다. 검은색 코와 분홍색 혀를 가진 작은 흰색 강아지가 배경에 다리가 있는 풀밭을 가로질러 달립니다.

시작하기

GenAI Image Description API를 시작하려면 프로젝트의 빌드 파일에 이 종속 항목을 추가합니다.

implementation("com.google.mlkit:genai-image-description:1.0.0-beta1")

Image Description API를 앱에 통합하려면 먼저 ImageDescriber 클라이언트를 가져와야 합니다. 그런 다음 필요한 기기 내 모델 기능의 상태를 확인하고 기기에 아직 없는 경우 모델을 다운로드해야 합니다. ImageDescriptionRequest에서 이미지 입력을 준비한 후 클라이언트를 사용하여 추론을 실행하여 이미지 설명 텍스트를 가져옵니다. 마지막으로 클라이언트를 닫아 리소스를 해제해야 합니다.

Kotlin

// Create an image describer
val options = ImageDescriberOptions.builder(context).build()
val imageDescriber = ImageDescription.getClient(options)

suspend fun prepareAndStartImageDescription(
    bitmap: Bitmap
) {
  // Check feature availability, status will be one of the following:
  // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
  val featureStatus = imageDescriber.checkFeatureStatus().await()

  if (featureStatus == FeatureStatus.DOWNLOADABLE) {
      // Download feature if necessary.
      // If downloadFeature is not called, the first inference request
      // will also trigger the feature to be downloaded if it's not
      // already downloaded.
      imageDescriber.downloadFeature(object : DownloadCallback {
          override fun onDownloadStarted(bytesToDownload: Long) { }

          override fun onDownloadFailed(e: GenAiException) { }

          override fun onDownloadProgress(totalBytesDownloaded: Long) {}

          override fun onDownloadCompleted() {
              startImageDescriptionRequest(bitmap, imageDescriber)
          }
      })
  } else if (featureStatus == FeatureStatus.DOWNLOADING) {
      // Inference request will automatically run once feature is
      // downloaded.
      // If Gemini Nano is already downloaded on the device, the
      // feature-specific LoRA adapter model will be downloaded
      // very quickly. However, if Gemini Nano is not already
      // downloaded, the download process may take longer.
      startImageDescriptionRequest(bitmap, imageDescriber)
  } else if (featureStatus == FeatureStatus.AVAILABLE) {
      startImageDescriptionRequest(bitmap, imageDescriber)
  }
}

fun startImageDescriptionRequest(
    bitmap: Bitmap,
    imageDescriber: ImageDescriber
) {
    // Create task request
    val imageDescriptionRequest = ImageDescriptionRequest
        .builder(bitmap)
        .build()
}

  // Run inference with a streaming callback
  val imageDescriptionResultStreaming =
      imageDescriber.runInference(imageDescriptionRequest) { outputText ->
          // Append new output text to show in UI
          // This callback is called incrementally as the description
          // is generated
      }

  // You can also get a non-streaming response from the request
  // val imageDescription = imageDescriber.runInference(
  //        imageDescriptionRequest).await().description
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
imageDescriber.close()

자바

// Create an image describer
ImageDescriberOptions options = ImageDescriberOptions.builder(context).build();
ImageDescriber imageDescriber = ImageDescription.getClient(options);

void prepareAndStartImageDescription(
      Bitmap bitmap
) throws ExecutionException, InterruptedException {
  // Check feature availability, status will be one of the following:
  // UNAVAILABLE, DOWNLOADABLE, DOWNLOADING, AVAILABLE
  try {
      int featureStatus = imageDescriber.checkFeatureStatus().get();
      if (featureStatus == FeatureStatus.DOWNLOADABLE) {
          // Download feature if necessary.
          // If downloadFeature is not called, the first inference request
          // will also trigger the feature to be downloaded if it's not
          // already downloaded.
          imageDescriber.downloadFeature(new DownloadCallback() {
              @Override
              public void onDownloadCompleted() {
                  startImageDescriptionRequest(bitmap, imageDescriber);
              }

              @Override
              public void onDownloadFailed(GenAIException e) {}

              @Override
              public void onDownloadProgress(long totalBytesDownloaded) {}

              @Override
              public void onDownloadStarted(long bytesDownloaded) {}
          });
      } else if (featureStatus == FeatureStatus.DOWNLOADING) {
          // Inference request will automatically run once feature is
          // downloaded.
          // If Gemini Nano is already downloaded on the device, the
          // feature-specific LoRA adapter model will be downloaded
          // very quickly. However, if Gemini Nano is not already
          // downloaded, the download process may take longer.
          startImageDescriptionRequest(bitmap, imageDescriber);
      } else if (featureStatus == FeatureStatus.AVAILABLE) {
          startImageDescriptionRequest(bitmap, imageDescriber);
      }
  } catch (ExecutionException | InterruptedException e) {
      e.printStackTrace();
  }
}

void startImageDescriptionRequest(
     Bitmap bitmap,
     ImageDescriber imageDescriber
) {
  // Create task request
  ImageDescriptionRequest imageDescriptionRequest =
          ImageDescriptionRequest.builder(bitmap).build();

  // Start image description request with streaming response
  imageDescriber.runInference(imageDescriptionRequest, newText -> {
      // Append new output text to show in UI
      // This callback is called incrementally as the description
      // is generated
  });

  // You can also get a non-streaming response from the request
  // String imageDescription = imageDescriber.runInference(
  //        imageDescriptionRequest).get().getDescription();
}

// Be sure to release the resource when no longer needed
// For example, on viewModel.onCleared() or activity.onDestroy()
imageDescriber.close();

지원되는 기능 및 제한사항

GenAI Image Description API는 영어를 지원하며 향후 더 많은 언어가 추가될 예정입니다. API는 이미지에 관한 간단한 설명을 하나 반환합니다.

특정 기능 구성 (ImageDescriberOptions로 지정됨)의 사용 가능 여부는 특정 기기의 구성과 기기에 다운로드된 모델에 따라 다를 수 있습니다.

개발자가 요청된 ImageDescriberOptions가 있는 기기에서 의도한 API 기능이 지원되는지 확인하는 가장 안정적인 방법은 checkFeatureStatus() 메서드를 호출하는 것입니다. 이 메서드는 런타임에 기기의 기능 사용 가능 여부에 관한 확실한 상태를 제공합니다.

일반적인 설정 문제

ML Kit GenAI API는 Android AICore 앱을 사용하여 Gemini Nano에 액세스합니다. 기기가 설정된 직후 (초기화 포함)이거나 AICore 앱이 초기화된 직후 (예: 데이터 삭제, 제거 후 재설치)에는 AICore 앱이 초기화를 완료할 시간이 충분하지 않을 수 있습니다 (서버에서 최신 구성 다운로드 포함). 따라서 ML Kit GenAI API가 예상대로 작동하지 않을 수 있습니다. 다음은 표시될 수 있는 일반적인 설정 오류 메시지와 처리 방법입니다.

오류 메시지 예 처리 방법
AICore가 오류 유형 4-CONNECTION_ERROR 및 오류 코드 601-BINDING_FAILURE으로 실패했습니다. AICore 서비스가 바인딩되지 않았습니다. 이는 기기 설정 직후 ML Kit GenAI API를 사용하여 앱을 설치하거나 앱이 설치된 후 AICore가 제거될 때 발생할 수 있습니다. AICore 앱을 업데이트한 후 앱을 재설치하면 문제가 해결됩니다.
AICore가 오류 유형 3-PREPARATION_ERROR 및 오류 코드 606-FEATURE_NOT_FOUND: Feature ... is not available 오류로 실패했습니다. 이는 AICore가 최신 구성 다운로드를 완료하지 않은 경우 발생할 수 있습니다. 네트워크 연결을 유지하고 몇 분에서 몇 시간 정도 기다립니다.

기기의 부트로더가 잠금 해제된 경우에도 이 오류가 표시됩니다. 이 API는 부트로더가 잠금 해제된 기기를 지원하지 않습니다.
AICore가 오류 유형 1-DOWNLOAD_ERROR 및 오류 코드 0-UNKNOWN으로 실패했습니다. 기능 ... 실패 상태 0 및 오류 esz: UNAVAILABLE: 호스트를 확인할 수 없음 ... 네트워크 연결을 유지하고 몇 분 정도 기다린 후 다시 시도합니다.