Spaces:
Running
Running
Update ai_logic.py
Browse files- 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
|
29 |
MODELS = {}
|
30 |
|
31 |
# Lista de modelos mais estáveis e com maior chance de funcionar
|
32 |
NEW_MODELS_TO_TEST = [
|
33 |
-
("
|
34 |
-
("
|
35 |
-
("
|
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 = "
|
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 |
-
# ---
|
230 |
-
class
|
231 |
def __init__(self, token: str):
|
232 |
-
self.
|
233 |
-
self.
|
234 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
235 |
def check_model_status(self, model_name: str) -> Tuple[bool, str]:
|
236 |
-
"""Verifica se um modelo está disponível
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
252 |
|
253 |
-
if response.
|
254 |
-
|
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,
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
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
|
310 |
|
311 |
except Exception as e:
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
318 |
-
|
319 |
-
|
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
|
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 |
-
|
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 =
|
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(
|
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 |
-
|
458 |
model_name = MODELS[modelo]
|
459 |
-
resposta =
|
460 |
|
461 |
-
# Adiciona informação sobre
|
462 |
-
|
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
|
526 |
print("="*50)
|
527 |
-
print("
|
|
|
|
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")
|