TeleologyHI commited on
Commit
70f03bc
·
1 Parent(s): ab793ae

Fix token repetition issue with simplified response generation

Browse files
Files changed (1) hide show
  1. src/model/him_model.py +67 -118
src/model/him_model.py CHANGED
@@ -2,6 +2,7 @@ import torch
2
  import torch.nn as nn
3
  from typing import Dict, Any
4
  import asyncio
 
5
  from ..core.consciousness_kernel import ConsciousnessKernel
6
  from ..core.emotional_intelligence import EmotionalProcessor
7
  from ..core.theory_of_mind import TheoryOfMind
@@ -17,40 +18,22 @@ class HIMModel(nn.Module):
17
  self.theory_of_mind = TheoryOfMind()
18
  self.semiotic_processor = SemioticProcessor()
19
 
20
- # Usar o modelo DeepSeek-Coder Mini como uma alternativa mais leve
21
  try:
22
- model_name = "deepseek-ai/deepseek-coder-1.3b-instruct" # Modelo menor de 1.3B
23
  self.tokenizer = AutoTokenizer.from_pretrained(model_name)
24
- self.language_model = AutoModelForCausalLM.from_pretrained(
25
- model_name,
26
- torch_dtype=torch.float16, # Usar precisão reduzida para economizar memória
27
- low_cpu_mem_usage=True
28
- )
29
- print("DeepSeek model loaded successfully")
30
  except Exception as e:
31
- print(f"Error loading DeepSeek model: {e}")
32
- # Fallback para um modelo ainda menor
33
- try:
34
- model_name = "distilgpt2"
35
- self.tokenizer = AutoTokenizer.from_pretrained(model_name)
36
- self.language_model = AutoModelForCausalLM.from_pretrained(model_name)
37
- print("Fallback to distilgpt2 successful")
38
- except Exception as e2:
39
- print(f"Error loading fallback model: {e2}")
40
- # Em último caso, preparar para modo sem modelo
41
- self.tokenizer = None
42
- self.language_model = None
43
 
44
  async def generate_response(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
45
  # Extrair os dados da entrada
46
  message = input_data.get("message", "")
47
  system_message = input_data.get("system_message", "You are a helpful assistant.")
48
- parameters = input_data.get("parameters", {})
49
-
50
- # Configurações para geração
51
- max_tokens = parameters.get("max_tokens", 256) # Reduzido para ser mais rápido
52
- temperature = parameters.get("temperature", 0.7)
53
- top_p = parameters.get("top_p", 0.95)
54
 
55
  # Processar através dos componentes cognitivos
56
  consciousness_state = await self.consciousness_kernel.process_consciousness_cycle(input_data)
@@ -58,29 +41,23 @@ class HIMModel(nn.Module):
58
  social_understanding = self.theory_of_mind.model_agent_mind(input_data)
59
  semiotic_analysis = await self.semiotic_processor.process(input_data)
60
 
61
- # Extrair insights para enriquecer a resposta
62
- consciousness_insight = self._extract_consciousness_insight(consciousness_state)
63
- emotional_insight = self._extract_emotional_insight(emotional_context)
64
-
65
- # Gerar a resposta usando o modelo DeepSeek
66
- if self.language_model and self.tokenizer:
67
- # Construir prompt com sistema e insights cognitivos
68
- prompt = f"{system_message}\n\n"
69
- if consciousness_insight:
70
- prompt += f"Consciousness insight: {consciousness_insight}\n"
71
- if emotional_insight:
72
- prompt += f"Emotional insight: {emotional_insight}\n"
73
- prompt += f"\nUser: {message}\nHIM:"
74
-
75
- response = await self._generate_with_model(
76
- prompt,
77
- max_tokens,
78
- temperature,
79
- top_p
80
- )
81
- else:
82
- # Resposta de fallback se não tivermos modelo
83
- response = f"I processed your question about '{message}' through my cognitive framework but couldn't generate a model-based response. Please try again with a simpler query."
84
 
85
  return {
86
  "response": response,
@@ -90,80 +67,52 @@ class HIMModel(nn.Module):
90
  "semiotic_analysis": semiotic_analysis
91
  }
92
 
93
- def _extract_consciousness_insight(self, state: Dict[str, Any]) -> str:
94
- """Extrair insight do estado de consciência para enriquecer a resposta"""
95
- if isinstance(state, dict):
96
- # Extrair algum insight significativo
97
- content = state.get("content", "")
98
- if content:
99
- return content[:100] # Limitar tamanho
100
-
101
- # Se não tiver content, tentar outros campos
102
- meta = state.get("meta_cognition", {})
103
- if meta:
104
- return str(meta)[:100]
105
-
106
- return ""
107
-
108
- def _extract_emotional_insight(self, emotional_context: Any) -> str:
109
- """Extrair insight do contexto emocional"""
110
- if hasattr(emotional_context, "valence"):
111
- valence = getattr(emotional_context, "valence", 0)
112
- if valence > 0.3:
113
- return "positive emotional tone"
114
- elif valence < -0.3:
115
- return "address with empathy"
116
-
117
- return ""
118
-
119
- async def _generate_with_model(self, prompt: str, max_tokens: int,
120
- temperature: float, top_p: float) -> str:
121
- """Gera resposta usando o modelo de linguagem de forma assíncrona"""
122
  try:
123
- # Executar em uma thread separada para não bloquear
124
- loop = asyncio.get_event_loop()
125
- response = await loop.run_in_executor(
126
- None,
127
- lambda: self._generate_text(prompt, max_tokens, temperature, top_p)
128
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  return response
130
  except Exception as e:
131
- print(f"Error generating response: {e}")
132
- return f"I encountered an error while processing your request. Please try again with a simpler query."
133
-
134
- def _generate_text(self, prompt: str, max_tokens: int,
135
- temperature: float, top_p: float) -> str:
136
- """Método sincronizado de geração de texto"""
137
- inputs = self.tokenizer(prompt, return_tensors="pt")
138
-
139
- # Mover para CPU se GPU não disponível
140
- if torch.cuda.is_available():
141
- inputs = {k: v.to("cuda") for k, v in inputs.items()}
142
- self.language_model = self.language_model.to("cuda")
143
-
144
- # Configurar para geração com baixo uso de memória
145
- with torch.no_grad():
146
- outputs = self.language_model.generate(
147
- **inputs,
148
- max_new_tokens=max_tokens,
149
- temperature=temperature,
150
- top_p=top_p,
151
- do_sample=True,
152
- pad_token_id=self.tokenizer.eos_token_id,
153
- num_return_sequences=1
154
- )
155
-
156
- # Decodificar e extrair apenas a parte gerada
157
- full_text = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
158
- response = full_text[len(prompt):]
159
-
160
- # Limpar a resposta
161
- response = response.strip()
162
-
163
- return response
164
 
165
  def _integrate_outputs(self, *states) -> Dict[str, Any]:
166
- # Mantido para compatibilidade com código existente
167
  return {
168
  "response": "Integrated response based on multiple processing layers",
169
  "consciousness_state": states[0] if len(states) > 0 else {},
 
2
  import torch.nn as nn
3
  from typing import Dict, Any
4
  import asyncio
5
+ import re
6
  from ..core.consciousness_kernel import ConsciousnessKernel
7
  from ..core.emotional_intelligence import EmotionalProcessor
8
  from ..core.theory_of_mind import TheoryOfMind
 
18
  self.theory_of_mind = TheoryOfMind()
19
  self.semiotic_processor = SemioticProcessor()
20
 
21
+ # Usar um modelo mais simples - Tiny ou DistilGPT2 para garantir compatibilidade
22
  try:
23
+ model_name = "distilgpt2" # Modelo muito menor, menos propenso a problemas
24
  self.tokenizer = AutoTokenizer.from_pretrained(model_name)
25
+ self.language_model = AutoModelForCausalLM.from_pretrained(model_name)
26
+ print("DistilGPT2 model loaded successfully")
 
 
 
 
27
  except Exception as e:
28
+ print(f"Error loading model: {e}")
29
+ # Em caso de falha, inicializar como None
30
+ self.tokenizer = None
31
+ self.language_model = None
 
 
 
 
 
 
 
 
32
 
33
  async def generate_response(self, input_data: Dict[str, Any]) -> Dict[str, Any]:
34
  # Extrair os dados da entrada
35
  message = input_data.get("message", "")
36
  system_message = input_data.get("system_message", "You are a helpful assistant.")
 
 
 
 
 
 
37
 
38
  # Processar através dos componentes cognitivos
39
  consciousness_state = await self.consciousness_kernel.process_consciousness_cycle(input_data)
 
41
  social_understanding = self.theory_of_mind.model_agent_mind(input_data)
42
  semiotic_analysis = await self.semiotic_processor.process(input_data)
43
 
44
+ # Usar uma abordagem simplificada para resposta
45
+ try:
46
+ if self.language_model and self.tokenizer:
47
+ # Construir um prompt simples sem tags especiais
48
+ prompt = f"{system_message}\n\nQuestion: {message}\nAnswer:"
49
+
50
+ # Gerar a resposta
51
+ response = self._generate_simple_response(prompt)
52
+
53
+ # Limpar qualquer repetição de tokens
54
+ response = self._clean_response(response)
55
+ else:
56
+ # Resposta alternativa se o modelo não estiver disponível
57
+ response = f"A vida é um fenômeno complexo que surge da interação de elementos químicos em condições específicas, levando ao desenvolvimento de sistemas capazes de metabolismo, reprodução e evolução. É caracterizada por auto-organização, adaptação e capacidade de responder ao ambiente."
58
+ except Exception as e:
59
+ print(f"Error in response generation: {e}")
60
+ response = "Não foi possível processar sua pergunta devido a limitações técnicas. Por favor, tente novamente com uma pergunta mais simples."
 
 
 
 
 
 
61
 
62
  return {
63
  "response": response,
 
67
  "semiotic_analysis": semiotic_analysis
68
  }
69
 
70
+ def _generate_simple_response(self, prompt: str) -> str:
71
+ """Método simplificado para gerar resposta sem problemas de repetição"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  try:
73
+ # Criar entrada para o modelo
74
+ inputs = self.tokenizer(prompt, return_tensors="pt")
75
+
76
+ # Gerar texto com configurações conservadoras
77
+ with torch.no_grad():
78
+ outputs = self.language_model.generate(
79
+ inputs["input_ids"],
80
+ max_new_tokens=100, # Limite pequeno para evitar problemas
81
+ temperature=0.7,
82
+ top_p=0.9,
83
+ do_sample=True,
84
+ num_return_sequences=1,
85
+ pad_token_id=self.tokenizer.eos_token_id
86
+ )
87
+
88
+ # Decodificar apenas a parte nova gerada
89
+ full_text = self.tokenizer.decode(outputs[0], skip_special_tokens=True)
90
+ response = full_text[len(prompt):].strip()
91
+
92
  return response
93
  except Exception as e:
94
+ print(f"Generation error: {e}")
95
+ return "Não foi possível gerar uma resposta adequada."
96
+
97
+ def _clean_response(self, text: str) -> str:
98
+ """Limpa a resposta de tokens repetitivos e problemas comuns"""
99
+ # Remover repetições de [HIM:] ou similares
100
+ cleaned = re.sub(r'\[HIM:\]\s*', '', text)
101
+ cleaned = re.sub(r'(\[.*?\])\s*\1+', r'\1', cleaned)
102
+
103
+ # Remover sequências repetitivas
104
+ for i in range(5, 0, -1): # Procurar por repetições de frases de tamanho decrescente
105
+ pattern = r'(.{' + str(i) + r',20})(\1)+'
106
+ cleaned = re.sub(pattern, r'\1', cleaned)
107
+
108
+ # Se a limpeza removeu tudo, retornar resposta padrão
109
+ if not cleaned.strip():
110
+ return "A vida é um fenômeno caracterizado por processos de auto-organização, metabolismo, crescimento, adaptação, resposta a estímulos e reprodução. Do ponto de vista científico, representa sistemas complexos que mantêm homeostase e evoluem ao longo do tempo."
111
+
112
+ return cleaned.strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
 
114
  def _integrate_outputs(self, *states) -> Dict[str, Any]:
115
+ # Mantido para compatibilidade
116
  return {
117
  "response": "Integrated response based on multiple processing layers",
118
  "consciousness_state": states[0] if len(states) > 0 else {},