Spaces:
Sleeping
Sleeping
import gradio as gr | |
import torch | |
import transformers | |
import numpy as np | |
import torch.nn.functional as F | |
from accelerate import Accelerator | |
from torch.utils.data import Dataset | |
from transformers import AutoConfig, AutoModelForCausalLM, GPT2Tokenizer | |
from transformers import GPT2Tokenizer | |
modelo_llm = AutoModelForCausalLM.from_pretrained("modelos/modelo_final") | |
# Definindo uma classe chamada NumberTokenizer, que é usada para tokenizar os números | |
class DSATokenizer: | |
# Método construtor da classe, que é executado quando um objeto dessa classe é criado | |
def __init__(self, numbers_qty = 10): | |
# Lista de tokens possíveis que o tokenizador pode encontrar | |
vocab = ['+', '=', '-1', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] | |
# Definindo a quantidade de números que o tokenizador pode lidar | |
self.numbers_qty = numbers_qty | |
# Definindo o token de preenchimento (padding) | |
self.pad_token = '-1' | |
# Criando um dicionário que mapeia cada token para um índice único | |
self.encoder = {str(v):i for i,v in enumerate(vocab)} | |
# Criando um dicionário que mapeia cada índice único de volta ao token correspondente | |
self.decoder = {i:str(v) for i,v in enumerate(vocab)} | |
# Obtendo o índice do token de preenchimento no encoder | |
self.pad_token_id = self.encoder[self.pad_token] | |
# Método para decodificar uma lista de IDs de token de volta para uma string | |
def decode(self, token_ids): | |
return ' '.join(self.decoder[t] for t in token_ids) | |
# Método que é chamado quando o objeto da classe é invocado como uma função | |
def __call__(self, text): | |
# Dividindo o texto em tokens individuais e retornando uma lista dos IDs correspondentes | |
return [self.encoder[t] for t in text.split()] | |
# Cria o objeto | |
tokenizer = DSATokenizer(13) | |
# Definindo a função gera_solution com três parâmetros: input, solution_length e model | |
def faz_previsao(entrada, solution_length = 6, model = modelo_llm): | |
# Colocando o modelo em modo de avaliação. | |
model.eval() | |
# Convertendo a entrada (string) em tensor utilizando o tokenizer. | |
# O tensor é uma estrutura de dados que o modelo de aprendizado de máquina pode processar. | |
entrada = torch.tensor(tokenizer(entrada)) | |
# Iniciando uma lista vazia para armazenar a solução | |
solution = [] | |
# Loop que gera a solução de comprimento solution_length | |
for i in range(solution_length): | |
# Alimentando a entrada atual ao modelo e obtendo a saída | |
saida = model(entrada) | |
# Pegando o índice do maior valor no último conjunto de logits (log-odds) da saída, | |
# que é a previsão do modelo para o próximo token | |
predicted = saida.logits[-1].argmax() | |
# Concatenando a previsão atual com a entrada atual. | |
# Isso servirá como a nova entrada para a próxima iteração. | |
entrada = torch.cat((entrada, predicted.unsqueeze(0)), dim = 0) | |
# Adicionando a previsão atual à lista de soluções e convertendo o tensor em um número Python padrão | |
solution.append(predicted.cpu().item()) | |
# Decodificando a lista de soluções para obter a string de saída e retornando-a | |
return tokenizer.decode(solution) | |
# Testa a função | |
faz_previsao('3 + 5 =', solution_length = 2) | |
# Função para retornar a função que faz a previsão | |
def funcsolve(entrada): | |
return faz_previsao(entrada, solution_length = 2) | |
# Cria a web app | |
webapp = gr.Interface(fn = funcsolve, | |
inputs = [gr.Textbox(label = "Dados de Entrada", | |
lines = 1, | |
info = "Os dados devem estar na forma: '1 + 2 =' com um único espaço entre cada caractere e apenas números de um dígito são permitidos.")], | |
outputs = [gr.Textbox(label = "Resultado (Previsão do Modelo)", lines = 1)], | |
title = "Deploy de LLM Após o Fine-Tuning", | |
description = "Digite os dados de entrada e clique no botão Submit para o modelo fazer a previsão.", | |
examples = ["5 + 3 =", "2 + 9 ="]) | |
webapp.launch(share=True) |