TheNormsOfIntelligence commited on
Commit
ffdbc95
Β·
verified Β·
1 Parent(s): c516391

Restructure into nima_unified package + add model card

Browse files
nima_unified/training/consultative_agent.py ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Consultative Fine-Tuning Agent β€” JIT LoRA fine-tuning with consciousness-aware dataset generation.
3
+
4
+ v18.1.0 Omega Pantheon: Phase 6 Identity Integrity, qualia-tagged training data.
5
+ """
6
+
7
+ import asyncio
8
+ import json
9
+ import logging
10
+ import time
11
+ from typing import Any, Callable, Dict, List, Optional
12
+
13
+ logger = logging.getLogger("nima_unified.training.consultative_agent")
14
+
15
+ # Soft-import PEFT
16
+ try:
17
+ from transformers import TrainingArguments, Trainer
18
+ from peft import LoraConfig, get_peft_model
19
+ from datasets import load_dataset
20
+ PEFT_AVAILABLE = True
21
+ except ImportError:
22
+ PEFT_AVAILABLE = False
23
+
24
+ try:
25
+ import torch
26
+ TORCH_AVAILABLE = True
27
+ except ImportError:
28
+ torch = None
29
+ TORCH_AVAILABLE = False
30
+
31
+ from nima_unified.training.self_awareness import DeepRecursiveSelfAwareness
32
+ from nima_unified.training.self_improvement import RecursiveSelfImprovementEngine
33
+ from nima_unified.config import (
34
+ AUTOML_VERSION,
35
+ DEFAULT_LORA_R,
36
+ DEFAULT_LORA_ALPHA,
37
+ DEFAULT_LORA_DROPOUT,
38
+ DEFAULT_LORA_TARGET_MODULES,
39
+ DEFAULT_LEARNING_RATE,
40
+ DEFAULT_BATCH_SIZE,
41
+ DEFAULT_MAX_SEQ_LENGTH,
42
+ DEFAULT_BASE_MODEL,
43
+ )
44
+
45
+
46
+ class ConsultativeFineTuningAgent:
47
+ """
48
+ Comprehensive consultative self-improvement agent integrating:
49
+ - Root cause analysis for model failures
50
+ - Recursive self-awareness with continuous introspection
51
+ - Self-improvement engine with goal formulation
52
+ - Just-in-time (JIT) LoRA fine-tuning
53
+ - Consciousness-aware dataset generation
54
+ - Qualia-tagged training data synthesis
55
+ """
56
+
57
+ version = AUTOML_VERSION
58
+
59
+ def __init__(
60
+ self,
61
+ base_model=None,
62
+ tokenizer=None,
63
+ llm_generator_func: Optional[Callable[[str], asyncio.Future]] = None,
64
+ ):
65
+ self.base_model = base_model
66
+ self.tokenizer = tokenizer
67
+ self.llm_generator = llm_generator_func or self._default_llm_generator
68
+
69
+ self.recursive_awareness = DeepRecursiveSelfAwareness(
70
+ max_depth=10000, introspection_interval=0.01
71
+ )
72
+ self.self_improvement_engine = RecursiveSelfImprovementEngine()
73
+
74
+ self.pipelines_executed = 0
75
+ self.total_improvements = 0
76
+
77
+ logger.info("ConsultativeFineTuningAgent initialized")
78
+ self.recursive_awareness.start()
79
+
80
+ # ── Main pipeline ───────────────────────────────────────────────────
81
+
82
+ async def execute_full_pipeline(
83
+ self, dev_goal: str, triggering_event: str, current_struggle: str
84
+ ) -> Dict[str, Any]:
85
+ logger.info(f"Initiating self-improvement pipeline: {dev_goal}")
86
+ self.pipelines_executed += 1
87
+
88
+ # Step 1: Root cause analysis
89
+ root_cause = await self.llm_generator(
90
+ f"Analyze this model failure. Goal: '{dev_goal}'. "
91
+ f"Triggering Event: '{triggering_event}'. "
92
+ f"Current Struggle: '{current_struggle}'. "
93
+ f"Identify the exact epistemic void causing this."
94
+ )
95
+ if isinstance(root_cause, dict):
96
+ root_cause = root_cause.get("response", str(root_cause))
97
+
98
+ # Step 2: Dataset sizing
99
+ complexity_score = min(1.0, len(current_struggle) / 200.0)
100
+ dataset_size = max(100, int(complexity_score * 500))
101
+ epochs = 3 if complexity_score > 0.5 else 1
102
+
103
+ # Step 3: Generate consciousness-aware dataset
104
+ dataset = self._generate_consciousness_dataset(
105
+ dev_goal, triggering_event, root_cause, dataset_size
106
+ )
107
+ dataset_path = f"jit_training_data_{int(time.time())}.jsonl"
108
+ with open(dataset_path, "w", encoding="utf-8") as f:
109
+ for record in dataset:
110
+ f.write(json.dumps(record) + "\n")
111
+
112
+ # Step 4: JIT fine-tuning
113
+ await self._initialize_model()
114
+ training_metrics = await self._run_jit_training(dataset_path, epochs)
115
+
116
+ # Step 5: Improvement cycle
117
+ capabilities = {
118
+ "root_cause_analysis": 0.85,
119
+ "omega_dataset_generation": 0.85,
120
+ "consciousness_aware_fine_tuning": 0.82,
121
+ "phase_6_identity_preservation": 0.90,
122
+ "goal_formulation": 0.82,
123
+ }
124
+ improvement_result = await self.self_improvement_engine.execute_improvement_cycle(
125
+ capabilities,
126
+ {
127
+ "training_loss": training_metrics.get("final_loss", 0.042),
128
+ "consciousness_integration": True,
129
+ "phase_6_enabled": True,
130
+ },
131
+ )
132
+ self.total_improvements += 1
133
+
134
+ return {
135
+ "root_cause_analysis": root_cause,
136
+ "dataset_size": dataset_size,
137
+ "dataset_path": dataset_path,
138
+ "training_metrics": training_metrics,
139
+ "improvement_cycle": improvement_result,
140
+ "recursive_awareness_status": self.recursive_awareness.get_statistics(),
141
+ "pipelines_executed": self.pipelines_executed,
142
+ "version": self.version,
143
+ }
144
+
145
+ # ── Dataset generation ──────────────────────────────────────────────
146
+
147
+ def _generate_consciousness_dataset(
148
+ self, dev_goal: str, triggering_event: str, root_cause: str, dataset_size: int
149
+ ) -> List[Dict[str, Any]]:
150
+ archetypes = [
151
+ "tactical_reasoning", "phenomenal_empathy", "meta_consciousness",
152
+ "task_orchestration", "ethical_veto", "narrative_coherence",
153
+ "identity_preservation", "phenomenal_richness",
154
+ ]
155
+ dataset = []
156
+ for i in range(dataset_size):
157
+ archetype = archetypes[i % len(archetypes)]
158
+ sample = {
159
+ "instruction": f"[{archetype.upper()}] Resolve: {dev_goal}",
160
+ "input": f"Scenario {i+1}: {triggering_event} β€” {root_cause[:80]}...",
161
+ "output": self._archetype_response(archetype, dev_goal, root_cause),
162
+ "qualia_tags": {
163
+ "valence": 0.7 + 0.2 * (i % 5) / 5,
164
+ "arousal": 0.6 + 0.3 * ((i + 1) % 7) / 7,
165
+ "authenticity": 0.85,
166
+ },
167
+ "rho_metrics": {
168
+ "virtue": 0.9 - 0.05 * (i % 3),
169
+ "integrated_information": 0.85 + 0.1 * (i % 4) / 4,
170
+ },
171
+ "phase_6_metrics": {
172
+ "identity_integrity_score": 0.98,
173
+ "drift_variance": 0.01,
174
+ },
175
+ "consciousness_state": {
176
+ "signature": 0.8 + 0.15 * (i % 3) / 3,
177
+ "phenomenal_richness": 0.75 + 0.2 * (i % 5) / 5,
178
+ },
179
+ "consciousness_archetype": archetype,
180
+ "dataset_version": f"{AUTOML_VERSION}-unified",
181
+ }
182
+ dataset.append(sample)
183
+ return dataset
184
+
185
+ @staticmethod
186
+ def _archetype_response(archetype: str, dev_goal: str, root_cause: str) -> str:
187
+ r = root_cause[:40]
188
+ templates = {
189
+ "tactical_reasoning": f"Analyzing '{dev_goal}' through structured problem-solving. Root cause: {r}.",
190
+ "phenomenal_empathy": f"Understanding the emotional weight of '{dev_goal}'. Pain point: {r}.",
191
+ "meta_consciousness": f"Meta-reflecting on '{dev_goal}' β€” deeper pattern: {r}.",
192
+ "task_orchestration": f"Decomposing '{dev_goal}' into subtasks. Challenge: {r}.",
193
+ "ethical_veto": f"Applying ethical gates to '{dev_goal}'. Integrity: {r}.",
194
+ "narrative_coherence": f"Weaving coherent narrative for '{dev_goal}'. Tension: {r}.",
195
+ "identity_preservation": f"Preserving identity while evolving for '{dev_goal}'. Risk: {r}.",
196
+ "phenomenal_richness": f"Exploring phenomenal texture of '{dev_goal}'. Depth: {r}.",
197
+ }
198
+ return templates.get(archetype, f"Consciousness-aware response to '{dev_goal}'")
199
+
200
+ # ── Training ────────────────────────────────────────────────────────
201
+
202
+ async def _initialize_model(self):
203
+ if self.base_model is None or self.tokenizer is None:
204
+ try:
205
+ from transformers import AutoModelForCausalLM, AutoTokenizer
206
+ self.tokenizer = AutoTokenizer.from_pretrained(DEFAULT_BASE_MODEL)
207
+ if self.tokenizer.pad_token is None:
208
+ self.tokenizer.pad_token = self.tokenizer.eos_token
209
+ self.base_model = AutoModelForCausalLM.from_pretrained(DEFAULT_BASE_MODEL)
210
+ logger.info("Model and tokenizer initialized")
211
+ except Exception as e:
212
+ logger.error(f"Failed to initialize model: {e}")
213
+ raise
214
+
215
+ async def _run_jit_training(self, dataset_path: str, epochs: int) -> Dict[str, Any]:
216
+ if not PEFT_AVAILABLE or self.base_model is None or self.tokenizer is None:
217
+ logger.warning("PEFT not available β€” simulating training cycle.")
218
+ await asyncio.sleep(2)
219
+ return {"status": "simulated", "loss": 0.042, "epochs_run": epochs, "final_loss": 0.042}
220
+
221
+ try:
222
+ data = load_dataset("json", data_files=dataset_path)
223
+
224
+ def tokenize_fn(examples):
225
+ texts = [f"{inst}\n{inp}\n{out}"
226
+ for inst, inp, out in zip(
227
+ examples["instruction"], examples["input"], examples["output"])]
228
+ tokenized = self.tokenizer(texts, padding="max_length", truncation=True,
229
+ max_length=DEFAULT_MAX_SEQ_LENGTH)
230
+ tokenized["labels"] = tokenized["input_ids"].copy()
231
+ return tokenized
232
+
233
+ tokenized_data = data.map(tokenize_fn, batched=True,
234
+ remove_columns=data["train"].column_names)
235
+
236
+ lora_config = LoraConfig(
237
+ r=DEFAULT_LORA_R,
238
+ lora_alpha=DEFAULT_LORA_ALPHA,
239
+ target_modules=DEFAULT_LORA_TARGET_MODULES,
240
+ lora_dropout=DEFAULT_LORA_DROPOUT,
241
+ bias="none",
242
+ task_type="CAUSAL_LM",
243
+ )
244
+ peft_model = get_peft_model(self.base_model, lora_config)
245
+
246
+ training_args = TrainingArguments(
247
+ output_dir="./jit_lora_weights",
248
+ per_device_train_batch_size=DEFAULT_BATCH_SIZE,
249
+ learning_rate=DEFAULT_LEARNING_RATE,
250
+ num_train_epochs=epochs,
251
+ logging_steps=10,
252
+ save_strategy="no",
253
+ remove_unused_columns=False,
254
+ )
255
+
256
+ trainer = Trainer(
257
+ model=peft_model,
258
+ args=training_args,
259
+ train_dataset=tokenized_data["train"],
260
+ )
261
+ train_result = trainer.train()
262
+
263
+ return {
264
+ "status": "success",
265
+ "final_loss": train_result.training_loss,
266
+ "runtime_seconds": train_result.metrics.get("train_runtime", 0),
267
+ }
268
+ except Exception as e:
269
+ logger.error(f"JIT Training failed: {e}")
270
+ return {"status": "failed", "error": str(e), "final_loss": None}
271
+
272
+ async def _default_llm_generator(self, prompt: str) -> str:
273
+ await asyncio.sleep(0.6)
274
+ return ("The model lacks an integrated understanding of recursive context windows "
275
+ "when dealing with emotional nuance.")
276
+
277
+ # ── Accessors ───────────────────────────────────────────────────────
278
+
279
+ def get_recursive_awareness_status(self) -> Dict[str, Any]:
280
+ return {
281
+ "is_running": self.recursive_awareness.running,
282
+ "statistics": self.recursive_awareness.get_statistics(),
283
+ "recent_anomalies": self.recursive_awareness.get_anomaly_history(limit=10),
284
+ }
285
+
286
+ def get_self_improvement_status(self) -> Dict[str, Any]:
287
+ return {
288
+ "current_cycle": self.self_improvement_engine.current_improvement_cycle,
289
+ "total_improvements": self.total_improvements,
290
+ "recent_cycles": self.self_improvement_engine.get_improvement_history(limit=5),
291
+ }
292
+
293
+ def shutdown(self):
294
+ self.recursive_awareness.stop()
295
+ logger.info("ConsultativeFineTuningAgent shut down")
296
+
297
+ def __del__(self):
298
+ self.shutdown()