DHEIVER commited on
Commit
e49e7e7
·
verified ·
1 Parent(s): a31ad5a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +139 -121
app.py CHANGED
@@ -1,152 +1,170 @@
1
  import os
 
2
  import gradio as gr
3
  from langchain_community.document_loaders import PyPDFLoader
4
  from langchain.text_splitter import RecursiveCharacterTextSplitter
5
  from langchain_community.embeddings import HuggingFaceEmbeddings
6
  from langchain_community.vectorstores import FAISS
 
7
  from langchain.chains import RetrievalQA
8
- from langchain_community.llms import HuggingFaceHub
9
- from typing import Optional
10
  import tempfile
11
 
12
  # Configurações
13
  EMBEDDING_MODEL = "sentence-transformers/all-mpnet-base-v2"
14
- LLM_REPO_ID = "google/flan-t5-large"
15
-
16
- def create_temporary_file(file_content: bytes) -> str:
17
- """Cria um arquivo temporário a partir dos bytes do arquivo."""
18
- try:
19
- temp_dir = tempfile.mkdtemp()
20
- temp_path = os.path.join(temp_dir, "temp.pdf")
21
-
22
- with open(temp_path, 'wb') as f:
23
- f.write(file_content)
24
-
25
- return temp_path
26
- except Exception as e:
27
- raise Exception(f"Erro ao criar arquivo temporário: {str(e)}")
28
 
29
- def load_and_process_pdf(pdf_path: str) -> Optional[FAISS]:
30
- """
31
- Carrega e processa o PDF, com tratamento de erros adequado.
32
- """
33
- try:
34
- # Carrega o PDF
35
- loader = PyPDFLoader(pdf_path)
36
- documents = loader.load()
 
 
37
 
38
- if not documents:
39
- return None
40
-
41
- # Divide o texto em chunks
42
- text_splitter = RecursiveCharacterTextSplitter(
43
- chunk_size=1000,
44
- chunk_overlap=200,
45
- length_function=len
 
46
  )
47
- texts = text_splitter.split_documents(documents)
48
 
49
- # Cria embeddings e armazena no vetor store
50
- embeddings = HuggingFaceEmbeddings(
 
 
 
51
  model_name=EMBEDDING_MODEL,
52
  model_kwargs={'device': 'cpu'}
53
  )
54
- db = FAISS.from_documents(texts, embeddings)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
 
56
- return db
 
57
 
58
- except Exception as e:
59
- print(f"Erro ao processar o PDF: {str(e)}")
60
- return None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
- def generate_response(file_obj, query: str) -> str:
63
- """
64
- Gera resposta para a consulta usando RAG, com tratamento de erros.
65
- """
66
- if file_obj is None:
67
- return "Erro: Nenhum arquivo PDF foi carregado."
68
-
69
- if not query.strip():
70
- return "Erro: Por favor, insira uma pergunta."
71
 
72
- try:
73
- # Cria arquivo temporário e processa o PDF
74
- temp_path = create_temporary_file(file_obj)
75
- db = load_and_process_pdf(temp_path)
 
 
 
 
76
 
77
- if db is None:
78
- return "Erro: Não foi possível processar o PDF."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
 
80
- # Configura o modelo de linguagem
81
- llm = HuggingFaceHub(
82
- repo_id=LLM_REPO_ID,
83
- huggingfacehub_api_token=os.environ.get("HUGGINGFACE_API_TOKEN"),
84
- model_kwargs={
85
- "temperature": 0.7,
86
- "max_length": 512,
87
- "top_p": 0.95
88
- }
89
  )
90
 
91
- # Cria a cadeia de RAG
92
- qa_chain = RetrievalQA.from_chain_type(
93
- llm=llm,
94
- chain_type="stuff",
95
- retriever=db.as_retriever(search_kwargs={"k": 3}),
96
- return_source_documents=True,
97
- verbose=True
98
  )
99
-
100
- # Executa a consulta
101
- result = qa_chain({"query": query})
102
-
103
- # Limpa arquivos temporários
104
- os.remove(temp_path)
105
- os.rmdir(os.path.dirname(temp_path))
106
-
107
- return result["result"]
108
-
109
- except Exception as e:
110
- return f"Erro ao gerar resposta: {str(e)}"
111
-
112
- # Interface Gradio
113
- with gr.Blocks() as demo:
114
- gr.Markdown("# Sistema de RAG com LangChain")
115
- gr.Markdown("Faça upload de um PDF e faça perguntas sobre o conteúdo.")
116
-
117
- with gr.Row():
118
- with gr.Column():
119
- file_input = gr.File(
120
- label="Upload PDF",
121
- type="binary",
122
- file_types=[".pdf"]
123
- )
124
- query_input = gr.Textbox(
125
- label="Sua Pergunta",
126
- placeholder="Digite sua pergunta aqui...",
127
- lines=3
128
- )
129
- submit_btn = gr.Button("Enviar Pergunta")
130
-
131
- with gr.Column():
132
- output = gr.Textbox(
133
- label="Resposta Gerada",
134
- lines=10
135
- )
136
-
137
- submit_btn.click(
138
- fn=generate_response,
139
- inputs=[file_input, query_input],
140
- outputs=output
141
- )
142
 
143
- gr.Examples(
144
- examples=[
145
- [None, "Qual é o principal tema deste documento?"],
146
- [None, "Pode resumir os pontos principais?"]
147
- ],
148
- inputs=[file_input, query_input]
149
- )
150
 
151
  if __name__ == "__main__":
 
152
  demo.launch()
 
1
  import os
2
+ from typing import Optional
3
  import gradio as gr
4
  from langchain_community.document_loaders import PyPDFLoader
5
  from langchain.text_splitter import RecursiveCharacterTextSplitter
6
  from langchain_community.embeddings import HuggingFaceEmbeddings
7
  from langchain_community.vectorstores import FAISS
8
+ from langchain_community.llms import HuggingFacePipeline
9
  from langchain.chains import RetrievalQA
10
+ from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline
11
+ import torch
12
  import tempfile
13
 
14
  # Configurações
15
  EMBEDDING_MODEL = "sentence-transformers/all-mpnet-base-v2"
16
+ LLM_MODEL = "mistralai/Mistral-7B-v0.1"
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
+ class RAGSystem:
19
+ def __init__(self):
20
+ # Inicializa o modelo de linguagem
21
+ self.tokenizer = AutoTokenizer.from_pretrained(LLM_MODEL)
22
+ self.model = AutoModelForCausalLM.from_pretrained(
23
+ LLM_MODEL,
24
+ torch_dtype=torch.float16,
25
+ device_map="auto",
26
+ load_in_8bit=True # Usa quantização 8-bit para reduzir uso de memória
27
+ )
28
 
29
+ # Configura o pipeline
30
+ pipe = pipeline(
31
+ "text-generation",
32
+ model=self.model,
33
+ tokenizer=self.tokenizer,
34
+ max_length=2048,
35
+ temperature=0.7,
36
+ top_p=0.95,
37
+ repetition_penalty=1.15
38
  )
 
39
 
40
+ # Configura o modelo LangChain
41
+ self.llm = HuggingFacePipeline(pipeline=pipe)
42
+
43
+ # Configura embeddings
44
+ self.embeddings = HuggingFaceEmbeddings(
45
  model_name=EMBEDDING_MODEL,
46
  model_kwargs={'device': 'cpu'}
47
  )
48
+
49
+ def process_pdf(self, file_content: bytes) -> Optional[FAISS]:
50
+ """Processa o PDF e cria a base de conhecimento"""
51
+ try:
52
+ # Cria arquivo temporário
53
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.pdf') as tmp_file:
54
+ tmp_file.write(file_content)
55
+ tmp_path = tmp_file.name
56
+
57
+ # Carrega e processa o PDF
58
+ loader = PyPDFLoader(tmp_path)
59
+ documents = loader.load()
60
+
61
+ # Remove arquivo temporário
62
+ os.unlink(tmp_path)
63
+
64
+ if not documents:
65
+ return None
66
+
67
+ # Divide o texto em chunks
68
+ text_splitter = RecursiveCharacterTextSplitter(
69
+ chunk_size=1000,
70
+ chunk_overlap=200,
71
+ length_function=len,
72
+ separators=["\n\n", "\n", ".", " ", ""]
73
+ )
74
+ texts = text_splitter.split_documents(documents)
75
+
76
+ # Cria base de conhecimento
77
+ db = FAISS.from_documents(texts, self.embeddings)
78
+ return db
79
+
80
+ except Exception as e:
81
+ print(f"Erro ao processar PDF: {str(e)}")
82
+ return None
83
+
84
+ def generate_response(self, file_obj, query: str) -> str:
85
+ """Gera resposta para a consulta"""
86
+ if file_obj is None:
87
+ return "Por favor, faça upload de um arquivo PDF."
88
 
89
+ if not query.strip():
90
+ return "Por favor, insira uma pergunta."
91
 
92
+ try:
93
+ # Processa o PDF
94
+ db = self.process_pdf(file_obj)
95
+ if db is None:
96
+ return "Não foi possível processar o PDF."
97
+
98
+ # Configura o chain RAG
99
+ qa_chain = RetrievalQA.from_chain_type(
100
+ llm=self.llm,
101
+ chain_type="stuff",
102
+ retriever=db.as_retriever(
103
+ search_kwargs={
104
+ "k": 3,
105
+ "fetch_k": 5
106
+ }
107
+ ),
108
+ return_source_documents=True
109
+ )
110
+
111
+ # Gera resposta
112
+ result = qa_chain({"query": query})
113
+ return result["result"]
114
+
115
+ except Exception as e:
116
+ return f"Erro ao gerar resposta: {str(e)}"
117
 
118
+ # Interface Gradio
119
+ def create_demo():
120
+ rag = RAGSystem()
 
 
 
 
 
 
121
 
122
+ with gr.Blocks() as demo:
123
+ gr.Markdown("# 📚 Sistema RAG com Mistral-7B")
124
+ gr.Markdown("""
125
+ ### Instruções:
126
+ 1. Faça upload de um arquivo PDF
127
+ 2. Digite sua pergunta sobre o conteúdo
128
+ 3. Aguarde a resposta gerada pelo modelo
129
+ """)
130
 
131
+ with gr.Row():
132
+ with gr.Column(scale=1):
133
+ file_input = gr.File(
134
+ label="Upload do PDF",
135
+ type="binary",
136
+ file_types=[".pdf"]
137
+ )
138
+ query_input = gr.Textbox(
139
+ label="Sua Pergunta",
140
+ placeholder="Digite sua pergunta sobre o documento...",
141
+ lines=3
142
+ )
143
+ submit_btn = gr.Button("🔍 Pesquisar", variant="primary")
144
+
145
+ with gr.Column(scale=1):
146
+ output = gr.Textbox(
147
+ label="Resposta",
148
+ lines=10
149
+ )
150
 
151
+ submit_btn.click(
152
+ fn=rag.generate_response,
153
+ inputs=[file_input, query_input],
154
+ outputs=output
 
 
 
 
 
155
  )
156
 
157
+ gr.Examples(
158
+ examples=[
159
+ [None, "Qual é o tema principal deste documento?"],
160
+ [None, "Pode fazer um resumo dos pontos principais?"],
161
+ [None, "Quais são as principais conclusões?"]
162
+ ],
163
+ inputs=[file_input, query_input]
164
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
+ return demo
 
 
 
 
 
 
167
 
168
  if __name__ == "__main__":
169
+ demo = create_demo()
170
  demo.launch()