diff --git "a/Notebooks/Gerador_de_base_sintética.ipynb" "b/Notebooks/Gerador_de_base_sintética.ipynb" new file mode 100644--- /dev/null +++ "b/Notebooks/Gerador_de_base_sintética.ipynb" @@ -0,0 +1 @@ +{"cells":[{"cell_type":"markdown","metadata":{"id":"_F3Ye3WSEdrH"},"source":["## **Trabalho Prático Final de NLP**\n","### **Etapa 2: Geração de Base de Dados Sintética de Instruções**\n","**Professores:** André Carvalho e Altigran da Silva\n","\n","**Alunos:**\n","\n","\n","Bianka Vasconcelos\n","\n","Girlana Souza\n","\n","Ricardo Bonfim\n","\n","\n","**Descrição do Trabalho:** Este trabalho consiste em desenvolver uma LLM que responda perguntas sobre a legislação acadêmica da UFAM. O trabalho envolve o download e pré-processamento dos documentos da legislação, a criação de uma base de dados sintética de instruções, o treinamento do modelo usando técnicas de LoRA/QLoRA, e a implementação de um sistema de RAG (Retrieval-Augmented Generation) para fornecer respostas precisas baseadas nos documentos da legislação."]},{"cell_type":"markdown","metadata":{"id":"fc_JIQzuFL88"},"source":["### **Objetivo:** Neste notebook, iremos fazer a geração da base de dados sintética de instruções. Tomaremos como base os documentos de texto gerados no pré processamento e utilizaremos um modelo do Hugging Face para fazer conexão com a sua API e gerar a base de dados sintética."]},{"cell_type":"markdown","metadata":{"id":"eva6FnVby1-d"},"source":["### **Configurando o ambiente**\n","\n","Vamos começar com algumas importações básicas para configurar o ambiente."]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T11:26:53.646113Z","start_time":"2024-08-04T11:26:52.997856Z"},"id":"45bJ9CeD6Uv0"},"outputs":[],"source":["import re\n","import os\n","import json\n","import csv\n","import ast\n","import time\n","import requests\n","import pandas as pd\n","from tqdm import tqdm\n","from huggingface_hub import InferenceApi # faz conexão com a API"]},{"cell_type":"markdown","metadata":{"id":"-Fdx7gvHGNmR"},"source":["Configurando a chave de API do Hugging Face:"]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T11:26:53.651387Z","start_time":"2024-08-04T11:26:53.647746Z"},"colab":{"base_uri":"https://localhost:8080/"},"id":"JBjQ1AFZLZDd","outputId":"cd9ffe6e-544c-4316-e92e-7cf98a2a22ea"},"outputs":[],"source":["os.environ[\"HUGGINGFACEHUB_API_TOKEN\"] = \"\" # chave de API do Hugging Face\n","\n","print(os.environ.get(\"HUGGINGFACEHUB_API_TOKEN\"))"]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T11:26:53.746070Z","start_time":"2024-08-04T11:26:53.743039Z"},"colab":{"base_uri":"https://localhost:8080/"},"id":"0FIuSRBwLLRo","outputId":"b0ab98c6-a165-4ebb-a8ef-defcef89bd2c"},"outputs":[{"name":"stdout","output_type":"stream","text":["Token foi definido.\n"]}],"source":["# verificando se está funcionando\n","if \"HUGGINGFACEHUB_API_TOKEN\" not in os.environ:\n"," raise ValueError(\"Token não foi definido.\")\n","else:\n"," print(\"Token foi definido.\")"]},{"cell_type":"markdown","metadata":{"id":"ViMdu4Th-cQJ"},"source":["### **Escolha do Modelo e Hugging Face e Inferência**\n","\n","O modelo escolhido foi o `meta llama 3-70B Instruct`, visto que ele apresentou os melhores resultados durante os nossos testes. Como é um modelo Pro e de tamanho elevado, usaremos **inferência** via essa API, visto que usar a inferência via API permite aproveitar a otimizações do provedor de serviços, garantindo eficiência e mais rapidez nos cálculos pesados. Isso não só evitou falhas e lentidão na execução local, mas também facilitou o processo de implementação e uso do modelo em diferentes ambientes.\n","\n","A célula abaixo configura a API de inferência para o modelo."]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T02:56:32.202109Z","start_time":"2024-08-04T02:56:32.199960Z"},"id":"k9gsk4Yi5dmL"},"outputs":[],"source":["model_name = \"meta-llama/Meta-Llama-3-70B-Instruct\" # modelo escolhido\n","# model_name = 'meta-llama/Meta-Llama-3.1-405B-Instruct' # usado para teste\n","# model_name = 'mistralai/Mistral-Large-Instruct-2407' # usado para teste"]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T02:56:32.606370Z","start_time":"2024-08-04T02:56:32.203012Z"},"colab":{"base_uri":"https://localhost:8080/"},"id":"yUst0-cT4oli","outputId":"1f576482-5145-49e2-a9e9-4a260085fe97"},"outputs":[{"name":"stderr","output_type":"stream","text":["/home/biankavm/miniconda3/lib/python3.12/site-packages/huggingface_hub/utils/_deprecation.py:131: FutureWarning: 'InferenceApi' (from 'huggingface_hub.inference_api') is deprecated and will be removed from version '1.0'. `InferenceApi` client is deprecated in favor of the more feature-complete `InferenceClient`. Check out this guide to learn how to convert your script to use it: https://huggingface.co/docs/huggingface_hub/guides/inference#legacy-inferenceapi-client.\n"," warnings.warn(warning_message, FutureWarning)\n"]}],"source":["# Configurando a API de inferência (para não ter problemas para rodar o modelo, pois ele tem um tamanho considerável)\n","api_key = \"\"\n","inference = InferenceApi(repo_id=model_name, token=api_key)"]},{"cell_type":"markdown","metadata":{"id":"NhOC2XZ2_Y6u"},"source":["### **Conexão, API URL e Headers**\n","\n","Nas células abaixo estabelecemos conexão com o google drive para conseguir acessar os documentos de texto, criamos uma URL para acessar o modelo de inferência no Hugging Face e criamos um dicionário chamado `headers` que será usado para autenticação nas solicitações à API."]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T02:56:32.614459Z","start_time":"2024-08-04T02:56:32.610491Z"},"id":"VSzS-yJoQnqY"},"outputs":[],"source":["API_URL = f\"https://api-inference.huggingface.co/models/{model_name}\"\n","headers = {\"Authorization\": f\"Bearer {api_key}\"}"]},{"cell_type":"code","execution_count":null,"metadata":{"colab":{"base_uri":"https://localhost:8080/"},"executionInfo":{"elapsed":23339,"status":"ok","timestamp":1722776289508,"user":{"displayName":"Bianka Vasconcelos","userId":"00512411367206176161"},"user_tz":240},"id":"rgqL0vtfb3TD","outputId":"c6ceba46-0233-4436-c711-ce0cb1847946"},"outputs":[{"name":"stdout","output_type":"stream","text":["Mounted at /content/drive\n"]}],"source":["from google.colab import drive\n","drive.mount('/content/drive')"]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T02:56:32.618395Z","start_time":"2024-08-04T02:56:32.615404Z"},"id":"jD0Zo_34IxMq","outputId":"9f3372e6-bb30-4171-8dea-190062169be8"},"outputs":[{"name":"stdout","output_type":"stream","text":["/home/biankavm/Documents/Backup-Linux/Ciencia-da-Computacao/7 Período/NLP/TP3 (Final)/processamento_pdfs\n"]}],"source":["directory = \"/content/drive/MyDrive/NLP-2024-1/TP3 (Final)/Documentos da base/Arquivos de texto corrigidos\"\n","# directory = os.path.join(os.path.join(os.getcwd(), \"Documentos da base\"), \"Arquivos de texto corrigidos\") # usado pra rodar local\n","# print(os.getcwd())"]},{"cell_type":"markdown","metadata":{"id":"zmqjk3SNb3TD"},"source":["#### **O Prompt**\n","\n","O prompt abaixo é utilizado para gerar exatamente 14 pares de instrução e resposta baseados nos documentos legislativos da Universidade Federal do Amazonas. As saídas são formatadas em formato de um dicionário, e vale destacar que com temos 75 documentos, para gerar 1000 instruções, é preciso gerar aproximadamente 14 pares para cada documento. Por essa razão, definimos 14 instruções geradas para cada documento analisado.\n","\n","**Como funciona:**\n","\n","- size: Armazena o tamanho do documento. Isso é necessário para garantir que o modelo não ultrapasse sua capacidade de geração de tokens, o que acontece para documentos muito grandes.\n","\n","- prompt: O prompt é o que será passado como requisição para o modelo. Aqui temos os seguintes elementos:\n"," - INPUT: Fornece o texto ao modelo para que ele gere as instruções baseadas no documento que será especificado mais abaixo no prompt.\n"," - Example Output: Fornece alguns exemplos para o modelo se basear para gerar as instruções exatamente nesse formato.\n"," - Document: Especifica o documento passado ao modelo. Limitamos o modelo ao mínimo entre 4000 e o tamanho do documento, para não ultrapassar os limites de processamento do modelo.\n"," - OUTPUT: Aqui é onde teremos a saída do modelo.\n","\n","- payload: Um dicionário que contém as informações necessárias para a requisição à API de inferência da Hugging Face. Ele inclui:\n"," - inputs: O prompt formatado que será enviado ao modelo.\n"," - parameters: Parâmetros para ajustar a geração de texto pelo modelo.\n","\n","- response: Envio da requisição para a URL da API de inferência. Se a resposta for OK, retorna o conteúdo da resposta em formato json. Caso contrário, retorna erro da requisição.\n","\n","Segue a função abaixo que será responsável pela geração de texto.\n"]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T02:56:32.631545Z","start_time":"2024-08-04T02:56:32.619517Z"},"id":"yAyjex1mb3TE"},"outputs":[],"source":["def prompt_gera_texto(text,API_URL = API_URL, headers=headers, timeout=60):\n"," size = len(text)\n"," prompt = f\"\"\"\n"," ### INPUT: Based on the information in the Federal University of Amazonas legislation document and considering the existing instructions provided, generate exactly 14 new pairs of Q-A about the document in English. Each pair should be provided as a dictionary in the following format:\n","\n"," - Each dictionary should have two keys: 'Q' for the question and 'A' for the answer.\n"," - Ensure that the output is one dictionary per line.\n"," - Do not include any additional text or explanations outside of these dictionaries.\n","\n"," ### Example Output:\n"," {{'Q': \"Which law is responsible for regulating internships?\", 'A': \"The law responsible for regulating internships is Law number 11788.\"}}\n"," {{'Q': \"Who can propose the creation of a new course?\", 'A': \"According to the legislation document of the Federal University of Amazonas, the academic unit can propose the creation of a new course.\"}}\n"," {{'Q': \"The Decree-law No. 1,044 was created when?\", 'A': \"It was created on October 21, 1969.\"}}\\n\n","\n"," ### Document: {text[:min(4000, size)]}\n","\n"," ### OUTPUT:\n"," \"\"\"\n","\n"," payload = {\n"," \"inputs\": prompt,\n"," \"parameters\": {\n"," \"temperature\": 0.7, # quão aleatório é o texto\n"," \"top_p\": 0.9, # considera tokens de prob 0.9\n"," \"do_sample\": True, # amostragem\n"," \"repetition_penalty\": 1.25, # penalidade se repetir\n"," \"return_full_text\": False, # resposta retornada não inclui o prompt\n"," \"max_new_tokens\": 8000 - size if size < 4000 else 4000 # define número máximo de novos tokens que o modelo pode gerar. (o meta llama 70B gera até 8192)\n"," }\n"," }\n","\n"," # manda pra API\n"," response = requests.post(API_URL,headers=headers, json = payload)\n"," if response.status_code == 200:\n"," return response.json()\n"," else:\n"," response.raise_for_status()"]},{"cell_type":"markdown","metadata":{"id":"7iiMl-kzb3TE"},"source":["### **Funções auxiliares**\n","\n","Abaixo, definimos as funções auxiliares que usaremos para fazer a filtragem das respostas corretas da API. Isso porque, mesmo sendo um modelo razoavalemente bom, ele ainda pode gerar um texto que não é exatamente do formato especificado, o que seria problemático para gerar a base de dados.\n","\n","Com isso, a função `resposta_limpa` é responsável por encontrar o padrão de dicionário em uma resposta da API. Usamos a regex `r\"\\{[^{}]*\\}\"` para encontrar todas as substrings dentro de chaves {} que não contêm outras chaves aninhadas. Logo, ela procura por padrões que se assemelham a dicionários simples no texto.\n","\n","Por fim, a `processa_resposta` vai analisar as respostas válidas retornadas pela API, ou seja, aquelas que seguem o padrão de estar dentro de um dicionário."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"IuunLDWjb3TE"},"outputs":[],"source":["def resposta_limpa(response_text):\n"," # tira qualquer texto que não seja do dicionário\n"," matches = re.findall(r\"\\{[^{}]*\\}\", response_text)\n"," return matches\n","\n","def processa_resposta(response):\n"," def valida_dicio(text):\n"," # checar se o texto é um dicionário\n"," try:\n"," parsed = ast.literal_eval(text) # tenta converter string para obj python\n"," return isinstance(parsed, dict) # esse obj é um dicionário?\n"," except (ValueError, SyntaxError): # não conseguiu, então retorna false\n"," return False\n","\n"," if isinstance(response, str): # verifica se a resposta é uma string\n"," # extrai dicionários\n"," texto_limpo = resposta_limpa(response)\n"," # filtrar os dicionários válidos\n"," return [ast.literal_eval(item) for item in texto_limpo if valida_dicio(item)]\n"," return response"]},{"cell_type":"markdown","metadata":{"id":"LAF2nhazb3TF"},"source":["A função auxiliar `escreve_no_csv` abaixo, é responsável por escrever as instruções retornadas pela API em um arquivo csv, para ser usado posteriormente no fine tunning."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"Ni5WxzY7b3TF"},"outputs":[],"source":["def escreve_no_csv(data, filename='instrucoes.csv'):\n","\n"," arq_existe = os.path.isfile(filename) # analisa se o arquivo já existe\n"," with open(filename, mode='a', newline='', encoding='utf-8') as file:\n"," writer = csv.writer(file)\n"," # escreve o cabeçalho das colunas se o arquivo ainda não existe (Q: pergunta, A: resposta)\n"," if not arq_existe:\n"," writer.writerow(['Q', 'A'])\n"," # aqui escreve as linhas, ignorando as entradas se tiverem Q ou A vazios\n"," for entrada in data:\n"," q = entrada.get('Q', '').strip()\n"," a = entrada.get('A', '').strip()\n"," if q and a: # ambos não são vazios, então escreve\n"," writer.writerow([q, a])"]},{"cell_type":"markdown","metadata":{"id":"9jEzA1hfb3TF"},"source":["Por fim, a última função auxiliar criada, é responsável por normalizar o texto retornado pela API para ficar no formato { 'Q': \"pergunta\", 'A': \"resposta\"}. Nos nossos testes, o modelo \"criava\" aspas que não foram solicitadas no prompt, como combinações de aspas simples com duplas, aspas estilizadas, etc. Por isso, precisamos fazer esse tratamento específico de normalização para todas as respostas do modelo, garantindo obter a resposta no formato especificado."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"yniwMNvMb3TF"},"outputs":[],"source":["def normalize_text(generated_text):\n"," return generated_text.replace('“', \"'\").replace('”', \"'\").replace('„', \"'\").replace('‟', \"'\").replace('‘', \"'\").replace('’', \"'\").replace('‚', \"'\").replace('‛', \"'\").replace('´', \"'\").replace('`', \"'\").replace('::', \":\").replace(\"''\", '\"').replace(\"'q'\", \"'Q'\").replace(\"'a'\", \"'A'\").strip()"]},{"cell_type":"markdown","metadata":{"id":"-kCcmMiLb3TF"},"source":["### **Processamento dos textos**\n","\n","Na célula abaixo, iniciamos o processamento dos documentos de texto. Utilizamos a biblioteca `tqdm` para exibir uma barra de progresso que acompanha o andamento do processamento dos arquivos. Para cada arquivo '.txt' encontrado no diretório especificado, o código realiza as seguintes etapas:\n","\n","**Lendo e preparando arquivos:**\n","- Abrimos o arquivo de texto e lemos seu conteúdo, substituindo quebras de linha por espaços para obter um texto mais contínuo.\n","\n","**Gerando as instruções:**\n","- Tentamos gerar instruções a partir do texto usando a função `prompt_gera_texto` definida anteriormente. Esta função é chamada até três vezes (para tentar gerar o texto novamente), com intervalos de espera exponenciais entre as tentativas, caso ocorram erros relacionados à sobrecarga do modelo, excesso de requisições, ou serviço indisponível.\n","\n","**Validando e processando os dados:**\n","- Validamos se o texto gerado está no formato correto com a função `processa_resposta`. Se estiver, o texto será escrito em um arquivo csv, com a chamada da função `escreve_no_csv`. Caso contrário, tratamos os erros e tentamos de novo.\n","\n","**Gerenciando os erros de envio para a API:**\n","- Se ocorrer um erro HTTP, o código identifica o tipo de erro e realiza uma pausa antes de tentar novamente. O tratamento inclui erros relacionados a sobrecarga do modelo, número excessivo de requisições, e indisponibilidade do serviço.\n","- É importante ressaltar que esses erros ocorreram com bastante frequência ao usar o modelo `meta-llama-3.1-405B-Instruct`, devido ao seu alto custo de processamento. Mas, ao trocar para o modelo `llama-3-70B`, esses erros pararam, pois o modelo é mais leve e exige menos recursos computacionais.\n","\n","Dessa forma, conseguimos fazer todo o processamento necessário e criar o arquivo csv com a base sintética de instruções. Segue a função abaixo."]},{"cell_type":"code","execution_count":null,"metadata":{"id":"8cu6Yqg4b3TF"},"outputs":[],"source":["def processa_textos(directory, contador_documentos):\n"," arquivos = [x for x in os.listdir(directory) if x.endswith(\".txt\")]\n"," print(\"VAMOS COMEÇAR!\")\n"," with tqdm(total=len(arquivos), desc=\"Processando arquivos\") as pbar:\n"," for id, nome_arquivo in enumerate(arquivos):\n"," pbar.set_description(f\"\\nProcessando {nome_arquivo}\")\n"," print(\"Plotei a barra!!\")\n"," if id < contador_documentos: # pular os documentos já contados\n"," continue\n","\n"," with open(os.path.join(directory, nome_arquivo), 'r', encoding='utf-8') as file:\n"," texto = file.read()\n"," texto = texto.replace('\\n', ' ')\n","\n"," print(\"O arquivo foi aberto...\")\n","\n"," sucesso = False\n"," for attempt in range(3):\n"," print(\"Attempt\", attempt + 1)\n"," try:\n"," print(\"Estou tentando gerar...\")\n"," instrucoes = prompt_gera_texto(texto)\n"," print(\"Instrucoes tentadas: \", instrucoes)\n"," time.sleep(1)\n","\n"," if isinstance(instrucoes, list):\n"," for instrucao in instrucoes:\n"," print(\"Estou validando...\")\n"," generated_text = instrucao.get('generated_text', '')\n"," generated_text = processa_resposta(normalize_text(generated_text))\n","\n"," if isinstance(generated_text, list):\n"," # escrever texto processado no csv\n"," print(\"Escrevi no csv!!!!!!!\")\n"," escreve_no_csv(generated_text)\n","\n"," sucesso = True\n"," break\n"," else:\n"," print(f'Erro no formato: {generated_text}')\n"," else:\n"," print(f\"Não é instancia de lista {instrucoes}!\")\n"," if sucesso:\n"," print(\"Gerei com sucesso!\")\n"," break\n"," except requests.exceptions.HTTPError as http_err:\n"," try:\n"," error_response = http_err.response.json()\n"," except json.JSONDecodeError:\n"," error_response = {}\n"," if error_response.get('error') == 'overloaded': # erro de overloaded (sobrecarga)\n"," print(f\"Model overloaded processing {nome_arquivo}, attempt {attempt + 1}/3\")\n"," time.sleep(5 * (2 ** attempt)) # exponcencial backoff: 5s, 10s, 20s\n"," elif http_err.response.status_code == 429:\n"," print(f\"Too many requests processing {nome_arquivo}, attempt {attempt + 1}/3\")\n"," time.sleep(10 * (2 ** attempt)) # exponcencial backoff: 10s, 20s, 40s\n"," elif http_err.response.status_code == 503:\n"," print(f\"Service unavailable processing {nome_arquivo}, attempt {attempt + 1}/3\")\n"," time.sleep(10 * (2 ** attempt)) # exponcencial backoff: 10s, 20s, 40s\n"," else:\n"," print(f\"HTTP Error processing {nome_arquivo}: {http_err}\")\n"," break\n","\n"," if not sucesso:\n"," print(f\"Falha ao processar {nome_arquivo} no formato correto após 3 tentativas\")\n","\n"," pbar.update(1)\n"," contador_documentos += 1\n"," time.sleep(5)"]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T02:56:32.635950Z","start_time":"2024-08-04T02:56:32.633357Z"},"id":"8A88-dGkD58B"},"outputs":[],"source":["contador_documentos = 0 # controlar quantos documentos já foram processados"]},{"cell_type":"code","execution_count":null,"metadata":{"ExecuteTime":{"end_time":"2024-08-04T03:28:42.326481Z","start_time":"2024-08-04T02:56:32.636957Z"},"colab":{"base_uri":"https://localhost:8080/"},"id":"xPDMJUhdHh5t","outputId":"179cf68e-b510-46d5-b1ff-c6b6e845aa8f"},"outputs":[{"name":"stdout","output_type":"stream","text":["VAMOS COMEÇAR!\n"]},{"name":"stderr","output_type":"stream","text":["Processando arquivos: 0%| | 0/75 [00:00\n","
\n","\n","\n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n"," \n","
QA
0What does article 4 say regarding students who...Article 4 states that such students will still...
1How many days after publication would it take ...This law becomes effective thirty days from it...
2In which year did President Luiz Inacio Lula D...Law 12.089 was signed by him in November of 2009
3Is there an exception allowing someone current...Yes
4Can you enroll in only a single vacancy even i...No
.........
1032Is there flexibility allowed in terms of proje...No specific details were mentioned explicitly ...
1033Are qualifications required for teaching staff...Academic qualification is among factors evalua...
1034Does infrastructure play a role in determining...Infrastructure facilities form part of the par...
1035Will financial resources impact an institute's...Financial capacity forms part of consideration...
1036Do students who complete recognized degree pro...This aspect has been left unclear, but presuma...
\n","

1037 rows × 2 columns

\n","
\n","
\n","\n","
\n"," \n","\n"," \n","\n"," \n","
\n","\n","\n","
\n"," \n","\n","\n","\n"," \n","
\n","\n","
\n"," \n"," \n"," \n","
\n","\n","
\n"," \n"],"text/plain":[" Q \\\n","0 What does article 4 say regarding students who... \n","1 How many days after publication would it take ... \n","2 In which year did President Luiz Inacio Lula D... \n","3 Is there an exception allowing someone current... \n","4 Can you enroll in only a single vacancy even i... \n","... ... \n","1032 Is there flexibility allowed in terms of proje... \n","1033 Are qualifications required for teaching staff... \n","1034 Does infrastructure play a role in determining... \n","1035 Will financial resources impact an institute's... \n","1036 Do students who complete recognized degree pro... \n","\n"," A \n","0 Article 4 states that such students will still... \n","1 This law becomes effective thirty days from it... \n","2 Law 12.089 was signed by him in November of 2009 \n","3 Yes \n","4 No \n","... ... \n","1032 No specific details were mentioned explicitly ... \n","1033 Academic qualification is among factors evalua... \n","1034 Infrastructure facilities form part of the par... \n","1035 Financial capacity forms part of consideration... \n","1036 This aspect has been left unclear, but presuma... \n","\n","[1037 rows x 2 columns]"]},"metadata":{},"output_type":"display_data"}],"source":["arquivo = 'instrucoes.csv'\n","base_sintetica = pd.read_csv(f'/content/drive/MyDrive/NLP-2024-1/TP3 (Final)/Trabalho Final de NLP/{arquivo}', sep=',', na_values=[' ', 'NA', 'N/A', '--'])\n","display(base_sintetica)"]},{"cell_type":"markdown","metadata":{"id":"nuz9umtie-oG"},"source":["Portanto, essa foi a metodologia usada para criarmos a base sintética de instruções. Agora, o próximo passo será utilizá-la no fine tunning do modelo com Lora/QLora."]}],"metadata":{"colab":{"provenance":[]},"kernelspec":{"display_name":"Python 3 (ipykernel)","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.11.7"}},"nbformat":4,"nbformat_minor":0}