DHEIVER commited on
Commit
6050f7a
·
verified ·
1 Parent(s): 957e316

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +42 -39
app.py CHANGED
@@ -1,23 +1,33 @@
1
  import gradio as gr
2
  import torch
3
  from sentence_transformers import SentenceTransformer, util
4
- from transformers import T5ForConditionalGeneration, T5Tokenizer
 
5
  from pypdf import PdfReader
6
  import os
7
 
8
- # --- 1. Carregamento dos Modelos (sem alterações) ---
 
9
  print("Carregando o modelo de recuperação (Sentence Transformer)...")
10
  retriever_model = SentenceTransformer('all-MiniLM-L6-v2')
11
- print("Carregando o modelo de geração (Flan-T5)...")
12
- generator_tokenizer = T5Tokenizer.from_pretrained('google/flan-t5-base')
13
- generator_model = T5ForConditionalGeneration.from_pretrained('google/flan-t5-base')
 
 
 
 
 
 
 
 
 
14
  print("Modelos carregados com sucesso!")
15
 
16
- # --- 2. Função para Processar Arquivos Enviados ---
17
  def process_files(files):
18
  if not files:
19
  return None, "Por favor, envie um ou mais arquivos."
20
-
21
  knowledge_text = ""
22
  for file in files:
23
  file_path = file.name
@@ -40,11 +50,7 @@ def process_files(files):
40
  if not knowledge_text.strip():
41
  return None, "Não foi possível extrair texto dos arquivos fornecidos."
42
 
43
- # MUDANÇA 1: Melhorando o "Chunking" (Divisão do Texto)
44
- # Em vez de dividir por parágrafos (\n\n), dividimos por linha (\n).
45
- # Isso cria chunks menores e mais focados, o que é melhor para documentos técnicos.
46
  text_chunks = [chunk.strip() for chunk in knowledge_text.split('\n') if chunk.strip() and len(chunk) > 10]
47
-
48
  if not text_chunks:
49
  return None, "O texto extraído não continha blocos de texto válidos para processamento."
50
 
@@ -54,59 +60,56 @@ def process_files(files):
54
 
55
  return (text_chunks, knowledge_base_embeddings), f"✅ Sucesso! {len(files)} arquivo(s) processado(s), gerando {len(text_chunks)} blocos de texto."
56
 
57
-
58
- # --- 3. A Função Principal do RAG (com melhorias) ---
59
  def answer_question(question, knowledge_state):
60
  if not question:
61
  return "Por favor, insira uma pergunta."
62
-
63
  if not knowledge_state or not knowledge_state[0] or knowledge_state[1] is None:
64
  return "⚠️ A base de conhecimento está vazia. Por favor, processe alguns arquivos primeiro."
65
 
66
  knowledge_base, knowledge_base_embeddings = knowledge_state
67
 
68
- # Etapa de Recuperação (Retrieval)
69
  question_embedding = retriever_model.encode(question, convert_to_tensor=True)
70
-
71
- # MUDANÇA 2: Recuperando mais contexto (top_k=3)
72
- # Em vez de pegar apenas o melhor chunk, pegamos os 3 melhores.
73
- # Isso dá mais informação para a IA gerar uma resposta completa.
74
  cosine_scores = util.cos_sim(question_embedding, knowledge_base_embeddings)
75
- top_k = min(3, len(knowledge_base)) # Garante que não tentamos pegar mais chunks do que existem
76
  top_results = torch.topk(cosine_scores, k=top_k, dim=-1)
77
-
78
- # Junta os 3 melhores chunks em um único contexto
79
  retrieved_context = "\n---\n".join([knowledge_base[i] for i in top_results.indices[0]])
80
 
81
  print(f"\n--- Nova Pergunta de Auditoria ---")
82
  print(f"Pergunta: {question}")
83
  print(f"Contexto Recuperado (Top {top_k}):\n{retrieved_context}")
84
 
85
- # Etapa de Geração (Generation)
86
-
87
- # MUDANÇA 3: Prompt de Geração Aprimorado
88
- # Damos instruções mais claras para que a IA elabore a resposta.
89
- prompt = f"""
90
- Você é um assistente de auditoria especialista. Sua tarefa é responder à pergunta do usuário de forma clara e concisa, baseando-se exclusivamente nos trechos de documentos fornecidos abaixo. Elabore uma resposta completa em vez de simplesmente copiar o texto.
91
 
92
- **Documentos Relevantes:**
93
- {retrieved_context}
94
 
95
- **Pergunta do Auditor:**
96
- {question}
97
 
98
- **Resposta Elaborada:**
99
- """
100
 
101
  input_ids = generator_tokenizer(prompt, return_tensors="pt").input_ids
 
 
 
102
  outputs = generator_model.generate(
103
  input_ids,
104
- max_length=256,
105
- num_beams=5,
106
- early_stopping=True
 
107
  )
108
 
109
- answer = generator_tokenizer.decode(outputs[0], skip_special_tokens=True)
 
 
 
 
110
  return answer
111
 
112
  # --- 4. Interface Gráfica (sem alterações na estrutura) ---
@@ -114,7 +117,7 @@ with gr.Blocks(theme=gr.themes.Soft()) as interface:
114
  knowledge_state = gr.State()
115
  gr.Markdown(
116
  """
117
- # 🤖 RAG - Auditor de Documentos (v3)
118
  **1. Carregue seus arquivos**: Envie um ou mais certificados ou documentos nos formatos `.pdf` ou `.txt`.
119
  **2. Processe os arquivos**: Clique no botão para criar a base de conhecimento.
120
  **3. Faça perguntas**: Após o processamento, faça perguntas sobre o conteúdo dos documentos.
 
1
  import gradio as gr
2
  import torch
3
  from sentence_transformers import SentenceTransformer, util
4
+ # MUDANÇA: Usaremos AutoTokenizer e AutoModelForCausalLM para o novo modelo
5
+ from transformers import AutoTokenizer, AutoModelForCausalLM
6
  from pypdf import PdfReader
7
  import os
8
 
9
+ # --- 1. Carregamento dos Modelos ---
10
+ # Modelo de recuperação não muda, ele é excelente para essa tarefa.
11
  print("Carregando o modelo de recuperação (Sentence Transformer)...")
12
  retriever_model = SentenceTransformer('all-MiniLM-L6-v2')
13
+
14
+ # MUDANÇA: Carregando o modelo DeepSeek
15
+ print("Carregando o modelo de geração (DeepSeek)...")
16
+ # Nota: "trust_remote_code=True" é necessário para carregar a arquitetura do DeepSeek
17
+ generator_tokenizer = AutoTokenizer.from_pretrained(
18
+ 'deepseek-ai/deepseek-coder-1.3b-instruct',
19
+ trust_remote_code=True
20
+ )
21
+ generator_model = AutoModelForCausalLM.from_pretrained(
22
+ 'deepseek-ai/deepseek-coder-1.3b-instruct',
23
+ trust_remote_code=True
24
+ )
25
  print("Modelos carregados com sucesso!")
26
 
27
+ # --- 2. Função para Processar Arquivos Enviados (sem alterações) ---
28
  def process_files(files):
29
  if not files:
30
  return None, "Por favor, envie um ou mais arquivos."
 
31
  knowledge_text = ""
32
  for file in files:
33
  file_path = file.name
 
50
  if not knowledge_text.strip():
51
  return None, "Não foi possível extrair texto dos arquivos fornecidos."
52
 
 
 
 
53
  text_chunks = [chunk.strip() for chunk in knowledge_text.split('\n') if chunk.strip() and len(chunk) > 10]
 
54
  if not text_chunks:
55
  return None, "O texto extraído não continha blocos de texto válidos para processamento."
56
 
 
60
 
61
  return (text_chunks, knowledge_base_embeddings), f"✅ Sucesso! {len(files)} arquivo(s) processado(s), gerando {len(text_chunks)} blocos de texto."
62
 
63
+ # --- 3. A Função Principal do RAG (com prompt e decodificação ajustados) ---
 
64
  def answer_question(question, knowledge_state):
65
  if not question:
66
  return "Por favor, insira uma pergunta."
 
67
  if not knowledge_state or not knowledge_state[0] or knowledge_state[1] is None:
68
  return "⚠️ A base de conhecimento está vazia. Por favor, processe alguns arquivos primeiro."
69
 
70
  knowledge_base, knowledge_base_embeddings = knowledge_state
71
 
72
+ # Etapa de Recuperação (sem alterações)
73
  question_embedding = retriever_model.encode(question, convert_to_tensor=True)
 
 
 
 
74
  cosine_scores = util.cos_sim(question_embedding, knowledge_base_embeddings)
75
+ top_k = min(3, len(knowledge_base))
76
  top_results = torch.topk(cosine_scores, k=top_k, dim=-1)
 
 
77
  retrieved_context = "\n---\n".join([knowledge_base[i] for i in top_results.indices[0]])
78
 
79
  print(f"\n--- Nova Pergunta de Auditoria ---")
80
  print(f"Pergunta: {question}")
81
  print(f"Contexto Recuperado (Top {top_k}):\n{retrieved_context}")
82
 
83
+ # MUDANÇA: Prompt ajustado para o formato de instrução do DeepSeek
84
+ prompt = f"""### Instruction:
85
+ Você é um assistente de auditoria especialista. Sua tarefa é sintetizar as informações dos documentos fornecidos para responder à pergunta do auditor. Elabore uma resposta completa e concisa.
 
 
 
86
 
87
+ **Documentos:**
88
+ {retrieved_context}
89
 
90
+ **Pergunta:**
91
+ {question}
92
 
93
+ ### Response:
94
+ """
95
 
96
  input_ids = generator_tokenizer(prompt, return_tensors="pt").input_ids
97
+ input_length = input_ids.shape[1]
98
+
99
+ # MUDANÇA: Ajuste nos parâmetros de geração
100
  outputs = generator_model.generate(
101
  input_ids,
102
+ max_new_tokens=256, # Controla o tamanho da *nova* resposta gerada
103
+ do_sample=False, # Desativa a amostragem para respostas mais diretas
104
+ eos_token_id=generator_tokenizer.eos_token_id,
105
+ pad_token_id=generator_tokenizer.eos_token_id # Evita warnings
106
  )
107
 
108
+ # MUDANÇA: Decodificação correta para modelos Causal LM
109
+ # Precisamos remover o prompt inicial da saída gerada.
110
+ generated_tokens = outputs[0, input_length:]
111
+ answer = generator_tokenizer.decode(generated_tokens, skip_special_tokens=True)
112
+
113
  return answer
114
 
115
  # --- 4. Interface Gráfica (sem alterações na estrutura) ---
 
117
  knowledge_state = gr.State()
118
  gr.Markdown(
119
  """
120
+ # 🤖 RAG - Auditor de Documentos (v5 - DeepSeek)
121
  **1. Carregue seus arquivos**: Envie um ou mais certificados ou documentos nos formatos `.pdf` ou `.txt`.
122
  **2. Processe os arquivos**: Clique no botão para criar a base de conhecimento.
123
  **3. Faça perguntas**: Após o processamento, faça perguntas sobre o conteúdo dos documentos.