借助 LLM Inference API,您可以完全在设备端为 Android 应用运行大语言模型 (LLM),并用它来执行各种任务,例如生成文本、以自然语言形式检索信息以及对文档进行总结。该任务提供对多个文本到文本大语言模型的内置支持,以便您可以将最新的设备端生成式 AI 模型应用于 Android 应用。
该任务支持 Gemma 2B,Gemma 2B 是一个轻量级先进的开放模型系列的一部分,这些模型基于创建 Gemini 模型所用的研究和技术构建而成。它还支持以下外部模型:Phi-2、Falcon-RW-1B 和 StableLM-3B,以及通过 AI Edge 导出的所有模型。
如需详细了解此任务的功能、模型和配置选项,请参阅概览。
代码示例
本指南提供了一个适用于 Android 的基本文本生成应用示例。您可以使用该应用作为基础来开发自己的 Android 应用,也可以在修改现有应用时参考该应用。示例代码托管在 GitHub 上。
下载代码
以下说明介绍了如何使用 git 命令行工具创建示例代码的本地副本。
如需下载示例代码,请执行以下操作:
- 使用以下命令克隆 Git 代码库:
git clone https://github.com/google-ai-edge/mediapipe-samples
- (可选)将您的 Git 实例配置为使用稀疏结账,这样您就只有 LLM Inference API 示例应用的文件:
cd mediapipe git sparse-checkout init --cone git sparse-checkout set examples/llm_inference/android
创建示例代码的本地版本后,您可以将项目导入 Android Studio 并运行应用。有关说明,请参阅 Android 设置指南。
设置
本部分介绍了专门为使用 LLM Inference API 而设置开发环境和代码项目的关键步骤。如需了解如何为使用 MediaPipe 任务设置开发环境的一般信息(包括平台版本要求),请参阅 Android 设置指南。
依赖项
LLM Inference API 使用 com.google.mediapipe:tasks-genai
库。请将以下依赖项添加到 Android 应用的 build.gradle
文件中:
dependencies {
implementation 'com.google.mediapipe:tasks-genai:0.10.14'
}
模型
MediaPipe LLM Inference API 需要与此任务兼容的经过训练的文本到文本语言模型。下载模型后,安装所需的依赖项并将模型推送到 Android 设备。如果您使用的是 Gemma 以外的模型,则必须将该模型转换为与 MediaPipe 兼容的格式。
如需详细了解适用于 LLM Inference API 的经过训练的模型,请参阅任务概览“模型”部分。
下载模型
在初始化 LLM Inference API 之前,请下载一个受支持的模型,并将该文件存储在项目目录中:
- Gemma 2B:这是一个先进的轻量级开放模型系列的一部分,这些模型基于创建 Gemini 模型所用的研究和技术构建而成。非常适合各种文本生成任务,包括问答、摘要和推理。
- Phi-2:27 亿个参数 Transformer 模型,最适合问答、聊天和代码格式。
- Falcon-RW-1B:使用 RefinedWeb 的 350B 令牌训练的 10 亿个参数因解码器模型。
- StableLM-3B:基于各种英语和代码数据集的 1 万亿令牌进行预训练的 30 亿个参数解码器语言模型。
或者,您也可以使用通过 AI Edge Troch 映射和导出的模型。
建议使用 Gemma 2B,该工具可在 Kaggle 模型中使用,其格式已与 LLM Inference API 兼容。如果您使用的是其他 LLM,则需要将模型转换为适用于 MediaPipe 的格式。如需详细了解 Gemma 2B,请访问 Gemma 网站。如需详细了解其他可用模型,请参阅任务概览“模型”部分。
将模型转换为 MediaPipe 格式
原生模型转换
如果您使用的是外部 LLM(Phi-2、Falcon 或 StableLM)或非 Kaggle 版本的 Gemma,请使用我们的转换脚本来设置模型格式,使其与 MediaPipe 兼容。
模型转换过程需要使用 MediaPipe PyPI 软件包。在 0.10.11
之后,所有 MediaPipe 软件包中都提供转换脚本。
使用以下命令安装并导入依赖项:
$ python3 -m pip install mediapipe
使用 genai.converter
库转换模型:
import mediapipe as mp
from mediapipe.tasks.python.genai import converter
config = converter.ConversionConfig(
input_ckpt=INPUT_CKPT,
ckpt_format=CKPT_FORMAT,
model_type=MODEL_TYPE,
backend=BACKEND,
output_dir=OUTPUT_DIR,
combine_file_only=False,
vocab_model_file=VOCAB_MODEL_FILE,
output_tflite_file=OUTPUT_TFLITE_FILE,
)
converter.convert_checkpoint(config)
如需转换 LoRA 模型,ConversionConfig
应指定基本模型选项以及额外的 LoRA 选项。请注意,由于 API 仅支持使用 GPU 进行 LoRA 推断,因此必须将后端设置为 'gpu'
。
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_TFLITE_FILE,
)
converter.convert_checkpoint(config)
转换器将输出两个 TFLite 平面缓冲区文件,一个用于基本模型,另一个用于 LoRA 模型。
参数 | 说明 | 可接受的值 |
---|---|---|
input_ckpt |
指向 model.safetensors 或 pytorch.bin 文件的路径。请注意,有时模型安全张量格式会被分片为多个文件,例如 model-00001-of-00003.safetensors 、model-00001-of-00003.safetensors 。您可以指定文件格式,例如 model*.safetensors 。 |
PATH |
ckpt_format |
模型文件格式。 | {"safetensors", "pytorch"} |
model_type |
正在转换的 LLM。 | {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B"} |
backend |
用于运行模型的处理器(代理)。 | {"cpu", "gpu"} |
output_dir |
托管每层权重文件的输出目录的路径。 | PATH |
output_tflite_file |
输出文件的路径。例如,“model_cpu.bin”或“model_gpu.bin”。此文件仅与 LLM Inference API 兼容,无法用作常规“tflite”文件。 | PATH |
vocab_model_file |
存储 tokenizer.json 和 tokenizer_config.json 文件的目录的路径。对于 Gemma,请指向单个 tokenizer.model 文件。 |
PATH |
lora_ckpt |
安全张量文件的 LoRA ckpt 路径,用于存储 LoRA 适配器权重。 | PATH |
lora_rank |
一个整数,表示 LoRA ckpt 的排名。必需,以便转换 lora 权重。如果未提供,则转换器会假定没有 LoRA 权重。注意:只有 GPU 后端支持 LoRA。 | 整数 |
lora_output_tflite_file |
输出 LoRA 权重的 tflite 文件名。 | PATH |
AI Edge 模型转换
如果您正在使用通过 AI Edge 映射到 TFLite 模型的 LLM,请使用我们的捆绑脚本创建任务包。捆绑流程会使用额外的元数据(例如Tokenizer 参数)。
模型捆绑过程需要使用 MediaPipe PyPI 软件包。在 0.10.14
之后,所有 MediaPipe 软件包中都提供转换脚本。
使用以下命令安装并导入依赖项:
$ python3 -m pip install mediapipe
使用 genai.bundler
库捆绑模型:
import mediapipe as mp
from mediapipe.tasks.python.genai import bundler
config = bundler.BundleConfig(
tflite_model=TFLITE_MODEL,
tokenizer_model=TOKENIZER_MODEL,
start_token=START_TOKEN,
stop_tokens=STOP_TOKENS,
output_filename=OUTPUT_FILENAME,
enable_bytes_to_unicode_mapping=ENABLE_BYTES_TO_UNICODE_MAPPING,
)
bundler.create_bundle(config)
参数 | 说明 | 可接受的值 |
---|---|---|
tflite_model |
AI Edge 导出的 TFLite 模型的路径。 | PATH |
tokenizer_model |
到 SentencePiece 分词器模型的路径。 | PATH |
start_token |
模型专用的开始令牌。起始标记必须存在于提供的分词器模型中。 | 字符串 |
stop_tokens |
模型专用的停止令牌。停止标记必须存在于提供的分词器模型中。 | 列表 [字符串] |
output_filename |
输出任务包文件的名称。 | PATH |
将模型推送到设备
将 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.bin
创建任务
MediaPipe LLM Inference API 使用 createFromOptions()
函数来设置任务。createFromOptions()
函数接受配置选项的值。如需详细了解配置选项,请参阅配置选项。
以下代码使用基本配置选项初始化任务:
// Set the configuration options for the LLM Inference task
val options = LlmInferenceOptions.builder()
.setModelPATH('/data/local/.../')
.setMaxTokens(1000)
.setTopK(40)
.setTemperature(0.8)
.setRandomSeed(101)
.build()
// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, options)
配置选项
您可以使用以下配置选项设置 Android 应用:
选项名称 | 说明 | 值范围 | 默认值 |
---|---|---|---|
modelPath |
项目目录中存储模型的路径。 | PATH | N/A |
maxTokens |
模型处理的词元(输入词元 + 输出词元)的数量上限。 | 整数 | 512 |
topK |
模型在生成时的每一步考虑的词元数。将预测限制为前 k 个概率最高的词元。设置 topK 时,您还必须为 randomSeed 设置一个值。 |
整数 | 40 |
temperature |
生成期间引入的随机性。较高的温度可以使生成的文本更具创造性,而较低的温度会产生更可预测的生成。设置 temperature 时,您还必须为 randomSeed 设置一个值。 |
浮点数 | 0.8 |
randomSeed |
在文本生成过程中使用的随机种子。 | 整数 | 0 |
loraPath |
设备本地 LoRA 模型的绝对路径。注意:这仅与 GPU 模型兼容。 | PATH | N/A |
resultListener |
设置结果监听器,以异步接收结果。 仅在使用异步生成方法时适用。 | N/A | N/A |
errorListener |
设置可选的错误监听器。 | N/A | N/A |
准备数据
LLM Inference API 接受以下输入:
- prompt(字符串):问题或提示。
val inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."
运行任务
使用 generateResponse()
方法针对上一部分中提供的输入文本 (inputPrompt
) 生成文本响应。这会生成一个生成的响应。
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)
处理和显示结果
LLM Inference API 会返回 LlmInferenceResult
,其中包含生成的响应文本。
Here's a draft you can use:
Subject: Lunch on Saturday Reminder
Hi Brett,
Just a quick reminder about our lunch plans this Saturday at noon.
Let me know if that still works for you.
Looking forward to it!
Best,
[Your Name]
LoRA 模型自定义
Mediapipe LLM 推理 API 可以配置为支持针对大型语言模型的低秩自适应 (LoRA)。利用经微调的 LoRA 模型,开发者可以通过经济高效的训练过程来自定义 LLM 的行为。
LLM Inference API 的 LoRA 支持适用于 GPU 后端的 Gemma-2B 和 Phi-2 模型,LoRA 权重仅适用于注意力层。这一初始实现可用作未来开发的实验性 API,并计划在未来的更新中支持更多模型和各种类型的层。
准备 LoRA 模型
按照 HuggingFace 说明,使用受支持的模型类型(Gemma-2B 或 Phi-2)在您自己的数据集上训练微调后的 LoRA 模型。HuggingFace 上均以安全张量格式提供 Gemma-2B 和 Phi-2 模型。由于 LLM Inference API 仅支持注意力层上的 LoRA,因此请在创建 LoraConfig
时仅指定注意力层,如下所示:
# For Gemma-2B
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"],
)
对于测试,HuggingFace 上提供适用于 LLM Inference API 且经过微调的可公开访问的 LoRA 模型。例如,对于 Gemma-2B,使用 monsterapi/gemma-2b-lora-maths-orca-200k,对于 Phi-2,使用 lole25/phi-2-sft-ultrachat-lora。
使用准备好的数据集进行训练并保存模型后,您会获得一个 adapter_model.safetensors
文件,其中包含微调后的 LoRA 模型权重。safetensors 文件是在模型转换中使用的 LoRA 检查点。
接下来,您需要使用 MediaPipe Python 软件包将模型权重转换为 TensorFlow Lite FlatBuffer。ConversionConfig
应指定基本模型选项以及其他 LoRA 选项。请注意,由于 API 仅支持使用 GPU 进行 LoRA 推断,因此后端必须设置为 'gpu'
。
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_TFLITE_FILE,
)
converter.convert_checkpoint(config)
转换器将输出两个 TFLite 平面缓冲区文件,一个用于基本模型,另一个用于 LoRA 模型。
LoRA 模型推断
Web、Android 和 iOS LLM Inference API 已更新,以支持 LoRA 模型推断。Web 支持动态 LoRA,其可以在运行时切换不同的 LoRA 模型。Android 和 iOS 支持静态 LoRA,它会在任务的生命周期内使用相同的 LoRA 权重。
Android 在初始化期间支持静态 LoRA。如需加载 LoRA 模型,用户需指定 LoRA 模型路径以及基本 LLM。// Set the configuration options for the LLM Inference task
val options = LlmInferenceOptions.builder()
.setModelPath('<path to base model>')
.setMaxTokens(1000)
.setTopK(40)
.setTemperature(0.8)
.setRandomSeed(101)
.setLoraPath('<path to LoRA model>')
.build()
// Create an instance of the LLM Inference task
llmInference = LlmInference.createFromOptions(context, options)
如需使用 LoRA 运行 LLM 推断,请使用与基本模型相同的 generateResponse()
或 generateResponseAsync()
方法。