felag/AS05
0
1# -*- coding: utf-8 -*-2"""AS053 4Automatically generated by Colab.5 6Original file is located at7 https://colab.research.google.com/drive/1TB66onDDHfER-JTpJCJjUEoqVHwMTLKI8"""9 10#!pip install pdfplumber pandas openai pinecone-client sentence-transformers gradio transformers torch11 12import pdfplumber13import pandas as pd14from openai import OpenAI15import openai16import pinecone17from pinecone import Pinecone, ServerlessSpec18import os19from sentence_transformers import SentenceTransformer20import gradio as gr21import mimetypes22from transformers import AutoTokenizer, AutoModelForQuestionAnswering, pipeline23 24"""## Funções"""25 26def extrair_texto_pdf(path_pdf):27 texto_extraido = ""28 with pdfplumber.open(path_pdf) as pdf:29 for pagina in pdf.pages:30 texto_extraido += pagina.extract_text()31 return texto_extraido32 33def dividir_texto(texto, max_size=300, min_trechos=3):34 paragrafos = texto.split('\n\n')35 trechos = []36 37 for paragrafo in paragrafos:38 palavras = paragrafo.split()39 trecho_atual = []40 total_palavras = 041 42 for palavra in palavras:43 if total_palavras + len(palavra) + 1 > max_size:44 trechos.append(' '.join(trecho_atual))45 trecho_atual = []46 total_palavras = 047 trecho_atual.append(palavra)48 total_palavras += len(palavra) + 149 50 if trecho_atual:51 trechos.append(' '.join(trecho_atual))52 53 if len(trechos) < min_trechos:54 tamanho_extra = len(texto) // min_trechos55 palavras = texto.split()56 trechos = []57 trecho_atual = []58 total_palavras = 059 60 for palavra in palavras:61 if total_palavras + len(palavra) + 1 > tamanho_extra:62 trechos.append(' '.join(trecho_atual))63 trecho_atual = []64 total_palavras = 065 trecho_atual.append(palavra)66 total_palavras += len(palavra) + 167 68 if trecho_atual:69 trechos.append(' '.join(trecho_atual))70 71 return trechos72 73def gerar_embeddings(trechos):74 bert = SentenceTransformer('bert-base-nli-mean-tokens')75 embeddings = bert.encode(trechos, show_progress_bar=True)76 return embeddings77 78def carregar_embeddings_no_pinecone(embeddings, documentos, index):79 assert len(embeddings) == len(documentos)80 data_to_upsert = [81 (str(i), embedding) for i, embedding in enumerate(embeddings)82 ]83 84 index.upsert(vectors=data_to_upsert)85 print(f"{len(embeddings)} embeddings carregados no índice Pinecone com sucesso!")86 87def gerar_embeddings_consulta(consulta):88 return gerar_embeddings([consulta])[0]89 90def buscar_no_pinecone(consulta_embedding, index, top_k=5):91 consulta_embedding = consulta_embedding.tolist()92 93 resposta = index.query(94 vector=consulta_embedding,95 top_k=top_k,96 include_metadata=True97 )98 return resposta['matches']99 100def combinar_contextos(contextos):101 return "\n".join(contextos[:3])102 103tokenizer = AutoTokenizer.from_pretrained("deepset/roberta-base-squad2")104model = AutoModelForQuestionAnswering.from_pretrained("deepset/roberta-base-squad2")105 106qa_pipeline = pipeline("question-answering", model=model, tokenizer=tokenizer)107 108 109def responder_consulta_hf(contextos, consulta):110 respostas = []111 contexto_combinado = combinar_contextos(contextos)112 try:113 if len(tokenizer(contexto_combinado)["input_ids"]) > tokenizer.model_max_length:114 contexto_combinado = contexto_combinado[:tokenizer.model_max_length]115 116 resultado = qa_pipeline(question=consulta, context=contexto_combinado)117 resposta = resultado.get('answer', 'Sem resposta relevante')118 respostas.append(resposta)119 except Exception as e:120 respostas.append(f"Erro ao processar consulta: {e}")121 122 return "\n".join(respostas) if respostas else "Nenhuma resposta relevante encontrada."123 124def responder_consulta(consulta):125 try:126 if not consulta.strip():127 return "Por favor, insira uma consulta válida."128 129 consulta_embedding = gerar_embeddings_consulta(consulta)130 resultados = buscar_no_pinecone(consulta_embedding, index, top_k=5)131 132 if not resultados:133 return "Nenhum resultado encontrado para a consulta."134 135 contextos = [match['metadata']['conteudo'] for match in resultados]136 resposta = responder_consulta_hf(contextos, consulta)137 return resposta138 139 except Exception as e:140 return f"Ocorreu um erro ao processar a consulta: {e}"141 142def processar_pdfs(arquivos):143 try:144 if not arquivos:145 return "Nenhum arquivo selecionado.", gr.update(interactive=False)146 147 textos_extraidos = []148 for arquivo in arquivos:149 tipo_mime, _ = mimetypes.guess_type(arquivo.name)150 if tipo_mime != "application/pdf":151 return f"O arquivo '{arquivo.name}' não é um PDF válido.", gr.update(interactive=False)152 153 texto = extrair_texto_pdf(arquivo)154 textos_extraidos.append({"documento": arquivo.name, "conteudo": texto})155 156 for texto_extraido in textos_extraidos:157 trechos = dividir_texto(texto_extraido["conteudo"])158 embedding = gerar_embeddings(trechos)[0]159 index.upsert ([160 {161 "id": texto_extraido["documento"],162 "values": embedding,163 "metadata": {164 "document": texto_extraido["documento"],165 "conteudo": texto_extraido["conteudo"]166 }167 }168 ])169 170 return "PDFs processados e carregados com sucesso! Você já pode fazer consultas.", gr.update(interactive=True)171 172 except Exception as e:173 erro = f"Erro ao processar PDFs: {str(e)}"174 return erro, gr.update(interactive=False)175 176"""## main"""177 178os.environ["PINECONE_API_KEY"]="pcsk_va92b_8pBAjZ23b1bsbxQCkUgPqb9TmfCVsfLzyqDz3HJXpDnfkWnz8QvEDN1EoZ5EzZ8"179 180pc = Pinecone(181 api_key=os.environ["PINECONE_API_KEY"]182)183 184index_name = "documentos"185if index_name not in pc.list_indexes().names():186 pc.create_index(187 name=index_name,188 dimension=384,189 metric="cosine",190 spec=ServerlessSpec(191 cloud="aws",192 region="us-east-1"193 )194 )195 196index = pc.Index(index_name)197 198with gr.Blocks() as interface:199 with gr.Row():200 gr.Markdown("### Assistente Conversacional")201 202 with gr.Row():203 campo_upload = gr.File(label="Upload seus PDFs", file_types=[".pdf"], file_count="multiple")204 botao_processar = gr.Button("Processar PDFs")205 mensagem_status = gr.Textbox(label="Status", interactive=False)206 207 with gr.Row():208 campo_consulta = gr.Textbox(label="Digite sua consulta:", interactive=False)209 botao_consultar = gr.Button("Consultar")210 resposta_consulta = gr.Textbox(label="Resultados:", interactive=False)211 212 botao_processar.click(213 fn=processar_pdfs,214 inputs=[campo_upload],215 outputs=[mensagem_status, campo_consulta],216 )217 218 botao_consultar.click(219 fn=responder_consulta,220 inputs=[campo_consulta],221 outputs=[resposta_consulta]222 )223 224interface.launch(server_name="0.0.0.0", server_port=7860)