Guia de inferência de LLM para Web

A API de inferência de LLM permite executar modelos de linguagem grandes (LLMs) completamente no navegador para aplicativos da Web, que podem ser usados para realizar uma ampla gama de tarefas, como gerar texto, recuperar informações em linguagem natural e resumir documentos. A tarefa oferece suporte integrado a vários modelos de linguagem grandes de texto para texto, para que você possa aplicar os modelos de IA generativa mais recentes no dispositivo aos seus apps da Web.

Confira essa tarefa em ação com a demonstração do MediaPipe Studio. Para mais informações sobre os recursos, modelos e opções de configuração dessa tarefa, consulte a Visão geral.

Exemplo de código

O exemplo de aplicativo para a API de inferência do LLM fornece uma implementação básica dessa tarefa em JavaScript para sua referência. Use este app de exemplo para começar a criar seu próprio app de geração de texto.

É possível acessar o app de exemplo de API LLM Inference no GitHub (em inglês).

Configuração

Esta seção descreve as principais etapas para configurar seu ambiente de desenvolvimento e projetos de código especificamente para usar a API de inferência de LLM. Para informações gerais sobre como configurar seu ambiente de desenvolvimento para usar as tarefas do MediaPipe, incluindo os requisitos da versão da plataforma, consulte o Guia de configuração para a Web.

Compatibilidade com navegadores

A API LLM Inference requer um navegador da Web compatível com a WebGPU. Para ver uma lista completa de navegadores compatíveis, consulte Compatibilidade do navegador da GPU.

Pacotes JavaScript

O código da API LLM Inference está disponível pelo pacote @mediapipe/tasks-genai. Você pode encontrar e fazer o download dessas bibliotecas nos links fornecidos no guia de configuração da plataforma.

Instale os pacotes necessários para o preparo local:

npm install @mediapipe/tasks-genai

Para implantar em um servidor, use um serviço de rede de fornecimento de conteúdo (CDN), como o jsDelivr, para adicionar código diretamente à página HTML:

<head>
  <script src="https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai/genai_bundle.cjs"
    crossorigin="anonymous"></script>
</head>

Modelo

A API MediaPipe LLM Inference requer um modelo treinado compatível com essa tarefa. Para aplicativos da Web, o modelo precisa ser compatível com GPU.

Para mais informações sobre modelos treinados disponíveis para a API LLM Inference, consulte a visão geral da tarefa seção Modelos.

Fazer o download de um modelo

Antes de inicializar a API de inferência de LLM, faça o download de um dos modelos compatíveis e armazene o arquivo no diretório do projeto:

  • Gemma-2 2B: a versão mais recente da família de modelos Gemma. Parte de uma família de modelos abertos leves e de última geração, criados com a mesma pesquisa e tecnologia usada para criar os modelos do Gemini.
  • Gemma 2B: faz parte de uma família de modelos abertos leves e de última geração criados com a mesma pesquisa e tecnologia usadas para criar os modelos do Gemini. Adequado para diversas tarefas de geração de texto, incluindo resposta a perguntas, resumo e raciocínio.
  • Phi-2: modelo Transformer de 2,7 bilhões de parâmetros, mais adequado para o formato de perguntas e respostas, chat e código.
  • Falcon-RW-1B: modelo somente decodificador causal com 1 bilhão de parâmetros treinado em 350 bilhões de tokens de RefinedWeb (link em inglês).
  • StableLM-3B: modelo de linguagem de apenas decodificador de parâmetros de 3 bilhões pré-treinado em 1 trilhão de tokens de diversos conjuntos de dados de inglês e código.

Recomendamos usar o Gemma-2 2B, que está disponível nos modelos do Kaggle. Para mais informações sobre os outros modelos disponíveis, consulte a seção "Modelos" da visão geral da tarefa.

Converter modelo para o formato MediaPipe

Conversão de modelo nativo

Se você estiver usando um LLM externo (Phi-2, Falcon ou StableLM) ou uma versão do Gemma que não seja do Kaggle, use nossos scripts de conversão para formatar o modelo para que ele seja compatível com o MediaPipe.

O processo de conversão do modelo requer o pacote PyPI do MediaPipe. O script de conversão está disponível em todos os pacotes do MediaPipe após 0.10.11.

Instale e importe as dependências com o seguinte:

$ python3 -m pip install mediapipe

Use a biblioteca genai.converter para converter o modelo:

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)

Para converter o modelo LoRA, o ConversionConfig precisa especificar as opções do modelo base, bem como as opções adicionais de LoRA. Como a API só oferece suporte à inferência LoRA com GPU, o back-end precisa ser definido como '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)

O conversor vai gerar dois arquivos TFLite flatbuffer, um para o modelo base e outro para o modelo LoRA.

Parâmetro Descrição Valores aceitos
input_ckpt O caminho para o arquivo model.safetensors ou pytorch.bin. Às vezes, o formato de safetensors do modelo é dividido em vários arquivos, por exemplo, model-00001-of-00003.safetensors, model-00001-of-00003.safetensors. É possível especificar um padrão de arquivo, como model*.safetensors. CAMINHO
ckpt_format O formato do arquivo do modelo. {"safetensors", "pytorch"}
model_type O LLM sendo convertido. {"PHI_2", "FALCON_RW_1B", "STABLELM_4E1T_3B", "GEMMA_2B", "GEMMA_7B", "GEMMA-2_2B"}
backend O processador (delegado) usado para executar o modelo. {"cpu", "gpu"}
output_dir O caminho para o diretório de saída que hospeda os arquivos de peso por camada. CAMINHO
output_tflite_file O caminho para o arquivo de saída. Por exemplo, "model_cpu.bin" ou "model_gpu.bin". Esse arquivo é compatível apenas com a API de inferência LLM e não pode ser usado como um arquivo "tflite" geral. CAMINHO
vocab_model_file O caminho para o diretório que armazena os arquivos tokenizer.json e tokenizer_config.json. No Gemma, aponte para o arquivo tokenizer.model único. CAMINHO
lora_ckpt O caminho para o arquivo de safetensors do LoRA ckpt que armazena o peso do adaptador LoRA. CAMINHO
lora_rank Um número inteiro que representa a classificação do ckpt do LoRA. Obrigatório para converter os pesos lora. Se não for fornecido, o conversor presumirá que não há pesos LoRA. Observação: somente o back-end da GPU oferece suporte ao LoRA. Número inteiro
lora_output_tflite_file Nome do arquivo tflite de saída para os pesos do LoRA. CAMINHO

Conversão de modelo do AI Edge

Se você estiver usando um LLM mapeado para um modelo TFLite pelo AI Edge, use nosso script de agrupamento para criar um pacote de tarefas. O processo de agrupamento empacota o modelo mapeado com metadados adicionais (por exemplo, parâmetros de tokenizador) necessários para executar a inferência de ponta a ponta.

O processo de empacotamento de modelos requer o pacote MediaPipe PyPI. O script de conversão está disponível em todos os pacotes MediaPipe após 0.10.14.

Instale e importe as dependências com o seguinte:

$ python3 -m pip install mediapipe

Use a biblioteca genai.bundler para agrupar o modelo:

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)
Parâmetro Descrição Valores aceitos
tflite_model O caminho para o modelo TFLite exportado do AI Edge. CAMINHO
tokenizer_model O caminho para o modelo de tokenizador do SentencePiece. CAMINHO
start_token Token inicial específico do modelo. O token de início precisa estar presente no modelo de tokenizador fornecido. STRING
stop_tokens Modelo de tokens de parada específicos. Os tokens de parada precisam estar presentes no modelo de tokenizador fornecido. LIST[STRING]
output_filename O nome do arquivo do pacote de tarefas de saída. CAMINHO

Adicionar modelo ao diretório do projeto

Armazene o modelo no diretório do projeto:

<dev-project-root>/assets/gemma-2b-it-gpu-int4.bin

Especifique o caminho do modelo com o parâmetro modelAssetPath do objeto baseOptions:

baseOptions: { modelAssetPath: `/assets/gemma-2b-it-gpu-int4.bin`}

Criar a tarefa

Use uma das funções createFrom...() da API Inference do LLM para preparar a tarefa para executar inferências. É possível usar a função createFromModelPath() com um caminho relativo ou absoluto para o arquivo de modelo treinado. O exemplo de código usa a função createFromOptions(). Para mais informações sobre as opções de configuração disponíveis, consulte Opções de configuração.

O código abaixo demonstra como criar e configurar essa tarefa:

const genai = await FilesetResolver.forGenAiTasks(
    // path/to/wasm/root
    "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm"
);
llmInference = await LlmInference.createFromOptions(genai, {
    baseOptions: {
        modelAssetPath: '/assets/gemma-2b-it-gpu-int4.bin'
    },
    maxTokens: 1000,
    topK: 40,
    temperature: 0.8,
    randomSeed: 101
});

Opções de configuração

Esta tarefa tem as seguintes opções de configuração para apps da Web e JavaScript:

Nome da opção Descrição Intervalo de valor Valor padrão
modelPath O caminho para onde o modelo está armazenado no diretório do projeto. CAMINHO N/A
maxTokens O número máximo de tokens (tokens de entrada + tokens de saída) que o modelo processa. Número inteiro 512
topK O número de tokens que o modelo considera em cada etapa de geração. Limita as previsões aos k tokens mais prováveis. Número inteiro 40
temperature A quantidade de aleatoriedade introduzida durante a geração. Uma temperatura mais alta resulta em mais criatividade no texto gerado, enquanto uma temperatura mais baixa produz uma geração mais previsível. Ponto flutuante 0,8
randomSeed A semente aleatória usada durante a geração de texto. Número inteiro 0
loraRanks Classificações da LoRA que serão usadas pelos modelos da LoRA durante a execução. Observação: isso só é compatível com modelos de GPU. Matriz de números inteiros N/A

Preparar dados

A API LLM Inference aceita dados de texto (string). A tarefa processa a entrada de dados, incluindo a tokenização e o pré-processamento de tensores.

Todo o pré-processamento é feito na função generateResponse(). Não há necessidade de pré-processamento adicional do texto de entrada.

const inputPrompt = "Compose an email to remind Brett of lunch plans at noon on Saturday.";

Executar a tarefa

A API LLM Inference usa a função generateResponse() para acionar inferências. Para classificação de texto, isso significa retornar as categorias possíveis para o texto de entrada.

O código abaixo demonstra como executar o processamento com o modelo de tarefas.

const response = await llmInference.generateResponse(inputPrompt);
document.getElementById('output').textContent = response;

Para transmitir a resposta, use o seguinte:

llmInference.generateResponse(
  inputPrompt,
  (partialResult, done) => {
        document.getElementById('output').textContent += partialResult;
});

Processar e mostrar resultados

A API de inferência do LLM retorna uma string, que inclui o texto da resposta gerada.

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]

Personalização de modelo LoRA

A API de inferência de LLM do Mediapipe pode ser configurada para oferecer suporte à adaptação de baixa classificação (LoRA) para modelos de linguagem grandes. Usando modelos LoRA ajustados, os desenvolvedores podem personalizar o comportamento dos LLMs com um processo de treinamento econômico.

O suporte da LoRA à API LLM Inference funciona para modelos Gemma-2B e Phi-2 para o back-end da GPU, com pesos LoRA aplicáveis apenas às camadas de atenção. Essa implementação inicial serve como uma API experimental para desenvolvimentos futuros, com planos de oferecer suporte a mais modelos e vários tipos de camadas nas próximas atualizações.

Preparar modelos LoRA

Siga as instruções do HuggingFace para treinar um modelo LoRA ajustado em seu próprio conjunto de dados com os tipos de modelo com suporte, Gemma-2B ou Phi-2. Os modelos Gemma-2B e Phi-2 estão disponíveis no HuggingFace no formato de seguros. Como a API LLM Inference oferece suporte apenas a LoRA em camadas de atenção, especifique apenas essas camadas ao criar o LoraConfig da seguinte maneira:

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

Para testes, há modelos LoRA ajustados e acessíveis publicamente que combinam com a API LLM Inference disponível no HuggingFace. Por exemplo, monsterapi/gemma-2b-lora-maths-orca-200k para Gemma-2B e lole25/phi-2-sft-ultrachat-lora para Phi-2.

Depois de treinar no conjunto de dados preparado e salvar o modelo, você recebe um arquivo adapter_model.safetensors contendo os pesos do modelo LoRA ajustado. O arquivo safetensors é o checkpoint LoRA usado na conversão do modelo.

Na próxima etapa, você precisa converter os pesos do modelo em um Flatbuffer do TensorFlow Lite usando o pacote MediaPipe Python. O ConversionConfig precisa especificar as opções do modelo base, bem como outras opções de LoRA. Como a API só oferece suporte à inferência LoRA com GPU, o back-end precisa ser definido como '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)

O conversor vai gerar dois arquivos flatbuffer do TFLite, um para o modelo base e outro para o modelo LoRA.

Inferência de modelo LoRA

A API LLM Inference para Web, Android e iOS foi atualizada para oferecer suporte à inferência de modelos LoRA. A Web oferece suporte à LoRA dinâmica, que pode alternar entre diferentes modelos LoRA durante a execução. O Android e o iOS são compatíveis com a LoRA estática, que usa os mesmos pesos da LoRA durante o ciclo de vida da tarefa.

A Web oferece suporte ao LoRA dinâmico durante a execução. Ou seja, os usuários declaram que as classificações LoRA serão usadas durante a inicialização e podem trocar diferentes modelos LoRA durante o tempo de execução.

const genai = await FilesetResolver.forGenAiTasks(
    // path/to/wasm/root
    "https://cdn.jsdelivr.net/npm/@mediapipe/tasks-genai@latest/wasm"
);
const llmInference = await LlmInference.createFromOptions(genai, {
    // options for the base model
    ...
    // LoRA ranks to be used by the LoRA models during runtime
    loraRanks: [4, 8, 16]
});

Durante a execução, depois que o modelo base for inicializado, carregue os modelos LoRA a serem usados. Além disso, acione o modelo LoRA passando a referência do modelo LoRA enquanto gera a resposta do LLM.

// Load several LoRA models. The returned LoRA model reference is used to specify
// which LoRA model to be used for inference.
loraModelRank4 = await llmInference.loadLoraModel(loraModelRank4Url);
loraModelRank8 = await llmInference.loadLoraModel(loraModelRank8Url);

// Specify LoRA model to be used during inference
llmInference.generateResponse(
  inputPrompt,
  loraModelRank4,
  (partialResult, done) => {
        document.getElementById('output').textContent += partialResult;
});