Przewodnik po wnioskowaniu LLM na Androida

.

Interfejs LLM Inference API umożliwia uruchamianie dużych modeli językowych (LLM) całkowicie na urządzeniu dla aplikacji na Androida, które pozwalają wykonywać wiele różnych zadań, takie jak generowanie tekstu, pobieranie informacji w języku naturalnym podsumowywanie dokumentów. Zadanie ma wbudowaną obsługę wielu dużych modeli językowych (tekst na tekst) i zastosować modeli generatywnej AI w Twoich aplikacjach na Androida.

Zadanie obsługuje Gemmę 2B, część rodziny lekkich, najnowocześniejszych modeli otwartych opartych na tych samych badaniach i technologii wykorzystywanej do tworzenia modeli Gemini. Obsługuje również te modele zewnętrzne: Phi-2 Falcon-RW-1B StableLM-3B wraz ze wszystkimi modelami wyeksportowanymi przez AI Edge.

Więcej informacji o funkcjach, modelach i opcjach konfiguracji zapoznaj się z Przeglądem.

Przykładowy kod

W tym przewodniku podajemy przykład podstawowej aplikacji do generowania tekstu na Androida. Ty możesz używać tej aplikacji jako punktu wyjścia dla własnej aplikacji na Androida podczas modyfikowania istniejącej aplikacji. Przykładowy kod jest hostowany GitHub

Pobieranie kodu

Poniżej znajdziesz instrukcje tworzenia lokalnej kopii przykładu. za pomocą narzędzia wiersza poleceń git.

Aby pobrać przykładowy kod:

  1. Sklonuj repozytorium git za pomocą tego polecenia:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Opcjonalnie możesz skonfigurować instancję git tak, aby wykorzystywała rozproszony proces płatności, aby tylko pliki przykładowej aplikacji LLM Inference API:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/llm_inference/android
    

Po utworzeniu lokalnej wersji przykładowego kodu możesz zaimportować projekt w Android Studio i uruchom aplikację. Odpowiednie instrukcje znajdziesz w Przewodniku po konfiguracji na urządzeniu z Androidem.

Konfiguracja

W tej sekcji opisujemy najważniejsze czynności związane z konfigurowaniem środowiska programistycznego oraz w projektach kodu wyłącznie z użyciem interfejsu LLM Inference API. Ogólne informacje na temat: skonfigurować środowisko programistyczne do korzystania z zadań MediaPipe, w tym wymagań wersji platformy znajdziesz w przewodniku konfiguracji dla na urządzeniu z Androidem.

Zależności

LLM Inference API korzysta z biblioteki com.google.mediapipe:tasks-genai. Dodaj to zależność od pliku build.gradle aplikacji na Androida:

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

Model

Interfejs MediaPipe LLM Inference API wymaga wytrenowanego modelu języka zamiany tekstu na tekst, które są zgodne z tym zadaniem. Po pobraniu modelu zainstaluj wymagane zależności i przekazać model na urządzenie z Androidem. Jeśli używasz modelu inny niż Gemma, musisz przekonwertować model na format zgodny z MediaPipe.

Więcej informacji o dostępnych wytrenowanych modelach dla LLM Inference API znajdziesz w zadaniu zapoznaj się z sekcją Modele.

Pobierz model

Zanim zainicjujesz interfejs LLM Inference API, pobierz 1 z obsługiwanych modeli i zapisz plik w katalogu projektu:

  • Gemma 2B: Należąca do rodziny lekkich, nowoczesnych modeli otwartych stworzonych tych samych badań i technologii, których użyto do stworzenia Modele Gemini. Odpowiednie dla różnych zadania związane z generowaniem tekstu, w tym odpowiadanie na pytania, streszczenie, wyciągania wniosków.
  • Phi-2 2,7 mld parametrów. Transformer, najlepiej dopasowany do funkcji Question-Answer, czatu i kodu .
  • Falcon-RW-1B: 1 miliard modelowy model wyłącznie oparty na dekoderze parametrów, wytrenowany na 350 mld tokenów RefinedWeb.
  • StableLM-3B: 3 Model językowy oparty tylko na dekoderze parametrów został wstępnie wytrenowany na 1 bilionie parametrów tokenów różnorodnych zbiorów danych w języku angielskim i kodu.

Możesz też używać modeli zmapowanych i eksportowanych za pomocą AI Edge Troch

Zalecamy korzystanie z pakietu Gemma 2B, który jest dostępny w Kaggle Modele i dostępne w formacie, który jest już zgodny z interfejsem LLM Inference API. Jeśli używasz innego LLM, musisz przekonwertować go na Format dostosowany do MediaPipe. Więcej informacji o Gemma 2B znajdziesz w Gemma witrynie. Aby dowiedzieć się więcej o innym dostępne modele znajdziesz w omówieniu zadań w sekcji Modele.

Konwertuj model na format MediaPipe

Konwersja modelu natywnego

Jeśli używasz zewnętrznego modelu LLM (Phi-2, Falcon lub StableLM) albo urządzenia innego niż Kaggle Gemma, użyj naszych skryptów konwersji, aby sformatować model zgodne z MediaPipe.

Proces konwersji modelu wymaga pakietu MediaPipe PyPI. Konwersja skrypt jest dostępny we wszystkich pakietach MediaPipe od 0.10.11.

Zainstaluj i zaimportuj zależności, korzystając z tych elementów:

$ python3 -m pip install mediapipe

Aby przekonwertować model, użyj biblioteki 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)

Aby przekonwertować model LoRA, element ConversionConfig powinien określać model podstawowy oraz dodatkowe opcje LoRA. Zwróć uwagę, że skoro tylko interfejs API obsługuje wnioskowanie o LoRA z użyciem GPU, backend musi być ustawiony na '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)

Konwerter wygeneruje 2 pliki płaskiego bufora TFLite, jeden dla modelu podstawowego a drugą w modelu LoRA.

Parametr Opis Akceptowane wartości
input_ckpt Ścieżka do pliku model.safetensors lub pytorch.bin. Pamiętaj, że czasami format Safetensors modelu jest czasami dzielony na wiele plików, np. model-00001-of-00003.safetensors, model-00001-of-00003.safetensors. Możesz podać wzorzec pliku, na przykład model*.safetensors. ŚCIEŻKA
ckpt_format Format pliku modelu. {"safetensors", "pytorch"}
model_type Konwertowany LLM. {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B"}
backend Procesor (przekazany) używany do uruchomienia modelu. {"cpu", "gpu"}
output_dir Ścieżka do katalogu wyjściowego, który hostuje pliki wagi poszczególnych warstw. ŚCIEŻKA
output_tflite_file Ścieżka do pliku wyjściowego. Na przykład „model_cpu.bin” lub „model_gpu.bin”. Ten plik jest zgodny tylko z interfejsem LLM Inference API i nie można go używać jako ogólnego pliku tflite. ŚCIEŻKA
vocab_model_file Ścieżka do katalogu, w którym są przechowywane: tokenizer.json oraz Pliki: tokenizer_config.json. W przypadku Gemma wskaż pojedynczy plik tokenizer.model. ŚCIEŻKA
lora_ckpt Ścieżka do pliku ckpt zabezpieczeń LoRA zawierającego wagę adaptera LoRA. ŚCIEŻKA
lora_rank Liczba całkowita określająca rangę ckpt LoRA. Wymagane do przeliczania wag lora. Jeśli nie zostanie podany, konwerter zakłada, że nie ma wag LoRA. Uwaga: tylko backend z GPU obsługuje LoRA. Liczba całkowita
lora_output_tflite_file Nazwa wyjściowego pliku tflite dla wagi LoRA. ŚCIEŻKA

Konwersja modelu AI Edge

Jeśli używasz LLM zmapowanego na model TFLite za pomocą AI Edge, użyj naszego skrypt łączenia, aby utworzyć pakiet zadań. Proces grupowania obejmuje zmapowany model z dodatkowymi metadanymi (np. (parametry tokenizera) potrzebne aby przeprowadzić pełne wnioskowanie.

Proces grupowania modeli wymaga pakietu MediaPipe PyPI. Konwersja skrypt jest dostępny we wszystkich pakietach MediaPipe od 0.10.14.

Zainstaluj i zaimportuj zależności, korzystając z tych elementów:

$ python3 -m pip install mediapipe

Użyj biblioteki genai.bundler, aby połączyć model:

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)
Parametr Opis Akceptowane wartości
tflite_model Ścieżka do modelu TFLite wyeksportowanego z AI Edge. ŚCIEŻKA
tokenizer_model Ścieżka do modelu tokenizacji SentencePiece. ŚCIEŻKA
start_token Token początkowy konkretnego modelu. Token początkowy musi znajdować się w udostępniony model tokenizacji. CIĄG ZNAKÓW
stop_tokens Tokeny zatrzymania dotyczące konkretnego modelu. Tokeny zatrzymania muszą znajdować się w udostępniony model tokenizacji. LISTA[STRING]
output_filename Nazwa wyjściowego pliku pakietu zadań. ŚCIEŻKA

Wypchnij model na urządzenie

Przekaż zawartość folderu output_path na Androida urządzenia.

$ 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

Tworzenie zadania

Interfejs MediaPipe LLM Inference API używa funkcji createFromOptions() do konfigurowania zadanie. Funkcja createFromOptions() akceptuje wartości konfiguracji . Więcej informacji o opcjach konfiguracji znajdziesz w sekcji Konfiguracja .

Ten kod inicjuje zadanie przy użyciu podstawowych opcji konfiguracji:

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

Opcje konfiguracji

Aby skonfigurować aplikację na Androida, użyj tych opcji konfiguracji:

Nazwa opcji Opis Zakres wartości Wartość domyślna
modelPath Ścieżka do miejsca, w którym model jest przechowywany w katalogu projektu. ŚCIEŻKA Nie dotyczy
maxTokens Maksymalna liczba tokenów (tokenów wejściowych + tokenów wyjściowych) obsługiwanych przez model. Liczba całkowita 512
topK Liczba tokenów uwzględnianych przez model na każdym etapie generowania. Ogranicza prognozy do k najbardziej prawdopodobnych tokenów. Liczba całkowita 40
temperature Wielkość losowości wprowadzonej podczas generowania. Wyższa wartość poprawia kreatywność generowanego tekstu, a niższa temperatura zapewnia bardziej przewidywalne generowanie. Liczba zmiennoprzecinkowa 0,8
randomSeed Losowy wynik wyjściowy używany podczas generowania tekstu. Liczba całkowita 0
loraPath Ścieżka bezwzględna do modelu LoRA lokalnie na urządzeniu. Uwaga: ta funkcja jest zgodna tylko z modelami GPU. ŚCIEŻKA Nie dotyczy
resultListener Konfiguruje detektor wyników tak, aby asynchronicznie odbierał wyniki. Ma zastosowanie tylko w przypadku korzystania z metody generowania asynchronicznego. Nie dotyczy Nie dotyczy
errorListener Ustawia opcjonalny detektor błędów. Nie dotyczy Nie dotyczy

Przygotuj dane

Interfejs LLM Inference API akceptuje te dane wejściowe:

  • prompt (ciąg znaków): pytanie lub prompt.
val inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday."

Uruchamianie zadania

Użyj metody generateResponse(), aby wygenerować odpowiedź tekstową na dane wejściowe. tekst podany w poprzedniej sekcji (inputPrompt). Ta funkcja generuje .

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

Aby przesłać odpowiedź strumieniowo, użyj metody generateResponseAsync().

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

llmInference.generateResponseAsync(inputPrompt)

Obsługa i wyświetlanie wyników

LLM Inference API zwraca wartość LlmInferenceResult, która zawiera wygenerowany tekst odpowiedzi.

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]

Dostosowanie modelu LoRA

Interfejs Mediapipe LLM API wnioskowania można skonfigurować pod kątem obsługi adaptacji niskiego rankingu (LoRA) dla dużych modeli językowych. Dzięki dostrojonym modelom LoRA deweloperzy mogą dostosowywać zachowanie LLM przez ekonomiczny proces trenowania.

Obsługa LoRA interfejsu LLM Inference API działa w przypadku modeli Gemma-2B i Phi-2 dla: backendu GPU, a wagi LoRA mają zastosowanie tylko do warstw uwagi. Ten wstępna implementacja służy jako eksperymentalny interfejs API do wykorzystania w przyszłości z planami dodania obsługi kolejnych modeli i różnych typów warstw aktualizacje.

Przygotuj modele LoRA

Postępuj zgodnie z instrukcjami w HuggingFace, aby wytrenować dostrojony model LoRA na własnym zbiorze danych z użyciem obsługiwanych typów modeli – Gemma-2B lub Phi-2. Modele Gemma-2B i Phi-2 są dostępne w HuggingFace w formacie Safetensors. Ponieważ LLM Inference API obsługuje LoRA tylko w warstach uwagi, podczas tworzenia obiektu LoraConfig określ tylko warstwy uwagi w ten sposób:

# 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"],
)

Do testów dostępne są publicznie dostępne, dostrojone modele LoRA pasujące do interfejsu LLM Inference API. np. monsterapi/gemma-2b-lora-maths-orca-200k w przypadku Gemma-2B i lole25/phi-2-sft-ultrachat-lora w przypadku Phi-2.

Po wytrenowaniu na przygotowanym zbiorze danych i zapisaniu modelu uzyskujesz plik adapter_model.safetensors zawierający dostrojone wagi modelu LoRA. Plik Safetensors to punkt kontrolny LoRA używany w konwersji modelu.

W następnym kroku musisz przekonwertować wagi modelu na płaski bufor TensorFlow Lite za pomocą pakietu MediaPipe w Pythonie. ConversionConfig powinien określać opcje modelu podstawowego i dodatkowe opcje LoRA. Zwróć uwagę, że interfejs API obsługuje tylko wnioskowanie o LORA z użyciem GPU, dlatego backend musi być ustawiony na '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)

Konwerter wygeneruje 2 pliki płaskiego bufora TFLite, jeden dla modelu podstawowego a drugą w modelu LoRA.

Wnioskowanie modelu LoRA

Internet, Android i iOS LLM Inference API zostały zaktualizowane, aby obsługiwać wnioskowanie z modelu LoRA. Internet obsługuje dynamiczną architekturę LoRA, która może przełączać różne modele LoRA w czasie działania. Android i iOS obsługują statyczną algorytm LoRA, który przez cały czas trwania zadania wykorzystuje te same wagi LoRA.

Android obsługuje statyczną regulację LoRA podczas inicjowania. Aby wczytać model LoRA, użytkownicy muszą podać ścieżkę modelu LoRA oraz podstawowy 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)

Aby uruchomić wnioskowanie LLM z LoRA, użyj tych samych metod generateResponse() lub generateResponseAsync() co model podstawowy.