DHEIVER commited on
Commit
ce906cb
·
verified ·
1 Parent(s): 0a7d265

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +95 -79
app.py CHANGED
@@ -9,46 +9,55 @@ from functools import lru_cache
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
12
- class SimpleBibleRAG:
13
  def __init__(self):
14
  self.device = "cuda" if torch.cuda.is_available() else "cpu"
15
- logger.info(f"Using device: {self.device}")
16
 
17
- # Load model and tokenizer
18
- model_name = "bert-base-multilingual-cased"
19
  self.tokenizer = AutoTokenizer.from_pretrained(model_name)
20
  self.model = AutoModel.from_pretrained(model_name).to(self.device)
21
- self.sentiment_analyzer = pipeline("sentiment-analysis", model="distilbert-base-uncased-finetuned-sst-2-english")
22
 
23
- self.bible_data = self.load_bible_data()
24
- self.passage_embeddings = self.compute_embeddings()
 
 
 
 
25
 
26
- def load_bible_data(self):
27
- # Simulated database with multilingual support
28
  return [
29
  {
30
- "reference": "João 3:16 / John 3:16",
31
- "text": {
32
- "pt": "Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito, para que todo aquele que nele crê não pereça, mas tenha a vida eterna.",
33
- "en": "For God so loved the world that he gave his one and only Son, that whoever believes in him shall not perish but have eternal life."
34
- },
35
- "topic": "Salvation/Salvação"
 
 
 
 
 
 
 
 
 
 
 
 
36
  },
37
  {
38
- "reference": "1 Coríntios 13:4-7 / 1 Corinthians 13:4-7",
39
- "text": {
40
- "pt": "O amor é paciente, o amor é bondoso. Não inveja, não se vangloria, não se orgulha. Não maltrata, não procura seus interesses, não se ira facilmente, não guarda rancor. O amor não se alegra com a injustiça, mas se alegra com a verdade. Tudo sofre, tudo crê, tudo espera, tudo suporta.",
41
- "en": "Love is patient, love is kind. It does not envy, it does not boast, it is not proud. It does not dishonor others, it is not self-seeking, it is not easily angered, it keeps no record of wrongs. Love does not delight in evil but rejoices with the truth. It always protects, always trusts, always hopes, always perseveres."
42
- },
43
- "topic": "Love/Amor"
44
  },
45
  {
46
- "reference": "Filipenses 4:13 / Philippians 4:13",
47
- "text": {
48
- "pt": "Posso todas as coisas naquele que me fortalece.",
49
- "en": "I can do all things through Christ who strengthens me."
50
- },
51
- "topic": "Faith/Fé"
52
  }
53
  ]
54
 
@@ -57,69 +66,75 @@ class SimpleBibleRAG:
57
  input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
58
  return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
59
 
60
- def get_embedding(self, text: str) -> np.ndarray:
61
- inputs = self.tokenizer(text, padding=True, truncation=True, return_tensors='pt').to(self.device)
62
  with torch.no_grad():
63
  model_output = self.model(**inputs)
64
  sentence_embeddings = self.mean_pooling(model_output, inputs['attention_mask'])
65
  return sentence_embeddings.cpu().numpy()
66
 
67
- def compute_embeddings(self):
68
- return [self.get_embedding(d['text']['en'])[0] for d in self.bible_data]
69
 
70
- def search_passages(self, query: str, k: int = 2) -> List[Dict]:
71
- query_embedding = self.get_embedding(query)[0]
72
- similarities = [np.dot(query_embedding, passage_embedding) /
73
- (np.linalg.norm(query_embedding) * np.linalg.norm(passage_embedding))
74
- for passage_embedding in self.passage_embeddings]
75
 
76
- top_k_idx = np.argsort(similarities)[-k:][::-1]
77
- return [self.bible_data[idx] for idx in top_k_idx]
78
 
79
  @lru_cache(maxsize=100)
80
- def generate_response(self, query: str, lang: str = 'en') -> str:
81
  try:
82
- relevant_passages = self.search_passages(query)
83
 
84
- response = "Based on these verses:\n\n" if lang == 'en' else "Baseado nestes versículos:\n\n"
85
 
86
- for passage in relevant_passages:
87
- response += f"📖 {passage['reference']}\n"
88
- response += f"{passage['text'][lang]}\n\n"
89
 
90
- sentiment = self.analyze_sentiment(query)
91
- sentiment_text = "positive" if sentiment == "POSITIVE" else "negative"
92
- sentiment_msg = f"\nYour question seems to have a {sentiment_text} tone." if lang == 'en' else \
93
- f"\nSua pergunta parece ter um tom {'positivo' if sentiment_text == 'positive' else 'negativo'}."
94
 
95
- response += sentiment_msg
 
 
96
 
97
- return response
98
 
99
  except Exception as e:
100
- logger.error(f"Error generating response: {str(e)}")
101
- return "An error occurred while processing your request." if lang == 'en' else \
102
- "Ocorreu um erro ao processar sua solicitação."
103
 
104
- def analyze_sentiment(self, text: str) -> str:
105
- result = self.sentiment_analyzer(text)[0]
106
- return result['label']
 
 
 
 
 
 
107
 
108
- def process_message(message: str, history: List, lang: str) -> str:
109
  try:
110
- rag = SimpleBibleRAG()
111
- response = rag.generate_response(message, lang)
112
- return response
113
  except Exception as e:
114
- logger.error(f"Error: {str(e)}")
115
- return "Sorry, an error occurred." if lang == 'en' else "Desculpe, ocorreu um erro."
116
 
117
- # Gradio Interface
118
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
119
  gr.HTML("""
120
  <div style="text-align: center; padding: 20px;">
121
- <h1>📚 Bible Assistant</h1>
122
- <p>Ask questions about the Bible and receive verse-based answers</p>
123
  </div>
124
  """)
125
 
@@ -129,28 +144,29 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
129
  with gr.Row():
130
  msg = gr.Textbox(
131
  show_label=False,
132
- placeholder="Ask your question about the Bible...",
133
  scale=4
134
  )
135
- lang = gr.Dropdown(["en", "pt"], label="Language", value="en")
136
- clear = gr.Button("Clear", scale=1)
137
 
138
  with gr.Column(scale=1):
139
  gr.Markdown("""
140
- ### How to use
141
- 1. Select your language
142
- 2. Type your question
143
- 3. The system will find relevant verses
144
- 4. A response will be generated with sentiment analysis
145
 
146
- ### Examples:
147
- - What is love?
148
- - How to have faith in difficult times?
149
- - What is God's plan for salvation?
 
 
150
  """)
151
 
152
- msg.submit(process_message, [msg, chatbot, lang], [chatbot])
153
- clear.click(lambda: None, None, chatbot, queue=False)
154
 
155
  if __name__ == "__main__":
156
  demo.launch()
 
9
  logging.basicConfig(level=logging.INFO)
10
  logger = logging.getLogger(__name__)
11
 
12
+ class AssistenteBiblico:
13
  def __init__(self):
14
  self.device = "cuda" if torch.cuda.is_available() else "cpu"
15
+ logger.info(f"Usando dispositivo: {self.device}")
16
 
17
+ # Carregando modelo e tokenizer em português
18
+ model_name = "neuralmind/bert-base-portuguese-cased"
19
  self.tokenizer = AutoTokenizer.from_pretrained(model_name)
20
  self.model = AutoModel.from_pretrained(model_name).to(self.device)
 
21
 
22
+ # Usando modelo de sentimentos em português
23
+ self.analisador_sentimento = pipeline("sentiment-analysis",
24
+ model="pierreguillou/bert-base-multilingual-cased-sentiment-brazilian-news")
25
+
26
+ self.dados_biblia = self.carregar_dados_biblia()
27
+ self.embeddings_versiculos = self.computar_embeddings()
28
 
29
+ def carregar_dados_biblia(self):
30
+ # Base de dados simulada em português
31
  return [
32
  {
33
+ "referencia": "João 3:16",
34
+ "texto": "Porque Deus amou o mundo de tal maneira que deu o seu Filho unigênito, para que todo aquele que nele crê não pereça, mas tenha a vida eterna.",
35
+ "topico": "Salvação"
36
+ },
37
+ {
38
+ "referencia": "1 Coríntios 13:4-7",
39
+ "texto": "O amor é paciente, o amor é bondoso. Não inveja, não se vangloria, não se orgulha. Não maltrata, não procura seus interesses, não se ira facilmente, não guarda rancor. O amor não se alegra com a injustiça, mas se alegra com a verdade. Tudo sofre, tudo crê, tudo espera, tudo suporta.",
40
+ "topico": "Amor"
41
+ },
42
+ {
43
+ "referencia": "Filipenses 4:13",
44
+ "texto": "Posso todas as coisas naquele que me fortalece.",
45
+ "topico": "Fé"
46
+ },
47
+ {
48
+ "referencia": "Salmos 23:1",
49
+ "texto": "O Senhor é o meu pastor, nada me faltará.",
50
+ "topico": "Confiança"
51
  },
52
  {
53
+ "referencia": "Mateus 11:28",
54
+ "texto": "Vinde a mim, todos os que estais cansados e oprimidos, e eu vos aliviarei.",
55
+ "topico": "Conforto"
 
 
 
56
  },
57
  {
58
+ "referencia": "Provérbios 3:5-6",
59
+ "texto": "Confie no Senhor de todo o seu coração e não se apoie em seu próprio entendimento; reconheça o Senhor em todos os seus caminhos, e ele endireitará as suas veredas.",
60
+ "topico": "Sabedoria"
 
 
 
61
  }
62
  ]
63
 
 
66
  input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
67
  return torch.sum(token_embeddings * input_mask_expanded, 1) / torch.clamp(input_mask_expanded.sum(1), min=1e-9)
68
 
69
+ def get_embedding(self, texto: str) -> np.ndarray:
70
+ inputs = self.tokenizer(texto, padding=True, truncation=True, return_tensors='pt').to(self.device)
71
  with torch.no_grad():
72
  model_output = self.model(**inputs)
73
  sentence_embeddings = self.mean_pooling(model_output, inputs['attention_mask'])
74
  return sentence_embeddings.cpu().numpy()
75
 
76
+ def computar_embeddings(self):
77
+ return [self.get_embedding(d['texto'])[0] for d in self.dados_biblia]
78
 
79
+ def buscar_versiculos(self, pergunta: str, k: int = 2) -> List[Dict]:
80
+ query_embedding = self.get_embedding(pergunta)[0]
81
+ similaridades = [np.dot(query_embedding, emb_versiculo) /
82
+ (np.linalg.norm(query_embedding) * np.linalg.norm(emb_versiculo))
83
+ for emb_versiculo in self.embeddings_versiculos]
84
 
85
+ top_k_idx = np.argsort(similaridades)[-k:][::-1]
86
+ return [self.dados_biblia[idx] for idx in top_k_idx]
87
 
88
  @lru_cache(maxsize=100)
89
+ def gerar_resposta(self, pergunta: str) -> str:
90
  try:
91
+ versiculos_relevantes = self.buscar_versiculos(pergunta)
92
 
93
+ resposta = "Baseado nestes versículos:\n\n"
94
 
95
+ for versiculo in versiculos_relevantes:
96
+ resposta += f"📖 {versiculo['referencia']}\n"
97
+ resposta += f"{versiculo['texto']}\n\n"
98
 
99
+ # Análise de sentimento da pergunta
100
+ sentimento = self.analisar_sentimento(pergunta)
101
+ resposta += f"\nSua pergunta parece ter um tom {sentimento}."
 
102
 
103
+ # Adiciona tópicos relacionados
104
+ topicos = [v['topico'] for v in versiculos_relevantes]
105
+ resposta += f"\n\nTópicos relacionados: {', '.join(topicos)}"
106
 
107
+ return resposta
108
 
109
  except Exception as e:
110
+ logger.error(f"Erro gerando resposta: {str(e)}")
111
+ return "Ocorreu um erro ao processar sua solicitação."
 
112
 
113
+ def analisar_sentimento(self, texto: str) -> str:
114
+ resultado = self.analisador_sentimento(texto)[0]
115
+ # Converte as labels do modelo para português
116
+ mapa_sentimentos = {
117
+ 'positive': 'positivo',
118
+ 'negative': 'negativo',
119
+ 'neutral': 'neutro'
120
+ }
121
+ return mapa_sentimentos.get(resultado['label'], 'neutro')
122
 
123
+ def processar_mensagem(mensagem: str, historico: List) -> str:
124
  try:
125
+ assistente = AssistenteBiblico()
126
+ resposta = assistente.gerar_resposta(mensagem)
127
+ return resposta
128
  except Exception as e:
129
+ logger.error(f"Erro: {str(e)}")
130
+ return "Desculpe, ocorreu um erro."
131
 
132
+ # Interface Gradio
133
  with gr.Blocks(theme=gr.themes.Soft()) as demo:
134
  gr.HTML("""
135
  <div style="text-align: center; padding: 20px;">
136
+ <h1>📚 Assistente Bíblico</h1>
137
+ <p>Faça perguntas sobre a Bíblia e receba respostas baseadas em versículos</p>
138
  </div>
139
  """)
140
 
 
144
  with gr.Row():
145
  msg = gr.Textbox(
146
  show_label=False,
147
+ placeholder="Faça sua pergunta sobre a Bíblia...",
148
  scale=4
149
  )
150
+ limpar = gr.Button("Limpar", scale=1)
 
151
 
152
  with gr.Column(scale=1):
153
  gr.Markdown("""
154
+ ### Como usar
155
+ 1. Digite sua pergunta
156
+ 2. O sistema encontrará versículos relevantes
157
+ 3. Uma resposta será gerada com análise de sentimento
158
+ 4. Os tópicos relacionados serão mostrados
159
 
160
+ ### Exemplos de perguntas:
161
+ - O que é o amor segundo a Bíblia?
162
+ - Como ter em tempos difíceis?
163
+ - Qual é o plano de Deus para salvação?
164
+ - Como encontrar paz e conforto?
165
+ - O que a Bíblia diz sobre sabedoria?
166
  """)
167
 
168
+ msg.submit(processar_mensagem, [msg, chatbot], [chatbot])
169
+ limpar.click(lambda: None, None, chatbot, queue=False)
170
 
171
  if __name__ == "__main__":
172
  demo.launch()