aldohenrique commited on
Commit
557d276
·
verified ·
1 Parent(s): f034f07

Update ai_logic.py

Browse files
Files changed (1) hide show
  1. ai_logic.py +178 -47
ai_logic.py CHANGED
@@ -27,38 +27,25 @@ MODELS = {
27
 
28
  # Novos modelos para testar
29
  NEW_MODELS_TO_TEST = [
30
- ("LLaMA 2-7B Chat", "meta-llama/Llama-2-7b-chat"),
31
  ("LLaMA 3.2-3B Instruct", "meta-llama/Llama-3.2-3B-Instruct"),
32
  ("Gemma 2B Instruct", "google/gemma-2b-it"),
33
  ("Qwen2 7B Instruct", "Qwen/Qwen2-7B-Instruct"),
34
  ("Falcon 7B Instruct", "tiiuae/falcon-7b-instruct"),
35
  ("Mixtral 8x7B Instruct", "mistralai/Mixtral-8x7B-Instruct-v0.1"),
36
  ("LLaMA 3.1-8B Instruct", "meta-llama/Llama-3.1-8B-Instruct"),
37
- ("GPT2 XL", "gpt2-xl"),
38
- ("T5 Base", "t5-base"),
39
- ("Grok 2 Mini", "xAI/grok2-mini"),
40
  ("CodeLlama 7B Instruct", "codellama/CodeLlama-7b-Instruct-hf"),
41
- ("Starling LM 7B", "HuggingFaceH4/starling-lm-7b-alpha"),
42
  ("OpenHermes 2.5 Mistral", "teknium/OpenHermes-2.5-Mistral-7B"),
43
- ("Gemma 2B Instruct (Leve e Eficaz)", "google/gemma-2b-it"),
44
- ("Qwen2 7B Instruct (Versátil)", "Qwen/Qwen2-7B-Instruct"),
45
- ("OpenHermes 2.5 Mistral (Para Chat)", "teknium/OpenHermes-2.5-Mistral-7B"),
46
- ("LLaMA 2-7B Chat (Requer aceitação de licença Meta)", "meta-llama/Llama-2-7b-chat"),
47
- ("LLaMA 3.1-8B Instruct (Requer aceitação de licença Meta)", "meta-llama/Llama-3.1-8B-Instruct"),
48
- ("Mistral 7B (Mais assertivo)", "mistralai/Mistral-7B-Instruct-v0.3"),
49
- ("Phi-3 Mini (Mais rápido)", "microsoft/Phi-3-mini-4k-instruct"),
50
- ("Zephyr 7B (Meio termo)", "HuggingFaceH4/zephyr-7b-beta"),
51
  ("Gemma 7B Instruct", "google/gemma-7b-it"),
52
  ("Qwen 2.5-7B Instruct", "Qwen/Qwen2.5-7B-Instruct"),
53
- ("Falcon3-Mamba 7B Instruct", "tiiuae/Falcon3-Mamba-7B-Instruct"),
54
- ("Dream 7B Instruct", "Dream-org/Dream-v0-Instruct-7B"),
55
- ("OLMo 7B Instruct", "allenai/OLMo-7B-Instruct")
56
  ]
57
  DEFAULT_MODEL = "Mistral 7B (Mais acertivo)"
58
 
59
  # --- Gerenciamento de Sessão ---
60
- user_sessions: Dict[str, Dict[str, List | Dict]] = {} # {session_id: {'conversation': [], 'user_profile': {}}}
61
- MAX_MEMORY_LENGTH = 5 # Máximo de trocas (user + assistant)
62
 
63
  def get_session_memory_path(session_id: str) -> str:
64
  """Retorna o caminho do arquivo de memória para a sessão."""
@@ -107,13 +94,11 @@ def update_user_profile(session_id: str, user_message: str):
107
  profile = user_sessions[session_id]['user_profile']
108
  message_lower = user_message.lower()
109
 
110
- # Atualiza nível
111
  if any(word in message_lower for word in ['básico', 'iniciante']):
112
  profile['nivel'] = 'iniciante'
113
  elif any(word in message_lower for word in ['avançado', 'complexo']):
114
  profile['nivel'] = 'avançado'
115
 
116
- # Atualiza interesses
117
  topics = {
118
  'java': ['java', 'classe', 'objeto'],
119
  'web': ['html', 'css', 'javascript'],
@@ -129,7 +114,7 @@ def update_user_profile(session_id: str, user_message: str):
129
  def get_conversation_context(session_id: str) -> str:
130
  """Gera o contexto da conversa recente."""
131
  load_conversation_memory(session_id)
132
- conversation = user_sessions[session_id]['conversation'][-4:] # Últimas 2 trocas
133
  if not conversation:
134
  return ""
135
  return "\n".join(f"{msg['role'].upper()}: {msg['content']}" for msg in conversation)
@@ -231,34 +216,141 @@ class HuggingFaceAPIClient:
231
  def __init__(self, token: str):
232
  self.headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
233
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  def query_model(self, model_name: str, messages: List[Dict], max_tokens: int = 1000) -> str:
235
- """Faz requisição à API do Hugging Face."""
236
- url = f"https://api-inference.huggingface.co/models/{model_name}/v1/chat/completions"
 
 
 
237
  payload = {
238
- "model": model_name,
239
- "messages": messages,
240
- "max_tokens": max_tokens,
241
- "temperature": 0.7
 
 
 
242
  }
 
243
  try:
244
- response = requests.post(url, headers=self.headers, json=payload, timeout=30)
245
  response.raise_for_status()
246
- return response.json()["choices"][0]["message"]["content"].strip()
 
 
 
 
 
 
 
 
247
  except requests.exceptions.HTTPError as http_err:
248
  return f"Erro HTTP: {http_err.response.status_code} - {http_err.response.text}"
249
  except requests.exceptions.RequestException as e:
250
  return f"Erro na requisição: {str(e)}"
251
 
252
- def test_model_availability(self, model_name: str) -> Tuple[bool, str]:
253
- """Testa se um modelo está disponível na API do Hugging Face."""
254
- test_messages = [{"role": "user", "content": "Teste de disponibilidade."}]
255
- try:
256
- response = self.query_model(model_name, test_messages, max_tokens=10)
257
- if response.startswith("Erro"):
258
- return False, response
259
- return True, "Modelo disponível."
260
- except Exception as e:
261
- return False, f"Erro ao testar modelo: {str(e)}"
 
 
 
 
 
 
262
 
263
  api_client = HuggingFaceAPIClient(HF_TOKEN)
264
 
@@ -266,28 +358,61 @@ api_client = HuggingFaceAPIClient(HF_TOKEN)
266
  def test_and_update_models():
267
  """Testa a disponibilidade dos novos modelos e atualiza a lista MODELS."""
268
  print("Testando disponibilidade dos novos modelos...")
 
 
 
269
  available_models = []
270
  unavailable_models = []
271
 
272
  for model_label, model_name in NEW_MODELS_TO_TEST:
273
  is_available, message = api_client.test_model_availability(model_name)
 
274
  if is_available:
275
  MODELS[model_label] = model_name
276
  available_models.append((model_label, model_name, message))
 
277
  else:
278
  unavailable_models.append((model_label, model_name, message))
279
-
280
- # Exibir resultados
281
- print("\nResultados da validação:")
 
 
 
 
 
 
 
282
  if available_models:
283
- print("\nModelos disponíveis e adicionados:")
284
  for label, name, msg in available_models:
285
- print(f"- {label} ({name}): {msg}")
 
 
 
 
286
  if unavailable_models:
287
- print("\nModelos não disponíveis:")
288
  for label, name, msg in unavailable_models:
289
- print(f"- {label} ({name}): {msg}")
290
- print(f"\nTotal de modelos disponíveis em MODELS: {len(MODELS)}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
 
292
  # --- Chat Principal ---
293
  def responder_como_aldo(session_id: str, pergunta: str, modelo: str = DEFAULT_MODEL) -> str:
@@ -344,7 +469,13 @@ def inicializar_sistema():
344
 
345
  if __name__ == "__main__":
346
  inicializar_sistema()
 
347
  session_id = "teste_123"
 
 
 
348
  print(responder_como_aldo(session_id, "O que é Java?"))
 
349
  print(responder_como_aldo(session_id, "Mostre um exemplo de código Java."))
 
350
  print(clear_memory(session_id))
 
27
 
28
  # Novos modelos para testar
29
  NEW_MODELS_TO_TEST = [
30
+ ("LLaMA 2-7B Chat", "meta-llama/Llama-2-7b-chat-hf"),
31
  ("LLaMA 3.2-3B Instruct", "meta-llama/Llama-3.2-3B-Instruct"),
32
  ("Gemma 2B Instruct", "google/gemma-2b-it"),
33
  ("Qwen2 7B Instruct", "Qwen/Qwen2-7B-Instruct"),
34
  ("Falcon 7B Instruct", "tiiuae/falcon-7b-instruct"),
35
  ("Mixtral 8x7B Instruct", "mistralai/Mixtral-8x7B-Instruct-v0.1"),
36
  ("LLaMA 3.1-8B Instruct", "meta-llama/Llama-3.1-8B-Instruct"),
 
 
 
37
  ("CodeLlama 7B Instruct", "codellama/CodeLlama-7b-Instruct-hf"),
38
+ ("Starling LM 7B", "berkeley-nest/Starling-LM-7B-alpha"),
39
  ("OpenHermes 2.5 Mistral", "teknium/OpenHermes-2.5-Mistral-7B"),
 
 
 
 
 
 
 
 
40
  ("Gemma 7B Instruct", "google/gemma-7b-it"),
41
  ("Qwen 2.5-7B Instruct", "Qwen/Qwen2.5-7B-Instruct"),
42
+ ("OLMo 7B Instruct", "allenai/OLMo-7B-Instruct-hf")
 
 
43
  ]
44
  DEFAULT_MODEL = "Mistral 7B (Mais acertivo)"
45
 
46
  # --- Gerenciamento de Sessão ---
47
+ user_sessions: Dict[str, Dict[str, List | Dict]] = {}
48
+ MAX_MEMORY_LENGTH = 5
49
 
50
  def get_session_memory_path(session_id: str) -> str:
51
  """Retorna o caminho do arquivo de memória para a sessão."""
 
94
  profile = user_sessions[session_id]['user_profile']
95
  message_lower = user_message.lower()
96
 
 
97
  if any(word in message_lower for word in ['básico', 'iniciante']):
98
  profile['nivel'] = 'iniciante'
99
  elif any(word in message_lower for word in ['avançado', 'complexo']):
100
  profile['nivel'] = 'avançado'
101
 
 
102
  topics = {
103
  'java': ['java', 'classe', 'objeto'],
104
  'web': ['html', 'css', 'javascript'],
 
114
  def get_conversation_context(session_id: str) -> str:
115
  """Gera o contexto da conversa recente."""
116
  load_conversation_memory(session_id)
117
+ conversation = user_sessions[session_id]['conversation'][-4:]
118
  if not conversation:
119
  return ""
120
  return "\n".join(f"{msg['role'].upper()}: {msg['content']}" for msg in conversation)
 
216
  def __init__(self, token: str):
217
  self.headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
218
 
219
+ def check_model_info(self, model_name: str) -> Tuple[bool, str]:
220
+ """Verifica informações do modelo via API do Hugging Face."""
221
+ url = f"https://huggingface.co/api/models/{model_name}"
222
+ try:
223
+ response = requests.get(url, headers=self.headers, timeout=10)
224
+ if response.status_code == 200:
225
+ model_info = response.json()
226
+ # Verifica se o modelo não está desabilitado
227
+ if model_info.get('disabled', False):
228
+ return False, "Modelo desabilitado"
229
+ # Verifica se requer aprovação
230
+ if model_info.get('gated', False):
231
+ return False, "Modelo requer aprovação/aceite de licença"
232
+ return True, "Modelo disponível"
233
+ elif response.status_code == 404:
234
+ return False, "Modelo não encontrado"
235
+ else:
236
+ return False, f"Erro HTTP {response.status_code}"
237
+ except requests.exceptions.RequestException as e:
238
+ return False, f"Erro na requisição: {str(e)}"
239
+
240
+ def test_model_inference(self, model_name: str) -> Tuple[bool, str]:
241
+ """Testa se o modelo está disponível para inferência."""
242
+ # Primeiro, tenta o endpoint de text-generation (mais comum)
243
+ url = f"https://api-inference.huggingface.co/models/{model_name}"
244
+ test_payload = {
245
+ "inputs": "Teste de disponibilidade do modelo.",
246
+ "parameters": {
247
+ "max_new_tokens": 10,
248
+ "temperature": 0.1,
249
+ "return_full_text": False
250
+ }
251
+ }
252
+
253
+ try:
254
+ response = requests.post(url, headers=self.headers, json=test_payload, timeout=30)
255
+
256
+ if response.status_code == 200:
257
+ result = response.json()
258
+ if isinstance(result, list) and len(result) > 0:
259
+ return True, "Modelo disponível para inferência"
260
+ elif isinstance(result, dict) and 'error' not in result:
261
+ return True, "Modelo disponível para inferência"
262
+ else:
263
+ return False, f"Resposta inesperada: {result}"
264
+
265
+ elif response.status_code == 503:
266
+ return False, "Modelo está carregando (503)"
267
+ elif response.status_code == 400:
268
+ error_msg = response.json().get('error', 'Erro 400')
269
+ if 'loading' in error_msg.lower():
270
+ return False, "Modelo está carregando"
271
+ return False, f"Erro 400: {error_msg}"
272
+ elif response.status_code == 401:
273
+ return False, "Token inválido ou sem permissão"
274
+ elif response.status_code == 404:
275
+ return False, "Modelo não encontrado"
276
+ else:
277
+ return False, f"Erro HTTP {response.status_code}: {response.text}"
278
+
279
+ except requests.exceptions.Timeout:
280
+ return False, "Timeout na requisição"
281
+ except requests.exceptions.RequestException as e:
282
+ return False, f"Erro na requisição: {str(e)}"
283
+
284
+ def test_model_availability(self, model_name: str) -> Tuple[bool, str]:
285
+ """Testa se um modelo está disponível, combinando verificação de info e inferência."""
286
+ print(f"Testando modelo: {model_name}")
287
+
288
+ # Primeiro verifica as informações do modelo
289
+ info_available, info_msg = self.check_model_info(model_name)
290
+ if not info_available:
291
+ return False, f"Info check failed: {info_msg}"
292
+
293
+ print(f" ✓ Info check: {info_msg}")
294
+
295
+ # Em seguida testa a inferência
296
+ inference_available, inference_msg = self.test_model_inference(model_name)
297
+
298
+ if inference_available:
299
+ print(f" ✓ Inference check: {inference_msg}")
300
+ return True, f"Disponível - {info_msg}"
301
+ else:
302
+ print(f" ✗ Inference check: {inference_msg}")
303
+ return False, f"Não disponível para inferência: {inference_msg}"
304
+
305
  def query_model(self, model_name: str, messages: List[Dict], max_tokens: int = 1000) -> str:
306
+ """Faz requisição ao modelo usando text-generation."""
307
+ # Converte mensagens para prompt simples
308
+ prompt = self._convert_messages_to_prompt(messages)
309
+
310
+ url = f"https://api-inference.huggingface.co/models/{model_name}"
311
  payload = {
312
+ "inputs": prompt,
313
+ "parameters": {
314
+ "max_new_tokens": max_tokens,
315
+ "temperature": 0.7,
316
+ "do_sample": True,
317
+ "return_full_text": False
318
+ }
319
  }
320
+
321
  try:
322
+ response = requests.post(url, headers=self.headers, json=payload, timeout=60)
323
  response.raise_for_status()
324
+
325
+ result = response.json()
326
+ if isinstance(result, list) and len(result) > 0:
327
+ return result[0].get('generated_text', '').strip()
328
+ elif isinstance(result, dict) and 'generated_text' in result:
329
+ return result['generated_text'].strip()
330
+ else:
331
+ return f"Formato de resposta inesperado: {result}"
332
+
333
  except requests.exceptions.HTTPError as http_err:
334
  return f"Erro HTTP: {http_err.response.status_code} - {http_err.response.text}"
335
  except requests.exceptions.RequestException as e:
336
  return f"Erro na requisição: {str(e)}"
337
 
338
+ def _convert_messages_to_prompt(self, messages: List[Dict]) -> str:
339
+ """Converte mensagens do formato chat para prompt simples."""
340
+ prompt_parts = []
341
+ for msg in messages:
342
+ role = msg['role']
343
+ content = msg['content']
344
+
345
+ if role == 'system':
346
+ prompt_parts.append(f"Sistema: {content}")
347
+ elif role == 'user':
348
+ prompt_parts.append(f"Usuário: {content}")
349
+ elif role == 'assistant':
350
+ prompt_parts.append(f"Assistente: {content}")
351
+
352
+ prompt_parts.append("Assistente:")
353
+ return "\n\n".join(prompt_parts)
354
 
355
  api_client = HuggingFaceAPIClient(HF_TOKEN)
356
 
 
358
  def test_and_update_models():
359
  """Testa a disponibilidade dos novos modelos e atualiza a lista MODELS."""
360
  print("Testando disponibilidade dos novos modelos...")
361
+ print(f"Token HF disponível: {'Sim' if HF_TOKEN else 'Não'}")
362
+ print("-" * 60)
363
+
364
  available_models = []
365
  unavailable_models = []
366
 
367
  for model_label, model_name in NEW_MODELS_TO_TEST:
368
  is_available, message = api_client.test_model_availability(model_name)
369
+
370
  if is_available:
371
  MODELS[model_label] = model_name
372
  available_models.append((model_label, model_name, message))
373
+ print(f"✓ {model_label}")
374
  else:
375
  unavailable_models.append((model_label, model_name, message))
376
+ print(f"✗ {model_label} - {message}")
377
+
378
+ # Pequena pausa para evitar rate limiting
379
+ time.sleep(1)
380
+
381
+ # Exibir resultados finais
382
+ print("\n" + "=" * 60)
383
+ print("RESULTADOS DA VALIDAÇÃO:")
384
+ print("=" * 60)
385
+
386
  if available_models:
387
+ print(f"\n✓ MODELOS DISPONÍVEIS ({len(available_models)}):")
388
  for label, name, msg in available_models:
389
+ print(f" - {label}")
390
+ print(f" {name}")
391
+ print(f" Status: {msg}")
392
+ print()
393
+
394
  if unavailable_models:
395
+ print(f"\n✗ MODELOS NÃO DISPONÍVEIS ({len(unavailable_models)}):")
396
  for label, name, msg in unavailable_models:
397
+ print(f" - {label}")
398
+ print(f" {name}")
399
+ print(f" Motivo: {msg}")
400
+ print()
401
+
402
+ print(f"TOTAL DE MODELOS DISPONÍVEIS: {len(MODELS)}")
403
+ print("=" * 60)
404
+
405
+ # Salva a lista atualizada de modelos
406
+ save_updated_models()
407
+
408
+ def save_updated_models():
409
+ """Salva a lista atualizada de modelos em um arquivo."""
410
+ try:
411
+ with open("models_available.json", "w", encoding="utf-8") as f:
412
+ json.dump(MODELS, f, ensure_ascii=False, indent=2)
413
+ print("Lista de modelos disponíveis salva em 'models_available.json'")
414
+ except Exception as e:
415
+ print(f"Erro ao salvar lista de modelos: {e}")
416
 
417
  # --- Chat Principal ---
418
  def responder_como_aldo(session_id: str, pergunta: str, modelo: str = DEFAULT_MODEL) -> str:
 
469
 
470
  if __name__ == "__main__":
471
  inicializar_sistema()
472
+ # Teste básico
473
  session_id = "teste_123"
474
+ print("\n" + "="*50)
475
+ print("TESTE DO CHATBOT:")
476
+ print("="*50)
477
  print(responder_como_aldo(session_id, "O que é Java?"))
478
+ print("\n" + "-"*50)
479
  print(responder_como_aldo(session_id, "Mostre um exemplo de código Java."))
480
+ print("\n" + "-"*50)
481
  print(clear_memory(session_id))