Alura > Cursos de Inteligência Artificial > Cursos de Engenharia de Modelos & Fine-Tuning > Conteúdos de Engenharia de Modelos & Fine-Tuning > Primeiras aulas do curso Modelos de linguagem: fine-tuning e quantização para análise de sentimentos

Modelos de linguagem: fine-tuning e quantização para análise de sentimentos

Panorama e dataset do projeto - Apresentação

Apresentando o curso e o cronograma

Olá! Seja bem-vinde ao curso de GammaFactor, no qual nós vamos realizar fine-tuning (ajuste fino) de modelos. Aqui no nosso curso, além de abordarmos como fazemos o treinamento, vamos mostrar como implementar este projeto em algo criado especialmente para o curso: um SaaS (software como serviço) pequeno, que se chamará Scooter-A. Ele será responsável por coletar o sentimento de uma pessoa, terá um agente de LLM para tratar essas informações e utilizará nosso modelo com fine-tuning (ajuste fino).

Para que você entenda desde já o que vamos fazer no curso, nós preparamos um schedule (cronograma) para motivar você a seguir conosco. Como mencionamos, a ideia é que este seja um curso completo, então buscamos abordar diversos temas do treinamento.

Todo o projeto do curso está separado em branches (ramificações) do repositório do curso, em partes numeradas de 1 a 6. Ao longo das aulas, passaremos por dataset (conjunto de dados), fine-tuning com LoRA, QLoRA, o ecossistema da Hugging Face, o harness (estrutura de testes) e o projeto final, que é o Scooter-A.

Explorando o harness e seus componentes

Para facilitar a visualização do projeto, nesta introdução vamos mostrar um pouco do que veremos. Incluímos uma imagem da OpenAI, do Codex. Consideramos essa abordagem interessante e útil no dia a dia, no qual construímos um harness. O que esse harness faz? Ele compreende o nosso projeto e utiliza tecnologias como Codex, agentes, subagentes, MCP do GitHub, MCP da Stripe. Temos diversos componentes instalados, além de cobrir como preparar o dataset, os arquivos de fine-tuning com LoRA e QLoRA, conteúdos que aprenderemos ao longo do curso. Esse harness está completo, também utiliza o Graphify e um modelo pequeno do Codex, o Luna, que está funcionando muito bem.

Isso é interessante porque conseguimos construir outros modelos com fine-tuning (ajuste fino), além do que veremos no curso.

Priorizando o ajuste fino sem interface web

A grande estrela aqui é o LLaMA Factory. Todo o fine-tuning que foi construído para o Codex foi pensado para o LLaMA Factory. Não utilizaremos, neste curso, a interface Web do LLaMA Factory. A documentação do LLaMA, por padrão, está em inglês; nós a traduzimos para o português, pois este curso é focado no público brasileiro.

Neste curso, não passaremos pela interface web. Nosso foco será preparar os dados e executar as inferências do modelo, trabalhando com LoRA e QLoRA, e percorrendo todos esses aspectos ao longo do conteúdo.

Configurando ambientes local e remoto

Organizamos o ambiente de duas formas:

Todo o material e ferramentas utilizados serão gratuitos.

No cenário local com LoRA, deixamos configurados o MLflow (que explicaremos adiante) e o Jupyter, pois executaremos na própria máquina. O projeto da "Scrut-A", mencionado na apresentação do curso, será desenvolvido em Next.js. O Harness está preparado tanto para treinar o modelo quanto para construir a aplicação da "Scrut-A", nossa empresa fictícia. Também aplicaremos melhores práticas de React utilizando o Harness, que oferece recursos para criação do modelo.

Também teremos um modelo integrado à "Scrut-A" utilizando o GPT-OS e o Ollama; novamente, tudo sem custo.

Publicando e servindo o modelo

Publicaremos nosso modelo na Hugging Face — tanto o LoRA completo quanto o QLoRA — para serem consumidos via FastAPI. Essa API entregará a análise de sentimento para a pessoa usuária; mostraremos isso na introdução do curso, no projeto da "Scrut-A".

Mencionamos o Qwen: trabalharemos tanto com um modelo LoRA quanto com QLoRA, que utiliza quantização; poderemos quantizar um modelo maior do Qwen. Detalharemos isso mais à frente.

Antecipando a arquitetura do projeto

No primeiro vídeo do curso, apresentaremos a arquitetura do projeto e como construiremos nosso modelo com fine-tuning (ajuste fino), capaz de analisar sentimento.

É isso. Eu aguardo você no curso. Um grande abraço do MD. [♪]

Panorama e dataset do projeto - Configurando ambiente e dependências do projeto

Apresentando o dataset e ferramentas do ambiente

Nesta primeira parte do curso, nós vamos trazer o nosso dataset (conjunto de dados) para o Scutia, que será responsável por armazenar os dados para a análise de sentimento que queremos realizar. Baixamos a Parte 1 (as features — características) do dataset para o ambiente local, o que facilita copiar alguns arquivos que queremos utilizar no projeto.

Também utilizaremos o uv. Ele é um controlador de pacotes extremamente rápido e um gerenciador de projetos escrito em Rust para Python. Em outras palavras, instala e gerencia dependências com muita rapidez. Antigamente utilizávamos o poetry, mas o uv apresenta desempenho superior de forma evidente, o que o torna muito interessante e ágil para o que queremos neste projeto.

Outro utilitário que vamos utilizar é o pyenv. Ele controla diversas versões do Python na máquina, o que é muito útil. No nosso caso, como utilizaremos alguns modelos e o treinamento é feito por CPU, há pacotes que funcionam apenas com Python 3.12.10. Por esse motivo, não queremos mudar a versão nativa de Python do sistema. Chegamos a testar a 3.14, mas temos mantido a 3.13 recentemente no ambiente. Para não ficar trocando a versão do Python da máquina inteira, o pyenv é apropriado porque permite instalar a 3.12 no ambiente do projeto sem alterar a configuração global do sistema.

Iniciando o projeto e fixando a versão do python

Com isso definido, vamos iniciar o projeto. Mantemos a pasta "scutia-files", mencionada anteriormente. Baixamos ali a Parte 1 das características do dataset, portanto os arquivos já estão disponíveis, o que facilita copiar o que for necessário para o projeto. No seu ambiente local, crie uma pasta para o projeto. Recomendamos manter o mesmo nome por conta do harness (estrutura de testes) que vamos criar no futuro. Trata-se de uma pasta vazia chamada "scutia".

A primeira ação será definir a versão do Python que vamos utilizar com o pyenv, selecionando a 3.12.10 como versão local do projeto. Para isso, executamos:

pyenv local 3.12.10

Essa operação gera um arquivo de configuração contendo apenas a versão definida (“Python 3.12.10”). Neste momento, é basicamente isso que o pyenv faz por nós.

Em seguida, abrimos o projeto no VS Code e ajustamos o zoom para facilitar a visualização. No terminal, abrimos o editor diretamente na pasta do projeto com:

code .

Sincronizando dependências e selecionando o interpretador

Conforme mencionado, já baixamos alguns arquivos e recomendamos que você faça o mesmo, colando-os na raiz do projeto — e não dentro da pasta "scutia". Abrimos o VS Code na raiz exatamente por isso. Queremos o projeto na pasta "Demo". Vamos trazer os arquivos uv.lock e pyproject.toml para a raiz. Esses dois arquivos já contêm o que precisamos: todas as bibliotecas que vamos utilizar no projeto. Há bastante dependência ali, e é importante manter todas, pois utilizaremos tudo o que está configurado. Recomendamos não alterar, inclusive porque há configurações do PyTorch para XPU, que serão necessárias para o modelo.

Na sequência, vamos sincronizar as dependências do projeto com o uv utilizando TLS nativo:

uv sync --native-tls

Enquanto a instalação ocorre, para ganharmos tempo, no VS Code abrimos a paleta de comandos (Ctrl+Shift+P), escolhemos “Python: Select Interpreter” e selecionamos o interpretador do Python do ambiente do projeto. Para isso, utilizamos a busca pelo caminho dentro da pasta "Demo", navegando até "venv" e "Scripts" e selecionando o executável do Python. Deixamos, assim, o ambiente do Python já selecionado para utilizarmos esse ambiente virtual no projeto.

Organizando pastas do dataset e configurando o jupyter

Agora, vamos preparar o ambiente de trabalho. Dentro do projeto, criamos a pasta "Dataset", onde ficará o nosso conjunto de dados para o modelo. Em seguida, adicionamos pastas importantes para a organização: a pasta "Dados" e a pasta "Scripts". A pasta "Scripts" conterá utilitários que vão auxiliar o conjunto de dados a funcionar corretamente.

Utilizaremos o Jupyter Notebook como ambiente de trabalho visual. A ideia é permitir acompanhar de forma mais clara o que estamos fazendo. Seria possível colocar tudo em um script Python, mas a visualização no terminal não facilita o acompanhamento passo a passo.

Dentro da pasta "Dataset", criamos a pasta "Dados", onde ficarão:

Criamos agora a pasta "Scripts", que armazenará os utilitários auxiliares do projeto.

Trazemos, então, os arquivos do Jupyter que mencionamos. O primeiro arquivo se chama Análise Dataset Scutia. Após salvar, verificamos no VS Code se o kernel (núcleo) selecionado para o Notebook está correto. Caso não esteja, em “Python Environments” ajustamos para o ambiente local do projeto. No seletor, ao digitar “/”, o VS Code tenta buscar diretórios automaticamente; alternativamente, podemos executar o comando pwd para copiar o caminho completo e apontar para onde está a venv do Python, caso o VS Code não a encontre de imediato. Para obter o caminho atual no terminal, utilizamos:

pwd

Ativando o ambiente e configurando o editor

Podemos ativar o ambiente virtual de duas formas. A primeira é navegando até o caminho desejado utilizando as barras (/) e o ponto (.) para localizar o diretório do ambiente virtual. Selecionamos o ambiente diretamente por esse caminho. A segunda forma é, a partir da raiz do projeto, executar no terminal o comando de ativação do ambiente virtual (por exemplo, com “.”, “venv”, “Scripts”, “activate”). No nosso caso, utilizamos o PowerShell e ativamos por esse método:

.\.venv\Scripts\activate

Com o ambiente virtual ativo, podemos executar o comando “code” no terminal para abrir o VS Code:

code .

Ajustamos o zoom para 5. O editor deve detectar automaticamente o environment (ambiente) com o qual estamos trabalhando.

Como fizemos anteriormente, abrimos o atalho CTRL+SHIFT+P e escolhemos Python Select Interpreter. Em seguida, utilizamos o recurso de busca (Find (buscar)) para localizar “Venv”, “Scripts” e “Python”, e selecionamos o interpretador correspondente. Se pressionarmos novamente CTRL+SHIFT+P, veremos que o interpretador ativo está associado ao ambiente do Llama. Repetimos a verificação mais uma vez para confirmar: “Scripts” e “Python” estão corretos. Com isso, sabemos que o interpretador está configurado adequadamente.

Vamos criar o próximo item: um script (script). Ele se chamará Dataset Script A. Esses nomes constam na feature (funcionalidade) que baixamos do nosso repositório.

Dentro da pasta "Dados", criaremos mais três pastas:

Essas pastas serão preenchidas conforme formos construindo o nosso dataset (conjunto de dados) e avançando no trabalho.

Ainda dentro de "Dados", incluiremos o nosso dataset local. Trata-se de um dataset rotulado manualmente por nós, com o objetivo de conter um rótulo que determina se cada exemplo é positivo, negativo ou neutro. Em outras palavras, quando fornecermos algo como “estamos felizes”, queremos que isso seja analisado como sentimento positivo. Esse formato envolve uma instrução, uma entrada e uma saída, e queremos que a saída represente o sentimento. Para isso, será necessário treinar o modelo para que compreenda esse padrão. Estamos, portanto, criando a base de dados na qual esse treinamento ocorrerá. Como exemplo, um trecho desse arquivo pode ser:

id,texto,rotulo
1,"Acordei animado e com vontade de começar o dia.",positivo
2,"Foi muito bom conversar com meus amigos ontem.",positivo
3,"Estou orgulhoso do resultado que consegui no trabalho.",positivo
4,"Hoje encontrei uma solução para um problema difícil.",positivo
5,"Sinto esperança de que as coisas vão melhorar.",positivo

Automatizando o fluxo de dados

Para ganhar tempo no curso, também adicionaremos um dataset que não abriremos em aula, pois contém textos do Twitter; esse material pode incluir conteúdos inadequados para a gravação. Em ambiente seguro, recomendamos examiná-lo. A razão de já incluirmos esse arquivo é evitar o download (transferência) durante a demonstração, pois teremos um script que fará o download do dataset. Esse será um dos passos para finalizar a nossa configuração, ao lado dos scripts de preparo.

O primeiro script que incluiremos é o de download do dataset. Ele fará o download a partir do Hugging Face, cujo link já deixamos preparado. Esse dataset possui versão em português (o que é positivo para nosso caso), é multilíngue e auxilia na tarefa de classificação de texto. Como queremos classificar sentimento, ele é adequado por ter uma base extensa, com bastante conteúdo para treinar nesse formato. No código, definimos o repositório e a revisão:

DATASET_REPOSITORY = "cardiffnlp/tweet_sentiment_multilingual"
DATASET_REVISION = "606156db529f327fd871513cccbe14dcbafeef682"

Em seguida, adicionaremos um script para limpar resultados. A finalidade é permitir reexecuções: quando já executamos uma vez e quisermos executar novamente, esse script remove o que foi gerado antes, possibilitando refazer o processo, inclusive quando aumentarmos os dados. No nosso dataset local, há cerca de 31 entradas (pelo header (cabeçalho), possivelmente 29). Se quisermos acrescentar mais exemplos, precisaremos treinar novamente; por isso, a limpeza é importante. A documentação do utilitário deixa claro o escopo da limpeza:

"""Remove apenas resultados gerados da preparação do dataset do EscutiA.

As fontes, o notebook, os scripts e a documentação ficam preservados.
Use este utilitário para voltar ao estado de primeira execução do
dataset.
"""

O próximo script é o de preparação do dataset. Seu papel é preparar os dados para uso futuro. O Llama Factory precisa que o conjunto de dados esteja em um formato específico para ser utilizado em um modelo que depois será ajustado por fine-tuning. Dentro do Llama, isso é chamado de formato Alpaca, um padrão que organiza os exemplos para possibilitar o treinamento. No nosso caso, como realizaremos treinamento supervisionado e queremos que, ao final, o modelo faça classificação de texto, precisamos que, quando isso for executado, os dados estejam estruturados nesse padrão. No trecho abaixo, montamos o registro que será persistido durante a preparação:

        record = {
            **base,
            "instruction": INSTRUCTION,
            "input": text,
            "output_label": label,
            "comparison_key": key,
        }

Conforme já mencionamos (e como está ilustrado no Scaledraw), o formato inclui três campos: instrução, input (entrada) e output (saída). Esse padrão é necessário para que o modelo entenda como executar a tarefa. O preparo dos dados atende exatamente a esse requisito. Assim, se indicarmos “estamos felizes”, esperamos que a análise resultante seja positiva; para que isso aconteça, o modelo precisa compreender que há uma entrada, uma instrução e uma saída. O modelo avaliará sistematicamente esse tripé para produzir o resultado final. Estamos, portanto, preparando o dataset para viabilizar exatamente esse fluxo.

Por fim, incluiremos um script que valida o dataset. Queremos verificar se ele está válido, estruturado corretamente e pronto para uso. O ponto de entrada dessa validação pode ser definido assim:

def validar() -> None:

Encerrando e próximos passos

Dito isso, com toda essa preparação, já podemos começar, no próximo vídeo, a construir o nosso dataset e iniciar o trabalho de dados.

Para este primeiro vídeo, é isso. Espero que você esteja gostando deste início. Te aguardo no próximo vídeo. Um grande abraço!

Panorama e dataset do projeto - Apresentando o panorama do projeto Scout A

Apresentando o panorama do projeto

Como primeira parte do nosso curso, vamos apresentar um panorama do projeto: o que veremos, como está estruturado, onde estão os repositórios e quais são as partes que compõem o projeto como um todo. Neste primeiro vídeo, faremos uma apresentação completa da estrutura, dos agentes que vamos desenvolver, do Harness que nós construímos e das configurações que temos. Será, portanto, uma visão detalhada de tudo o que vamos trabalhar.

O projeto, chamado Scout A, é um pequeno SaaS (software como serviço) que nosso Harness nos ajudou a construir. Grande parte do que está aqui foi trabalhada e ajustada conforme a estrutura deste curso. Esse produto foi criado especificamente para o curso e se compõe, basicamente, de um site que explica o que é o Scout A, algo semelhante a um SaaS comum de mercado, e de um dashboard (painel) para a pessoa usuária acompanhar sua situação.

Nosso projeto baseia-se em um Harness realizando fine-tuning (ajuste fino) de um modelo da família Qwen. A ideia é que esse modelo faça análise de sentimentos, recebendo textos mais longos e capazes de serem processados pelo modelo. Poderíamos, de fato, treinar um modelo de classificação usando o scikit-learn — seria uma proposta viável. Entretanto, queremos utilizar o modelo Qwen dentro de um agente, com uma experiência mais conversacional, que é justamente a proposta do projeto.

Explorando a interface e recursos do produto

Faremos, portanto, uma combinação de modelos: utilizaremos tanto o GPT-4o quanto o Qwen para realizar a análise de sentimentos, que é o que vemos na tela. Assim, conseguimos identificar sentimentos negativos, neutros e positivos que ocorreram durante a conversa conduzida pelo nosso agente.

Na visão geral, observamos um resumo das conversas, os dias em que estivemos bem e os dias em que não estivemos bem. Estes são todos registros de teste. Também conseguimos ver todos os registros na interface e consultar o calendário, que mostra os dias em que estivemos com sentimentos negativos, neutros e positivos.

Por ora, não acessaremos a seção de conversa. Na área de conta e dados, é possível excluir as informações ou baixá-las. Em plano e uso, deixamos alguns planos fictícios, mas integrados à Stripe — a Stripe está ativa no projeto. Há, inclusive, um webhook (gancho de integração via web) configurado para testes. O ambiente está em modo de testes, não em produção.

Interagindo com o agente e justificando a abordagem

Na seção de conversa, que é o destaque, observamos no canto a análise de sentimentos. Esta API está executando nosso modelo publicado no Hugging Face, com fine-tuning do Qwen. Ela está funcional na aplicação. Por exemplo: “Estou gravando o curso da Alura e me sentindo feliz.” Registramos o sentimento e a aplicação chama a nossa API de sentimentos, onde o modelo está implementado.

Também é possível conversar utilizando a mesma API. Por exemplo: “Estou mostrando para as pessoas nosso modelo em uso.” Ao enviar essa mensagem, além de utilizar o GPT-4o em segundo plano, por meio de um agente — o que veremos ao longo do curso —, a aplicação também chama nossa análise de sentimentos baseada no fine-tuning do Qwen. Com isso, o sistema consegue receber textos mais longos para avaliação.

Esse ponto é relevante porque, retomando a pergunta: por que não utilizar o scikit-learn para treinar um modelo de classificação de sentimentos? Concordamos que seria uma alternativa viável. Contudo, como queremos construir agentes e colocar uma LLM (modelo de linguagem de grande porte) para avaliar textos potencialmente longos — mesmo que no exemplo tenhamos usado um texto curto, poderíamos enviar um texto extenso —, além de priorizarmos a experiência gerativa e conversacional, essa abordagem se encaixa melhor no objetivo do projeto. Assim, uma LLM faz muito sentido aqui, assim como o uso de fine-tuning.

Nós não vamos explicar agora, porque queremos deixar mais à frente o motivo pelo qual vamos realizar o fine-tuning (ajuste fino) de um modelo. Talvez surja a pergunta: não poderíamos colocar um RAG (geração aumentada por recuperação), por exemplo? Não poderíamos utilizar a própria LLM (modelo de linguagem grande) e ensinar a questão de sentimentos? Novamente, são boas provocações, mas gostaríamos de deixar uma questão em mente. Lembrando a frase que temos utilizado bastante aqui: “sem custo”. Repare que trouxemos um SaaS (software como serviço) também. Imagine o seguinte cenário: podemos publicar este projeto valendo-nos de planos gratuitos e sem ter o custo de uma LLM (modelo de linguagem grande) executando ou de um banco de dados. Como mencionamos, não vamos explicar agora, porque queremos preparar um momento em que falaremos disso com mais detalhes. Por ora, é importante que você já vá considerando todos esses aspectos.

Estruturando branches e habilidades do projeto

Uma vez apresentado o projeto, vale saber que todas as partes têm suas branches: em Dataset (conjunto de dados), em LoRA (adaptação de baixo posto), em QLoRA (LoRA quantizada), em Hugging Face (plataforma Hugging Face), no próprio Harness (estrutura) e no projeto final. Tudo está separado para que seja possível acompanhar a evolução.

Também vale mencionar um ponto importante: por mais que possuamos um Harness (estrutura) bastante completo, capaz de lidar com o projeto do Sculpt IA tanto na interface quanto no treinamento, é importante que passemos por todas as partes. Destacamos isso porque, embora a IA possa encurtar caminhos e facilitar, é essencial conhecer as etapas para enviar boas solicitações de ajustes — exatamente o que veremos no curso. Há diversos aspectos relevantes para que seja possível solicitar algo ao seu Harness (estrutura) ou até melhorá-lo. Por exemplo: queremos adicionar uma nova skill (habilidade), criar um sub-agent (subagente) ou ajustar o agente principal para que execute determinada tarefa. Para isso, é necessário conhecimento de cada etapa que vamos percorrer no curso.

Separamos algumas skills (habilidades) criadas especialmente para o curso. A skill (habilidade) de preparação do dataset (conjunto de dados) não é uma skill (habilidade) obtida no Skill SH; embora saibamos que existem essas skills (habilidades) lá e possamos reaproveitá-las, é importante saber como criar algo específico para o projeto, que conheça o projeto e não seja genérico. Essa foi a ideia. Assim, essa skill (habilidade) conhece os aspectos do Sculpt IA e sabe como preparar os dados adequadamente, assim como temos no Harness (estrutura) sub-agents (subagentes) escritos especialmente para o projeto.

O orquestrador, um sub-agent (subagente) do nosso Harness (estrutura), além de orquestrar tudo, conhece quais são as skills (habilidades) corretas, quem é o Sculpt IA e onde estão as partes do projeto; portanto, possui bastante detalhe nesse aspecto. O mesmo vale para o componente de Training (treinamento), que atua diretamente na etapa de treinamento. Quando for executar um LoRA (adaptação de baixo posto), sabe onde estão os recursos necessários para realizar o fine-tuning (ajuste fino). O agente principal está no arquivo Agents.md e conhece todo o contexto do projeto; por exemplo, sabe que precisa usar o Graphify (ferramenta de grafos) quando aplicável. Para chegarmos a esse resultado, foi necessário passar por todas essas etapas. Com isso, conseguimos construir um Harness (estrutura) efetivo, que realmente entende o projeto, e não um conjunto de skills (habilidades) e agentes dispersos.

Preparando o dataset de sentimentos

Dito isso, na sequência, vamos iniciar o projeto pelo dataset (conjunto de dados), preparando nossos dados para que o sistema compreenda, de fato, o que é um sentimento. Para isso, utilizaremos tanto um dataset (conjunto de dados) local quanto outro baixado do próprio X (antigo Twitter), que contém informações de sentimentos que vamos rotular conjuntamente. Vamos criar esses rótulos para indicar o que é um sentimento positivo, neutro ou negativo.

Era isso que considerávamos importante neste primeiro vídeo, para começarmos seguindo a sequência passo a passo. No próximo vídeo, já estaremos direcionados sobre onde vamos criar a pasta. Já deixamos preparado um espaço vazio. Vamos mostrar a utilização do pyenv (gerenciador de versões do Python), com o Python 3.12 — explicaremos o motivo depois — e também estamos usando o uv (gerenciador de ambientes e pacotes).

No próximo vídeo, vamos começar configurando o ambiente e aprendendo a executar o nosso dataset (conjunto de dados).

Eu aguardo você no próximo vídeo. Um grande abraço.

Sobre o curso Modelos de linguagem: fine-tuning e quantização para análise de sentimentos

O curso Modelos de linguagem: fine-tuning e quantização para análise de sentimentos possui 237 minutos de vídeos, em um total de 37 atividades. Gostou? Conheça nossos outros cursos de Engenharia de Modelos & Fine-Tuning em Inteligência Artificial, ou leia nossos artigos de Inteligência Artificial.

Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:

Aprenda Engenharia de Modelos & Fine-Tuning acessando integralmente esse e outros cursos, comece hoje!

Conheça os Planos para Empresas