aldohenrique commited on
Commit
1563f63
·
verified ·
1 Parent(s): 7f856fe

Update ai_logic.py

Browse files
Files changed (1) hide show
  1. ai_logic.py +102 -111
ai_logic.py CHANGED
@@ -9,6 +9,7 @@ from urllib.parse import urljoin, urlparse
9
  from langchain.text_splitter import RecursiveCharacterTextSplitter
10
  from langchain_community.vectorstores import FAISS
11
  from langchain_community.embeddings import HuggingFaceEmbeddings
 
12
  import asyncio
13
 
14
  # --- Configurações ---
@@ -25,24 +26,24 @@ if not HF_TOKEN:
25
 
26
  print(f"Token HF encontrado: {HF_TOKEN[:10]}...")
27
 
28
- # --- Modelos para teste (versão simplificada e mais robusta) ---
29
  MODELS = {}
30
 
31
  # Lista de modelos mais estáveis e com maior chance de funcionar
32
  NEW_MODELS_TO_TEST = [
33
- ("GPT-2", "gpt2"),
34
- ("DistilGPT-2", "distilgpt2"),
35
- ("GPT-2 Medium", "gpt2-medium"),
36
- ("Microsoft DialoGPT", "microsoft/DialoGPT-medium"),
37
- ("Google T5 Small", "google/flan-t5-small"),
38
- ("Google T5 Base", "google/flan-t5-base"),
39
- ("Facebook BART", "facebook/bart-base"),
40
- ("TinyLlama 1B", "TinyLlama/TinyLlama-1.1B-Chat-v1.0"),
41
- ("Phi-3 Mini", "microsoft/Phi-3-mini-4k-instruct"),
42
  ("Mistral 7B", "mistralai/Mistral-7B-Instruct-v0.3"),
 
 
 
 
 
 
43
  ]
44
 
45
- DEFAULT_MODEL = "GPT-2"
46
 
47
  # --- Gerenciamento de Sessão ---
48
  user_sessions: Dict[str, Dict[str, List | Dict]] = {}
@@ -226,122 +227,102 @@ def retrieve_context_from_blog(query: str, k: int = 4) -> str:
226
  print(f"Erro ao buscar contexto: {e}")
227
  return ""
228
 
229
- # --- API Client (Versão Melhorada) ---
230
- class HuggingFaceAPIClient:
231
  def __init__(self, token: str):
232
- self.headers = {"Authorization": f"Bearer {token}"}
233
- self.base_url = "https://api-inference.huggingface.co/models/"
234
-
 
 
 
 
 
 
 
 
 
235
  def check_model_status(self, model_name: str) -> Tuple[bool, str]:
236
- """Verifica se um modelo está disponível via API."""
237
- url = f"{self.base_url}{model_name}"
238
-
239
- # Teste simples para verificar se o modelo responde
240
- test_payload = {
241
- "inputs": "Hello",
242
- "parameters": {
243
- "max_new_tokens": 5,
244
- "temperature": 0.1,
245
- "return_full_text": False
246
- }
247
- }
248
-
249
  try:
250
  print(f" Testando {model_name}...")
251
- response = requests.post(url, headers=self.headers, json=test_payload, timeout=30)
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
- if response.status_code == 200:
254
- result = response.json()
255
- if isinstance(result, list) and len(result) > 0:
256
- return True, "Modelo disponível"
257
- elif isinstance(result, dict) and 'generated_text' in result:
258
- return True, "Modelo disponível"
259
- else:
260
- return False, f"Resposta inesperada: {result}"
261
-
262
- elif response.status_code == 503:
263
- return False, "Modelo carregando (503)"
264
- elif response.status_code == 401:
265
- return False, "Token inválido (401)"
266
- elif response.status_code == 400:
267
- error_msg = response.json().get('error', 'Erro desconhecido')
268
- if 'loading' in error_msg.lower():
269
- return False, "Modelo carregando"
270
- return False, f"Erro 400: {error_msg}"
271
  else:
272
- return False, f"HTTP {response.status_code}: {response.text[:100]}"
273
 
274
- except requests.exceptions.Timeout:
275
- return False, "Timeout"
276
- except requests.exceptions.RequestException as e:
277
- return False, f"Erro de conexão: {str(e)[:100]}"
278
  except Exception as e:
279
- return False, f"Erro inesperado: {str(e)[:100]}"
 
 
 
 
 
 
 
 
 
 
280
 
281
- def query_model(self, model_name: str, messages: List[Dict], max_tokens: int = 500) -> str:
282
- """Faz requisição ao modelo."""
283
- # Converte mensagens para formato de prompt simples
284
- prompt = self._convert_messages_to_prompt(messages)
285
-
286
- url = f"{self.base_url}{model_name}"
287
- payload = {
288
- "inputs": prompt,
289
- "parameters": {
290
- "max_new_tokens": max_tokens,
291
- "temperature": 0.7,
292
- "do_sample": True,
293
- "return_full_text": False
294
- }
295
- }
296
-
297
  try:
298
- response = requests.post(url, headers=self.headers, json=payload, timeout=60)
 
 
 
 
 
 
 
 
299
 
300
- if response.status_code == 200:
301
- result = response.json()
302
- if isinstance(result, list) and len(result) > 0:
303
- return result[0].get('generated_text', '').strip()
304
- elif isinstance(result, dict) and 'generated_text' in result:
305
- return result['generated_text'].strip()
306
- else:
307
- return f"Formato de resposta inesperado: {result}"
308
  else:
309
- return f"Erro na requisição: {response.status_code} - {response.text[:200]}"
310
 
311
  except Exception as e:
312
- return f"Erro ao consultar modelo: {str(e)}"
313
-
314
- def _convert_messages_to_prompt(self, messages: List[Dict]) -> str:
315
- """Converte mensagens para prompt simples."""
316
- prompt_parts = []
317
- for msg in messages:
318
- role = msg['role']
319
- content = msg['content']
320
-
321
- if role == 'system':
322
- prompt_parts.append(f"Sistema: {content}")
323
- elif role == 'user':
324
- prompt_parts.append(f"Usuário: {content}")
325
- elif role == 'assistant':
326
- prompt_parts.append(f"Assistente: {content}")
327
-
328
- prompt_parts.append("Assistente:")
329
- return "\n\n".join(prompt_parts)
330
 
331
- # --- Função para Testar e Atualizar Modelos (SEMPRE RETORNA TODOS) ---
332
  def test_and_update_models() -> int:
333
  """Testa modelos e adiciona TODOS à lista MODELS, independente da disponibilidade."""
334
  print("Testando disponibilidade dos modelos...")
335
  print(f"Token HF disponível: {'Sim' if HF_TOKEN else 'Não'}")
336
  print("-" * 60)
337
 
338
- api_client = HuggingFaceAPIClient(HF_TOKEN)
339
  model_status = {} # Para armazenar status de cada modelo
340
 
341
  # Testa todos os modelos mas adiciona TODOS à lista MODELS
342
  for model_label, model_name in NEW_MODELS_TO_TEST:
343
  try:
344
- is_available, message = api_client.check_model_status(model_name)
345
 
346
  # Armazena o status para exibição
347
  model_status[model_label] = {
@@ -364,7 +345,7 @@ def test_and_update_models() -> int:
364
  }
365
 
366
  # Pausa para evitar rate limiting
367
- time.sleep(2)
368
 
369
  # SEMPRE adiciona TODOS os modelos, independente da disponibilidade
370
  global MODELS
@@ -453,14 +434,13 @@ def responder_como_aldo(session_id: str, pergunta: str, modelo: str = None) -> s
453
  {"role": "user", "content": mensagem_usuario}
454
  ]
455
 
456
- # Faz requisição
457
- api_client = HuggingFaceAPIClient(HF_TOKEN)
458
  model_name = MODELS[modelo]
459
- resposta = api_client.query_model(model_name, messages)
460
 
461
- # Adiciona informação sobre tentativa com modelo indisponível
462
- if "Erro na requisição:" in resposta or "Erro ao consultar modelo:" in resposta:
463
- resposta += f"\n\n*Nota: Tentativa feita com {modelo}, mas o modelo pode estar indisponível. Tente outro modelo ou aguarde.*"
464
 
465
  # Salva na memória
466
  add_to_memory(session_id, pergunta, resposta)
@@ -472,6 +452,15 @@ def inicializar_sistema():
472
  print("Inicializando Chatbot Dr. Aldo...")
473
  print("=" * 50)
474
 
 
 
 
 
 
 
 
 
 
475
  # Testa modelos (agora sempre retorna todos)
476
  num_total_models = test_and_update_models()
477
 
@@ -515,13 +504,15 @@ if __name__ == "__main__":
515
  print(f"\n3. {clear_memory(session_id)}")
516
 
517
  print("\n" + "="*50)
518
- print("SISTEMA PRONTO PARA USO! ")
519
  print("="*50)
 
520
  print("⚠ Lembre-se: nem todos os modelos podem estar funcionais.")
521
  print("⚠ Teste diferentes modelos se encontrar erros.")
522
 
523
  else:
524
  print("\n" + "="*50)
525
- print("ERRO INESPERADO NA INICIALIZAÇÃO")
526
  print("="*50)
527
- print("Verifique as configurações e tente novamente.")
 
 
9
  from langchain.text_splitter import RecursiveCharacterTextSplitter
10
  from langchain_community.vectorstores import FAISS
11
  from langchain_community.embeddings import HuggingFaceEmbeddings
12
+ from huggingface_hub import InferenceClient
13
  import asyncio
14
 
15
  # --- Configurações ---
 
26
 
27
  print(f"Token HF encontrado: {HF_TOKEN[:10]}...")
28
 
29
+ # --- Modelos para teste (versão com InferenceClient) ---
30
  MODELS = {}
31
 
32
  # Lista de modelos mais estáveis e com maior chance de funcionar
33
  NEW_MODELS_TO_TEST = [
34
+ ("Llama 3.2 1B", "meta-llama/Llama-3.2-1B-Instruct"),
35
+ ("Llama 3.2 3B", "meta-llama/Llama-3.2-3B-Instruct"),
36
+ ("Llama 3.1 8B", "meta-llama/Meta-Llama-3.1-8B-Instruct"),
 
 
 
 
 
 
37
  ("Mistral 7B", "mistralai/Mistral-7B-Instruct-v0.3"),
38
+ ("Mistral Nemo", "mistralai/Mistral-Nemo-Instruct-2407"),
39
+ ("Phi-3.5 Mini", "microsoft/Phi-3.5-mini-instruct"),
40
+ ("Qwen2.5 7B", "Qwen/Qwen2.5-7B-Instruct"),
41
+ ("Gemma 2 2B", "google/gemma-2-2b-it"),
42
+ ("CodeLlama 7B", "codellama/CodeLlama-7b-Instruct-hf"),
43
+ ("Zephyr 7B", "HuggingFaceH4/zephyr-7b-beta"),
44
  ]
45
 
46
+ DEFAULT_MODEL = "Llama 3.2 1B"
47
 
48
  # --- Gerenciamento de Sessão ---
49
  user_sessions: Dict[str, Dict[str, List | Dict]] = {}
 
227
  print(f"Erro ao buscar contexto: {e}")
228
  return ""
229
 
230
+ # --- Inference Client (Versão Melhorada com huggingface_hub) ---
231
+ class HuggingFaceInferenceClient:
232
  def __init__(self, token: str):
233
+ self.token = token
234
+ self.clients = {} # Cache de clientes para diferentes modelos
235
+
236
+ def get_client(self, model_name: str) -> InferenceClient:
237
+ """Obtém ou cria um cliente para o modelo especificado."""
238
+ if model_name not in self.clients:
239
+ self.clients[model_name] = InferenceClient(
240
+ model=model_name,
241
+ token=self.token
242
+ )
243
+ return self.clients[model_name]
244
+
245
  def check_model_status(self, model_name: str) -> Tuple[bool, str]:
246
+ """Verifica se um modelo está disponível."""
 
 
 
 
 
 
 
 
 
 
 
 
247
  try:
248
  print(f" Testando {model_name}...")
249
+ client = self.get_client(model_name)
250
+
251
+ # Teste simples com mensagem básica
252
+ test_messages = [
253
+ {"role": "user", "content": "Hello"}
254
+ ]
255
+
256
+ # Tenta fazer uma requisição de teste
257
+ response = client.chat_completion(
258
+ messages=test_messages,
259
+ max_tokens=5,
260
+ temperature=0.1
261
+ )
262
 
263
+ if response and hasattr(response, 'choices') and len(response.choices) > 0:
264
+ return True, "Modelo disponível"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
  else:
266
+ return False, "Resposta inválida do modelo"
267
 
 
 
 
 
268
  except Exception as e:
269
+ error_msg = str(e).lower()
270
+ if 'loading' in error_msg or 'currently loading' in error_msg:
271
+ return False, "Modelo carregando"
272
+ elif 'rate limit' in error_msg:
273
+ return False, "Rate limit atingido"
274
+ elif 'token' in error_msg or 'unauthorized' in error_msg:
275
+ return False, "Token inválido"
276
+ elif 'model not found' in error_msg:
277
+ return False, "Modelo não encontrado"
278
+ else:
279
+ return False, f"Erro: {str(e)[:100]}"
280
 
281
+ def query_model(self, model_name: str, messages: List[Dict], max_tokens: int = 500, temperature: float = 0.7) -> str:
282
+ """Faz requisição ao modelo usando chat completion."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
283
  try:
284
+ client = self.get_client(model_name)
285
+
286
+ # Faz a requisição usando chat completion
287
+ response = client.chat_completion(
288
+ messages=messages,
289
+ max_tokens=max_tokens,
290
+ temperature=temperature,
291
+ stream=False
292
+ )
293
 
294
+ # Extrai a resposta
295
+ if response and hasattr(response, 'choices') and len(response.choices) > 0:
296
+ content = response.choices[0].message.content
297
+ return content.strip() if content else "Resposta vazia do modelo"
 
 
 
 
298
  else:
299
+ return "Erro: Resposta inválida do modelo"
300
 
301
  except Exception as e:
302
+ error_msg = str(e)
303
+ if 'loading' in error_msg.lower():
304
+ return f"Modelo {model_name} está carregando. Tente novamente em alguns minutos."
305
+ elif 'rate limit' in error_msg.lower():
306
+ return "Rate limit atingido. Aguarde alguns momentos e tente novamente."
307
+ elif 'token' in error_msg.lower() or 'unauthorized' in error_msg.lower():
308
+ return "Erro de autenticação. Verifique seu token HuggingFace."
309
+ else:
310
+ return f"Erro ao consultar modelo: {error_msg}"
 
 
 
 
 
 
 
 
 
311
 
312
+ # --- Função para Testar e Atualizar Modelos ---
313
  def test_and_update_models() -> int:
314
  """Testa modelos e adiciona TODOS à lista MODELS, independente da disponibilidade."""
315
  print("Testando disponibilidade dos modelos...")
316
  print(f"Token HF disponível: {'Sim' if HF_TOKEN else 'Não'}")
317
  print("-" * 60)
318
 
319
+ inference_client = HuggingFaceInferenceClient(HF_TOKEN)
320
  model_status = {} # Para armazenar status de cada modelo
321
 
322
  # Testa todos os modelos mas adiciona TODOS à lista MODELS
323
  for model_label, model_name in NEW_MODELS_TO_TEST:
324
  try:
325
+ is_available, message = inference_client.check_model_status(model_name)
326
 
327
  # Armazena o status para exibição
328
  model_status[model_label] = {
 
345
  }
346
 
347
  # Pausa para evitar rate limiting
348
+ time.sleep(3)
349
 
350
  # SEMPRE adiciona TODOS os modelos, independente da disponibilidade
351
  global MODELS
 
434
  {"role": "user", "content": mensagem_usuario}
435
  ]
436
 
437
+ # Faz requisição usando InferenceClient
438
+ inference_client = HuggingFaceInferenceClient(HF_TOKEN)
439
  model_name = MODELS[modelo]
440
+ resposta = inference_client.query_model(model_name, messages)
441
 
442
+ # Adiciona informação sobre modelo usado
443
+ resposta += f"\n\n*Resposta gerada pelo modelo: {modelo} ({model_name})*"
 
444
 
445
  # Salva na memória
446
  add_to_memory(session_id, pergunta, resposta)
 
452
  print("Inicializando Chatbot Dr. Aldo...")
453
  print("=" * 50)
454
 
455
+ # Verificar se huggingface_hub está instalado
456
+ try:
457
+ from huggingface_hub import InferenceClient
458
+ print("✓ huggingface_hub disponível")
459
+ except ImportError:
460
+ print("⚠ AVISO: huggingface_hub não encontrado!")
461
+ print("Execute: pip install huggingface_hub")
462
+ return False, {}
463
+
464
  # Testa modelos (agora sempre retorna todos)
465
  num_total_models = test_and_update_models()
466
 
 
504
  print(f"\n3. {clear_memory(session_id)}")
505
 
506
  print("\n" + "="*50)
507
+ print("SISTEMA PRONTO PARA USO!")
508
  print("="*50)
509
+ print("✓ Usando huggingface_hub.InferenceClient")
510
  print("⚠ Lembre-se: nem todos os modelos podem estar funcionais.")
511
  print("⚠ Teste diferentes modelos se encontrar erros.")
512
 
513
  else:
514
  print("\n" + "="*50)
515
+ print("ERRO NA INICIALIZAÇÃO")
516
  print("="*50)
517
+ print("Instale as dependências necessárias:")
518
+ print("pip install huggingface_hub")