Spaces:
Runtime error
Runtime error
from fastapi import FastAPI | |
from transformers import AutoTokenizer, T5ForConditionalGeneration | |
import json | |
import os | |
import logging | |
# Configura logging para capturar mais detalhes | |
logging.basicConfig(level=logging.INFO) | |
logger = logging.getLogger(__name__) | |
app = FastAPI() | |
# Carrega o arquivo questions.json | |
try: | |
with open("questions.json", "r", encoding="utf-8") as f: | |
examples = json.load(f) | |
logger.info("questions.json carregado com sucesso.") | |
except FileNotFoundError: | |
examples = [] | |
logger.warning("questions.json não encontrado, usando lista vazia.") | |
# Função para carregar o modelo e tokenizer sob demanda | |
def get_model(): | |
if not hasattr(get_model, "model_data"): | |
logger.info("Carregando modelo e tokenizer pela primeira vez...") | |
try: | |
tokenizer = AutoTokenizer.from_pretrained( | |
"unicamp-dl/ptt5-base-portuguese-vocab", | |
legacy=False, | |
clean_up_tokenization_spaces=True | |
) | |
logger.info("Tokenizer carregado com sucesso.") | |
model = T5ForConditionalGeneration.from_pretrained( | |
"unicamp-dl/ptt5-base-portuguese-vocab", | |
device_map="cpu" # Força uso da CPU | |
) | |
logger.info("Modelo carregado com sucesso.") | |
get_model.model_data = {"tokenizer": tokenizer, "model": model} | |
except Exception as e: | |
logger.error(f"Erro ao carregar modelo ou tokenizer: {e}") | |
get_model.model_data = None | |
return get_model.model_data | |
def generate_question_from_prompt(theme, difficulty, example_question=None): | |
model_data = get_model() | |
if not model_data or not model_data["tokenizer"] or not model_data["model"]: | |
return {"question": "Erro: Modelo ou tokenizer não carregado.", "options": [], "answer": "", "explanation": "Por favor, verifique os logs."} | |
tokenizer = model_data["tokenizer"] | |
model = model_data["model"] | |
if example_question: | |
example_text = ( | |
f"Enunciado clínico: {example_question['question'].split('Considerando')[-1].strip()} " | |
f"Alternativas: {', '.join(example_question['options'])} " | |
f"Gabarito: {example_question['answer']} " | |
f"Explicação: {example_question['explanation']}" | |
) | |
prompt = ( | |
f"Baseado no exemplo: '{example_text}', gere uma nova questão de múltipla escolha " | |
f"sobre o tema '{theme}', com dificuldade {difficulty}, no estilo da prova de residência médica da USP. " | |
"Use o formato: 'Enunciado clínico: [texto detalhado com dados do paciente, exames e pergunta]. " | |
"Alternativas: A) [opção], B) [opção], C) [opção], D) [opção]. Gabarito: [letra]. " | |
"Explicação: [texto].'" | |
) | |
else: | |
prompt = ( | |
f"Gere uma questão de múltipla escolha sobre o tema '{theme}', " | |
f"com dificuldade {difficulty}, no estilo da prova de residência médica da USP. " | |
"Use o formato: 'Enunciado clínico: [texto detalhado com dados do paciente, exames e pergunta]. " | |
"Alternativas: A) [opção], B) [opção], C) [opção], D) [opção]. Gabarito: [letra]. " | |
"Explicação: [texto].'" | |
) | |
try: | |
inputs = tokenizer(prompt, return_tensors="pt", padding=True, truncation=True, max_length=512) | |
outputs = model.generate(**inputs, max_new_tokens=512, temperature=0.7, top_p=0.9) | |
response = tokenizer.decode(outputs[0], skip_special_tokens=True) | |
parts = response.split("Alternativas:") | |
if len(parts) > 1: | |
question_part = parts[0].replace("Enunciado clínico:", "").strip() | |
options_part = parts[1].split("Gabarito:")[0].strip() | |
answer_part = parts[1].split("Gabarito:")[1].split("Explicação:")[0].strip() | |
explanation_part = parts[1].split("Explicação:")[1].strip() if "Explicação:" in parts[1] else "Explicação padrão" | |
options = [opt.strip() for opt in options_part.split(",")] | |
if len(options) >= 4: | |
return { | |
"question": f"Enunciado clínico: {question_part}", | |
"options": [f"A) {options[0]}", f"B) {options[1]}", f"C) {options[2]}", f"D) {options[3]}"], | |
"answer": answer_part, | |
"explanation": explanation_part | |
} | |
return {"question": response, "options": [], "answer": "", "explanation": "Explicação padrão"} | |
except Exception as e: | |
return {"question": f"Erro na geração: {e}", "options": [], "answer": "", "explanation": "Tente novamente."} | |
async def generate_question(theme: str, difficulty: str): | |
example = examples[0] if examples else None | |
return generate_question_from_prompt(theme, difficulty, example) | |
async def get_simulado(num_questions: int = 5): | |
simulado = [] | |
for _ in range(num_questions): | |
example = examples[_ % len(examples)] if examples else None | |
question_data = generate_question_from_prompt("clinica medica", "medio", example) | |
simulado.append(question_data) | |
return {"simulado": simulado} |