Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -4,97 +4,99 @@ from sentence_transformers import SentenceTransformer, util
|
|
4 |
from transformers import T5ForConditionalGeneration, T5Tokenizer
|
5 |
|
6 |
# --- 1. Carregamento dos Modelos (faça isso apenas uma vez) ---
|
|
|
7 |
|
8 |
# Modelo para criar embeddings (vetores) a partir do texto
|
9 |
-
# 'all-MiniLM-L6-v2' é um modelo rápido e eficaz para essa tarefa.
|
10 |
print("Carregando o modelo de recuperação (Sentence Transformer)...")
|
11 |
retriever_model = SentenceTransformer('all-MiniLM-L6-v2')
|
12 |
|
13 |
# Modelo para gerar as respostas (um T5 do Hugging Face)
|
14 |
-
# 'google/flan-t5-base' é ótimo para tarefas de pergunta e resposta.
|
15 |
print("Carregando o modelo de geração (Flan-T5)...")
|
16 |
generator_tokenizer = T5Tokenizer.from_pretrained('google/flan-t5-base')
|
17 |
generator_model = T5ForConditionalGeneration.from_pretrained('google/flan-t5-base')
|
18 |
print("Modelos carregados com sucesso!")
|
19 |
|
20 |
-
|
21 |
-
#
|
|
|
|
|
|
|
22 |
|
23 |
knowledge_base = [
|
24 |
-
"
|
25 |
-
"
|
26 |
-
"
|
27 |
-
"
|
28 |
-
"
|
29 |
]
|
30 |
|
31 |
# --- 3. Pré-processamento da Base de Conhecimento ---
|
32 |
-
#
|
33 |
-
|
34 |
knowledge_base_embeddings = retriever_model.encode(knowledge_base, convert_to_tensor=True)
|
|
|
35 |
|
36 |
|
37 |
# --- 4. A Função Principal do RAG ---
|
38 |
-
|
39 |
def answer_question(question):
|
40 |
"""
|
41 |
-
Esta função recebe uma pergunta, encontra o
|
42 |
-
e gera uma resposta baseada
|
43 |
"""
|
44 |
# Etapa de Recuperação (Retrieval)
|
45 |
-
# 1. Codificar a pergunta do usuário em um vetor.
|
46 |
question_embedding = retriever_model.encode(question, convert_to_tensor=True)
|
47 |
-
|
48 |
-
# 2. Calcular a similaridade de cosseno entre a pergunta e todos os documentos da base.
|
49 |
-
# Isso nos diz qual documento é o mais "parecido" com a pergunta.
|
50 |
cosine_scores = util.cos_sim(question_embedding, knowledge_base_embeddings)
|
51 |
-
|
52 |
-
# 3. Encontrar o documento com a maior pontuação de similaridade.
|
53 |
best_doc_index = torch.argmax(cosine_scores)
|
54 |
retrieved_context = knowledge_base[best_doc_index]
|
55 |
|
56 |
-
|
|
|
57 |
print(f"Pergunta: {question}")
|
58 |
-
print(f"
|
59 |
|
60 |
# Etapa de Geração (Generation)
|
61 |
-
# 1. Criar um prompt combinando o contexto recuperado e a pergunta.
|
62 |
-
# Este formato instrui o modelo T5 a usar o contexto para responder.
|
63 |
prompt = f"""
|
64 |
Contexto: {retrieved_context}
|
65 |
|
66 |
Pergunta: {question}
|
67 |
|
68 |
-
Com base
|
69 |
Resposta:
|
70 |
"""
|
71 |
|
72 |
-
# 2. Tokenizar o prompt para o modelo gerador.
|
73 |
input_ids = generator_tokenizer(prompt, return_tensors="pt").input_ids
|
74 |
|
75 |
-
# 3. Gerar a resposta usando o modelo.
|
76 |
outputs = generator_model.generate(
|
77 |
input_ids,
|
78 |
-
max_length=
|
79 |
-
num_beams=5,
|
80 |
-
early_stopping=True
|
81 |
)
|
82 |
|
83 |
-
# 4. Decodificar a resposta gerada para texto legível.
|
84 |
answer = generator_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
85 |
-
|
86 |
return answer
|
87 |
|
88 |
# --- 5. Criação da Interface com Gradio ---
|
89 |
-
|
90 |
interface = gr.Interface(
|
91 |
fn=answer_question,
|
92 |
-
inputs=gr.Textbox(
|
93 |
-
|
94 |
-
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
)
|
97 |
|
98 |
# --- 6. Lançamento do App ---
|
99 |
if __name__ == "__main__":
|
100 |
-
interface.launch()
|
|
|
4 |
from transformers import T5ForConditionalGeneration, T5Tokenizer
|
5 |
|
6 |
# --- 1. Carregamento dos Modelos (faça isso apenas uma vez) ---
|
7 |
+
# Esta parte não muda. Usaremos os mesmos modelos eficientes.
|
8 |
|
9 |
# Modelo para criar embeddings (vetores) a partir do texto
|
|
|
10 |
print("Carregando o modelo de recuperação (Sentence Transformer)...")
|
11 |
retriever_model = SentenceTransformer('all-MiniLM-L6-v2')
|
12 |
|
13 |
# Modelo para gerar as respostas (um T5 do Hugging Face)
|
|
|
14 |
print("Carregando o modelo de geração (Flan-T5)...")
|
15 |
generator_tokenizer = T5Tokenizer.from_pretrained('google/flan-t5-base')
|
16 |
generator_model = T5ForConditionalGeneration.from_pretrained('google/flan-t5-base')
|
17 |
print("Modelos carregados com sucesso!")
|
18 |
|
19 |
+
|
20 |
+
# --- 2. Base de Conhecimento: DADOS DOS CERTIFICADOS DE CALIBRAÇÃO ---
|
21 |
+
# Esta é a principal modificação.
|
22 |
+
# Cada string representa os dados essenciais de um certificado de calibração.
|
23 |
+
# Em um sistema real, isso viria de um banco de dados ou da leitura de PDFs.
|
24 |
|
25 |
knowledge_base = [
|
26 |
+
"Certificado ID: CAL-2023-001. Instrumento TAG: PI-101 (Manômetro de Pressão). Data da Calibração: 15/01/2023. Próxima Calibração: 15/01/2024. Resultado: APROVADO. Incerteza da medição: 0.05 bar. Padrão utilizado: Fluke 754 (ID: P-05). Técnico: Ana Oliveira.",
|
27 |
+
"Certificado ID: CAL-2023-002. Instrumento TAG: TT-205 (Transmissor de Temperatura). Data da Calibração: 20/02/2023. Próxima Calibração: 20/08/2023. Resultado: REPROVADO 'como encontrado', APROVADO 'como deixado' após ajuste. Tolerância: ±0.1°C. Observação: Encontrado desvio de +0.3°C no ponto de 100°C.",
|
28 |
+
"Certificado ID: CAL-2023-003. Instrumento TAG: FV-300 (Válvula de Controle). Data do Teste: 05/03/2023. Próximo Teste: 05/03/2025. Procedimento: POP-123-Rev02. Resultado: APROVADO. Observação: Histerese de 1.5% encontrada, dentro do limite de 2.0%.",
|
29 |
+
"Certificado ID: CAL-2023-004. Instrumento TAG: BAL-01 (Balança Analítica). Data da Calibração: 10/04/2023. Próxima Calibração: 10/04/2024. Resultado: APROVADO. Incerteza da medição: ±0.001g. Padrões de massa com rastreabilidade à RBC/Inmetro.",
|
30 |
+
"Certificado ID: CAL-2023-005. Instrumento TAG: PI-102 (Manômetro de Pressão de reserva). Data da Calibração: 18/01/2023. Próxima Calibração: 18/01/2024. Resultado: APROVADO. Técnico: Carlos Pereira. O instrumento estava armazenado e foi calibrado antes do uso potencial."
|
31 |
]
|
32 |
|
33 |
# --- 3. Pré-processamento da Base de Conhecimento ---
|
34 |
+
# Esta parte não muda. Convertemos nossa nova base de conhecimento em vetores.
|
35 |
+
print("Processando a base de conhecimento (certificados)...")
|
36 |
knowledge_base_embeddings = retriever_model.encode(knowledge_base, convert_to_tensor=True)
|
37 |
+
print("Base de conhecimento pronta!")
|
38 |
|
39 |
|
40 |
# --- 4. A Função Principal do RAG ---
|
41 |
+
# Esta função é agnóstica ao domínio, então não precisa de alterações.
|
42 |
def answer_question(question):
|
43 |
"""
|
44 |
+
Esta função recebe uma pergunta, encontra o certificado mais relevante na base de conhecimento
|
45 |
+
e gera uma resposta baseada nos dados daquele certificado.
|
46 |
"""
|
47 |
# Etapa de Recuperação (Retrieval)
|
|
|
48 |
question_embedding = retriever_model.encode(question, convert_to_tensor=True)
|
|
|
|
|
|
|
49 |
cosine_scores = util.cos_sim(question_embedding, knowledge_base_embeddings)
|
|
|
|
|
50 |
best_doc_index = torch.argmax(cosine_scores)
|
51 |
retrieved_context = knowledge_base[best_doc_index]
|
52 |
|
53 |
+
# Log para depuração, para vermos qual certificado foi recuperado.
|
54 |
+
print(f"\n--- Nova Pergunta de Auditoria ---")
|
55 |
print(f"Pergunta: {question}")
|
56 |
+
print(f"Certificado Recuperado (Contexto): {retrieved_context}")
|
57 |
|
58 |
# Etapa de Geração (Generation)
|
|
|
|
|
59 |
prompt = f"""
|
60 |
Contexto: {retrieved_context}
|
61 |
|
62 |
Pergunta: {question}
|
63 |
|
64 |
+
Com base estritamente no contexto do certificado fornecido, responda à pergunta do auditor.
|
65 |
Resposta:
|
66 |
"""
|
67 |
|
|
|
68 |
input_ids = generator_tokenizer(prompt, return_tensors="pt").input_ids
|
69 |
|
|
|
70 |
outputs = generator_model.generate(
|
71 |
input_ids,
|
72 |
+
max_length=150,
|
73 |
+
num_beams=5,
|
74 |
+
early_stopping=True
|
75 |
)
|
76 |
|
|
|
77 |
answer = generator_tokenizer.decode(outputs[0], skip_special_tokens=True)
|
|
|
78 |
return answer
|
79 |
|
80 |
# --- 5. Criação da Interface com Gradio ---
|
81 |
+
# Modificamos o título e a descrição para a nossa nova aplicação.
|
82 |
interface = gr.Interface(
|
83 |
fn=answer_question,
|
84 |
+
inputs=gr.Textbox(
|
85 |
+
lines=3,
|
86 |
+
placeholder="Faça uma pergunta sobre um certificado ou instrumento...\nEx: Qual o resultado do manômetro PI-101?\nQuando vence a calibração do TT-205?\nQuem calibrou a balança BAL-01?",
|
87 |
+
label="Pergunta do Auditor"
|
88 |
+
),
|
89 |
+
outputs=gr.Textbox(label="Resposta Baseada no Certificado"),
|
90 |
+
title="🤖 RAG - Auditor de Certificados de Calibração",
|
91 |
+
description="Este sistema usa RAG para responder perguntas sobre certificados de calibração. Pergunte sobre o status, datas, técnicos ou resultados de um instrumento específico (PI-101, TT-205, FV-300, BAL-01).",
|
92 |
+
examples=[
|
93 |
+
["Qual foi o resultado da calibração do PI-101?"],
|
94 |
+
["Quando é a próxima calibração do transmissor TT-205?"],
|
95 |
+
["Qual a incerteza da balança BAL-01?"],
|
96 |
+
["Houve alguma observação no certificado da válvula FV-300?"]
|
97 |
+
]
|
98 |
)
|
99 |
|
100 |
# --- 6. Lançamento do App ---
|
101 |
if __name__ == "__main__":
|
102 |
+
interface.launch()
|