Hướng dẫn dự đoán LLM dành cho Android

LLM Inference API cho phép bạn chạy các mô hình ngôn ngữ lớn (LLM) hoàn toàn trên thiết bị cho các ứng dụng Android. Bạn có thể dùng API này để thực hiện nhiều việc, chẳng hạn như tạo văn bản, truy xuất thông tin ở dạng ngôn ngữ tự nhiên và tóm tắt tài liệu. Tác vụ này cung cấp khả năng hỗ trợ tích hợp cho nhiều mô hình ngôn ngữ lớn từ văn bản sang văn bản, nhờ đó, bạn có thể áp dụng các mô hình AI tạo sinh mới nhất trên thiết bị cho các ứng dụng Android của mình.

Để nhanh chóng thêm LLM Inference API vào ứng dụng Android, hãy làm theo hướng dẫn Bắt đầu nhanh. Để biết ví dụ cơ bản về một ứng dụng Android đang chạy LLM Inference API, hãy xem ứng dụng mẫu. Để hiểu rõ hơn về cách hoạt động của LLM Inference API, hãy tham khảo các phần lựa chọn cấu hình, chuyển đổi mô hìnhđiều chỉnh LoRA.

Bạn có thể xem tác vụ này hoạt động trong bản minh hoạ MediaPipe Studio. Để biết thêm thông tin về các chức năng, mô hình và lựa chọn cấu hình của tác vụ này, hãy xem phần Tổng quan.

Bắt đầu nhanh

Hãy làm theo các bước sau để thêm LLM Inference API vào ứng dụng Android của bạn. LLM Inference API được tối ưu hoá cho các thiết bị Android cao cấp, chẳng hạn như Pixel 8 và Samsung S23 trở lên, đồng thời không hỗ trợ trình mô phỏng thiết bị một cách đáng tin cậy.

Thêm phần phụ thuộc

LLM Inference API sử dụng thư viện com.google.mediapipe:tasks-genai. Thêm phần phụ thuộc này vào tệp build.gradle của ứng dụng Android:

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

Tải một mô hình xuống

Tải Gemma-3 1B xuống ở định dạng được lượng tử hoá 4 bit từ Hugging Face. Để biết thêm thông tin về các mô hình hiện có, hãy xem Tài liệu về mô hình.

Đẩy nội dung của thư mục output_path vào thiết bị 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

Khởi chạy Task

Khởi chạy tác vụ bằng các lựa chọn cấu hình cơ bản:

// 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)

Chạy tác vụ

Sử dụng phương thức generateResponse() để tạo một câu trả lời bằng văn bản. Thao tác này sẽ tạo ra một câu trả lời duy nhất.

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

Để truyền trực tuyến phản hồi, hãy sử dụng phương thức generateResponseAsync().

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

llmInference.generateResponseAsync(inputPrompt)

Ứng dụng mẫu

Để xem LLM Inference API hoạt động và khám phá nhiều tính năng AI tạo sinh trên thiết bị, hãy xem ứng dụng Google AI Edge Gallery.

Google AI Edge Gallery là một ứng dụng Android nguồn mở, đóng vai trò là một sân chơi tương tác cho các nhà phát triển. Thẻ này giới thiệu:

  • Ví dụ thực tế về cách sử dụng LLM Inference API cho nhiều tác vụ, bao gồm:
    • Hỏi về hình ảnh: Tải một hình ảnh lên rồi đặt câu hỏi về hình ảnh đó. Nhận nội dung mô tả, giải quyết vấn đề hoặc xác định đối tượng.
    • Prompt Lab: Tóm tắt, viết lại, tạo mã hoặc sử dụng câu lệnh tự do để khám phá các trường hợp sử dụng LLM một lượt.
    • AI Chat: Tham gia các cuộc trò chuyện nhiều lượt.
  • Khả năng khám phá, tải xuống và thử nghiệm nhiều mô hình được tối ưu hoá bằng LiteRT từ Cộng đồng LiteRT của Hugging Face và các bản phát hành chính thức của Google (ví dụ: Gemma 3N).
  • Điểm chuẩn hiệu suất theo thời gian thực trên thiết bị cho các mô hình khác nhau (Thời gian hiển thị mã thông báo đầu tiên, tốc độ giải mã, v.v.).
  • Cách nhập và kiểm thử các mô hình .litertlm hoặc .task tuỳ chỉnh của riêng bạn.

Ứng dụng này là một tài nguyên giúp bạn hiểu rõ cách triển khai thực tế LLM Inference API và tiềm năng của AI tạo sinh trên thiết bị. Khám phá mã nguồn và tải ứng dụng xuống qua kho lưu trữ Google AI Edge Gallery GitHub.

Các lựa chọn về cấu hình

Sử dụng các lựa chọn cấu hình sau để thiết lập một ứng dụng Android:

Tên tuỳ chọn Mô tả Phạm vi giá trị Giá trị mặc định
modelPath Đường dẫn đến nơi mô hình được lưu trữ trong thư mục dự án. ĐƯỜNG DẪN Không áp dụng
maxTokens Số lượng mã thông báo tối đa (mã thông báo đầu vào + mã thông báo đầu ra) mà mô hình xử lý. Số nguyên 512
topK Số lượng mã thông báo mà mô hình xem xét ở mỗi bước tạo. Giới hạn dự đoán ở k mã thông báo có khả năng xảy ra nhất. Số nguyên 40
temperature Mức độ ngẫu nhiên được đưa vào trong quá trình tạo. Nhiệt độ càng cao thì văn bản được tạo càng sáng tạo, còn nhiệt độ càng thấp thì văn bản được tạo càng dễ dự đoán. Số thực dấu phẩy động 0,8
randomSeed Dữ liệu gốc ngẫu nhiên được dùng trong quá trình tạo văn bản. Số nguyên 0
loraPath Đường dẫn tuyệt đối đến mô hình LoRA trên thiết bị. Lưu ý: chế độ này chỉ tương thích với các mô hình GPU. ĐƯỜNG DẪN Không áp dụng
resultListener Đặt trình nghe kết quả để nhận kết quả một cách không đồng bộ. Chỉ áp dụng khi sử dụng phương thức tạo không đồng bộ. Không áp dụng Không áp dụng
errorListener Đặt một trình nghe lỗi không bắt buộc. Không áp dụng Không áp dụng

Đặt câu lệnh đa phương thức

Các API Android của LLM Inference API hỗ trợ câu lệnh đa phương thức với các mô hình chấp nhận dữ liệu đầu vào là văn bản, hình ảnh và âm thanh. Khi bật tính năng đa phương thức, người dùng có thể kết hợp hình ảnh và văn bản hoặc âm thanh và văn bản trong câu lệnh.Sau đó, LLM sẽ đưa ra câu trả lời bằng văn bản.

Để bắt đầu, hãy sử dụng một biến thể tương thích với MediaPipe của Gemma 3n:

  • Gemma-3n-E2B: một mô hình 2B hiệu quả thuộc họ Gemma-3n.
  • Gemma-3n-E4B: một mô hình 4B hiệu quả thuộc họ Gemma-3n.

Để biết thêm thông tin, hãy xem tài liệu về Gemma-3n.

Hãy làm theo các bước bên dưới để bật tính năng nhập hình ảnh hoặc âm thanh cho LLM Inference API.

Đầu vào hình ảnh

Để cung cấp hình ảnh trong một câu lệnh, hãy chuyển đổi hình ảnh hoặc khung hình đầu vào thành một đối tượng com.google.mediapipe.framework.image.MPImage trước khi truyền đối tượng đó đến LLM Inference API:

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()

Để bật tính năng hỗ trợ thị giác cho LLM Inference API, hãy đặt lựa chọn cấu hình EnableVisionModality thành true trong các lựa chọn Đồ thị:

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

Đặt tối đa 10 hình ảnh cho mỗi phiên.

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

Sau đây là ví dụ về cách triển khai API Suy luận LLM được thiết lập để xử lý dữ liệu đầu vào là hình ảnh và văn bản:

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();
}

Đầu vào âm thanh

Bật tính năng hỗ trợ âm thanh trong LlmInferenceOptions

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

Bật tính năng hỗ trợ âm thanh trong sessionOptions

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

Gửi dữ liệu âm thanh trong quá trình suy luận. Lưu ý: Âm thanh phải có định dạng đơn âm dưới dạng .wav


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

Sau đây là ví dụ về cách triển khai LLM Inference API được thiết lập để xử lý dữ liệu đầu vào là âm thanh và văn bản:

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()
  }
}

Tuỳ chỉnh LoRA

LLM Inference API hỗ trợ tinh chỉnh LoRA (Thích ứng cấp thấp) bằng cách sử dụng thư viện PEFT (Tinh chỉnh hiệu quả về tham số). Quá trình tinh chỉnh LoRA tuỳ chỉnh hành vi của LLM thông qua quy trình huấn luyện tiết kiệm chi phí, tạo một nhóm nhỏ các trọng số có thể huấn luyện dựa trên dữ liệu huấn luyện mới thay vì huấn luyện lại toàn bộ mô hình.

LLM Inference API hỗ trợ việc thêm trọng số LoRA vào các lớp chú ý của mô hình Gemma-2 2B, Gemma 2BPhi-2. Tải mô hình xuống ở định dạng safetensors.

Mô hình cơ sở phải ở định dạng safetensors để tạo trọng số LoRA. Sau khi huấn luyện LoRA, bạn có thể chuyển đổi các mô hình thành định dạng FlatBuffers để chạy trên MediaPipe.

Chuẩn bị trọng số LoRA

Sử dụng hướng dẫn Phương pháp LoRA của PEFT để huấn luyện một mô hình LoRA được tinh chỉnh trên tập dữ liệu của riêng bạn.

LLM Inference API chỉ hỗ trợ LoRA trên các lớp chú ý, vì vậy, bạn chỉ cần chỉ định các lớp chú ý trong 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"],
)

Sau khi huấn luyện trên tập dữ liệu đã chuẩn bị và lưu mô hình, các trọng số mô hình LoRA được tinh chỉnh sẽ có trong adapter_model.safetensors. Tệp safetensors là điểm kiểm tra LoRA được dùng trong quá trình chuyển đổi mô hình.

Chuyển đổi mô hình

Sử dụng Gói Python MediaPipe để chuyển đổi trọng số mô hình thành định dạng Flatbuffer. ConversionConfig chỉ định các lựa chọn mô hình cơ sở cùng với các lựa chọn LoRA bổ sung.

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)

Trình chuyển đổi sẽ tạo ra hai tệp Flatbuffer, một cho mô hình cơ sở và một cho mô hình LoRA.

Suy luận mô hình LoRA

Android hỗ trợ LoRA tĩnh trong quá trình khởi tạo. Để tải một mô hình LoRA, hãy chỉ định đường dẫn mô hình LoRA cũng như LLM cơ sở.

// 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)

Để chạy suy luận LLM bằng LoRA, hãy sử dụng các phương thức generateResponse() hoặc generateResponseAsync() tương tự như mô hình cơ sở.