{"id":652182,"date":"2025-10-28T23:18:20","date_gmt":"2025-10-28T22:18:20","guid":{"rendered":"https:\/\/blog.jetbrains.com\/?post_type=pycharm&#038;p=652182"},"modified":"2025-10-28T23:18:28","modified_gmt":"2025-10-28T22:18:28","slug":"ajustando-e-implantando-modelos-gpt-usando-o-transformers-do-hugging-face","status":"publish","type":"pycharm","link":"https:\/\/blog.jetbrains.com\/pt-br\/pycharm\/2025\/10\/ajustando-e-implantando-modelos-gpt-usando-o-transformers-do-hugging-face\/","title":{"rendered":"Ajustando e implantando modelos GPT usando o Transformers do Hugging Face"},"content":{"rendered":"<p>Hugging Face \u00e9 atualmente um nome conhecido entre pesquisadores e entusiastas do machine learning. Um dos seus maiores sucessos \u00e9 o <a href=\"https:\/\/huggingface.co\/docs\/transformers\/en\/index\" target=\"_blank\" rel=\"noopener\">Transformers<\/a>, um framework de defini\u00e7\u00e3o de modelos para modelos de machine learning em texto, vis\u00e3o computacional, \u00e1udio e v\u00eddeo. Devido ao vasto reposit\u00f3rio de modelos de machine learning de \u00faltima gera\u00e7\u00e3o dispon\u00edveis no <a href=\"https:\/\/huggingface.co\/models\" target=\"_blank\" rel=\"noopener\">Hugging Face Hub<\/a> e a compatibilidade do Transformers com a maioria dos frameworks de treinamento, ele \u00e9 amplamente utilizado para infer\u00eancia e treinamento de modelos.<\/p>\n<h2 class=\"wp-block-heading\">Por que fazer o ajuste-fino de um modelo de IA?<\/h2>\n<p>A otimiza\u00e7\u00e3o de modelos de IA \u00e9 crucial para adaptar seu desempenho a tarefas e conjuntos de dados espec\u00edficos, permitindo que eles alcancem maior precis\u00e3o e efici\u00eancia em compara\u00e7\u00e3o com o uso de um modelo de uso geral. Ao adaptar um modelo pr\u00e9-treinado, o ajuste fino reduz a necessidade de treinar do zero, economizando tempo e recursos. Ele tamb\u00e9m permite um melhor tratamento de formatos espec\u00edficos, nuances e casos extremos dentro de um determinado dom\u00ednio, gerando resultados mais confi\u00e1veis e personalizados.<\/p>\n<p>Neste post do nosso blog, vamos otimizar um modelo GPT com racioc\u00ednio matem\u00e1tico para que ele lide melhor com quest\u00f5es matem\u00e1ticas.<\/p>\n<h2 class=\"wp-block-heading\">Usando modelos da Hugging Face<\/h2>\n<p>Ao usarmos o PyCharm, podemos facilmente navegar e adicionar qualquer modelo da Hugging Face. Em um novo arquivo Python, no menu <em>Code<\/em>, na parte superior, selecione <em>Insert HF Model<\/em>.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"946\" height=\"1070\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-40.png\" alt=\"Utilizando modelos da Hugging Face\" class=\"wp-image-594074\" \/><\/figure>\n<p>No menu que \u00e9 aberto, voc\u00ea pode navegar pelos modelos por categoria ou come\u00e7ar a digitar na barra de pesquisa na parte superior. Ao selecionar um modelo, voc\u00ea pode ver sua descri\u00e7\u00e3o \u00e0 direita.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"923\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-41.png\" alt=\"Explore os modelos da Hugging Face\" class=\"wp-image-594085\" \/><\/figure>\n<p>Ao clicar em <em>Use Model<\/em>, voc\u00ea ver\u00e1 um trecho de c\u00f3digo adicionado ao seu arquivo. E \u00e9 isso \u2013 agora est\u00e1 tudo pronto para voc\u00ea come\u00e7ar a usar seu modelo da Hugging Face.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"312\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-42.png\" alt=\"Usar modelos da Hugging Face no PyCharm\" class=\"wp-image-594096\" \/><\/figure>\n<h2 class=\"wp-block-heading\">Modelos GPT (Generative Pre-Trained Transformer)<\/h2>\n<p>Os modelos GPT s\u00e3o muito populares no <a href=\"https:\/\/huggingface.co\/models\" target=\"_blank\" rel=\"noopener\">Hugging Face Hub<\/a>, mas o que s\u00e3o? Os GPTs s\u00e3o modelos treinados que compreendem a linguagem natural e geram textos de alta qualidade. Eles s\u00e3o usados principalmente em tarefas relacionadas a associa\u00e7\u00e3o textual, resposta a perguntas, similaridade sem\u00e2ntica e classifica\u00e7\u00e3o de documentos. O exemplo mais famoso \u00e9 o <a href=\"https:\/\/openai.com\/index\/chatgpt\/\" target=\"_blank\" rel=\"noopener\">ChatGPT, criado pela OpenAI<\/a>.<\/p>\n<p>Muitos modelos GPT da OpenAI est\u00e3o dispon\u00edveis no <a href=\"https:\/\/huggingface.co\/models\" target=\"_blank\" rel=\"noopener\">Hugging Face Hub<\/a>, e aprenderemos como usar esses modelos com o <em>Transformers<\/em>, ajust\u00e1-los com nossos pr\u00f3prios dados e implant\u00e1-los em um aplicativo<em>.<\/em><\/p>\n<h2 class=\"wp-block-heading\">Benef\u00edcios do uso do Transformers<\/h2>\n<p>O Transformers, juntamente com outras ferramentas fornecidas pela Hugging Face, oferece ferramentas de alto n\u00edvel para o ajuste fino de qualquer modelo sofisticado de aprendizado profundo. Em vez de exigir que voc\u00ea compreenda totalmente a arquitetura e o m\u00e9todo de tokeniza\u00e7\u00e3o de um determinado modelo, essas ferramentas ajudam a tornar os modelos \u201cplug and play\u201d com quaisquer dados de treinamento compat\u00edveis, ao mesmo tempo em que oferecem uma grande quantidade de personaliza\u00e7\u00e3o em tokeniza\u00e7\u00e3o e treinamento.<\/p>\n<h2 class=\"wp-block-heading\">Transformers em a\u00e7\u00e3o<\/h2>\n<p>Para ver mais de perto o<em> <\/em>Transformers em a\u00e7\u00e3o, vamos ver como podemos us\u00e1-lo para interagir com um modelo GPT.<\/p>\n<h3 class=\"wp-block-heading\">Infer\u00eancia usando um modelo pr\u00e9-treinado com um pipeline<\/h3>\n<p>Ap\u00f3s selecionar e adicionar o modelo GPT-2 da OpenAI ao c\u00f3digo, este \u00e9 o resultado obtido:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from transformers import pipeline\n\n\npipe = pipeline(\"text-generation\", model=\"openai-community\/gpt2\")<\/pre>\n<p>Antes de podermos us\u00e1-lo, precisamos fazer alguns preparativos. Primeiro, precisamos instalar um framework de machine learning. Neste exemplo, escolhemos o <a href=\"https:\/\/pytorch.org\/get-started\/locally\/\" target=\"_blank\" rel=\"noopener\">PyTorch<\/a>. Voc\u00ea pode instal\u00e1-lo facilmente atrav\u00e9s da janela <em>Python Packages<\/em> no PyCharm.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"920\" height=\"654\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-43.png\" alt=\"Instalar o PyTorch no PyCharm\" class=\"wp-image-594107\" \/><\/figure>\n<p>Em seguida, precisamos instalar o Transformers<em> <\/em>usando a op\u00e7\u00e3o `torch`. Voc\u00ea pode fazer isso usando o terminal \u2013 abra-o usando o bot\u00e3o \u00e0 esquerda ou use a tecla de atalho <em>\u2325 F12 <\/em>(macOS) ou <em>Alt + F12<\/em> (Windows).<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"838\" height=\"502\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-44.png\" alt=\"Instalar o Transformers no terminal do PyCharm\" class=\"wp-image-594118\" \/><\/figure>\n<p>No terminal, como estamos usando o uv, usamos os seguintes comandos para adicion\u00e1-lo como depend\u00eancia e instal\u00e1-lo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">uv add \u201ctransformers[torch]\u201d\nuv sync<\/pre>\n<p>Se voc\u00ea estiver usando o pip:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pip install \u201ctransformers[torch]\u201d<\/pre>\n<p>Tamb\u00e9m instalaremos mais algumas bibliotecas que precisaremos posteriormente, incluindo python-dotenv, datasets<em>, <\/em>notebook<em> <\/em>e<em> <\/em>ipywidgets<em>. <\/em>Voc\u00ea pode usar qualquer um dos m\u00e9todos acima para instal\u00e1-los.<br \/>Depois disso, talvez seja melhor adicionar um dispositivo GPU para acelerar o modelo. Dependendo do que voc\u00ea tem na sua m\u00e1quina, voc\u00ea pode adicion\u00e1-lo definindo o par\u00e2metro do dispositivo no pipeline.<em>. <\/em>Como estou usando um computador Mac M2, posso definir<code data-enlighter-language=\"python\" class=\"EnlighterJSRAW\"> device=\"mps\"<\/code> desta maneira:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">pipe = pipeline(\"text-generation\", model=\"openai-community\/gpt2\", device=\"mps\")<\/pre>\n<p>Se voc\u00ea tiver GPUs CUDA, tamb\u00e9m poder\u00e1 definir <code data-enlighter-language=\"python\" class=\"EnlighterJSRAW\">device=\"cuda\"<\/code>.<\/p>\n<p>Agora que configuramos nosso pipeline, vamos test\u00e1-lo com um prompt simples:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from transformers import pipeline\n\n\npipe = pipeline(\"text-generation\", model=\"openai-community\/gpt2\", device=\"mps\")\n\n\nprint(pipe(\"A rectangle has a perimeter of 20 cm. If the length is 6 cm, what is the width?\", max_new_tokens=200))<\/pre>\n<p>Execute o script com o bot\u00e3o <em>Run<\/em> (<img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/AD_4nXf6ZDm7vSGyFlO0DzXegK6WP9JxsStUiJA-bkRZ0mwPsUsmn8M70emV5Sr8f17-fEK6z9V1EQKWEm3RPHdT8n8uqG18faVmQn5y09psVInQLU0CZQKXAEg2q7m7AOsh4hPU7G8gcQ.png\" width=\"30\" height=\"23\">) na parte superior:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1050\" height=\"282\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-45.png\" alt=\"Execute o script no PyCharm\" class=\"wp-image-594129\" \/><\/figure>\n<p>O resultado ser\u00e1 semelhante a este:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[{'generated_text': 'A rectangle has a perimeter of 20 cm. If the length is 6 cm, what is the width?nnA rectangle has a perimeter of 20 cm. If the length is 6 cm, what is the width? A rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width? A rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width? A rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width?nnA rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width? A rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width? A rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width? A rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width?nnA rectangle has a perimeter of 20 cm. If the width is 6 cm, what is the width? A rectangle has a perimeter'}]<\/pre>\n<p>N\u00e3o h\u00e1 muito racioc\u00ednio nisso, apenas um monte de coisas sem sentido.\u00a0<\/p>\n<p>Voc\u00ea tamb\u00e9m poder\u00e1 receber este aviso:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.<\/pre>\n<p>Esta \u00e9 a configura\u00e7\u00e3o padr\u00e3o. Voc\u00ea tamb\u00e9m pode adicion\u00e1-la manualmente, conforme mostrado abaixo, para que este aviso desapare\u00e7a, mas n\u00e3o precisamos nos preocupar muito com isso nesta fase.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">print(pipe(\"A rectangle has a perimeter of 20 cm. If the length is 6 cm, what is the width?\", max_new_tokens=200, pad_token_id=pipe.tokenizer.eos_token_id))<\/pre>\n<p>Agora que vimos como o GPT-2 se comporta imediatamente ap\u00f3s a implanta\u00e7\u00e3o, vamos ver se conseguimos melhor\u00e1-lo no racioc\u00ednio matem\u00e1tico com alguns ajustes.<\/p>\n<h3 class=\"wp-block-heading\">Carregue e prepare um conjunto de dados do Hugging Face Hub<\/h3>\n<p>Antes de trabalharmos no modelo GPT, precisamos primeiro de dados de treinamento. Vejamos como obter um conjunto de dados do Hugging Face Hub.<\/p>\n<p>Se ainda n\u00e3o o fez, inscreva-se para obter uma conta Hugging Face e <a href=\"https:\/\/huggingface.co\/docs\/hub\/security-tokens#user-access-tokens\" target=\"_blank\" rel=\"noopener\">criar um token de acesso<\/a>. Por enquanto, s\u00f3 precisamos de um token `read`. Armazene seu token em um arquivo `.env`, desta forma:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">HF_TOKEN=your-hugging-face-access-token<\/pre>\n<p>Usaremos este <a href=\"https:\/\/huggingface.co\/datasets\/Cheukting\/math-meta-reasoning-cleaned\" target=\"_blank\" rel=\"noopener\">Conjunto de dados de racioc\u00ednio matem\u00e1tico<\/a>, que cont\u00e9m texto descrevendo alguns racioc\u00ednios matem\u00e1ticos. Ajustaremos nosso modelo GPT com este conjunto de dados para que ele possa resolver problemas matem\u00e1ticos de maneira mais eficaz.<\/p>\n<p>Vamos criar um novo notebook Jupyter, que usaremos para o ajuste fino, pois ele nos permite executar diferentes trechos de c\u00f3digo, um por um, e monitorar o progresso.<\/p>\n<p>Na primeira c\u00e9lula, usamos este script para carregar o conjunto de dados do Hugging Face Hub:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from datasets import load_dataset\nfrom dotenv import load_dotenv\nimport os\n\n\nload_dotenv()\ndataset = load_dataset(\"Cheukting\/math-meta-reasoning-cleaned\", token=os.getenv(\"HF_TOKEN\"))\ndataset<\/pre>\n<p>Execute esta c\u00e9lula (pode demorar um pouco, dependendo da velocidade da sua internet), que ir\u00e1 baixar o conjunto de dados. Quando estiver pronto, podemos dar uma olhada no resultado:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">DatasetDict({\n    train: Dataset({\n        features: ['id', 'text', 'token_count'],\n        num_rows: 987485\n    })\n})\n<\/pre>\n<p>Se voc\u00ea estiver curioso e quiser dar uma olhada nos dados, pode fazer isso no PyCharm. Abra a janela <em>Jupyter Variables<\/em> usando o bot\u00e3o \u00e0 direita:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1052\" height=\"740\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-46.png\" alt=\"Abrindo Jupyter Variables no PyCharm\" class=\"wp-image-594140\" \/><\/figure>\n<p>Expanda <em>dataset<\/em>, e voc\u00ea ver\u00e1 a op\u00e7\u00e3o <em>View as DataFrame<\/em> ao lado de <em>dataset[\u2018train\u2019]<\/em>:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"980\" height=\"882\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-47.png\" alt=\"Jupyter Variables no PyCharm\" class=\"wp-image-594152\" \/><\/figure>\n<p>Clique nele para ver os dados na janela de ferramentas <em>Data View<\/em>:<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"980\" height=\"1102\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-48.png\" alt=\"Ferramenta Data View no PyCharm\" class=\"wp-image-594163\" \/><\/figure>\n<p>Em seguida, vamos tokenizar o texto no conjunto de dados:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from transformers import GPT2Tokenizer\n\n\ntokenizer = GPT2Tokenizer.from_pretrained(\"openai-community\/gpt2\")\ntokenizer.pad_token = tokenizer.eos_token\n\n\ndef tokenize_function(examples):\n   return tokenizer(examples['text'], truncation=True, padding='max_length', max_length=512)\n\n\ntokenized_datasets = dataset.map(tokenize_function, batched=True)<\/pre>\n<p>Aqui, usamos o tokenizador GPT-2 e definimos o <code>pad_token<\/code> para ser o <code>eos_token<\/code>, que \u00e9 o s\u00edmbolo que indica o fim da linha. Depois disso, vamos tokenizar o texto com uma fun\u00e7\u00e3o. Pode demorar um pouco na primeira vez que voc\u00ea execut\u00e1-lo, mas depois disso ele ser\u00e1 armazenado em cache e ficar\u00e1 mais r\u00e1pido se voc\u00ea precisar executar a c\u00e9lula novamente.<\/p>\n<p>O conjunto de dados tem quase 1 milh\u00e3o de linhas para treinamento. Se voc\u00ea tiver capacidade computacional suficiente para processar tudo, poder\u00e1 utiliz\u00e1-los todos. No entanto, nesta demonstra\u00e7\u00e3o, estamos treinando localmente em um laptop, ent\u00e3o \u00e9 melhor usar apenas uma pequena parte!<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">tokenized_datasets_split = tokenized_datasets[\"train\"].shard(num_shards=100, index=0).train_test_split(test_size=0.2, shuffle=True)\ntokenized_datasets_split<\/pre>\n<p>Aqui, uso apenas 1% dos dados e, em seguida, executo <code>train_test_split<\/code> <em><\/em>para dividir o conjunto de dados em dois:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">DatasetDict({\n    train: Dataset({\n        features: ['id', 'text', 'token_count', 'input_ids', 'attention_mask'],\n        num_rows: 7900\n    })\n    test: Dataset({\n        features: ['id', 'text', 'token_count', 'input_ids', 'attention_mask'],\n        num_rows: 1975\n    })\n})\n<\/pre>\n<p>Agora estamos prontos para fazer o ajuste fino do modelo GPT-2.<\/p>\n<h3 class=\"wp-block-heading\">Ajuste-fino de um modelo GPT<\/h3>\n<p>Na pr\u00f3xima c\u00e9lula vazia, definiremos nossos argumentos de treinamento:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from transformers import TrainingArguments\ntraining_args = TrainingArguments(\n   output_dir='.\/results',\n   num_train_epochs=5,\n   per_device_train_batch_size=8,\n   per_device_eval_batch_size=8,\n   warmup_steps=100,\n   weight_decay=0.01,\n   save_steps = 500,\n   logging_steps=100,\n   dataloader_pin_memory=False\n)<\/pre>\n<p>A maioria deles \u00e9 bastante comum para o ajuste fino de um modelo. No entanto, dependendo da configura\u00e7\u00e3o do seu computador, talvez seja necess\u00e1rio ajustar algumas coisas:<\/p>\n<ul>\n<li>Tamanho do lote: \u00e9 importante encontrar o tamanho ideal do lote, pois quanto maior ele for, mais r\u00e1pido ser\u00e1 o treinamento. No entanto, h\u00e1 um limite para a quantidade de mem\u00f3ria dispon\u00edvel para sua CPU ou GPU, portanto, voc\u00ea poder\u00e1 descobrir um valor m\u00e1ximo.<\/li>\n<li>Epochs \u2013 Ter mais epochs faz com que o treinamento demore mais. Voc\u00ea pode decidir quantos epochs s\u00e3o necess\u00e1rios.<\/li>\n<li>Save steps \u2013 Determina a frequ\u00eancia com que um checkpoint ser\u00e1 salvo no disco. Se o treinamento for lento e houver a possibilidade de ele parar inesperadamente, talvez seja melhor salvar com mais frequ\u00eancia (defina esse valor como menor).<\/li>\n<\/ul>\n<p>\u00a0Depois de configurarmos nossas defini\u00e7\u00f5es, montaremos o treinador na pr\u00f3xima c\u00e9lula:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from transformers import Trainer, DataCollatorForLanguageModeling\n\n\nmodel = GPT2LMHeadModel.from_pretrained(\"openai-community\/gpt2\")\ndata_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)\n\n\ntrainer = Trainer(\n   model=model,\n   args=training_args,\n   train_dataset=tokenized_datasets_split['train'],\n   eval_dataset=tokenized_datasets_split['test'],\n   data_collator=data_collator,\n)\n\n\ntrainer.train(resume_from_checkpoint=False)<\/pre>\n<p>Definimos `resume_from_checkpoint=False`, mas voc\u00ea pode defini-lo como `True` para continuar a partir do \u00faltimo checkpoint se o treinamento for interrompido.<\/p>\n<p>Ap\u00f3s o t\u00e9rmino do treinamento, avaliaremos e salvaremos o modelo:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">trainer.evaluate(tokenized_datasets_split['test'])\ntrainer.save_model(\".\/trained_model\")<\/pre>\n<p>Agora podemos usar o modelo treinado no pipeline. Vamos voltar para `model.py`, onde usamos um pipeline com um modelo pr\u00e9-treinado:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">from transformers import pipeline\n\n\npipe = pipeline(\"text-generation\", model=\"openai-community\/gpt2\", device=\"mps\")\n\n\nprint(pipe(\"A rectangle has a perimeter of 20 cm. If the length is 6 cm, what is the width?\", max_new_tokens=200, pad_token_id=pipe.tokenizer.eos_token_id))<\/pre>\n<p>Agora vamos alterar `model=\u201dopenai-community\/gpt2\u2033` para `model=\u201d.\/trained_model\u201d` e ver o que obtemos:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">[{'generated_text': \"A rectangle has a perimeter of 20 cm. If the length is 6 cm, what is the width?nAlright, let me try to solve this problem as a student, and I'll let my thinking naturally fall into the common pitfall as described.nn---nn**Step 1: Attempting the Problem (falling into the pitfall)**nnWe have a rectangle with perimeter 20 cm. The length is 6 cm. We want the width.nnFirst, I need to find the area under the rectangle.nnLet\u2019s set ( A = 20 - 12 ), where ( A ) is the perimeter.nn**Area under a rectangle:**  n[nA = (20-12)^2 + ((-12)^2)^2 = 20^2 + 12^2 = 24n]nnSo, ( 24 = (20-12)^2 = 27 ).nnNow, I\u2019ll just divide both sides by 6 to find the area under the rectangle.n\"}]<\/pre>\n<p>Infelizmente, isso ainda n\u00e3o resolve o problema.<br \/>\n No entanto, foi poss\u00edvel chegar a algumas f\u00f3rmulas matem\u00e1ticas e racioc\u00ednios at\u00e9 ent\u00e3o n\u00e3o utilizados. Se quiser, voc\u00ea pode tentar otimizar um pouco mais o modelo com os dados que n\u00e3o usamos.<\/p>\n<p>Na pr\u00f3xima se\u00e7\u00e3o, veremos como podemos implantar um modelo otimizado acess\u00edvel via endpoints da API usando as ferramentas fornecidas pela Hugging Face e FastAPI.<\/p>\n<h2 class=\"wp-block-heading\">Implanta\u00e7\u00e3o de um modelo otimizado<\/h2>\n<p>A maneira mais f\u00e1cil de implantar um modelo em um backend de servidor \u00e9 atrav\u00e9s da FastAPI. Anteriormente, escrevi um <a href=\"https:\/\/blog.jetbrains.com\/pycharm\/2024\/09\/how-to-use-fastapi-for-machine-learning\/\">post no nosso blog<\/a> sobre a implanta\u00e7\u00e3o de um modelo de machine learning com a FastAPI. Embora n\u00e3o entremos em tantos detalhes aqui, vamos abordar como implantar nosso modelo otimizado.<\/p>\n<p>Com a ajuda do <a href=\"https:\/\/www.jetbrains.com\/junie\/\" target=\"_blank\" rel=\"noopener\">Junie<\/a>, criamos alguns scripts que voc\u00ea pode ver <a href=\"https:\/\/github.com\/Cheukting\/fine-tune-gpt2\/tree\/main\/app\" target=\"_blank\" rel=\"noopener\">aqui<\/a>. Esses scripts nos permitem implantar um backend de servidor com endpoints FastAPI.\u00a0<\/p>\n<p>H\u00e1 algumas novas depend\u00eancias que precisamos adicionar:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"bash\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">uv add fastapi pydantic uvicorn\nuv sync<\/pre>\n<p>Vamos dar uma olhada em alguns pontos interessantes nos scripts, em `main.py`:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Initialize FastAPI app\napp = FastAPI(\n   title=\"Text Generation API\",\n   description=\"API for generating text using a fine-tuned model\",\n   version=\"1.0.0\"\n)\n\n\n# Initialize the model pipeline\ntry:\n   pipe = pipeline(\"text-generation\", model=\"..\/trained_model\", device=\"mps\")\nexcept Exception as e:\n   # Fallback to CPU if MPS is not available\n   try:\n       pipe = pipeline(\"text-generation\", model=\"..\/trained_model\", device=\"cpu\")\n   except Exception as e:\n       print(f\"Error loading model: {e}\")\n       pipe = None<\/pre>\n<p>Ap\u00f3s inicializar o aplicativo, o script tentar\u00e1 carregar o modelo em um pipeline. Se uma Metal GPU n\u00e3o estiver dispon\u00edvel, ele voltar\u00e1 a usar a CPU. Se voc\u00ea tiver uma GPU CUDA em vez de uma GPU Metal, poder\u00e1 substituir `mps` por `cuda`.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\"># Request model\nclass TextGenerationRequest(BaseModel):\n   prompt: str\n   max_new_tokens: int = 200\n  \n# Response model\nclass TextGenerationResponse(BaseModel):\n   generated_text: str<\/pre>\n<p>Duas novas classes s\u00e3o criadas, herdando do <em> <\/em>`BaseModel`<em> da Pydantic.<\/em><\/p>\n<p>Tamb\u00e9m podemos inspecionar nossos endpoints com a janela de ferramentas <em>Endpoints<\/em><em>. <\/em>Clique no globo ao lado de `app = FastAPI` na linha 11 e selecione <em>Show All Endpoints<\/em>.<\/p>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"833\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-49.png\" alt=\"Mostrar todos os endpoints no PyCharm\" class=\"wp-image-594174\" \/><\/figure>\n<p>Temos tr\u00eas endpoints. Como o endpoint raiz \u00e9 apenas uma mensagem de boas-vindas, vamos examinar os outros dois.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@app.post(\"\/generate\", response_model=TextGenerationResponse)\nasync def generate_text(request: TextGenerationRequest):\n   \"\"\"\n   Generate text based on the provided prompt.\n  \n   Args:\n       request: TextGenerationRequest containing the prompt and generation parameters\n      \n   Returns:\n       TextGenerationResponse with the generated text\n   \"\"\"\n   if pipe is None:\n       raise HTTPException(status_code=500, detail=\"Model not loaded properly\")\n  \n   try:\n       result = pipe(\n           request.prompt,\n           max_new_tokens=request.max_new_tokens,\n           pad_token_id=pipe.tokenizer.eos_token_id\n       )\n      \n       # Extract the generated text from the result\n       generated_text = result[0]['generated_text']\n      \n       return TextGenerationResponse(generated_text=generated_text)\n   except Exception as e:\n       raise HTTPException(status_code=500, detail=f\"Error generating text: {str(e)}\")\n<\/pre>\n<p>O endpoint `\/generate` coleta o prompt da solicita\u00e7\u00e3o e gera o texto da resposta com o modelo.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@app.get(\"\/health\")\nasync def health_check():\n   \"\"\"Check if the API and model are working properly.\"\"\"\n   if pipe is None:\n       raise HTTPException(status_code=500, detail=\"Model not loaded\")\n   return {\"status\": \"healthy\", \"model_loaded\": True}<\/pre>\n<p>O endpoint `\/health` verifica se o modelo est\u00e1 carregado corretamente. Isso pode ser \u00fatil se o aplicativo no lado do cliente precisar fazer uma verifica\u00e7\u00e3o antes de disponibilizar o outro endpoint em sua interface do usu\u00e1rio.<\/p>\n<p>Em `run.py`, usamos <a href=\"https:\/\/www.uvicorn.org\/\" target=\"_blank\" rel=\"noopener\">uvicorn<\/a> para executar o servidor:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import uvicorn\n\n\nif __name__ == \"__main__\":\n   uvicorn.run(\"main:app\", host=\"0.0.0.0\", port=8000, reload=True)<\/pre>\n<p>Quando executamos este script, o servidor ser\u00e1 iniciado em <a href=\"http:\/\/0.0.0.0:8000\/\" target=\"_blank\" rel=\"noopener\">http:\/\/0.0.0.0:8000\/<\/a>.<\/p>\n<p>Depois de iniciarmos o servidor, podemos acessar <a href=\"http:\/\/0.0.0.0:8000\/docs\" target=\"_blank\" rel=\"noopener\">http:\/\/0.0.0.0:8000\/docs<\/a> para testar os endpoints.\u00a0<\/p>\n<h2 class=\"wp-block-heading\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/09\/AD_4nXf6PXwz_Vz7VEQoyZs20NJ9TsO36oWJPf0w4iMjwHZ_EBP1Pk9c_8aWR2ybGE-wsmArM1zAQl1s8jHEr09I0g1A3boGD1Kt4i4CemufHZTHnATjIWrJ8x2ZUYg4Q7E4b3tc2XDmmg.png\" width=\"624\" height=\"269\"><\/h2>\n<p>Podemos tentar isso com o endpoint `\/generate`:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n  \"prompt\": \"5 people give each other a present. How many presents are given altogether?\",\n  \"max_new_tokens\": 300\n}<\/pre>\n<p>Esta \u00e9 a resposta que recebemos:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n  \"generated_text\": \"5 people give each other a present. How many presents are given altogether?nAlright, let's try to solve the problem:nn**Problem**  n1. Each person gives each other a present. How many presents are given altogether?n2. How many \"gift\" are given altogether?nn**Common pitfall**  nAssuming that each present is a \"gift\" without considering the implications of the original condition.nn---nn### Step 1: Attempting the problem (falling into the pitfall)nnOkay, so I have two people giving each other a present, and I want to know how many are present. I remember that there are three types of gifts\u2014gifts, gins, and ginses.nnLet me try to count how many of these:nn- Gifts: Let\u2019s say there are three people giving each other a present.n- Gins: Let\u2019s say there are three people giving each other a present.n- Ginses: Let\u2019s say there are three people giving each other a present.nnSo, total gins and ginses would be:nn- Gins: ( 2 times 3 = 1 ), ( 2 times 1 = 2 ), ( 1 times 1 = 1 ), ( 1 times 2 = 2 ), so ( 2 times 3 = 4 ).n- Ginses: ( 2 times 3 = 6 ), (\"\n}\n<\/pre>\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"1600\" height=\"873\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/08\/image-50.png\" alt=\"\" class=\"wp-image-594185\" \/><\/figure>\n<p>Sinta-se \u00e0 vontade para experimentar com outras solicita\u00e7\u00f5es.<\/p>\n<h2 class=\"wp-block-heading\">Conclus\u00e3o e pr\u00f3ximas etapas<\/h2>\n<p>Agora que voc\u00ea otimizou com sucesso um modelo LLM como o GPT-2 com um conjunto de dados de racioc\u00ednio matem\u00e1tico e o implantou com a FastAPI, poder\u00e1 fazer o ajuste fino em muitas outras LLMs de c\u00f3digo aberto dispon\u00edveis no Hugging Face Hub. Voc\u00ea pode experimentar o ajuste fino de outros modelos de LLM com os dados de c\u00f3digo aberto dispon\u00edveis ou com seus pr\u00f3prios conjuntos de dados. Se quiser (e a licen\u00e7a do modelo original permitir), voc\u00ea tamb\u00e9m pode enviar seu modelo ajustado para o Hugging Face Hub. Confira a <a href=\"https:\/\/huggingface.co\/docs\/transformers\/v4.53.3\/en\/main_classes\/trainer#transformers.Trainer.push_to_hub\" target=\"_blank\" rel=\"noopener\">documenta\u00e7\u00e3o<\/a> para saber como fazer isso.<\/p>\n<p>Uma \u00faltima observa\u00e7\u00e3o sobre o uso ou ajuste de modelos com recursos no Hugging Face Hub: certifique-se de ler as licen\u00e7as de qualquer modelo ou conjunto de dados que voc\u00ea usar para entender as condi\u00e7\u00f5es para trabalhar com esses recursos. \u00c9 permitido o uso comercial? \u00c9 necess\u00e1rio citar os recursos utilizados?<\/p>\n<p>Em futuras publica\u00e7\u00f5es no blog, continuaremos explorando mais exemplos de c\u00f3digo envolvendo Python, IA, machine learning e visualiza\u00e7\u00e3o de dados.<\/p>\n<p>Na minha opini\u00e3o, o <a href=\"https:\/\/www.jetbrains.com\/pycharm\/\" target=\"_blank\" rel=\"noopener\">PyCharm<\/a> oferece o melhor suporte para Python da categoria, garantindo velocidade e precis\u00e3o. Aproveite as vantagens da complementa\u00e7\u00e3o de c\u00f3digo mais inteligente, verifica\u00e7\u00f5es de conformidade com PEP 8, refatora\u00e7\u00f5es inteligentes e uma variedade de inspe\u00e7\u00f5es para atender a todas as suas necessidades de programa\u00e7\u00e3o. Conforme demonstrado neste post do nosso blog, o PyCharm oferece integra\u00e7\u00e3o com o Hugging Face Hub, permitindo que voc\u00ea navegue e use modelos sem sair do IDE. Isso o torna adequado para uma ampla variedade de projetos de ajuste fino de IA e LLM.<\/p>\n<div class=\"buttons\">\n<div class=\"buttons__row\">\n                                                <a href=\"https:\/\/www.jetbrains.com\/pycharm\/\" class=\"btn\" target=\"\" rel=\"noopener\">Baixe o PyCharm agora<\/a>\n                                                    <\/div>\n<\/p><\/div>\n\n\n<p><em>Artigo original em ingl\u00eas por:<\/em><\/p>\n\n\n    <div class=\"about-author \">\n        <div class=\"about-author__box\">\n            <div class=\"row\">\n                <div class=\"about-author__box-img\">\n                    <img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2025\/01\/CheukTingHo-Kimono-e1738750639162-200x200.jpg\" width=\"200\" height=\"200\" alt=\"Cheuk Ting Ho\" loading=\"lazy\"  class=\"avatar avatar-200 wp-user-avatar wp-user-avatar-200 photo avatar-default\">\n                <\/div>\n                <div class=\"about-author__box-text\">\n                                            <h4>Cheuk Ting Ho<\/h4>\n                                                        <\/div>\n            <\/div>\n        <\/div>\n    <\/div>\n","protected":false},"author":1086,"featured_media":653836,"comment_status":"closed","ping_status":"closed","template":"","categories":[952,1401],"tags":[8900,8428,3252],"cross-post-tag":[8851],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm\/652182"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/types\/pycharm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/users\/1086"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/comments?post=652182"}],"version-history":[{"count":2,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm\/652182\/revisions"}],"predecessor-version":[{"id":653848,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/pycharm\/652182\/revisions\/653848"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media\/653836"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/media?parent=652182"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/categories?post=652182"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/tags?post=652182"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/pt-br\/wp-json\/wp\/v2\/cross-post-tag?post=652182"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}