Руководство по выводу LLM для Android

API вывода LLM позволяет полностью запускать большие языковые модели (LLM) на устройстве для приложений Android, что позволяет выполнять широкий спектр задач, таких как генерация текста, извлечение информации на естественном языке и реферирование документов. Эта задача обеспечивает встроенную поддержку нескольких больших языковых моделей преобразования текста в текст, что позволяет применять новейшие модели генеративного ИИ на устройстве в своих приложениях Android.

Чтобы быстро добавить API вывода LLM в приложение Android, следуйте краткому руководству . Пример приложения Android, работающего с API вывода LLM, можно найти в примере приложения . Более подробное понимание работы API вывода LLM см. в разделах «Параметры конфигурации» , «Преобразование моделей » и «Настройка LoRA» .

Вы можете увидеть эту задачу в действии с помощью демо-версии MediaPipe Studio . Подробнее о возможностях, моделях и вариантах настройки этой задачи см. в разделе «Обзор» .

Быстрый старт

Чтобы добавить API вывода LLM в приложение Android, выполните следующие действия. API вывода LLM оптимизирован для высокопроизводительных устройств Android, таких как Pixel 8 и Samsung S23 или более поздние модели, и не поддерживает эмуляторы устройств.

Добавить зависимости

API вывода LLM использует библиотеку com.google.mediapipe:tasks-genai . Добавьте эту зависимость в файл build.gradle вашего приложения для Android:

dependencies {
    implementation 'com.google.mediapipe:tasks-genai:0.10.27'
}

Загрузить модель

Загрузите Gemma-3 1B в 4-битном квантованном формате с сайта Hugging Face . Подробнее о доступных моделях см. в документации по моделям .

Отправьте содержимое папки output_path на устройство Android.

$ adb shell rm -r /data/local/tmp/llm/ # Remove any previously loaded models
$ adb shell mkdir -p /data/local/tmp/llm/
$ adb push output_path /data/local/tmp/llm/model_version.task

Инициализировать задачу

Инициализируйте задачу с базовыми параметрами конфигурации:

// Set the configuration options for the LLM Inference task
val taskOptions = LlmInferenceOptions.builder()
        .setModelPath('/data/local/tmp/llm/model_version.task')
        .setMaxTopK(64)
        .build()

// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, taskOptions)

Выполнить задачу

Используйте метод generateResponse() для генерации текстового ответа. В результате будет сгенерирован один ответ.

val result = llmInference.generateResponse(inputPrompt)
logger.atInfo().log("result: $result")

Для потоковой передачи ответа используйте метод generateResponseAsync() .

val options = LlmInference.LlmInferenceOptions.builder()
  ...
  .setResultListener { partialResult, done ->
    logger.atInfo().log("partial result: $partialResult")
  }
  .build()

llmInference.generateResponseAsync(inputPrompt)

Образец заявления

Чтобы увидеть API вывода LLM в действии и изучить широкий спектр возможностей генеративного ИИ на устройстве, ознакомьтесь с приложением Google AI Edge Gallery .

Галерея Google AI Edge Gallery — это приложение для Android с открытым исходным кодом, которое служит интерактивной игровой площадкой для разработчиков. В нём представлены:

  • Практические примеры использования API вывода LLM для различных задач, включая:
    • Задайте вопрос по изображению: загрузите изображение и задайте вопросы по нему. Получите описание, решите задачи или идентифицируйте объекты.
    • Лабораторная работа: подытоживайте, переписывайте, генерируйте код или используйте подсказки свободной формы для изучения вариантов использования LLM в один оборот.
    • AI Chat: участвуйте в многопользовательских беседах.
  • Возможность находить, загружать и экспериментировать с различными оптимизированными для LiteRT моделями из сообщества Hugging Face LiteRT и официальных релизов Google (например, Gemma 3N).
  • Тесты производительности устройств в реальном времени для разных моделей (время до первого токена, скорость декодирования и т. д.).
  • Как импортировать и тестировать собственные пользовательские модели .litertlm или .task .

Это приложение — ресурс для понимания практической реализации API вывода LLM и потенциала генеративного ИИ на устройстве. Изучите исходный код и скачайте приложение из репозитория Google AI Edge Gallery на GitHub .

Параметры конфигурации

Для настройки приложения для Android используйте следующие параметры конфигурации:

Название опции Описание Диапазон значений Значение по умолчанию
modelPath Путь к месту хранения модели в каталоге проекта. ПУТЬ Н/Д
maxTokens Максимальное количество токенов (входные токены + выходные токены), которые обрабатывает модель. Целое число 512
topK Количество токенов, которые модель учитывает на каждом этапе генерации. Ограничивает прогнозы k наиболее вероятными токенами. Целое число 40
temperature Степень случайности, вносимая при генерации. Более высокая температура приводит к большей креативности в генерируемом тексте, тогда как более низкая температура обеспечивает более предсказуемую генерацию. Плавать 0,8
randomSeed Случайное начальное число, используемое при генерации текста. Целое число 0
loraPath Абсолютный путь к модели LoRA локально на устройстве. Примечание: совместимо только с моделями на базе графических процессоров. ПУТЬ Н/Д
resultListener Настраивает прослушиватель результатов на асинхронное получение результатов. Применимо только при использовании метода асинхронной генерации. Н/Д Н/Д
errorListener Устанавливает необязательный прослушиватель ошибок. Н/Д Н/Д

Мультимодальные подсказки

API вывода LLM. API Android поддерживают многомодальные подсказки с моделями, принимающими текст, изображения и аудио. При включении многомодальности пользователи могут включать в подсказки комбинации изображений и текста или аудио и текста. Затем LLM предоставляет текстовый ответ.

Для начала используйте вариант Gemma 3n , совместимый с MediaPipe:

  • Gemma-3n E2B : эффективная модель 2B семейства Gemma-3n.
  • Gemma-3n E4B : эффективная модель 4B семейства Gemma-3n.

Более подробную информацию см. в документации Gemma-3n .

Чтобы включить ввод изображения или звука для API вывода LLM, выполните следующие действия.

Ввод изображения

Чтобы предоставить изображения в приглашении, преобразуйте входные изображения или кадры в объект com.google.mediapipe.framework.image.MPImage перед передачей его в API вывода LLM:

import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage

// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(image).build()

Чтобы включить поддержку машинного зрения для API вывода LLM, установите для параметра конфигурации EnableVisionModality значение true в параметрах Graph:

LlmInferenceSession.LlmInferenceSessionOptions sessionOptions =
  LlmInferenceSession.LlmInferenceSessionOptions.builder()
    ...
    .setGraphOptions(GraphOptions.builder().setEnableVisionModality(true).build())
    .build();

Установите максимум 10 изображений за сеанс.

LlmInferenceOptions options = LlmInferenceOptions.builder()
  ...
  .setMaxNumImages(10)
  .build();

Ниже приведен пример реализации API вывода LLM, настроенного для обработки входных данных изображения и текста:

MPImage image = getImageFromAsset(BURGER_IMAGE);

LlmInferenceSession.LlmInferenceSessionOptions sessionOptions =
  LlmInferenceSession.LlmInferenceSessionOptions.builder()
    .setTopK(10)
    .setTemperature(0.4f)
    .setGraphOptions(GraphOptions.builder().setEnableVisionModality(true).build())
    .build();

try (LlmInference llmInference =
    LlmInference.createFromOptions(ApplicationProvider.getApplicationContext(), options);
  LlmInferenceSession session =
    LlmInferenceSession.createFromOptions(llmInference, sessionOptions)) {
  session.addQueryChunk("Describe the objects in the image.");
  session.addImage(image);
  String result = session.generateResponse();
}

Аудиовход

Включить поддержку звука в LlmInferenceOptions

val inferenceOptions = LlmInference.LlmInferenceOptions.builder()
  ...
  .setAudioModelOptions(AudioModelOptions.builder().build())
  .build()

Включить поддержку звука в sessionOptions

    val sessionOptions =  LlmInferenceSessionOptions.builder()
      ...
      .setGraphOptions(GraphOptions.builder().setEnableAudioModality(true).build())
      .build()

Передавать аудиоданные во время вывода. Примечание: аудио должно быть моноканальным и иметь формат .wav.


val audioData: ByteArray = ...
inferenceEngine.llmInferenceSession.addAudio(audioData)

Ниже приведен пример реализации API вывода LLM, настроенного для обработки аудио- и текстовых входных данных:

val audioData: ByteArray = ...
val inferenceOptions = LlmInference.LlmInferenceOptions.builder()
  ...
  .setAudioModelOptions(AudioModelOptions.builder().build())
  .build()
val sessionOptions =  LlmInferenceSessionOptions.builder()
  ...
  .setGraphOptions(GraphOptions.builder().setEnableAudioModality(true).build())
  .build()

LlmInference.createFromOptions(context, inferenceOptions).use { llmInference ->
  LlmInferenceSession.createFromOptions(llmInference, sessionOptions).use { session ->
    session.addQueryChunk("Transcribe the following speech segment:")
    session.addAudio(audioData)
    val result = session.generateResponse()
  }
}

Настройка LoRA

API вывода LLM поддерживает настройку LoRA (адаптация низкого ранга) с помощью библиотеки PEFT (эффективная тонкая настройка параметров). Настройка LoRA настраивает поведение LLM посредством экономичного процесса обучения, создавая небольшой набор обучаемых весов на основе новых обучающих данных, а не переобучая всю модель.

API вывода LLM поддерживает добавление весов LoRA к слоям внимания моделей Gemma-2 2B , Gemma 2B и Phi-2 . Загрузите модель в формате safetensors .

Для создания весовых коэффициентов LoRA базовая модель должна быть в формате safetensors . После обучения LoRA модели можно преобразовать в формат FlatBuffers для запуска в MediaPipe.

Подготовить веса LoRA

Используйте руководство по методам LoRA от PEFT для обучения точно настроенной модели LoRA на вашем собственном наборе данных.

API вывода LLM поддерживает LoRA только на уровнях внимания, поэтому укажите только уровни внимания в LoraConfig :

# For Gemma
from peft import LoraConfig
config = LoraConfig(
    r=LORA_RANK,
    target_modules=["q_proj", "v_proj", "k_proj", "o_proj"],
)

# For Phi-2
config = LoraConfig(
    r=LORA_RANK,
    target_modules=["q_proj", "v_proj", "k_proj", "dense"],
)

После обучения на подготовленном наборе данных и сохранения модели, точно настроенные веса модели LoRA доступны в файле adapter_model.safetensors . Файл safetensors представляет собой контрольную точку LoRA, используемую при конвертации модели.

Преобразование модели

Используйте пакет Python MediaPipe для преобразования весовых коэффициентов модели в формат Flatbuffer. ConversionConfig указаны базовые параметры модели и дополнительные параметры LoRA.

import mediapipe as mp
from mediapipe.tasks.python.genai import converter

config = converter.ConversionConfig(
  # Other params related to base model
  ...
  # Must use gpu backend for LoRA conversion
  backend='gpu',
  # LoRA related params
  lora_ckpt=LORA_CKPT,
  lora_rank=LORA_RANK,
  lora_output_tflite_file=LORA_OUTPUT_FILE,
)

converter.convert_checkpoint(config)

Конвертер создаст два файла Flatbuffer: один для базовой модели и другой для модели LoRA.

Вывод модели LoRA

Android поддерживает статическую модель LoRA во время инициализации. Чтобы загрузить модель LoRA, укажите путь к ней, а также базовый LLM.

// Set the configuration options for the LLM Inference task
val options = LlmInferenceOptions.builder()
        .setModelPath(BASE_MODEL_PATH)
        .setMaxTokens(1000)
        .setTopK(40)
        .setTemperature(0.8)
        .setRandomSeed(101)
        .setLoraPath(LORA_MODEL_PATH)
        .build()

// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, options)

Чтобы запустить вывод LLM с LoRA, используйте те же методы generateResponse() или generateResponseAsync() что и в базовой модели.