9
respostas

Somos brasileiros. Precisamos de soluções OpenSource.

Fiquei muito feliz quando ví o novo curso "LangChain e Python" na Alura. Não poderia chegar em um momento melhor para minha trilha de aprendizagem.

O problema é que os responsáveis pelo curso optaram por utilizar o modelo de LLM da OpenAI via API e isso tem custo, quase o mesmo valor mensal da Alura. Ou seja, esse curso para ser feito seguindo os mesmos passos do professor Guilherme Silveira, é necessário um investimento adicional que creio que a maioria de nós alunos não tem condições. Pelo menos eu não tenho.

Só acho estranho terem optado por este modelo sabendo disso. Acredito que tudo foi pensado antes, e se não foi deveriam ao menos ter pensado no impacto que teria se caso um aluno (como a maioria) tivesse que usar um outro modelo open source:

- Diferente configuração
- Uso de outros parâmetros
- Importação diferente
- Métodos diferentes

Imaginem agora um aluno que não é tão avançado ter que fazer todos esses passos sem ajuda de um professor? Afinal nós estamos acostumados a ter todo o suporte e conteúdo completo nos demais cursos da Alura, e é no mínimo com muito rúido que conseguiríamos fazer tais adaptações tendo que utilizar fontes externas de consultas, quando o que queríamos era um aprendizado direto desde a configuração até a conclusão do curso.

Indico fortemente que a diretoria avalie a possibilidade de incluir um vídeo guiando nas configurações ou adaptações necessárias para alunos que pretendem utilizar os modelos OpenSource. Ou até lançar uma reformulação do curso com tal modelo.

9 respostas

Olá Caio!

Entendo perfeitamente sua preocupação com os custos adicionais ao utilizar a API da OpenAI. Realmente, é importante considerar alternativas que sejam acessíveis para todos os estudantes. Felizmente, existem algumas opções open source que podem ser utilizadas como substitutas para o GPT-3.5 da OpenAI. Vou te mostrar uma alternativa usando o modelo GPT-2, que é open source e pode ser executado localmente.

Usando GPT-2 com Hugging Face

O GPT-2 é um modelo de linguagem desenvolvido pela OpenAI, mas que foi disponibilizado de forma open source. Podemos utilizá-lo através da biblioteca transformers da Hugging Face. Vou te mostrar como adaptar o código para usar o GPT-2.

  1. Instalando as dependências:

Primeiro, vamos instalar a biblioteca transformers e torch:

pip install transformers torch
  1. Adaptando o código:

Vamos criar um novo arquivo chamado main_gpt2.py e adaptar o código para usar o GPT-2.

from transformers import GPT2LMHeadModel, GPT2Tokenizer

# Carregar o modelo e o tokenizer
model_name = "gpt2"
model = GPT2LMHeadModel.from_pretrained(model_name)
tokenizer = GPT2Tokenizer.from_pretrained(model_name)

# Definir as variáveis
numero_de_dias = 7
numero_de_criancas = 2
atividade = "praia"

# Criar o prompt
prompt = f"Crie um roteiro de viagem de {numero_de_dias} dias, para uma família com {numero_de_criancas} crianças, que gostam de {atividade}."

# Tokenizar o prompt
inputs = tokenizer.encode(prompt, return_tensors="pt")

# Gerar a resposta
outputs = model.generate(inputs, max_length=150, num_return_sequences=1)

# Decodificar a resposta
resposta = tokenizer.decode(outputs[0], skip_special_tokens=True)

print(resposta)

Explicação:

  1. Instalação das dependências: Utilizamos pip install transformers torch para instalar as bibliotecas necessárias.

  2. Carregamento do modelo e tokenizer: Utilizamos o modelo gpt2 da biblioteca transformers.

  3. Definição das variáveis: Mantemos as mesmas variáveis do exemplo original.

  4. Criação do prompt: Criamos o prompt da mesma forma que no exemplo original.

  5. Tokenização do prompt: Convertendo o prompt em tokens que o modelo GPT-2 pode entender.

  6. Geração da resposta: Utilizamos o método generate para gerar uma resposta baseada no prompt.

  7. Decodificação da resposta: Convertendo os tokens de volta para texto legível.

Essa abordagem permite que você utilize um modelo de linguagem poderoso sem custos adicionais, e pode ser uma excelente alternativa para continuar seu aprendizado.

Vale lembrar que, no universo das ferramentas de IA, o mais comum é encontrar modelos pagos, devido ao alto custo de desenvolvimento e manutenção. Encontrar ferramentas 100% gratuitas e sem limites é um desafio, mas existem alternativas como o GPT-2 que podem ser bastante úteis para o aprendizado. Explore as opções disponíveis e encontre a que melhor se adapta às suas necessidades e orçamento.

Espero ter ajudado e bons estudos!

Professor Rodrigo, muito obrigado pela atenção e a solução alternativa.

Instalei as dependências citadas e criei o arquivo "main.py" do jeito indicado.

Ao tentar rodar o código no terminal Python, recebi o seguinte erro:

The attention mask and the pad token id were not set. As a consequence, you may observe unexpected behavior. Please pass your input's `attention_mask` to obtain reliable results.
Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.

Eu lembro em outro curso que tive que criar a máscara, mas não estou muito familiarizado.

Sabe como posso regularizar essa configuração?

Aguardando para poder indicar se esta solução está completa e pronta para ser utilizada por outros alunos.

Mais uma vez obrigado a todo o time da Alura que se mostrou completamente dedicado na solução desta questão.

Att, Caio Leão

Faz esses ajustes no código para resolver essa questão da máscara:

from transformers import GPT2LMHeadModel, GPT2Tokenizer

# Carregar o modelo e o tokenizer
model_name = "gpt2"
model = GPT2LMHeadModel.from_pretrained(model_name)
tokenizer = GPT2Tokenizer.from_pretrained(model_name)

# Definir as variáveis
numero_de_dias = 7
numero_de_criancas = 2
atividade = "praia"

# Criar o prompt
prompt = f"Crie um roteiro de viagem de {numero_de_dias} dias, para uma família com {numero_de_criancas} crianças, que gostam de {atividade}."

# Tokenizar o prompt e gerar a máscara de atenção
inputs = tokenizer(prompt, return_tensors="pt")

# Gerar a resposta, passando a máscara de atenção
outputs = model.generate(**inputs, max_length=150, num_return_sequences=1)

# Decodificar a resposta
resposta = tokenizer.decode(outputs[0], skip_special_tokens=True)

print(resposta)

Agora reportou este erro:

Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.

Na verdade isso é apenas um warning, que sempre vai aparecer mesmo quando o programa for executado.

Se não tiver gerado a resposta logo abaixo desse warning, altere o código

from transformers import GPT2LMHeadModel, GPT2Tokenizer

# Carregar o modelo e o tokenizer
model_name = "gpt2"
model = GPT2LMHeadModel.from_pretrained(model_name)
tokenizer = GPT2Tokenizer.from_pretrained(model_name)

# Definir o token de padding
tokenizer.pad_token = tokenizer.eos_token

# Definir as variáveis
numero_de_dias = 7
numero_de_criancas = 2
atividade = "praia"

# Criar o prompt
prompt = f"Crie um roteiro de viagem de {numero_de_dias} dias para Florianópolis, para uma família com {numero_de_criancas} crianças que gostam de {atividade}."

# Tokenizar o prompt
inputs = tokenizer(prompt, return_tensors="pt")

# Gerar a resposta
outputs = model.generate(**inputs, max_length=150, num_return_sequences=1)

# Decodificar a resposta
resposta = tokenizer.decode(outputs[0], skip_special_tokens=True)

print(resposta)

Acho que tem algo errado. Fiz a última alteração indicada:

from transformers import GPT2LMHeadModel, GPT2Tokenizer

# Carregar o modelo e o tokenizer
model_name = "gpt2"
model = GPT2LMHeadModel.from_pretrained(model_name)
tokenizer = GPT2Tokenizer.from_pretrained(model_name)

# Definir o token de padding
tokenizer.pad_token = tokenizer.eos_token

# Definir as variáveis
numero_de_dias = 7
numero_de_criancas = 2
atividade = "praia"

# Criar o prompt
prompt = f"Crie um roteiro de viagem de {numero_de_dias} dias para Florianópolis, para uma família com {numero_de_criancas} crianças que gostam de {atividade}."

# Tokenizar o prompt
inputs = tokenizer(prompt, return_tensors="pt")

# Gerar a resposta
outputs = model.generate(**inputs, max_length=150, num_return_sequences=1)

# Decodificar a resposta
resposta = tokenizer.decode(outputs[0], skip_special_tokens=True)

print(resposta)

E mesmo assim parece não estar funcionando ou com algum erro, pois a resposta foi:

Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.
Crie um roteiro de viagem de 7 dias para Florianópolis, para uma família com 2 crianças que gostam de praia.

Por de la vida, porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque porque

Process finished with exit code 0

Não seria melhor utilizar o próprio LangChain para manter a metodologia do curso original, e apenas optar por usar llama 3? Caso você consiga me ajudar com isso acho que irá funcionar corretamente, além do modelo da Meta ser mais atual e performático. E acredito que utilizando LangChain ficará mais parecido também com o que é proposto no curso.

Muito obrigado novamente.

Boa! Dá para fazer sim e fica até melhor. Pesquisei aqui um modelo em português e achei um que funcionou bem.

Código adaptado:

from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
import torch

# Configuração do modelo LLaMA
model_name = "adalbertojunior/Llama-3-8B-Instruct-Portuguese-v0.1"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name,
                                              device_map='auto',
                                              torch_dtype=torch.float16,
                                              low_cpu_mem_usage=True)

# Configurar o pipeline de geração de texto
pipe = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    max_new_tokens=150,
)

# Definir as variáveis
numero_de_dias = 7
numero_de_criancas = 2
atividade = "praia"
destino = "Florianópolis"

# Criar o prompt
prompt = f"Crie um roteiro de viagem de {numero_de_dias} dias para Florianópolis, para uma família com {numero_de_criancas} crianças que gostam de {atividade}."

# Gerar a resposta usando o pipeline configurado
outputs = pipe(prompt)

# Extrair e imprimir a resposta gerada
resposta = outputs[0]['generated_text']
print(resposta)

Bons estudos!

Insira aqui a descrição dessa imagem para ajudar na acessibilidade Estava tendo alguns erros e resolvi eu mesmo tentar resolver para poder chegar aqui com alguma resposta.

Consegui resolver aparentemente os erros de formatação pequenos, e dependências que pareciam estar faltando. O código agora parece funcionar, mas não apresenta nenhum resultado para o prompt no terminal.

Eu implementei algumas mensagens de depuração para tentar rastrear alguma etapa defeituosa, mas acho que não tem. Talvez alguma configuração ou parâmetro errado? Ou talvez algo com modelo usado? Afinal você disse que testou e parece que não funcionou aqui, então ainda pode ser a falta de alguma dependência? Posso tentar a utilização do Llama 8B e ver se consigo já que o tenho já instalado?

Aqui está o código corrigido com as mensagens de depuração:

from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
import torch

# Configuração do modelo LLaMA
model_name = "adalbertojunior/Llama-3-8B-Instruct-Portuguese-v0.1"
print("Carregando tokenizer...")
tokenizer = AutoTokenizer.from_pretrained(model_name)
print("Carregando modelo...")
model = AutoModelForCausalLM.from_pretrained(
    model_name,
    device_map='auto',
    torch_dtype=torch.float16,
    low_cpu_mem_usage=True
)

# Configurar o pipeline de geração de texto
print("Configurando o pipeline de geração de texto...")
pipe = pipeline(
    "text-generation",
    model=model,
    tokenizer=tokenizer,
    max_new_tokens=150,
)

# Definir as variáveis
numero_de_dias = 7
numero_de_criancas = 2
atividade = "praia"
destino = "Florianópolis"

# Criar o prompt
prompt = (
    f"Crie um roteiro de viagem de {numero_de_dias} dias para Florianópolis, "
    f"para uma família com {numero_de_criancas} crianças que gostam de {atividade}."
)
print(f"Prompt criado: {prompt}")

# Gerar a resposta usando o pipeline configurado
try:
    print("Gerando a resposta...")
    outputs = pipe(prompt)
    print(f"Outputs gerados: {outputs}")

    if outputs:
        resposta = outputs[0]['generated_text']
        print("Resposta gerada:")
        print(resposta)
    else:
        print("Nenhuma resposta gerada.")
except Exception as e:
    print(f"Ocorreu um erro durante a geração do texto: {e}")

Outra coisa! Notei que os processos ainda estavam acontecendo, e consumindo bastante dos meus 32gb de RAM! O terminal segue aparentemente sem erro, mas parece não conseguir exibir a mensagem de resposta ao prompt.

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Tem algumas dependências do Python que precisam ser instaladas:

  • transformers
  • pytorch
  • huggingface-hub
  • langchain
  • accelerate

Eu rodei o seu código e funcionou, porém tem um detalhe importante. Como será executado localmente, e não via integração com a API da OpenAI, a execução demora bastante para finalizar. No meu laptop demorou em torno de 6 minutos até finalizar e esse tempo vai variar de acordo com as configurações de hardware do seu computador.