Update app.py
Browse files
app.py
CHANGED
@@ -231,10 +231,12 @@ class TextProcessor:
|
|
231 |
|
232 |
class ModelManager:
|
233 |
"""Gerencia o modelo de IA e processamento de perguntas"""
|
234 |
-
|
235 |
def __init__(self):
|
236 |
self.model_name = "deepset/roberta-base-squad2"
|
237 |
self.device = 0 if torch.cuda.is_available() else -1
|
|
|
|
|
238 |
self.load_model()
|
239 |
|
240 |
def load_model(self):
|
@@ -243,9 +245,9 @@ class ModelManager:
|
|
243 |
self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
|
244 |
self.model = AutoModelForQuestionAnswering.from_pretrained(self.model_name)
|
245 |
self.nlp = pipeline('question-answering',
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
logger.info(f"Modelo {self.model_name} carregado com sucesso")
|
250 |
except Exception as e:
|
251 |
logger.error(f"Erro ao carregar modelo: {e}")
|
@@ -254,7 +256,11 @@ class ModelManager:
|
|
254 |
def get_answer(self, question: str, context: str) -> Dict:
|
255 |
"""Processa uma única pergunta/contexto"""
|
256 |
try:
|
257 |
-
return self.nlp(
|
|
|
|
|
|
|
|
|
258 |
except Exception as e:
|
259 |
logger.error(f"Erro ao processar resposta: {e}")
|
260 |
return {
|
@@ -278,13 +284,12 @@ class ModelManager:
|
|
278 |
|
279 |
answers = []
|
280 |
with ThreadPoolExecutor() as executor:
|
281 |
-
futures = [executor.submit(self.get_answer, question, chunk)
|
282 |
-
for chunk in chunks]
|
283 |
answers = [future.result() for future in futures]
|
284 |
|
285 |
# Filtrar respostas vazias
|
286 |
answers = [ans for ans in answers if ans['answer'].strip()]
|
287 |
-
|
288 |
if not answers:
|
289 |
return {
|
290 |
'answer': "Não foi possível encontrar uma resposta.",
|
@@ -295,18 +300,25 @@ class ModelManager:
|
|
295 |
}
|
296 |
|
297 |
best_answer = max(answers, key=lambda x: x['score'])
|
298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
return {
|
300 |
'answer': best_answer['answer'],
|
301 |
'score': best_answer['score'],
|
302 |
'confidence': f"{best_answer['score']*100:.2f}%",
|
303 |
-
'context':
|
304 |
-
'page_number': None #
|
305 |
}
|
306 |
except Exception as e:
|
307 |
-
logger.error(f"Erro ao
|
308 |
return {
|
309 |
-
'answer': "Erro ao processar
|
310 |
'score': 0,
|
311 |
'confidence': "0%",
|
312 |
'context': "",
|
|
|
231 |
|
232 |
class ModelManager:
|
233 |
"""Gerencia o modelo de IA e processamento de perguntas"""
|
234 |
+
|
235 |
def __init__(self):
|
236 |
self.model_name = "deepset/roberta-base-squad2"
|
237 |
self.device = 0 if torch.cuda.is_available() else -1
|
238 |
+
self.max_tokens_answer = 50 # Máximo de tokens na resposta
|
239 |
+
self.max_tokens_context = 300 # Máximo de tokens no contexto exibido
|
240 |
self.load_model()
|
241 |
|
242 |
def load_model(self):
|
|
|
245 |
self.tokenizer = AutoTokenizer.from_pretrained(self.model_name)
|
246 |
self.model = AutoModelForQuestionAnswering.from_pretrained(self.model_name)
|
247 |
self.nlp = pipeline('question-answering',
|
248 |
+
model=self.model,
|
249 |
+
tokenizer=self.tokenizer,
|
250 |
+
device=self.device)
|
251 |
logger.info(f"Modelo {self.model_name} carregado com sucesso")
|
252 |
except Exception as e:
|
253 |
logger.error(f"Erro ao carregar modelo: {e}")
|
|
|
256 |
def get_answer(self, question: str, context: str) -> Dict:
|
257 |
"""Processa uma única pergunta/contexto"""
|
258 |
try:
|
259 |
+
return self.nlp(
|
260 |
+
question=question,
|
261 |
+
context=context,
|
262 |
+
max_answer_len=self.max_tokens_answer # Limitar resposta
|
263 |
+
)
|
264 |
except Exception as e:
|
265 |
logger.error(f"Erro ao processar resposta: {e}")
|
266 |
return {
|
|
|
284 |
|
285 |
answers = []
|
286 |
with ThreadPoolExecutor() as executor:
|
287 |
+
futures = [executor.submit(self.get_answer, question, chunk) for chunk in chunks]
|
|
|
288 |
answers = [future.result() for future in futures]
|
289 |
|
290 |
# Filtrar respostas vazias
|
291 |
answers = [ans for ans in answers if ans['answer'].strip()]
|
292 |
+
|
293 |
if not answers:
|
294 |
return {
|
295 |
'answer': "Não foi possível encontrar uma resposta.",
|
|
|
300 |
}
|
301 |
|
302 |
best_answer = max(answers, key=lambda x: x['score'])
|
303 |
+
|
304 |
+
# Limitar contexto para o máximo de tokens configurado
|
305 |
+
limited_context = " ".join(
|
306 |
+
self.tokenizer.convert_ids_to_tokens(
|
307 |
+
self.tokenizer.encode(best_answer.get('context', ""), add_special_tokens=False)[:self.max_tokens_context]
|
308 |
+
)
|
309 |
+
)
|
310 |
+
|
311 |
return {
|
312 |
'answer': best_answer['answer'],
|
313 |
'score': best_answer['score'],
|
314 |
'confidence': f"{best_answer['score']*100:.2f}%",
|
315 |
+
'context': limited_context,
|
316 |
+
'page_number': None # Adapte conforme necessário
|
317 |
}
|
318 |
except Exception as e:
|
319 |
+
logger.error(f"Erro ao obter melhor resposta: {e}")
|
320 |
return {
|
321 |
+
'answer': "Erro ao processar o documento.",
|
322 |
'score': 0,
|
323 |
'confidence': "0%",
|
324 |
'context': "",
|