LiteRT in Google Play services CompiledModel Kotlin and Java API

The CompiledModel API is the recommended interface for running machine learning (ML) models with the LiteRT in Google Play services runtime. It runs your model on CPU or GPU through one API, without including the LiteRT runtime in your APK.

You use the same CompiledModel and TensorBuffer classes as standalone LiteRT (com.google.ai.edge.litert). Only the Environment instance comes from Google Play services. For general information about the CompiledModel API, see the CompiledModel Kotlin API guide.

1. Add project dependencies

Add the Google Play services LiteRT dependency to your app's build.gradle file. This package pulls in com.google.ai.edge.litert:litert-api transitively, so you do not need to declare litert-api separately.

dependencies {
  ...
  // LiteRT CompiledModel API dependency for Google Play services, version
  // 17.0.0 or later
  implementation 'com.google.android.gms:play-services-litert:17.0.0'
  // Optional: For Kotlin coroutines Task.await() support
  implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-play-services:1.10.2'
  ...
}

2. Initialize the LiteRT Environment

Initialize a LiteRT Environment from Google Play services using LiteRt.initialize(context) before creating a CompiledModel:

Kotlin

import com.google.ai.edge.litert.Environment
import com.google.android.gms.litert.LiteRt
import kotlinx.coroutines.tasks.await
...
// Initialize the Environment from Google Play services with an Android
// context object.
val env: Environment = LiteRt.initialize(context).await()

Java

import com.google.ai.edge.litert.Environment;
import com.google.android.gms.litert.LiteRt;
import com.google.android.gms.tasks.Task;
...
// Initialize the Environment from Google Play services with an Android
// context object.
//
// Callback pattern is recommended for Java to avoid blocking the thread.
// Tasks.await() is used here for simplicity.
Environment env = Tasks.await(LiteRt.initialize(context));

3. Create a CompiledModel and run inference (CPU)

Once the Environment is initialized, pass it to CompiledModel.create() along with CompiledModel.Options(Accelerator.CPU) to load the model on the CPU, and allocate input and output TensorBuffers.

Kotlin

import android.content.Context
import com.google.ai.edge.litert.Accelerator
import com.google.ai.edge.litert.CompiledModel
import com.google.ai.edge.litert.Environment
import com.google.ai.edge.litert.TensorBuffer
import com.google.android.gms.litert.LiteRt
import kotlinx.coroutines.tasks.await
...
// 1. Initialize the Environment and CompiledModel once off the main thread
val env: Environment = LiteRt.initialize(context).await()
val model =
  CompiledModel.create(
    context.assets,
    "model.tflite",
    CompiledModel.Options(Accelerator.CPU),
    env,
  )
val inputBuffers: List<TensorBuffer> = model.createInputBuffers()
val outputBuffers: List<TensorBuffer> = model.createOutputBuffers()

// 2. Run inference (reuse the compiled model and buffers across calls)
inputBuffers[0].writeFloat(inputData)
model.run(inputBuffers, outputBuffers)
val output: FloatArray = outputBuffers[0].readFloat()

// 3. Close resources when no longer needed
inputBuffers.forEach { it.close() }
outputBuffers.forEach { it.close() }
model.close()
env.close()

Java

import android.content.Context;
import com.google.ai.edge.litert.Accelerator;
import com.google.ai.edge.litert.CompiledModel;
import com.google.ai.edge.litert.Environment;
import com.google.ai.edge.litert.TensorBuffer;
import com.google.android.gms.litert.LiteRt;
import com.google.android.gms.tasks.Tasks;
import java.util.List;
...
// 1. Initialize the Environment and CompiledModel once off the main thread

// Callback pattern is recommended for Java to avoid blocking the thread.
// Tasks.await() is used here for simplicity.
Environment env = Tasks.await(LiteRt.initialize(context));
CompiledModel model =
    CompiledModel.create(
        context.getAssets(),
        "model.tflite",
        new CompiledModel.Options(Accelerator.CPU),
        env);
List<TensorBuffer> inputBuffers = model.createInputBuffers();
List<TensorBuffer> outputBuffers = model.createOutputBuffers();

// 2. Run inference (reuse the compiled model and buffers across calls)
inputBuffers.get(0).writeFloat(inputData);
model.run(inputBuffers, outputBuffers);
float[] output = outputBuffers.get(0).readFloat();

// 3. Close resources when no longer needed
for (TensorBuffer buffer : inputBuffers) {
  buffer.close();
}
for (TensorBuffer buffer : outputBuffers) {
  buffer.close();
}
model.close();
env.close();

4. Hardware acceleration

With the CompiledModel API in Google Play services, you can accelerate model inference across hardware accelerators:

  • CPU acceleration: Supported by default (Accelerator.CPU).
  • GPU acceleration: Supported on devices with a compatible GPU (Accelerator.GPU).
  • NPU acceleration: Available in standalone LiteRT; support in Google Play services is coming soon.

GPU acceleration

LiteRT's GPU accelerator is built on the open-source ML Drift engine. No extra dependency is needed for GPU acceleration—the play-services-litert package supports both CPU and GPU execution.

To use GPU acceleration with the CompiledModel API in Google Play services, first enable GPU accelerator support in LiteRtInitializationOptions when initializing the Environment with LiteRt.initialize(context, initOptions):

Kotlin

import com.google.ai.edge.litert.Environment
import com.google.android.gms.litert.LiteRt
import com.google.android.gms.litert.LiteRtDsl.initializationOptions
import kotlinx.coroutines.tasks.await
...
val initOptions = initializationOptions {
  setEnableGpu(true)
}
val env: Environment = LiteRt.initialize(context, initOptions).await()

Java

import com.google.ai.edge.litert.Environment;
import com.google.android.gms.litert.LiteRt;
import com.google.android.gms.litert.client.LiteRtInitializationOptions;
import com.google.android.gms.tasks.Task;
...
LiteRtInitializationOptions initOptions =
    LiteRtInitializationOptions.builder()
        .setEnableGpu(true)
        .build();
Task<Environment> environmentTask =
    LiteRt.initialize(context, initOptions);

Then create the CompiledModel with Accelerator.GPU and Accelerator.CPU to CompiledModel.Options so that LiteRT automatically falls back to CPU execution if GPU acceleration is unavailable on the device:

Kotlin

import com.google.ai.edge.litert.Accelerator
import com.google.ai.edge.litert.CompiledModel
...
// Specify GPU with CPU fallback if GPU is unavailable on the device
val model =
  CompiledModel.create(
    context.assets,
    "model.tflite",
    CompiledModel.Options(Accelerator.GPU, Accelerator.CPU),
    env,
  )

Java

import com.google.ai.edge.litert.Accelerator;
import com.google.ai.edge.litert.CompiledModel;
import com.google.ai.edge.litert.Environment;
import com.google.android.gms.tasks.Tasks;
...
// Callback pattern is recommended for Java to avoid blocking the thread.
// Tasks.await() is used here for simplicity.
Environment env = Tasks.await(environmentTask);

// Specify GPU with CPU fallback if GPU is unavailable on the device
CompiledModel model =
    CompiledModel.create(
        context.getAssets(),
        "model.tflite",
        new CompiledModel.Options(Accelerator.GPU, Accelerator.CPU),
        env);

Migrating from standalone LiteRT

If you are migrating an existing app from standalone LiteRT to the Google Play services runtime with the CompiledModel API, update your project using the following steps:

  1. Check that LiteRT in Google Play services fits your app.
  2. In your build.gradle file, remove the standalone LiteRT runtime dependencies (com.google.ai.edge.litert:litert and com.google.ai.edge.litert:litert-gpu) and add the Google Play services LiteRT dependency. This package provides the com.google.ai.edge.litert API classes (CompiledModel, TensorBuffer, Environment, and Accelerator) while loading the runtime dynamically from Google Play services to reduce your app size:

    dependencies {
        ...
        // Remove standalone LiteRT runtime dependencies:
        // implementation 'com.google.ai.edge.litert:litert:...'
        // implementation 'com.google.ai.edge.litert:litert-gpu:...'
    
        // Add the Google Play services LiteRT dependency:
        implementation 'com.google.android.gms:play-services-litert:17.0.0'
        ...
    }
    
  3. Replace standalone Environment.create() calls (or CompiledModel.create() calls that omit the Environment parameter) with LiteRt.initialize() from com.google.android.gms.litert.LiteRt:

    • For CPU inference: Call LiteRt.initialize(context).
    • For GPU acceleration: Configure LiteRtInitializationOptions with setEnableGpu(true) and call LiteRt.initialize(context, initOptions).
  4. Because LiteRt.initialize() is asynchronous and returns a Task<Environment>, wait for the task to complete (using Kotlin coroutines .await(), addOnSuccessListener(), or Tasks.await() on a background thread) and pass the initialized Environment explicitly to CompiledModel.create().

  5. Keep your buffer allocation and inference execution code unchanged. All other CompiledModel and TensorBuffer methods—such as createInputBuffers(), createOutputBuffers(), writeFloat(), run(), and readFloat()—work identically to standalone LiteRT.

The following example compares model initialization in standalone LiteRT with the Google Play services runtime:

Kotlin

// Before (standalone LiteRT):
// val env = Environment.create()
// val model = CompiledModel.create(
//   context.assets,
//   "model.tflite",
//   CompiledModel.Options(Accelerator.CPU),
//   env,
// )

// After (Google Play services):
val env = LiteRt.initialize(context).await()
val model = CompiledModel.create(
  context.assets,
  "model.tflite",
  CompiledModel.Options(Accelerator.CPU),
  env,
)

Java

// Before (standalone LiteRT):
// Environment env = Environment.create();
// CompiledModel model =
//     CompiledModel.create(
//         context.getAssets(),
//         "model.tflite",
//         new CompiledModel.Options(Accelerator.CPU),
//         env);

// After (Google Play services):
// Callback pattern is recommended for Java to avoid blocking the thread.
// Tasks.await() is used here for simplicity.
Environment env = Tasks.await(LiteRt.initialize(context));
CompiledModel model =
    CompiledModel.create(
        context.getAssets(),
        "model.tflite",
        new CompiledModel.Options(Accelerator.CPU),
        env);