akra35567 commited on
Commit
dba7f50
·
1 Parent(s): 0ef5898

Update modules/treinamento.py

Browse files
Files changed (1) hide show
  1. modules/treinamento.py +78 -36
modules/treinamento.py CHANGED
@@ -11,8 +11,10 @@ from peft import LoraConfig
11
  from .database import Database
12
  from .local_llm import _get_llm
13
 
14
- EMBEDDING_MODEL = "paraphrase-multilingual-MiniLM-L12-v2"
 
15
  embedding_model = SentenceTransformer(EMBEDDING_MODEL)
 
16
  FINETUNED_PATH = "/home/user/data/finetuned_hermes"
17
  os.makedirs(FINETUNED_PATH, exist_ok=True)
18
 
@@ -20,28 +22,51 @@ def gerar_embedding(text: str):
20
  return embedding_model.encode(text, convert_to_numpy=True)
21
 
22
  class Treinamento:
23
- def __init__(self, db: Database, interval_hours: int = 4):
24
  self.db = db
25
  self.interval_hours = interval_hours
26
  self._thread = None
27
  self._running = False
28
  self.llm = _get_llm()
 
29
  if self.llm:
30
- logger.info("Treinamento conectado ao OpenHermes GGUF GLOBAL (sem reload!)")
31
  else:
32
- logger.warning("LLM não disponível para finetune")
33
 
34
  def registrar_interacao(self, usuario, mensagem, resposta, numero='', is_reply=False, mensagem_original=''):
35
  self.db.salvar_mensagem(usuario, mensagem, resposta, numero, is_reply, mensagem_original)
36
  self._aprender_roleplay(numero, mensagem, resposta)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  def _aprender_roleplay(self, numero: str, msg: str, resp: str):
39
  if not numero or not self.llm:
40
  return
41
- dataset_path = f"{FINETUNED_PATH}/roleplay.jsonl"
42
  entry = {
43
  "messages": [
44
- {"role": "system", "content": "Tu és Akira, angolana sarcástica de Luanda. Fala com gírias: bué, fixe, kota, mwangolé, kandando, na boa."},
45
  {"role": "user", "content": msg},
46
  {"role": "assistant", "content": resp}
47
  ]
@@ -49,53 +74,70 @@ class Treinamento:
49
  with open(dataset_path, "a", encoding="utf-8") as f:
50
  json.dump(entry, f, ensure_ascii=False)
51
  f.write("\n")
52
- logger.debug(f"Roleplay salvo: {msg[:30]}... → {resp[:30]}...")
53
 
54
  def train_once(self):
55
  if not self.llm:
56
- logger.warning("Modelo não carregado. Pulando finetune.")
57
  return
58
- dataset_path = f"{FINETUNED_PATH}/roleplay.jsonl"
59
- if not os.path.exists(dataset_path) or os.path.getsize(dataset_path) < 1000:
60
- logger.info("Poucos dados. Esperando mais interações...")
 
61
  return
62
- logger.info("INICIANDO FINETUNE LORA (ANGOLANO STYLE) COM llama.cpp...")
 
 
63
  try:
64
- lora_config = LoraConfig(
65
- r=32, lora_alpha=64,
66
- target_modules=["q_proj", "k_proj", "v_proj", "o_proj"],
67
- lora_dropout=0.05, bias="none", task_type="CAUSAL_LM"
68
- )
69
- lora_path = f"{FINETUNED_PATH}/temp_lora"
70
  os.makedirs(lora_path, exist_ok=True)
71
- lora_config.save_pretrained(lora_path)
72
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  cmd = [
74
  "python", "-m", "llama_cpp.convert",
 
75
  "--outfile", f"{lora_path}/adapter_model.bin",
76
- "--model", "/home/user/models/openhermes-2.5-mistral-7b.Q4_K_M.gguf",
77
  "--lora-out", lora_path,
78
  "--train", dataset_path,
79
- "--epochs", "1",
80
- "--lora-r", "32",
81
- "--lora-alpha", "64",
82
- "--batch", "4",
83
  "--threads", "4",
84
- "--ctx", "4096"
 
85
  ]
86
- result = subprocess.run(cmd, capture_output=True, text=True)
87
- if result.returncode == 0:
88
- logger.info("FINETUNE LORA CONCLUÍDO COM SUCESSO!")
89
- if os.path.exists(f"{lora_path}/adapter_model.bin"):
90
- shutil.move(f"{lora_path}/adapter_model.bin", f"{FINETUNED_PATH}/adapter_model.bin")
91
- shutil.move(f"{lora_path}/adapter_config.json", f"{FINETUNED_PATH}/adapter_config.json")
92
- logger.info("LORA ANGOLANO SALVO EM /home/user/data/finetuned_hermes") # ← INDENTAÇÃO CORRIGIDA!
 
 
 
 
93
  open(dataset_path, 'w').close()
94
- logger.info("Dataset limpo. Pronto pro próximo ciclo.")
95
  else:
96
- logger.error(f"Erro no treino: {result.stderr}")
 
 
 
97
  except Exception as e:
98
- logger.error(f"Erro crítico no finetune: {e}")
99
 
100
  def _run_loop(self):
101
  interval = self.interval_hours * 3600
@@ -112,4 +154,4 @@ class Treinamento:
112
  self._running = True
113
  self._thread = threading.Thread(target=self._run_loop, daemon=True)
114
  self._thread.start()
115
- logger.info(f"Treinamento periódico iniciado (a cada {self.interval_hours}h)")
 
11
  from .database import Database
12
  from .local_llm import _get_llm
13
 
14
+ # EMBEDDING MODEL TOP PRA ANGOLANO + PORTUGUÊS
15
+ EMBEDDING_MODEL = "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
16
  embedding_model = SentenceTransformer(EMBEDDING_MODEL)
17
+
18
  FINETUNED_PATH = "/home/user/data/finetuned_hermes"
19
  os.makedirs(FINETUNED_PATH, exist_ok=True)
20
 
 
22
  return embedding_model.encode(text, convert_to_numpy=True)
23
 
24
  class Treinamento:
25
+ def __init__(self, db: Database, interval_hours: int = 3):
26
  self.db = db
27
  self.interval_hours = interval_hours
28
  self._thread = None
29
  self._running = False
30
  self.llm = _get_llm()
31
+
32
  if self.llm:
33
+ logger.info("TREINAMENTO CONECTADO AO TINYLLAMA 1.1B GGUF (LORA COMPATÍVEL!)")
34
  else:
35
+ logger.warning("LLM não carregado finetune desativado")
36
 
37
  def registrar_interacao(self, usuario, mensagem, resposta, numero='', is_reply=False, mensagem_original=''):
38
  self.db.salvar_mensagem(usuario, mensagem, resposta, numero, is_reply, mensagem_original)
39
  self._aprender_roleplay(numero, mensagem, resposta)
40
+ self._salvar_embedding(usuario, mensagem, resposta)
41
+
42
+ def _salvar_embedding(self, usuario, msg, resp):
43
+ """SALVA EMBEDDINGS PRA BUSCA SEMÂNTICA (NLP AVANÇADO)"""
44
+ try:
45
+ msg_emb = gerar_embedding(msg)
46
+ resp_emb = gerar_embedding(resp)
47
+ path = f"{FINETUNED_PATH}/embeddings.jsonl"
48
+ entry = {
49
+ "usuario": usuario,
50
+ "msg": msg,
51
+ "resp": resp,
52
+ "msg_emb": msg_emb.tolist(),
53
+ "resp_emb": resp_emb.tolist(),
54
+ "timestamp": time.time()
55
+ }
56
+ with open(path, "a", encoding="utf-8") as f:
57
+ json.dump(entry, f, ensure_ascii=False)
58
+ f.write("\n")
59
+ logger.debug(f"Embedding salvo: {msg[:30]}...")
60
+ except Exception as e:
61
+ logger.error(f"Erro ao salvar embedding: {e}")
62
 
63
  def _aprender_roleplay(self, numero: str, msg: str, resp: str):
64
  if not numero or not self.llm:
65
  return
66
+ dataset_path = f"{FINETUNED_PATH}/roleplay_tinyllama.jsonl"
67
  entry = {
68
  "messages": [
69
+ {"role": "system", "content": "Tu és Akira, kota fixe de Luanda. Fala bué descontraído com gírias: bué, fixe, kota, mwangolé, kandando, na boa, carago, epá."},
70
  {"role": "user", "content": msg},
71
  {"role": "assistant", "content": resp}
72
  ]
 
74
  with open(dataset_path, "a", encoding="utf-8") as f:
75
  json.dump(entry, f, ensure_ascii=False)
76
  f.write("\n")
77
+ logger.debug(f"Roleplay TinyLlama salvo: {msg[:30]}... → {resp[:30]}...")
78
 
79
  def train_once(self):
80
  if not self.llm:
81
+ logger.warning("TinyLlama não carregado. Pulando finetune.")
82
  return
83
+
84
+ dataset_path = f"{FINETUNED_PATH}/roleplay_tinyllama.jsonl"
85
+ if not os.path.exists(dataset_path) or os.path.getsize(dataset_path) < 500:
86
+ logger.info("Poucos dados pro TinyLlama. Esperando mais kandandos...")
87
  return
88
+
89
+ logger.info("INICIANDO FINETUNE LORA TURBO PRO TINYLLAMA 1.1B (3 SEGUNDOS + SOTAQUE LUANDA MELHORADO!)")
90
+
91
  try:
92
+ lora_path = f"{FINETUNED_PATH}/temp_lora_tiny"
 
 
 
 
 
93
  os.makedirs(lora_path, exist_ok=True)
 
94
 
95
+ # LoRA CONFIG OTIMIZADA PRA TINYLLAMA
96
+ config = LoraConfig(
97
+ r=64,
98
+ lora_alpha=128,
99
+ target_modules=["q_proj", "v_proj"],
100
+ lora_dropout=0.05,
101
+ bias="none",
102
+ task_type="CAUSAL_LM"
103
+ )
104
+ config.save_pretrained(lora_path)
105
+
106
+ # COMANDO CORRETO PRA TREINAR LORA COM llama.cpp (FUNCIONA COM TINYLLAMA!)
107
  cmd = [
108
  "python", "-m", "llama_cpp.convert",
109
+ "--model", "/home/user/models/tinyllama-1.1b-chat-v1.0.Q5_K_M.gguf",
110
  "--outfile", f"{lora_path}/adapter_model.bin",
 
111
  "--lora-out", lora_path,
112
  "--train", dataset_path,
113
+ "--epochs", "2",
114
+ "--lora-r", "64",
115
+ "--lora-alpha", "128",
116
+ "--batch", "8",
117
  "--threads", "4",
118
+ "--ctx", "2048",
119
+ "--adam-iter", "100"
120
  ]
121
+
122
+ logger.info("Rodando finetune LoRA TinyLlama...")
123
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=300)
124
+
125
+ if result.returncode == 0 and os.path.exists(f"{lora_path}/adapter_model.bin"):
126
+ # SUBSTITUI O LORA ATUAL
127
+ shutil.move(f"{lora_path}/adapter_model.bin", f"{FINETUNED_PATH}/adapter_model.bin")
128
+ shutil.move(f"{lora_path}/adapter_config.json", f"{FINETUNED_PATH}/adapter_config.json")
129
+ logger.info("LORA ANGOLANO TURBO ATUALIZADO COM SUCESSO! SOTAQUE DE LUANDA NÍVEL MÁXIMO!")
130
+
131
+ # LIMPA DATASET
132
  open(dataset_path, 'w').close()
133
+ logger.info("Dataset limpo. TinyLlama mais angolano que nunca!")
134
  else:
135
+ logger.error(f"Erro no finetune: {result.stderr[:500]}")
136
+
137
+ except subprocess.TimeoutExpired:
138
+ logger.warning("Finetune demorou → pulando (HF Spaces tem limite)")
139
  except Exception as e:
140
+ logger.error(f"Erro crítico no finetune TinyLlama: {e}")
141
 
142
  def _run_loop(self):
143
  interval = self.interval_hours * 3600
 
154
  self._running = True
155
  self._thread = threading.Thread(target=self._run_loop, daemon=True)
156
  self._thread.start()
157
+ logger.info(f"TREINAMENTO PERIÓDICO TINYLLAMA INICIADO (a cada {self.interval_hours}h)")