akra35567 commited on
Commit
c62ee29
·
1 Parent(s): a695583

Update modules/local_llm.py

Browse files
Files changed (1) hide show
  1. modules/local_llm.py +33 -24
modules/local_llm.py CHANGED
@@ -1,18 +1,20 @@
1
- # modules/local_llm.py — VERSÃO FINAL OFICIAL: RAM FULL, CPU CHILL, LUANDA NO COMANDO!
2
  from llama_cpp import Llama
3
  import os
4
  from loguru import logger
5
  import threading
6
 
7
  # CAMINHOS NO HF SPACES (CORRIGIDOS PARA O AMBIENTE ATUAL)
8
- FINETUNED_PATH = "/home/user/data/finetuned_hermes" # LoRA angolano
9
  # CORREÇÃO: O Dockerfile baixa para /home/user/models/
10
- GGUF_PATH = "/home/user/models/openhermes-2.5-mistral-7b.Q4_K_M.gguf"
 
11
 
12
- class HermesLLM:
13
  _llm = None
14
  _available_checked = False
15
  _is_available = False
 
 
16
 
17
  @classmethod
18
  def is_available(cls) -> bool:
@@ -24,9 +26,9 @@ class HermesLLM:
24
  cls._is_available = os.path.isfile(GGUF_PATH)
25
  cls._available_checked = True
26
  if cls._is_available:
27
- logger.info(f"HERMES 7B GGUF ENCONTRADO → {GGUF_PATH}")
28
  else:
29
- logger.warning(f"HERMES 7B GGUF NÃO ENCONTRADO! Caminho: {GGUF_PATH}")
30
  logger.warning("AKIRA VAI USAR MISTRAL/GEMINI COMO FALLBACK")
31
  return cls._is_available
32
 
@@ -34,28 +36,27 @@ class HermesLLM:
34
  def _get_llm(cls):
35
  """
36
  CARREGA O MODELO UMA ÚNICA VEZ → SINGLETON + mlock
37
- RAM ATÉ O PESCOÇOCPU 2 THREADS 8-12s POR RESPOSTA
38
  """
39
  if cls._llm is None and cls.is_available():
40
  try:
41
- logger.info("CARREGANDO OPENHERMES 7B GGUF Q4_K_M → RAM MÁXIMA, CPU MÍNIMA!")
42
  cls._llm = Llama(
43
  model_path=GGUF_PATH,
44
- n_ctx=4096, # Contexto gigante (mais RAM)
45
  n_batch=512, # Batch grande = menos CPU
46
  n_threads=2, # Só 2 threads → CPU em paz!
47
- n_gpu_layers=0, # Tudo na RAM (HF Spaces free não tem GPU)
48
  use_mlock=True, # Trava na RAM física → nunca swap!
49
  verbose=False,
50
- n_parts=1, # Carrega tudo de uma vez → RAM FULL
51
  seed=-1,
52
  logits_all=True,
53
  )
54
- logger.success("HERMES 7B GGUF CARREGADO COM SUCESSO → ~14-16GB RAM USADA!")
55
 
56
  # =================================================================
57
- # CORREÇÃO: A linha abaixo estava a causar o 'AttributeError'.
58
- # A funcionalidade LoRA foi removida para garantir que o modelo base funcione.
59
  # =================================================================
60
  lora_path = os.path.join(FINETUNED_PATH, "lora_leve")
61
  if os.path.isdir(lora_path):
@@ -64,36 +65,44 @@ class HermesLLM:
64
  logger.info("Usando modelo GGUF base (sem LoRA).")
65
 
66
  except Exception as e:
67
- logger.error(f"ERRO CRÍTICO AO CARREGAR HERMES GGUF: {e}")
68
  import traceback
69
  logger.error(traceback.format_exc())
70
- cls._llm = None # Garante que não tente de novo
71
  return cls._llm
72
 
73
  @classmethod
74
  def generate(cls, prompt: str, max_tokens: int = 60) -> str:
75
  """
76
- GERA RESPOSTA COM HERMES LOCAL
77
- max_tokens=60 → ~8-12 segundos no CPU free do HF Spaces
78
  """
79
  llm = cls._get_llm()
80
  if llm is None:
81
- raise RuntimeError("HermesLLM não está disponível ou falhou ao carregar")
82
 
83
  try:
84
- logger.info(f"[HERMES LOCAL] Gerando resposta {max_tokens} tokens")
 
 
 
85
  output = llm(
86
- prompt,
87
  max_tokens=max_tokens,
88
  temperature=0.72,
89
  top_p=0.92,
90
- stop=["<|im_end|>", "\n\n", "User:", "Assistant:"],
91
  echo=False,
92
  )
93
  text = output["choices"][0]["text"].strip()
94
- logger.success(f"HERMES RESPONDEU EM ~10s → {len(text)} chars")
 
 
 
 
 
95
  return text
96
 
97
  except Exception as e:
98
- logger.error(f"ERRO NA GERAÇÃO COM HERMES: {e}")
99
  raise
 
 
1
  from llama_cpp import Llama
2
  import os
3
  from loguru import logger
4
  import threading
5
 
6
  # CAMINHOS NO HF SPACES (CORRIGIDOS PARA O AMBIENTE ATUAL)
7
+ FINETUNED_PATH = "/home/user/data/finetuned_phi3" # LoRA angolano
8
  # CORREÇÃO: O Dockerfile baixa para /home/user/models/
9
+ GGUF_FILENAME = "Phi-3-mini-4k-instruct.Q4_K_M.gguf"
10
+ GGUF_PATH = f"/home/user/models/{GGUF_FILENAME}"
11
 
12
+ class Phi3LLM:
13
  _llm = None
14
  _available_checked = False
15
  _is_available = False
16
+ MODEL_ID = "PHI-3 3.8B"
17
+ MODEL_SIZE_RAM_GB = "~7-8GB"
18
 
19
  @classmethod
20
  def is_available(cls) -> bool:
 
26
  cls._is_available = os.path.isfile(GGUF_PATH)
27
  cls._available_checked = True
28
  if cls._is_available:
29
+ logger.info(f"{cls.MODEL_ID} GGUF ENCONTRADO → {GGUF_PATH}")
30
  else:
31
+ logger.warning(f"{cls.MODEL_ID} GGUF NÃO ENCONTRADO! Caminho: {GGUF_PATH}")
32
  logger.warning("AKIRA VAI USAR MISTRAL/GEMINI COMO FALLBACK")
33
  return cls._is_available
34
 
 
36
  def _get_llm(cls):
37
  """
38
  CARREGA O MODELO UMA ÚNICA VEZ → SINGLETON + mlock
39
+ PHI-3 é menor (3.8B)Deve usar menos RAM e ser mais rápido.
40
  """
41
  if cls._llm is None and cls.is_available():
42
  try:
43
+ logger.info(f"CARREGANDO {cls.MODEL_ID} GGUF Q4_K_M → RAM: {cls.MODEL_SIZE_RAM_GB}, CPU MÍNIMA!")
44
  cls._llm = Llama(
45
  model_path=GGUF_PATH,
46
+ n_ctx=4096, # Contexto gigante
47
  n_batch=512, # Batch grande = menos CPU
48
  n_threads=2, # Só 2 threads → CPU em paz!
49
+ n_gpu_layers=0, # Tudo na RAM
50
  use_mlock=True, # Trava na RAM física → nunca swap!
51
  verbose=False,
52
+ n_parts=1, # Carrega tudo de uma vez
53
  seed=-1,
54
  logits_all=True,
55
  )
56
+ logger.success(f"{cls.MODEL_ID} GGUF CARREGADO COM SUCESSO → {cls.MODEL_SIZE_RAM_GB} RAM USADA!")
57
 
58
  # =================================================================
59
+ # TENTA CARREGAR LORA SE EXISTIR (funcionalidade depende da versão llama-cpp-python)
 
60
  # =================================================================
61
  lora_path = os.path.join(FINETUNED_PATH, "lora_leve")
62
  if os.path.isdir(lora_path):
 
65
  logger.info("Usando modelo GGUF base (sem LoRA).")
66
 
67
  except Exception as e:
68
+ logger.error(f"ERRO CRÍTICO AO CARREGAR {cls.MODEL_ID} GGUF: {e}")
69
  import traceback
70
  logger.error(traceback.format_exc())
71
+ cls._llm = None # Garante que não tente de novo
72
  return cls._llm
73
 
74
  @classmethod
75
  def generate(cls, prompt: str, max_tokens: int = 60) -> str:
76
  """
77
+ GERA RESPOSTA COM PHI-3 LOCAL
78
+ max_tokens=60 → Deve ser mais rápido que o Hermes (7B)
79
  """
80
  llm = cls._get_llm()
81
  if llm is None:
82
+ raise RuntimeError(f"{cls.MODEL_ID} não está disponível ou falhou ao carregar")
83
 
84
  try:
85
+ # FORMATO DE CHAT PHI-3: <|user|>PROMPT<|end|><|assistant|>
86
+ formatted_prompt = f"<|user|>\n{prompt}<|end|>\n<|assistant|>"
87
+
88
+ logger.info(f"[{cls.MODEL_ID} LOCAL] Gerando resposta → {max_tokens} tokens")
89
  output = llm(
90
+ formatted_prompt,
91
  max_tokens=max_tokens,
92
  temperature=0.72,
93
  top_p=0.92,
94
+ stop=["<|end|>", "<|assistant|>", "<|user|>", "\n\n"],
95
  echo=False,
96
  )
97
  text = output["choices"][0]["text"].strip()
98
+
99
+ # Limpeza adicional para garantir que não haja tags residuais
100
+ if text.startswith("<|assistant|>"):
101
+ text = text[len("<|assistant|>"):].lstrip()
102
+
103
+ logger.success(f"{cls.MODEL_ID} RESPONDEU → {len(text)} chars")
104
  return text
105
 
106
  except Exception as e:
107
+ logger.error(f"ERRO NA GERAÇÃO COM {cls.MODEL_ID}: {e}")
108
  raise