คู่มือการสรุป LLM สำหรับ Android

LLM Inference API ช่วยให้คุณเรียกใช้โมเดลภาษาขนาดใหญ่ (LLM) ในอุปกรณ์ได้โดยสมบูรณ์สำหรับแอปพลิเคชัน Android ซึ่งคุณจะใช้ดำเนินการต่างๆ ได้มากมาย เช่น การสร้างข้อความ การดึงข้อมูลในรูปแบบที่เป็นภาษาธรรมชาติ และการสรุปเอกสาร งานนี้รองรับโมเดลภาษาขนาดใหญ่สำหรับการแปลงข้อความเป็นข้อความในตัว เพื่อให้คุณใช้โมเดล Generative AI ล่าสุดในอุปกรณ์กับแอป Android ได้

งานนี้รองรับ Gemma 2B ซึ่งเป็นส่วนหนึ่งของกลุ่มโมเดลแบบเปิดที่ทันสมัยและมีน้ำหนักเบา ซึ่งสร้างขึ้นจากการวิจัยและเทคโนโลยีเดียวกันกับที่ใช้สร้างโมเดล Gemini นอกจากนี้ยังรองรับโมเดลภายนอกต่อไปนี้ Phi-2, Falcon-RW-1B และ StableLM-3B พร้อมด้วยโมเดลทั้งหมดที่ส่งออกผ่าน AI Edge

ดูข้อมูลเพิ่มเติมเกี่ยวกับความสามารถ โมเดล และตัวเลือกการกำหนดค่าของงานนี้ได้ที่ภาพรวม

ตัวอย่างโค้ด

คู่มือนี้กล่าวถึงตัวอย่างแอปการสร้างข้อความพื้นฐานสำหรับ Android คุณสามารถใช้แอปเป็นจุดเริ่มต้นสำหรับแอป Android ของคุณเอง หรืออ้างอิงในแอปเมื่อแก้ไขแอปที่มีอยู่ โค้ดตัวอย่างโฮสต์อยู่ใน GitHub

ดาวน์โหลดโค้ด

วิธีการต่อไปนี้แสดงวิธีสร้างสำเนาโค้ดตัวอย่างในเครื่องโดยใช้เครื่องมือบรรทัดคำสั่ง git

วิธีดาวน์โหลดโค้ดตัวอย่าง

  1. โคลนที่เก็บ Git โดยใช้คำสั่งต่อไปนี้
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. (ไม่บังคับ) กำหนดค่าอินสแตนซ์ 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 เพิ่มทรัพยากร Dependency ต่อไปนี้ในไฟล์ build.gradle ของแอป Android

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

รุ่น

MediaPipe LLM Inference API ต้องใช้โมเดลภาษาจากข้อความเป็นข้อความที่ผ่านการฝึกแล้ว ซึ่งเข้ากันได้กับงานนี้ หลังจากดาวน์โหลดโมเดลแล้ว ให้ติดตั้งทรัพยากร Dependency ที่จำเป็นและพุชโมเดลไปยังอุปกรณ์ Android หากใช้โมเดลอื่นที่ไม่ใช่ Gemma คุณจะต้องแปลงโมเดลให้อยู่ในรูปแบบที่เข้ากันได้กับ MediaPipe

ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลที่ผ่านการฝึกแล้วสำหรับ LLM Inference API ได้ในภาพรวมงานส่วนโมเดล

ดาวน์โหลดโมเดล

ก่อนที่จะเริ่มต้น LLM Inference API ให้ดาวน์โหลดโมเดลที่รองรับมา 1 โมเดลและจัดเก็บไฟล์ไว้ในไดเรกทอรีโปรเจ็กต์ของคุณ

  • Gemma 2B: เป็นส่วนหนึ่งของกลุ่มโมเดลแบบเปิดที่ทันสมัยและมีน้ำหนักเบา ซึ่งสร้างขึ้นจากการวิจัยและเทคโนโลยีเดียวกันกับที่ใช้สร้างโมเดล Gemini เหมาะกับงานสร้างข้อความที่หลากหลาย รวมถึงการตอบคำถาม การสรุป และการให้เหตุผล
  • Phi-2: พารามิเตอร์ 2.7 พันล้านรายการ โมเดล Transformer เหมาะกับรูปแบบ Question-Answer, Chat และโค้ดมากที่สุด
  • Falcon-RW-1B: โมเดลถอดรหัสโดยทั่วไปของพารามิเตอร์ 1 พันล้านรายการได้รับการฝึกกับโทเค็น 350B ของ RefinedWeb
  • StableLM-3B: โมเดลภาษาแบบถอดรหัสพารามิเตอร์ 3 พันล้านชุดที่ฝึกล่วงหน้ากับชุดข้อมูลโค้ดและภาษาอังกฤษที่หลากหลายกว่า 1 ล้านล้านโทเค็น

หรือจะใช้โมเดลที่แมปและส่งออกผ่าน AI Edge Troch ก็ได้

เราขอแนะนำให้ใช้ Gemma 2B ซึ่งมีให้บริการในรุ่น Kaggle และอยู่ในรูปแบบที่เข้ากันได้กับ LLM Inference API อยู่แล้ว หากใช้ LLM อื่น คุณจะต้องแปลงโมเดลเป็นรูปแบบที่เหมาะกับ MediaPipe ดูข้อมูลเพิ่มเติมเกี่ยวกับ Gemma 2B ได้ที่เว็บไซต์ Gemma ดูข้อมูลเพิ่มเติมเกี่ยวกับโมเดลอื่นๆ ที่ใช้ได้ที่ภาพรวมงานส่วนโมเดล

แปลงโมเดลเป็นรูปแบบ MediaPipe

Conversion รูปแบบเนทีฟ

หากคุณใช้ LLM ภายนอก (Phi-2, Falcon หรือ StableLM) หรือ Gemma เวอร์ชันที่ไม่ใช่ Kaggle ให้ใช้สคริปต์ Conversion ของเราเพื่อจัดรูปแบบโมเดลให้เข้ากันได้กับ MediaPipe

กระบวนการแปลงรูปแบบต้องใช้แพ็กเกจ MediaPipe PyPI สคริปต์ Conversion จะพร้อมใช้งานในแพ็กเกจ MediaPipe ทั้งหมดหลังจากวันที่ 0.10.11

ติดตั้งและนำเข้าทรัพยากร Dependency พร้อมข้อมูลต่อไปนี้

$ 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 รองรับเฉพาะการอนุมาน LoRA กับ GPU เท่านั้น จึงต้องตั้งค่าแบ็กเอนด์เป็น '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 Flatbuffer 2 ไฟล์ โดยไฟล์หนึ่งสำหรับโมเดลฐานและอีกไฟล์หนึ่งสำหรับโมเดล LoRA

พารามิเตอร์ คำอธิบาย ค่าที่ยอมรับ
input_ckpt เส้นทางไปยังไฟล์ model.safetensors หรือ pytorch.bin โปรดทราบว่าบางครั้งรูปแบบ Safetensors ของโมเดลจะมีการชาร์ดออกเป็นหลายๆ ไฟล์ เช่น 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 ของไฟล์ Safetensors ที่จัดเก็บน้ำหนักของอะแดปเตอร์ LoRA PATH
lora_rank จำนวนเต็มที่แสดงอันดับของ LoRA ckpt ต้องระบุเพื่อแปลงน้ำหนักลอรา หากไม่ระบุ ตัวแปลงจะถือว่าไม่มีน้ำหนัก LoRA หมายเหตุ: เฉพาะแบ็กเอนด์ของ GPU เท่านั้นที่รองรับ LoRA จำนวนเต็ม
lora_output_tflite_file ชื่อไฟล์เอาต์พุต tflite สำหรับน้ำหนัก LoRA PATH

การแปลงรูปแบบ AI Edge

หากคุณใช้ LLM ที่แมปกับโมเดล TFLite ผ่าน AI Edge ให้ใช้สคริปต์การรวมกลุ่มของเราเพื่อสร้าง Task Bundle กระบวนการรวมกลุ่มจะแพ็กโมเดลที่แมป พร้อมข้อมูลเมตาเพิ่มเติม (เช่น พารามิเตอร์ Tokenizer) เพื่อเรียกใช้การอนุมานจากต้นทางถึงปลายทาง

กระบวนการรวมกลุ่มโมเดลต้องใช้แพ็กเกจ MediaPipe PyPI สคริปต์ Conversion จะพร้อมใช้งานในแพ็กเกจ MediaPipe ทั้งหมดหลังจากวันที่ 0.10.14

ติดตั้งและนำเข้าทรัพยากร Dependency พร้อมข้อมูลต่อไปนี้

$ 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 เส้นทางไปยังโมเดล TFLite ที่ส่งออกของ AI Edge PATH
tokenizer_model เส้นทางไปยังโมเดลเครื่องมือทำโทเค็นของ SentencePiece PATH
start_token โทเค็นเริ่มต้นที่เจาะจงรุ่น โทเค็นเริ่มต้นต้องมีอยู่ในโมเดล Tokenizer ที่ระบุ STRING
stop_tokens โทเค็นการหยุดที่เจาะจงของโมเดล โทเค็นหยุดต้องมีอยู่ในโมเดล Tokenizer ที่ระบุ รายการ [STRING]
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 ไม่มีข้อมูล
maxTokens จำนวนโทเค็นสูงสุดที่โมเดลจัดการ (โทเค็นอินพุต + โทเค็นเอาต์พุต) จำนวนเต็ม 512
topK จำนวนโทเค็นที่โมเดลจะพิจารณาในแต่ละขั้นตอนของการสร้าง จำกัดการคาดการณ์ไว้ที่โทเค็นที่เป็นไปได้มากที่สุดอันดับต้นๆ เมื่อตั้งค่า topK คุณต้องกำหนดค่าสำหรับ randomSeed ด้วย จำนวนเต็ม 40
temperature ปริมาณการสุ่มที่เกิดขึ้นระหว่างการสร้าง อุณหภูมิที่สูงขึ้นส่งผลให้ข้อความที่สร้างขึ้นมีความคิดสร้างสรรค์มากขึ้น ขณะที่อุณหภูมิที่ต่ำลงจะทําให้เกิดการสร้างที่คาดการณ์ได้มากขึ้น เมื่อตั้งค่า temperature คุณต้องกำหนดค่าสำหรับ randomSeed ด้วย ทศนิยม 0.8
randomSeed Seed แบบสุ่มที่ใช้ระหว่างการสร้างข้อความ จำนวนเต็ม 0
loraPath Absolute Path ที่นำไปยังโมเดล LoRA ในอุปกรณ์ หมายเหตุ: ใช้ได้กับรุ่น GPU เท่านั้น PATH ไม่มีข้อมูล
resultListener ตั้งค่า Listener ผลลัพธ์ให้รับผลลัพธ์แบบไม่พร้อมกัน ใช้ได้เฉพาะเมื่อใช้เมธอดการสร้างไม่พร้อมกัน ไม่มีข้อมูล ไม่มีข้อมูล
errorListener ตั้งค่า Listener ข้อผิดพลาดที่ไม่บังคับ ไม่มีข้อมูล ไม่มีข้อมูล

เตรียมข้อมูล

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 Inference API สามารถกำหนดค่าให้รองรับการปรับแรงก์ต่ำ (LoRA) สำหรับโมเดลภาษาขนาดใหญ่ได้ นักพัฒนาซอฟต์แวร์จะใช้โมเดล LoRA ที่ปรับแต่งมาปรับแต่งลักษณะการทำงานของ LLM ผ่านกระบวนการฝึกอบรมที่คุ้มค่า

การรองรับ LoRA ของ LLM Inference API ใช้งานได้กับรุ่น Gemma-2B และ Phi-2 สำหรับแบ็กเอนด์ GPU โดยน้ำหนัก LoRA จะใช้กับเลเยอร์ความสนใจเท่านั้น การใช้งานในช่วงแรกนี้เป็น API ทดลองสำหรับการพัฒนาในอนาคต โดยมีแผนที่จะรองรับโมเดลเพิ่มเติมและเลเยอร์ประเภทต่างๆ ในการอัปเดตที่กำลังจะมาถึง

เตรียมโมเดล LoRA

ทำตามวิธีการใน HuggingFace เพื่อฝึกโมเดล LoRA ที่ปรับแต่งอย่างละเอียดในชุดข้อมูลของคุณเองด้วยประเภทโมเดลที่รองรับ Gemma-2B หรือ Phi-2 ทั้งรุ่น Gemma-2B และ Phi-2 พร้อมใช้งานบน HuggingFace ในรูปแบบ Safetensors เนื่องจาก 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"],
)

สำหรับการทดสอบ มีโมเดล LoRA ที่ปรับแต่งแล้วที่เข้าถึงได้แบบสาธารณะซึ่งพอดีกับ LLM Inference API ที่พร้อมให้ใช้งานบน HuggingFace เช่น monsterapi/gemma-2b-lora-maths-orca-200k สำหรับ Gemma-2B และ lole25/phi-2-sft-ultrachat-lora สำหรับ Phi-2

หลังจากฝึกชุดข้อมูลที่เตรียมและบันทึกโมเดลแล้ว คุณจะได้รับไฟล์ adapter_model.safetensors ที่มีน้ำหนักของโมเดล LoRA ที่ปรับแต่งแล้ว ไฟล์ Safetensors คือจุดตรวจสอบ LoRA ที่ใช้ในการแปลงโมเดล

ในขั้นตอนถัดไป คุณต้องแปลงน้ำหนักของโมเดลเป็น TensorFlow Lite Flatbuffer โดยใช้แพ็กเกจ MediaPipe Python ConversionConfig ควรระบุตัวเลือกรุ่นพื้นฐานและตัวเลือก LoRA เพิ่มเติม โปรดทราบว่า เนื่องจาก API รองรับเฉพาะการอนุมาน LoRA กับ GPU เท่านั้น จึงต้องตั้งค่าแบ็กเอนด์เป็น '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 Flatbuffer 2 ไฟล์ โดยไฟล์หนึ่งสำหรับโมเดลฐานและอีกไฟล์หนึ่งสำหรับโมเดล LoRA

การอนุมานโมเดล LoRA

API การอนุมาน LLM บนเว็บ, Android และ iOS ได้รับการอัปเดตให้รองรับการอนุมานโมเดล LoRA เว็บรองรับ 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)

หากต้องการเรียกใช้การอนุมาน LLM ด้วย LoRA ให้ใช้เมธอด generateResponse() หรือ generateResponseAsync() เดียวกันกับโมเดลพื้นฐาน