Вам больше не придется выбирать между удобством готовых ИИ-моделей и гибкостью собственных. Теперь вы можете развернуть оба варианта в одном ультракомпактном приложении, не увеличивая его размер.
На этом занятии мы покажем, как создать такую двухстековую архитектуру в одном приложении для Android. Вы узнаете, как использовать ML Kit для готовых классических задач машинного обучения (например, сканирования документов) вместе с LiteRT в сервисах Google Play для собственных рабочих нагрузок, связанных с компьютерным зрением или аудио. Мы подробно расскажем, как оба пути реализации объединяются под капотом, чтобы использовать современную среду выполнения LiteRT, обеспечивая вашему приложению бесперебойную работу с аппаратным ускорением на ЦП и графических процессорах с практически нулевым объемом загрузки.
Основные выводы для разработчиков:
– Высокая производительность. Для готовых и пользовательских моделей автоматически используется аппаратное ускорение с помощью унифицированного CompiledModel API.
– Микро-APK. Значительно уменьшите размер скачиваемого приложения, перенеся среды выполнения ML Kit и LiteRT в сервисы Google Play.
- Гибридная интеграция: научитесь запускать несколько рабочих процессов машинного обучения параллельно в рабочей среде без конфликтов ресурсов.
play-services-litert, вызовите LiteRt.initialize, чтобы получить среду, и передайте ее в CompiledModel.create.Расшифровка
Добрый вечер!
Мы скоро начнем.
Поэтому, когда сегодня говорят "ИИ на устройстве", часто имеют в виду LLM.
Ранее сегодня вы видели несколько докладов о Gemini Nano, которые были посвящены ML Kit, Firebase и многим другим продуктам Google.
На этом занятии мы поговорим о второй половине: классическом ML и моделях, которые вы создаете сами.
Возможно, вы уже пользовались им сегодня, даже не подозревая об этом.
Вспомните, в каких приложениях вы размывали фон, сканировали штрихкод или редактировали изображения.
Многие из них основаны на классическом машинном обучении и обычно выполняются на устройстве.
И если вы когда-либо добавляли какую-либо из этих функций в свое приложение или APK, вы часто сталкивались с этим компромиссом: использовать ли мне в основном готовый API или использовать собственную модель?
Как это повлияет на размер приложения?
Сегодня вы увидите, что вам не нужно выбирать между готовой моделью и собственной.
Вы можете сделать и то, и другое с помощью одной среды выполнения.
Меня зовут Чинтан Парих.
Я менеджер по продукту LiteRT, а со мной Фергус, технический руководитель сервисов машинного обучения Android.
Здравствуйте!
В конце вы увидите, как создать приложение, которое запускает две модели для каждого кадра камеры со скоростью около 30 кадров в секунду.
Итак, в этой лекции четыре части.
В первой части мы поговорим о решениях Google для ИИ на устройстве, сосредоточившись на классическом машинном обучении, то есть ML Kit и LiteRT.
Затем мы расскажем о том, что нового появилось в LiteRT и сервисах Google Play.
Мы также рассмотрим новый API CompiledModel из LiteRT и поддерживаемые устройства.
В-третьих, мы покажем вам, как создать новое приложение.
Фергус расскажет, как создать приложение с ML Kit и собственной моделью в одном APK.
И наконец, мы покажем, как обновить существующее приложение с помощью режима агента.
Вы даже можете создать новое приложение с помощью этого агента.
Теперь
Для начала давайте разберемся, что такое LiteRT.
LiteRT – это среда выполнения Google для инференса на устройстве, которая позволяет использовать собственные модели.
Она использует тот же формат файлов .tflite, что и TensorFlow Lite.
Он был переработан для повышения производительности и теперь поддерживает несколько фреймворков.
Это значит, что вы можете импортировать модели из PyTorch, TensorFlow и даже JAX, чтобы преобразовать их в формат FlatBuffer для LiteRT.
С 2022 года TensorFlow Lite в сервисах Google Play – это официальная среда выполнения на устройстве для пользовательских моделей в Android.
Сегодня мы представляем его обновленную версию, о которой и пойдет речь.
В обновлении будет представлен последний API LiteRT CompiledModel, включая новый улучшенный инференс графического процессора, который будет работать в 1,4 раза быстрее, а также позволит вам создавать приложения меньшего размера в гораздо более компактных размерах APK.
Почему же мы распространяем его через сервисы Google Play?
Есть несколько преимуществ, и это определенно большая проблема, которую я вижу во многих разговорах, которые я слышу, когда размер приложения и раздувание APK становятся реальной проблемой, верно?
Так что вы получаете небольшую среду выполнения.
Среда выполнения не входит в APK, поэтому вы полагаетесь на тонкий клиент, что уменьшает размер APK примерно на 8 МБ.
Второе преимущество – эффективность.
У вас есть одна копия среды выполнения, поэтому среда выполнения LiteRT используется всеми приложениями.
Представьте, что у вас много приложений и каждое из них экономит по 8 МБ.
Это очень важно, если вы хотите сэкономить место на диске и сделать приложение более компактным.
Во-вторых, он поддерживается.
Google исправляет ошибки, решает проблемы с драйверами графического процессора, а также автоматически устанавливает обновления системы безопасности.
Как я уже говорил, графический процессор стал быстрее – в 1,4 раза.Мы ещё поговорим об этом подробнее.
А с точки зрения охвата мы можем поставлять на старые устройства Android.
LiteRT в сервисах Google Play поддерживает все версии Android вплоть до Android 7, выпущенной в 2016 году.
Фергус также покажет вам другие новые устройства, на которые мы расширяем поддержку, на следующих слайдах.
Итак, это средство доставки, а теперь давайте поговорим о следующем шаге – среде выполнения.
Так что LiteRT – это не новая и не экспериментальная технология.
TensorFlow Lite и LiteRT уже работают более чем в 250 000 приложений.
Сегодня она работает более чем на 3,8 миллиарда устройств.
Так что многие приложения, которыми вы пользуетесь, могут работать на этой технологии, а вы даже не будете об этом знать.
И это также эквивалентно более чем триллиону выводов каждый день, верно?
При таком масштабе мы, конечно, сталкивались со всеми возможными проблемами с чипсетами, ПЗУ и драйверами графических процессоров, и у нас есть решение для вас.
LiteRT также используется в основных приложениях Google на разных платформах и устройствах.
Эффекты в YouTube Shorts, сегментация фона в Meet, повышение резкости фотографий – вот лишь несколько примеров, когда LiteRT используется для обработки видео в реальном времени и работы со сложными моделями изображений.
Это также крайне важно, поскольку сделать варианты использования быстрыми и привлекательными для пользователей становится критически важным, верно?
Это та же среда выполнения, которую мы укрепили для флагманских функций, и именно ее вы получаете через сервисы Google Play.
Давайте также поговорим о том, зачем вообще использовать ИИ на устройстве.
Задержка, конфиденциальность, работа в офлайн-режиме или низкие затраты – если что-то из этого имеет для вас значение, запускайте модель в офлайн-режиме.
Причин может быть больше, но это самые очевидные из тех, что мы слышали для запуска на устройстве.
Кроме того, запуск на устройстве не всегда бесплатен.
В этом есть свои нюансы и сложности.
Поэтому мы также рассмотрим некоторые из этих проблем и предложим вам пути их решения.
Итак, производительность. Как вы видели на примерах предыдущих приложений, задержка и бюджеты памяти всегда ограничены.
Для передачи видео и аудио в реальном времени требуется высокая эффективность.
Даже простые интерактивные функции должны работать быстро.
В противном случае вы потеряете вовлеченность пользователей.
Разнообразие аппаратного обеспечения. Существуют сотни процессоров с разными конфигурациями ЦП и графических процессоров.
Вы не можете написать код для всех этих устройств, верно?
Как вы решаете эти проблемы?
Размер APK. Включение нативной среды выполнения также увеличивает размер каждого скачивания, что может повлиять на коэффициент конверсии.
Настройка. Обучение модели, качество, размер модели – все это будет иметь решающее значение ещё до развертывания.
Да, создать отличное приложение для устройства может быть непросто.
Но в каждой из этих ситуаций мы хотим, чтобы платформа работала на вас, а не наоборот, верно?
Решения Google для локальной обработки данных на устройствах помогают справиться с этими сложностями. О них мы поговорим далее.
Поэтому сегодня мы сосредоточимся на двух простых решениях.
Добавить ИИ на устройстве через сервисы Google Play можно двумя простыми способами.
Путь 1 – это готовое решение с использованием ML Kit, верно?
Это готовые к использованию API для распознавания изображений и речи, для работы с которыми не требуется глубоких знаний в области ML. Все модели предоставляются через сервисы Google Play.
На следующих слайдах мы рассмотрим несколько примеров.
Специальный путь – через LiteRT.
LiteRT позволяет использовать собственную модель и запускать ее на ЦП или графическом процессоре.
Среда выполнения также предоставляется сервисами Google Play.
То есть вы не включаете его в APK.
These aren't either-or.
Они также могут быть лучше вместе.
Именно это мы и сделаем сегодня за пару минут.
Но сначала давайте поговорим о том, что входит в ML Kit.
Вот что ML Kit предлагает по умолчанию.
Итак, если вы уже думаете, что некоторые из этих возможностей соответствуют вашим потребностям, это отличная отправная точка, и у вас уже есть преимущество.
У нас есть API для распознавания изображений, штрихкодов, документов, текста, поз и многого другого, а также API для работы с языком, например для перевода, быстрых ответов и даже извлечения сущностей.
Главное, что многие из этих API для распознавания изображений и языка работают на основе LiteRT.
Если ML Kit подходит для ваших задач, начните с него.
А если нет, вы можете использовать собственную модель.
И вот ключевой момент: ML Kit и ваша пользовательская модель не будут двумя средами выполнения, верно, как я уже упоминал.
Это будут две входные двери, ведущие к одному и тому же LiteRT, который будет работать под капотом.
LiteRT будет средой выполнения Play, которая будет управлять обеими этими возможностями.
Поэтому, если ваше приложение уже использует ML Kit из Google Play, продолжайте в том же духе.
В противном случае мы также рассмотрим путь LiteRT.
Давайте также коснемся того, что нового в LiteRT.
Как я уже говорил, LiteRT – это эволюция TensorFlow Lite.
Итак, самые большие улучшения – это более быстрый графический процессор.
Более быстрый графический процессор поддерживает OpenCL, OpenGL и кросс-платформенные решения, в том числе для бэкендов Metal.
Так что вы можете использовать его для нескольких платформ.
и проще.
У нас есть один унифицированный рабочий процесс для ускорения ЦП, графического процессора и NPU.
ЦП и графический процессор сейчас находятся в сервисах Google Play, а нейронный процессор поставляется через LiteRT.
То есть раньше для каждого ускорителя требовалась отдельная настройка делегата, верно?
Теперь это нужно сделать только один раз.
Таким образом, существует один API с автоматическим возвратом к ЦП, и вам не нужно выполнять специальные делегированные настройки.
И вы можете просто использовать вызовы ускорителя, которые могут управлять этим гораздо проще и с меньшим количеством кода.
Кроме того, это мощная модель, которая, как я уже говорил, работает на нескольких платформах.
Это будет иметь решающее значение, гибкость этой части.
Формат .tflite остается прежним.
Если у вас уже есть приложение, вы можете использовать этот формат.
Если вы создаете новое приложение, вы можете снова использовать этот формат файла.
Интересно также, что мы поддерживаем Interpreter API, который раньше был в TensorFlow Lite.
Если вы хотите переходить на новую версию постепенно, то Interpreter API также включен в LiteRT, что упрощает переход.
Это время выполнения.
Давайте поговорим о том, что вы можете создать с помощью этого.
Вот что создают разработчики приложений для Android сегодня.
Эффекты камеры, редактирование фото, умный ввод, игры, аватары – все это, верно?
Многим из этих приложений потребуются возможности реального времени.
Графический процессор отправляет кадры прямо с камеры, поэтому важно, чтобы все работало быстро и в реальном времени.
Некоторые из этих моделей для редактирования фотографий также становятся тяжелее.
То же самое касается возможностей AR/VR, которые вы также видели в некоторых демонстрациях с очками, многие из них работают на LiteRT.
Та же среда выполнения, которая используется во флагманских функциях Google и сервисах Google Play. Вам не нужно ничего добавлять в APK-файл.
Теперь давайте создадим приложение, и Фергус покажет нам, как это сделать.
Давайте сделаем это.
С уважением, Чинтан
Итак, я немного расскажу о том, что нового в LiteRT в сервисах Google Play.
И ещё одна новость перед тем, как мы начнем сборку. Все, что вы только что видели, работает не только на телефонах. LiteRT в сервисах Google Play также доступен на Wear OS и Android Automotive OS.
Поэтому вы можете запускать модели на устройстве, например на часах, другом носимом устройстве или в автомобиле.
Раньше можно было использовать приложение на телефоне, которое было бы сопутствующим приложением для Wear, но теперь вы можете запустить его на самом носимом устройстве, и то же самое с Android Automotive.
Таким образом, у вас есть один и тот же API, одна и та же модель .tflite, но больше поверхностей.
Вам не нужно создавать отдельную реализацию для каждого типа устройств.
Прелесть модели распространения сервисов Google Play в том, что мы можем перенести эту функцию на более старые устройства.
Для Android Automotive OS мы поддерживаем версии, начиная с Android 11, выпущенной в 2020 году, а для Wear OS – Wear OS 4 и более поздние.
Окей.
Теперь я расскажу о двух разных путях: создании нового приложения и обновлении существующего.
Об этом мы и поговорим.
Итак, я начну с примера приложения, в котором используется ML Kit с пользовательской моделью графического процессора, работающей на LiteRT.
А для обновления существующего приложения потребуется внести три небольших изменения: обновить зависимости в Gradle, включить LiteRT в сервисах Google Play и перейти с Interpreter API на CompiledModel API.
Но сначала мы расскажем о новом приложении, чтобы вы понимали, на что переходите.
Итак, создание нового приложения.
Вот приложение, которое мы собираемся создать.
Вы будете в фокусе, а фон станет художественным.
Итак, мы собираемся взять рамку камеры.
Изображения из кадра камеры мы будем передавать через сегментацию селфи ML Kit.
Это один из существующих готовых API ML Kit.
И это создаст маску переднего плана, которая в основном будет говорить, какие из пикселей на изображении соответствуют человеку на изображении.
Затем мы возьмем нашу пользовательскую модель, которая похожа на модель переноса стиля, и применим стиль к изображению.
Мы применим его ко всему кадру, но нас интересует только фон. В конце мы возьмем исходный кадр, маску и стилизованный фон и объединим их, чтобы получить композитный кадр, в котором объект останется прежним, а фон будет стилизован.
Поэтому мы используем готовые API, где это возможно, и собственные API, чтобы выделить наше приложение.
Итак, это первая часть, в которой мы вызываем API сегментации селфи ML Kit.
// 1. Configure and create segmenter client
val segmenter = Segmentation.getClient(
SelfieSegmenterOptions.Builder()
.setDetectorMode(
SelfieSegmenterOptions.STREAM_MODE)
.build())
// 2. Prepare image & run inference
fun processFrame(mediaImage: Image) {
val image = InputImage.fromMediaImage(
mediaImage, /* rotationDegrees= */ 0)
segmenter.process(image)
.addOnSuccessListener { mask -> … }
}То есть это обычный API?
Это основа основ для разработчиков Android.
Вы просто смотрите документацию по API или просите Gemini создать его для вас.
Но, знаете, это довольно просто.
Вы создаете клиент и передаете ему некоторые параметры.
В этом случае мы указываем режим потоковой передачи, чтобы мы могли обрабатывать кадры видео.
Затем вы вызываете метод process, и обратный вызов из него получает маску, которая возвращается и вычисляется сегментацией селфи.
А входные данные – это изображение с камеры.
И все эти API используют типы на уровне приложения, а не необработанные тензоры, поэтому вы действительно программируете на очень высоком уровне, и это действительно просто.
Для второй части, пользовательской модели, мы возьмем модель PyTorch.
Думаю, Чинтан взял это из Kaggle или Hugging Face…
Справа.
Да, или вы можете конвертировать свои собственные.
Вы можете создать собственную модель.
Извините, возвращаюсь.
Да, вот так выглядит этот стек.
Вы берете модель PyTorch, конвертируете и квантуете ее, а затем получаете модель LiteRT.
Затем вы можете распространять его вместе с приложением любым удобным способом.
Его можно включить в приложение в качестве объекта или скачать отдельно.
Оба варианта подходят.
которая, в свою очередь, работает на базе среды выполнения LiteRT в сервисах Google Play.
А ещё есть ядра ЦП для оптимизации на ЦП, и ML Drift – это название ускорителя графического процессора.
Да, как я уже сказал, вы получаете модель TFLite, которую можете обучить самостоятельно или найти существующую модель, оба варианта работают.
Для преобразования из PyTorch требуется всего несколько строк кода на Python.
import litert_torch
model = my_models.Stylizer().eval()
# Convert with torch.export under the hood
edge_model = litert_torch.convert(
model, sample_inputs)
edge_model.export("stylizer_f32.tflite")Итак, вы устанавливаете LiteRT-Torch с помощью pip, вызываете litert_torch.convert, передаете ему некоторые sample_inputs, которые могут быть случайными входными данными, и экспортируете файл TFLite.
Кстати, LiteRT-Torch – это новое название ai-edge-torch, если вы знакомы с этим инструментом.
Квантование тоже выполняется очень просто.
# Python
# previously ai_edge_quantizer
from litert_quantizer import quantizer, recipe
qt = quantizer.Quantizer("stylizer_f32.tflite")
# int8 weights, float activations
qt.load_quantization_recipe(
recipe.dynamic_wi8_afp32())
qt.quantize().export_model("stylizer_int8.tflite")Вы импортируете квантователь и рецепт из LiteRT Quantizer.
При создании квантователя вы передаете исходную модель с плавающей запятой, вы передаете рецепт, который является стандартным рецептом, который мы используем, который мы рекомендуем для графического процессора, который использует 8-битные целочисленные веса, но сохраняет активации как 32-битные с плавающей запятой.
Затем вы просто вызываете quantize, а затем export_model, чтобы сохранить выходную модель.
В результате вы получите квантованную модель, которая будет работать быстрее и эффективнее.
Да, API CompiledModel и графический процессор – это то, что нужно.
Итак, как упомянул Чинтан, вы знаете, значительное ускорение на устаревшем графическом процессоре TFLite.
Точные цифры будут немного отличаться от модели к модели, но вы можете рассчитывать на увеличение в 1,4 раза.
До 10 раз быстрее, чем инференс на ЦП, так что это, знаете ли, большая победа, верно?
Если вы используете модели, то, скорее всего, запускаете их на ЦП и упускаете возможность повысить производительность в 10 раз, которую может дать графический процессор.
Это отличный стимул.
Что делает его быстрым?
Итак, мы поддерживаем множество вещей, например, асинхронное выполнение, поэтому вы можете взять AHardwareBuffer и передать его напрямую или буфер OpenGL из этого конвейера рендеринга камеры, передать его прямо в буфер тензора.
Оптимизация без копирования. Мы поддерживаем оптимизацию без копирования, поэтому вы можете обрабатывать данные с низким бюджетом задержки. Например, если вам нужно обрабатывать каждый кадр за несколько десятков миллисекунд, то даже простое копирование буфера памяти может быть нетривиальной нагрузкой.
Поэтому для приложений с высокими требованиями к работе в реальном времени мы поддерживаем оптимизацию с нулевым копированием.
И, как уже упоминал Чинтан, это кроссплатформенная библиотека с поддержкой OpenGL, OpenCL и Metal в качестве серверных частей графического процессора.
И последнее, но не менее важное: ML Drift Optimizer – это инструмент с открытым исходным кодом.
Она доступна по лицензии Apache.
Недавно Google открыла исходный код этого инструмента.
Хорошо, а вот код приложения.
// Kotlin
// Build once, off the main thread.
private val model: CompiledModel =
CompiledModel.create(
context.assets,
"stylizer_int8.tflite",
// Simple GPU setup!
CompiledModel.Options(Accelerator.GPU),
environment
)
// Reuse buffers across frames.
private val inputBuffers = model.createInputBuffers()
private val outputBuffers = model.createOutputBuffers()
fun stylize(input: FloatArray): FloatArray {
inputBuffers[0].writeFloat(input)
model.run(inputBuffers, outputBuffers) // sync
return outputBuffers[0].readFloat()
}Как видите, он довольно небольшой и простой.
Вы создаете модель один раз, а затем используете ее в каждом кадре.
Итак, CompiledModel.create передает файл .tflite.
Вы просто указываете, что хотите запустить на графическом процессоре, а затем создаете входные данные и outputBuffers.
Затем в основном цикле, где вы обрабатываете каждый кадр, вы вызываете этот model.run, передавая входные и выходные данные.
После записи в inputBuffers вызовите model.run, а затем прочитайте данные из outputBuffers.
Окей.
Да, и если вы укажете там графический процессор, то он будет запущен на графическом процессоре.
Если вы укажете и ЦП, и графический процессор, будет использоваться графический процессор.
Если графический процессор по какой-либо причине недоступен, будет использоваться ЦП.
Поэтому в некоторых случаях резервный ЦП может быть недостаточно эффективным для вашего приложения, и именно тогда вы захотите использовать просто указать графический процессор, как это.
Чаще всего вам нужно будет использовать резервный ЦП.
Окей.
Поэтому мы создали его со встроенным LiteRT, который пока не использует сервисы Google Play.
Давайте посмотрим, как использовать LiteRT в сервисах Google Play.
Итак, у нас есть три изменения. Первое – это изменение зависимости.
// Easier with CompiledModel API: 3 steps
// 1. app/build.gradle: replace litert with play-services-litert
- implementation 'com.google.ai.edge.litert:litert:...'
+ implementation 'com.google.android.gms:play-services-litert:17.0.0' // also pulls in litert-apiВам нужно будет только заменить зависимости пакета Maven в файле Gradle или в другой системе сборки, которую вы используете.
Удалите зависимость litert или любые зависимости более старых пакетов TensorFlow Lite Maven и замените их на play-services-litert.
Это также приведет к установке пакета litert-api.
Если вы пишете промежуточный слой, который зависит от LiteRT, но неважно, откуда берется среда выполнения – из приложения или из сервисов Google Play, вы можете просто зависеть от LiteRT API и использовать среду в качестве входного параметра.
Второй шаг – параметр среды.
Именно здесь вы указываете внедрение зависимостей, чтобы сообщить, что хотите использовать LiteRT в сервисах Google Play.
Итак, вы импортируете gms.litert.LiteRt и вызываете функцию инициализации, передавая контекст, который является вашим действием Android.
// 2. Initialize the LiteRT Environment from Play services (context = your Activity)
- val environment = Environment.create(...)
+ import com.google.android.gms.litert.LiteRt
+ val environment = LiteRt.initialize(context).await()
// 3. Pass environment whenever you call CompiledModel.create
// That's it! The rest of your app uses the normal CompiledModel APIs from litert-api.Это асинхронный процесс, поэтому вам нужно вызвать .await или сделать так, чтобы остальная часть кода была основана на обратном вызове.
И наконец, когда у вас есть эта среда, вы просто передаете ее при каждом вызове CompiledModel.create.
И это заставит его использовать среду выполнения Play services LiteRT из сервисов Google Play.
Вот и всё.
Это означает, что остальная часть вашего приложения использует те же API LiteRT CompiledModel из LiteRT API.
Остальная часть кода вывода не меняется для использования сервисов Play.
При этом перенос можно выполнять постепенно.
Вы можете переносить компоненты по одному.
Если у вас большое приложение, имеет смысл перенести каждый компонент, использующий LiteRT, а затем вы можете переносить по одному и тестировать по одному.
Единственное предостережение заключается в том, что вы получаете только выигрыш в размере, экономия места происходит только тогда, когда вы удаляете последнюю зависимость от связанной среды выполнения.
И если вы это делаете, то не должны смешивать объекты между LiteRT в сервисах Google Play и LiteRT в комплекте.
Поэтому, если вы получаете тензоры, скомпилированные модели или интерпретаторы из LiteRT в сервисах Google Play, не передавайте их в LiteRT, встроенную в приложение, и наоборот.
Но в остальном смешивание этих вещей работает просто отлично.
Окей.
Итак, это было создание нового приложения.
Теперь я расскажу, как обновить существующее приложение.
Итак, у вас может быть существующее приложение, использующее Interpreter API.
Это то, что мы называем старым API TFLite, который использует интерпретатор в качестве основного класса.
Слева показан код, в котором используется Interpreter API, а справа – новый код CompiledModel API.
// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)
// Init
TfLite.initialize(context).await()
// Load
val interpreterOptions =
InterpreterApi.Options().apply {
runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
}
val interpreter =
InterpreterApi.create(modelFile, interpreterOptions)
// Prepare inputs/outputs
val inputs = …
val outputs = …
// Execute
interpreter.run(inputs, outputs)// Dependencies (Gradle):
// play-services-litert
// Init
val environment =
LiteRt.initialize(context).await()
// Load
val modelOptions = CompiledModel.Options(Accelerator.CPU)
val model =
CompiledModel.create(modelPath, modelOptions, environment)
// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()
// Execute
model.run(inputBuffers, outputBuffersТо есть вы просто меняете TfLite.initialize на LiteRt.initialize, и теперь возвращается среда.
Затем передайте среду в CompiledModel.create.
Это небольшое изменение, которое не увеличивает размер APK.
На следующем слайде мы покажем, как это сделать с помощью графического процессора, и это всего лишь ещё один вариант.
Итак, это дополнительный код, который вам нужен, чтобы включить графический процессор.
// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)
// Init
val initOptions = TfLiteInitializationOptions.builder()
.setEnableGpuDelegateSupport(true).build()
TfLite.initialize(context, initOptions).await()
val useGpu =
TfLiteGpu.isGpuDelegateAvailable(context).await()
// Load
val interpreterOptions =
InterpreterApi.Options().apply {
runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
}
if (useGpu) {
interpreterOptions.addDelegateFactory(
GpuDelegateFactory());
}
val interpreter =
InterpreterApi.create(modelFile, interpreterOptions)
// Prepare inputs/outputs
val inputs = …
val outputs = …
// Execute
interpreter.run(inputs, outputs)// Dependencies (Gradle):
// play-services-litert
// Init
val initOptions = LiteRtInitializationOptions.builder()
.setEnableGpu(true).build()
val environment = LiteRt.initialize(context, initOptions).await()
// Load
val modelOptions =
CompiledModel.Options(Accelerator.CPU, Accelerator.GPU)
val model =
CompiledModel.create(modelPath, modelOptions, environment)
// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()
// Execute
model.run(inputBuffers, outputBuffers)Как видите, код в новом API для включения графического процессора немного проще, чем предыдущий.
Таким образом, первый вызов setEnableGpu в параметрах инициализации LiteRT, которые вы затем передаете в LiteRt.initialize, приведет к загрузке кода для графического процессора в ваше приложение.
Затем, когда вы создаете modelOptions и передаете его в CompiledModel.create, вы указываете, какой ускоритель будет использоваться для конкретной модели, хотите ли вы, чтобы другая модель работала только на графическом процессоре, на графическом процессоре с резервным центральным процессором или только на центральном процессоре.
Теперь
Да, как видите, с новым API включить графический процессор намного проще.
Что же вы получаете?
Чинтан расскажет вам.
Теперь
Спасибо, Фергус.
Давайте поговорим о том, что все это нам дает.
Помните, мы говорили, что собираемся создать приложение? Давайте посмотрим, что у нас получилось.
Итак, это я, и то, что мы сделали здесь, это то, что произошло сейчас, это то, что мы использовали ML Kit, чтобы найти меня, поэтому сегментация выполняется с помощью готового API, такого как ML Kit.
Так, это просто моя голова.
Затем LiteRT использует модель, похожую на перенос стиля, чтобы закрасить фон.
И другие преимущества, как мы упоминали, заключаются в том, что вы экономите примерно 8 МБ места, теперь у вас есть одна среда выполнения, которая используется всеми вашими приложениями, или, по крайней мере, та, которая используется здесь совместно, и вы получаете автоматические обновления, а также у вас есть более быстрый графический процессор, который обеспечивает вам около 30 кадров в секунду на том, что должно быть в реальном времени для богатого пользовательского опыта.
И что самое главное, вам не нужно делать все это вручную.
Мы также только что запустили новый навык для Android – Android LiteRT, который позволяет за считанные минуты улучшить машинное обучение на устройстве.
Вы можете обновить существующее приложение, создать новое или обновить приложение, чтобы использовать новую интеграцию сервисов Google Play.
Все это доступно.
Ссылка есть на слайде, а также на GitHub, и она также появится в нашей документации и в нашем блоге.
Это тоже должно быть полезно для всех, кто планирует перейти на новую версию в ближайшее время.
Фергус расскажет, что будет дальше.
Поэтому мы стремимся развивать локальный ИИ с помощью LiteRT.
Мы продолжаем вкладывать значительные средства в улучшение ускорения графического процессора и охвата моделей, а также регулярно обновлять LiteRT 2.x как для пакета LiteRT с открытым исходным кодом, так и для пакета LiteRT Maven в сервисах Google Play.
Мы также продолжим обеспечивать обратную совместимость.
Среда выполнения сервисов Google Play продолжит поддерживать приложения, созданные с помощью более старых версий SDK.
Да.
Это очень важно для наших пользователей и для нас.
LiteRT 1.x SDK сейчас находятся в режиме обслуживания, поэтому для них выпускаются только критические исправления безопасности.
NNAPI, который мы объявили устаревшим в 2024 году, будет удален, скорее всего, в 2027 году.
Если вы используете NNAPI, перейдите на ускорение с помощью графического процессора или NPU, используя встроенный LiteRT.
Окей.
Да.
Поэтому чем раньше вы перейдете на версию 2.x и CompiledModel, тем меньше вам придется делать потом.
Итак, три вывода.
Так что стройте.
Начните с ML Kit. Если он уже делает то, что вам нужно, то это здорово.
Если нет, используйте LiteRT для собственных моделей.
Перейдите на LiteRT в сервисах Google Play, чтобы уменьшить размер APK и использовать общую среду выполнения.
Для более быстрого и простого инференса на графическом процессоре используйте API CompiledModel.
Да.
Вся информация есть на сайте документации LiteRT в разделе AI Edge по указанному URL.
Вот так.
Спасибо, что присоединились к нам. С нетерпением ждем ваших новых проектов.
// 1. Configure and create segmenter client
val segmenter = Segmentation.getClient(
SelfieSegmenterOptions.Builder()
.setDetectorMode(
SelfieSegmenterOptions.STREAM_MODE)
.build())
// 2. Prepare image & run inference
fun processFrame(mediaImage: Image) {
val image = InputImage.fromMediaImage(
mediaImage, /* rotationDegrees= */ 0)
segmenter.process(image)
.addOnSuccessListener { mask -> … }
}import litert_torch
model = my_models.Stylizer().eval()
# Convert with torch.export under the hood
edge_model = litert_torch.convert(
model, sample_inputs)
edge_model.export("stylizer_f32.tflite")# Python
# previously ai_edge_quantizer
from litert_quantizer import quantizer, recipe
qt = quantizer.Quantizer("stylizer_f32.tflite")
# int8 weights, float activations
qt.load_quantization_recipe(
recipe.dynamic_wi8_afp32())
qt.quantize().export_model("stylizer_int8.tflite")// Kotlin
// Build once, off the main thread.
private val model: CompiledModel =
CompiledModel.create(
context.assets,
"stylizer_int8.tflite",
// Simple GPU setup!
CompiledModel.Options(Accelerator.GPU),
environment
)
// Reuse buffers across frames.
private val inputBuffers = model.createInputBuffers()
private val outputBuffers = model.createOutputBuffers()
fun stylize(input: FloatArray): FloatArray {
inputBuffers[0].writeFloat(input)
model.run(inputBuffers, outputBuffers) // sync
return outputBuffers[0].readFloat()
}// Easier with CompiledModel API: 3 steps
// 1. app/build.gradle: replace litert with play-services-litert
- implementation 'com.google.ai.edge.litert:litert:...'
+ implementation 'com.google.android.gms:play-services-litert:17.0.0' // also pulls in litert-api// 2. Initialize the LiteRT Environment from Play services (context = your Activity)
- val environment = Environment.create(...)
+ import com.google.android.gms.litert.LiteRt
+ val environment = LiteRt.initialize(context).await()
// 3. Pass environment whenever you call CompiledModel.create
// That's it! The rest of your app uses the normal CompiledModel APIs from litert-api.// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)
// Init
TfLite.initialize(context).await()
// Load
val interpreterOptions =
InterpreterApi.Options().apply {
runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
}
val interpreter =
InterpreterApi.create(modelFile, interpreterOptions)
// Prepare inputs/outputs
val inputs = …
val outputs = …
// Execute
interpreter.run(inputs, outputs)// Dependencies (Gradle):
// play-services-litert
// Init
val environment =
LiteRt.initialize(context).await()
// Load
val modelOptions = CompiledModel.Options(Accelerator.CPU)
val model =
CompiledModel.create(modelPath, modelOptions, environment)
// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()
// Execute
model.run(inputBuffers, outputBuffers// Dependencies (Gradle):
// play-services-tflite-java and/or litert (bundled)
// Init
val initOptions = TfLiteInitializationOptions.builder()
.setEnableGpuDelegateSupport(true).build()
TfLite.initialize(context, initOptions).await()
val useGpu =
TfLiteGpu.isGpuDelegateAvailable(context).await()
// Load
val interpreterOptions =
InterpreterApi.Options().apply {
runtime = TfLiteRuntime.FROM_SYSTEM_ONLY
}
if (useGpu) {
interpreterOptions.addDelegateFactory(
GpuDelegateFactory());
}
val interpreter =
InterpreterApi.create(modelFile, interpreterOptions)
// Prepare inputs/outputs
val inputs = …
val outputs = …
// Execute
interpreter.run(inputs, outputs)// Dependencies (Gradle):
// play-services-litert
// Init
val initOptions = LiteRtInitializationOptions.builder()
.setEnableGpu(true).build()
val environment = LiteRt.initialize(context, initOptions).await()
// Load
val modelOptions =
CompiledModel.Options(Accelerator.CPU, Accelerator.GPU)
val model =
CompiledModel.create(modelPath, modelOptions, environment)
// Prepare inputs/outputs
val inputBuffers = model.createInputBuffers()
val outputBuffers = model.createOutputBuffers()
// Execute
model.run(inputBuffers, outputBuffers)