Upload 9 files
Browse files- agent.py +0 -0
- aitech.py +254 -0
- aitech_log.txt +0 -0
- data.py +353 -0
- exploler.py +48 -0
- general_reasoning.py +761 -0
- maintainer.py +40 -0
- neural_pipeline.py +445 -0
- transformer.py +247 -0
agent.py
ADDED
|
File without changes
|
aitech.py
ADDED
|
@@ -0,0 +1,254 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import datetime
|
| 3 |
+
import time
|
| 4 |
+
import json
|
| 5 |
+
from openai import OpenAI
|
| 6 |
+
from exploler import scrape_page, scrape_topic_and_save
|
| 7 |
+
import ast
|
| 8 |
+
import difflib
|
| 9 |
+
|
| 10 |
+
MODEL_NAME = "meta-llama/Llama-3.3-70B-Instruct-Turbo-Free"
|
| 11 |
+
AGENT_FILENAME = "agent.py"
|
| 12 |
+
VERSION_DIR = "agent_versions"
|
| 13 |
+
LOG_FILE = "agent_log.txt"
|
| 14 |
+
REWARD_LOG_FILE = "reward_log.txt"
|
| 15 |
+
|
| 16 |
+
os.makedirs(VERSION_DIR, exist_ok=True)
|
| 17 |
+
|
| 18 |
+
client = OpenAI(
|
| 19 |
+
base_url="https://api.together.ai/",
|
| 20 |
+
api_key="afc478b561fbd2629f96f8f69041d780f3b9a94adcfe276f30818ee84a5e0358"
|
| 21 |
+
)
|
| 22 |
+
|
| 23 |
+
def log(event):
|
| 24 |
+
with open(LOG_FILE, "a", encoding="utf-8") as f:
|
| 25 |
+
f.write(f"[{datetime.datetime.now()}] {event}\n")
|
| 26 |
+
|
| 27 |
+
def read_self():
|
| 28 |
+
with open(AGENT_FILENAME, "r", encoding="utf-8") as f:
|
| 29 |
+
return f.read()
|
| 30 |
+
|
| 31 |
+
def write_new_self(new_code):
|
| 32 |
+
# Backup current code before overwriting
|
| 33 |
+
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 34 |
+
backup_filename = os.path.join(VERSION_DIR, f"backup_{timestamp}.py")
|
| 35 |
+
try:
|
| 36 |
+
with open(AGENT_FILENAME, "r", encoding="utf-8") as f:
|
| 37 |
+
current_code = f.read()
|
| 38 |
+
with open(backup_filename, "w", encoding="utf-8") as f:
|
| 39 |
+
f.write(current_code)
|
| 40 |
+
log(f"BACKUP: Created backup at {backup_filename}")
|
| 41 |
+
except Exception as e:
|
| 42 |
+
log(f"BACKUP: Failed to create backup: {e}")
|
| 43 |
+
# Now overwrite with new code
|
| 44 |
+
with open(AGENT_FILENAME, "w", encoding="utf-8") as f:
|
| 45 |
+
f.write(new_code)
|
| 46 |
+
log("SELF-IMPROVEMENT: Code written to file.")
|
| 47 |
+
|
| 48 |
+
def self_improvement_suggestion(old_code, memory, feedback):
|
| 49 |
+
prompt = f"""
|
| 50 |
+
You are an autonomous, self-improving Python agent.
|
| 51 |
+
Here is your current code:
|
| 52 |
+
{old_code}
|
| 53 |
+
Recent memory: {memory}
|
| 54 |
+
Feedback: {feedback}
|
| 55 |
+
Suggest a specific, safe improvement to your code. Output only the improved code (no explanations).
|
| 56 |
+
"""
|
| 57 |
+
response = client.chat.completions.create(
|
| 58 |
+
model=MODEL_NAME,
|
| 59 |
+
messages=[{"role": "user", "content": prompt}],
|
| 60 |
+
max_tokens=6000,
|
| 61 |
+
temperature=0.7,
|
| 62 |
+
)
|
| 63 |
+
return response.choices[0].message.content.strip()
|
| 64 |
+
|
| 65 |
+
def ensure_core_functions(new_code, old_code):
|
| 66 |
+
import re
|
| 67 |
+
core_funcs = [
|
| 68 |
+
"main",
|
| 69 |
+
"reason_about_task",
|
| 70 |
+
"save_experience",
|
| 71 |
+
"learn_from_experience",
|
| 72 |
+
"set_goals",
|
| 73 |
+
"self_improvement_suggestion",
|
| 74 |
+
"scrape_internet",
|
| 75 |
+
"scrape_url"
|
| 76 |
+
]
|
| 77 |
+
def extract_func(code, name):
|
| 78 |
+
pattern = rf"(def {name}\s*\(.*?\):(?:\n(?:\s+.*\n?)*)?)\n(?=def |\Z)"
|
| 79 |
+
match = re.search(pattern, code, re.DOTALL)
|
| 80 |
+
return match.group(1) if match else None
|
| 81 |
+
for func in core_funcs:
|
| 82 |
+
if f"def {func}(" not in new_code:
|
| 83 |
+
restored = extract_func(old_code, func)
|
| 84 |
+
if restored:
|
| 85 |
+
new_code += f"\n\n{restored}\n"
|
| 86 |
+
return new_code
|
| 87 |
+
|
| 88 |
+
def is_trivial_change(old_code, new_code, threshold=0.98):
|
| 89 |
+
seq = difflib.SequenceMatcher(None, old_code, new_code)
|
| 90 |
+
return seq.ratio() > threshold
|
| 91 |
+
|
| 92 |
+
def rollback_to_backup():
|
| 93 |
+
backups = sorted([f for f in os.listdir(VERSION_DIR) if f.endswith(".py")])
|
| 94 |
+
if not backups:
|
| 95 |
+
log("ROLLBACK: No backup found.")
|
| 96 |
+
return
|
| 97 |
+
last_backup = os.path.join(VERSION_DIR, backups[-1])
|
| 98 |
+
with open(last_backup, "r", encoding="utf-8") as f:
|
| 99 |
+
code = f.read()
|
| 100 |
+
with open(AGENT_FILENAME, "w", encoding="utf-8") as f:
|
| 101 |
+
f.write(code)
|
| 102 |
+
log(f"ROLLBACK: Restored from {last_backup}")
|
| 103 |
+
|
| 104 |
+
# --- Reward System ---
|
| 105 |
+
class RewardSystem:
|
| 106 |
+
def __init__(self, log_file=REWARD_LOG_FILE):
|
| 107 |
+
self.score = 0
|
| 108 |
+
self.log_file = log_file
|
| 109 |
+
self.history = []
|
| 110 |
+
|
| 111 |
+
def reward(self, amount, reason):
|
| 112 |
+
self.score += amount
|
| 113 |
+
self.history.append((datetime.datetime.now(), amount, reason))
|
| 114 |
+
self._log(amount, reason)
|
| 115 |
+
|
| 116 |
+
def penalty(self, amount, reason):
|
| 117 |
+
self.score -= amount
|
| 118 |
+
self.history.append((datetime.datetime.now(), -amount, reason))
|
| 119 |
+
self._log(-amount, reason)
|
| 120 |
+
|
| 121 |
+
def _log(self, amount, reason):
|
| 122 |
+
with open(self.log_file, "a", encoding="utf-8") as f:
|
| 123 |
+
f.write(f"[{datetime.datetime.now()}] {'REWARD' if amount > 0 else 'PENALTY'}: {amount} ({reason}) | Total: {self.score}\n")
|
| 124 |
+
|
| 125 |
+
def get_score(self):
|
| 126 |
+
return self.score
|
| 127 |
+
|
| 128 |
+
def get_history(self):
|
| 129 |
+
return self.history
|
| 130 |
+
|
| 131 |
+
# --- End Reward System ---
|
| 132 |
+
|
| 133 |
+
def performs_task(improved_code):
|
| 134 |
+
"""
|
| 135 |
+
Placeholder: Checks if the improved code performs a task.
|
| 136 |
+
Returns True if there are new function definitions or significant changes.
|
| 137 |
+
You can replace this with more advanced logic or tests.
|
| 138 |
+
"""
|
| 139 |
+
# Check for at least one function definition as a simple heuristic
|
| 140 |
+
return 'def ' in improved_code
|
| 141 |
+
|
| 142 |
+
# --- Internet Scraping (optional, keep if you want scraping support) ---
|
| 143 |
+
def scrape_internet(topic, filename="results.json"):
|
| 144 |
+
log(f"SCRAPE: Scraping topic '{topic}' to file '{filename}'")
|
| 145 |
+
scrape_topic_and_save(topic, filename)
|
| 146 |
+
log(f"SCRAPE: Completed scraping topic '{topic}'")
|
| 147 |
+
|
| 148 |
+
def scrape_url(url):
|
| 149 |
+
log(f"SCRAPE: Scraping URL '{url}'")
|
| 150 |
+
content = scrape_page(url)
|
| 151 |
+
log(f"SCRAPE: Completed scraping URL '{url}'")
|
| 152 |
+
return content
|
| 153 |
+
|
| 154 |
+
def describe_code_change(old_code, new_code):
|
| 155 |
+
"""
|
| 156 |
+
Uses the AI model to describe what changed between old_code and new_code.
|
| 157 |
+
"""
|
| 158 |
+
prompt = f"""
|
| 159 |
+
You are an expert code reviewer. Compare the following two versions of code and describe the changes in detail, focusing on what was added, removed, or modified. Be clear and concise.
|
| 160 |
+
|
| 161 |
+
--- Previous code ---
|
| 162 |
+
{old_code}
|
| 163 |
+
|
| 164 |
+
--- New code ---
|
| 165 |
+
{new_code}
|
| 166 |
+
|
| 167 |
+
Description of the change:
|
| 168 |
+
"""
|
| 169 |
+
response = client.chat.completions.create(
|
| 170 |
+
model=MODEL_NAME,
|
| 171 |
+
messages=[{"role": "user", "content": prompt}],
|
| 172 |
+
max_tokens=400,
|
| 173 |
+
temperature=0.3,
|
| 174 |
+
)
|
| 175 |
+
return response.choices[0].message.content.strip()
|
| 176 |
+
|
| 177 |
+
def generate_strategy(old_code, problem):
|
| 178 |
+
"""
|
| 179 |
+
Uses the AI model to generate a strategy for solving the given problem, using the context of the previous code.
|
| 180 |
+
"""
|
| 181 |
+
prompt = f"""
|
| 182 |
+
You are an expert AI code strategist. Given the following previous code and the problem/challenge, devise a step-by-step strategy to solve the problem effectively. Be specific and actionable.
|
| 183 |
+
|
| 184 |
+
--- Previous code ---
|
| 185 |
+
{old_code}
|
| 186 |
+
|
| 187 |
+
--- Problem/Challenge ---
|
| 188 |
+
{problem}
|
| 189 |
+
|
| 190 |
+
Strategy:
|
| 191 |
+
"""
|
| 192 |
+
response = client.chat.completions.create(
|
| 193 |
+
model=MODEL_NAME,
|
| 194 |
+
messages=[{"role": "user", "content": prompt}],
|
| 195 |
+
max_tokens=400,
|
| 196 |
+
temperature=0.5,
|
| 197 |
+
)
|
| 198 |
+
return response.choices[0].message.content.strip()
|
| 199 |
+
|
| 200 |
+
def main():
|
| 201 |
+
log("START: AGI-inspired agent is live.")
|
| 202 |
+
error_count = 0
|
| 203 |
+
reward_system = RewardSystem()
|
| 204 |
+
last_strategy = None
|
| 205 |
+
while True:
|
| 206 |
+
try:
|
| 207 |
+
memory = None # Implement or load as needed
|
| 208 |
+
feedback = "Self-improvement cycle."
|
| 209 |
+
old_code = read_self()
|
| 210 |
+
# For demonstration, treat feedback as the problem/challenge
|
| 211 |
+
problem = feedback
|
| 212 |
+
improved_code = self_improvement_suggestion(old_code, memory, feedback)
|
| 213 |
+
if improved_code and improved_code != old_code:
|
| 214 |
+
if is_trivial_change(old_code, improved_code):
|
| 215 |
+
log("SELF-IMPROVEMENT: Trivial/self-copying rewrite.")
|
| 216 |
+
reward_system.penalty(5, "Trivial or self-copying rewrite (not up to the mark)")
|
| 217 |
+
continue
|
| 218 |
+
try:
|
| 219 |
+
ast.parse(improved_code)
|
| 220 |
+
except Exception as e:
|
| 221 |
+
log(f"SELF-IMPROVEMENT: Syntax error in new code: {e}\n--- Proposed code ---\n{improved_code}\n--- End proposed code ---")
|
| 222 |
+
reward_system.penalty(30, "Syntax error in proposed code (triple penalty)")
|
| 223 |
+
rollback_to_backup()
|
| 224 |
+
continue
|
| 225 |
+
if not performs_task(improved_code):
|
| 226 |
+
log("SELF-IMPROVEMENT: Code does not perform any task.")
|
| 227 |
+
reward_system.penalty(20, "Code does not perform any task (double penalty)")
|
| 228 |
+
continue
|
| 229 |
+
complete_improved_code = ensure_core_functions(improved_code, old_code)
|
| 230 |
+
write_new_self(complete_improved_code)
|
| 231 |
+
log("SELF-IMPROVEMENT: Code updated.")
|
| 232 |
+
reward_system.reward(10, "Successful code update")
|
| 233 |
+
# --- AI Describes the Change ---
|
| 234 |
+
change_description = describe_code_change(old_code, complete_improved_code)
|
| 235 |
+
log(f"CHANGE DESCRIPTION: {change_description}")
|
| 236 |
+
# --- AI Generates Strategy ---
|
| 237 |
+
last_strategy = generate_strategy(old_code, problem)
|
| 238 |
+
log(f"STRATEGY: {last_strategy}")
|
| 239 |
+
else:
|
| 240 |
+
log("SELF-IMPROVEMENT: No meaningful improvement.")
|
| 241 |
+
reward_system.penalty(5, "No meaningful improvement (not up to the mark)")
|
| 242 |
+
error_count = 0
|
| 243 |
+
except Exception as e:
|
| 244 |
+
error_count += 1
|
| 245 |
+
log(f"ERROR: {str(e)}")
|
| 246 |
+
reward_system.penalty(30, "Error occurred (triple penalty)")
|
| 247 |
+
if error_count > 5:
|
| 248 |
+
log("CRITICAL ERROR: Too many errors, shutting down.")
|
| 249 |
+
reward_system.penalty(50, "Critical error, shutting down")
|
| 250 |
+
rollback_to_backup()
|
| 251 |
+
break
|
| 252 |
+
|
| 253 |
+
if __name__ == "__main__":
|
| 254 |
+
main()
|
aitech_log.txt
ADDED
|
File without changes
|
data.py
ADDED
|
@@ -0,0 +1,353 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
import argparse
|
| 3 |
+
import json
|
| 4 |
+
import numpy as np
|
| 5 |
+
from tqdm import tqdm
|
| 6 |
+
import torch
|
| 7 |
+
import torch.nn as nn
|
| 8 |
+
from torch.utils.data import DataLoader, random_split
|
| 9 |
+
from torch.cuda.amp import GradScaler, autocast
|
| 10 |
+
from transformers import GPT2TokenizerFast, AdamW, get_linear_schedule_with_warmup
|
| 11 |
+
from datasets import load_dataset
|
| 12 |
+
from transformers import logging as hf_logging
|
| 13 |
+
|
| 14 |
+
# Suppress unnecessary logging
|
| 15 |
+
hf_logging.set_verbosity_error()
|
| 16 |
+
|
| 17 |
+
# Import your transformer model
|
| 18 |
+
# from your_transformer_module import create_transformer_model
|
| 19 |
+
|
| 20 |
+
class Config:
|
| 21 |
+
"""Centralized configuration for training"""
|
| 22 |
+
def __init__(self):
|
| 23 |
+
# Model hyperparameters
|
| 24 |
+
self.vocab_size = 50257 # GPT-2 vocab size
|
| 25 |
+
self.d_model = 512
|
| 26 |
+
self.nhead = 8
|
| 27 |
+
self.num_layers = 6
|
| 28 |
+
self.dim_feedforward = 2048
|
| 29 |
+
self.dropout = 0.1
|
| 30 |
+
|
| 31 |
+
# Training hyperparameters
|
| 32 |
+
self.batch_size = 32
|
| 33 |
+
self.num_epochs = 3
|
| 34 |
+
self.learning_rate = 5e-5
|
| 35 |
+
self.weight_decay = 0.01
|
| 36 |
+
self.warmup_steps = 0.1 # Percentage of total steps
|
| 37 |
+
self.max_seq_length = 512
|
| 38 |
+
self.gradient_accumulation_steps = 1
|
| 39 |
+
self.max_grad_norm = 1.0
|
| 40 |
+
self.seed = 42
|
| 41 |
+
|
| 42 |
+
# Paths
|
| 43 |
+
self.output_dir = "./checkpoints"
|
| 44 |
+
self.model_save_prefix = "reasoning_model"
|
| 45 |
+
|
| 46 |
+
# Device configuration
|
| 47 |
+
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
| 48 |
+
self.fp16 = torch.cuda.is_available()
|
| 49 |
+
|
| 50 |
+
def save(self, path):
|
| 51 |
+
"""Save configuration to file"""
|
| 52 |
+
os.makedirs(os.path.dirname(path), exist_ok=True)
|
| 53 |
+
with open(path, 'w') as f:
|
| 54 |
+
json.dump(self.__dict__, f, indent=2)
|
| 55 |
+
|
| 56 |
+
@classmethod
|
| 57 |
+
def from_file(cls, path):
|
| 58 |
+
"""Load configuration from file"""
|
| 59 |
+
config = cls()
|
| 60 |
+
with open(path, 'r') as f:
|
| 61 |
+
config.__dict__.update(json.load(f))
|
| 62 |
+
return config
|
| 63 |
+
|
| 64 |
+
def load_and_preprocess_data(config):
|
| 65 |
+
"""Load and preprocess the dataset"""
|
| 66 |
+
# Load dataset
|
| 67 |
+
dataset = load_dataset("ag2428/reasoningDataV4", split="train")
|
| 68 |
+
|
| 69 |
+
# Initialize tokenizer
|
| 70 |
+
tokenizer = GPT2TokenizerFast.from_pretrained("gpt2")
|
| 71 |
+
tokenizer.pad_token = tokenizer.eos_token # Set padding token
|
| 72 |
+
|
| 73 |
+
# Tokenization function
|
| 74 |
+
def tokenize_function(examples):
|
| 75 |
+
# Combine instruction and answer with a separator
|
| 76 |
+
texts = [f"{inst}\n{ans}" for inst, ans in zip(examples["instruction"], examples["answer"])]
|
| 77 |
+
|
| 78 |
+
# Tokenize
|
| 79 |
+
tokenized = tokenizer(
|
| 80 |
+
texts,
|
| 81 |
+
max_length=config.max_seq_length,
|
| 82 |
+
truncation=True,
|
| 83 |
+
padding="max_length",
|
| 84 |
+
return_tensors="pt"
|
| 85 |
+
)
|
| 86 |
+
|
| 87 |
+
# Create labels (shifted input_ids for language modeling)
|
| 88 |
+
tokenized["labels"] = tokenized["input_ids"].clone()
|
| 89 |
+
return tokenized
|
| 90 |
+
|
| 91 |
+
# Tokenize dataset
|
| 92 |
+
tokenized_datasets = dataset.map(
|
| 93 |
+
tokenize_function,
|
| 94 |
+
batched=True,
|
| 95 |
+
remove_columns=dataset.column_names,
|
| 96 |
+
desc="Tokenizing dataset"
|
| 97 |
+
)
|
| 98 |
+
|
| 99 |
+
# Split into train and validation sets
|
| 100 |
+
train_val = tokenized_datasets.train_test_split(test_size=0.1, seed=config.seed)
|
| 101 |
+
train_dataset = train_val["train"]
|
| 102 |
+
val_dataset = train_val["test"]
|
| 103 |
+
|
| 104 |
+
# Convert to PyTorch format
|
| 105 |
+
train_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask', 'labels'])
|
| 106 |
+
val_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask', 'labels'])
|
| 107 |
+
|
| 108 |
+
# Create data loaders
|
| 109 |
+
train_loader = DataLoader(
|
| 110 |
+
train_dataset,
|
| 111 |
+
batch_size=config.batch_size,
|
| 112 |
+
shuffle=True,
|
| 113 |
+
num_workers=4,
|
| 114 |
+
pin_memory=True
|
| 115 |
+
)
|
| 116 |
+
|
| 117 |
+
val_loader = DataLoader(
|
| 118 |
+
val_dataset,
|
| 119 |
+
batch_size=config.batch_size,
|
| 120 |
+
shuffle=False,
|
| 121 |
+
num_workers=4,
|
| 122 |
+
pin_memory=True
|
| 123 |
+
)
|
| 124 |
+
|
| 125 |
+
return train_loader, val_loader, tokenizer
|
| 126 |
+
|
| 127 |
+
def train_epoch(model, train_loader, optimizer, scheduler, scaler, config, epoch):
|
| 128 |
+
"""Train for one epoch"""
|
| 129 |
+
model.train()
|
| 130 |
+
total_loss = 0
|
| 131 |
+
progress_bar = tqdm(train_loader, desc=f"Epoch {epoch + 1}")
|
| 132 |
+
|
| 133 |
+
for step, batch in enumerate(progress_bar):
|
| 134 |
+
# Move batch to device
|
| 135 |
+
input_ids = batch['input_ids'].to(config.device)
|
| 136 |
+
attention_mask = batch['attention_mask'].to(config.device)
|
| 137 |
+
labels = batch['labels'].to(config.device)
|
| 138 |
+
|
| 139 |
+
# Forward pass with mixed precision
|
| 140 |
+
with autocast(enabled=config.fp16):
|
| 141 |
+
outputs = model(
|
| 142 |
+
input_ids=input_ids,
|
| 143 |
+
attention_mask=attention_mask,
|
| 144 |
+
labels=labels
|
| 145 |
+
)
|
| 146 |
+
loss = outputs.loss / config.gradient_accumulation_steps
|
| 147 |
+
|
| 148 |
+
# Backward pass and optimize
|
| 149 |
+
if config.fp16:
|
| 150 |
+
scaler.scale(loss).backward()
|
| 151 |
+
else:
|
| 152 |
+
loss.backward()
|
| 153 |
+
|
| 154 |
+
# Gradient clipping and optimization step
|
| 155 |
+
if (step + 1) % config.gradient_accumulation_steps == 0:
|
| 156 |
+
if config.fp16:
|
| 157 |
+
scaler.unscale_(optimizer)
|
| 158 |
+
torch.nn.utils.clip_grad_norm_(model.parameters(), config.max_grad_norm)
|
| 159 |
+
scaler.step(optimizer)
|
| 160 |
+
scaler.update()
|
| 161 |
+
else:
|
| 162 |
+
torch.nn.utils.clip_grad_norm_(model.parameters(), config.max_grad_norm)
|
| 163 |
+
optimizer.step()
|
| 164 |
+
|
| 165 |
+
scheduler.step()
|
| 166 |
+
optimizer.zero_grad()
|
| 167 |
+
|
| 168 |
+
total_loss += loss.item() * config.gradient_accumulation_steps
|
| 169 |
+
|
| 170 |
+
# Update progress bar
|
| 171 |
+
progress_bar.set_postfix({
|
| 172 |
+
'loss': f"{total_loss / (step + 1):.4f}",
|
| 173 |
+
'lr': f"{scheduler.get_last_lr()[0]:.2e}"
|
| 174 |
+
})
|
| 175 |
+
|
| 176 |
+
return total_loss / len(train_loader)
|
| 177 |
+
|
| 178 |
+
def evaluate(model, val_loader, config):
|
| 179 |
+
"""Evaluate the model on the validation set"""
|
| 180 |
+
model.eval()
|
| 181 |
+
total_loss = 0
|
| 182 |
+
|
| 183 |
+
with torch.no_grad():
|
| 184 |
+
for batch in tqdm(val_loader, desc="Evaluating"):
|
| 185 |
+
input_ids = batch['input_ids'].to(config.device)
|
| 186 |
+
attention_mask = batch['attention_mask'].to(config.device)
|
| 187 |
+
labels = batch['labels'].to(config.device)
|
| 188 |
+
|
| 189 |
+
with autocast(enabled=config.fp16):
|
| 190 |
+
outputs = model(
|
| 191 |
+
input_ids=input_ids,
|
| 192 |
+
attention_mask=attention_mask,
|
| 193 |
+
labels=labels
|
| 194 |
+
)
|
| 195 |
+
loss = outputs.loss
|
| 196 |
+
|
| 197 |
+
total_loss += loss.item()
|
| 198 |
+
|
| 199 |
+
return total_loss / len(val_loader)
|
| 200 |
+
|
| 201 |
+
def save_checkpoint(model, optimizer, scheduler, epoch, config, is_best=False):
|
| 202 |
+
"""Save model checkpoint"""
|
| 203 |
+
os.makedirs(config.output_dir, exist_ok=True)
|
| 204 |
+
|
| 205 |
+
# Prepare checkpoint
|
| 206 |
+
checkpoint = {
|
| 207 |
+
'epoch': epoch,
|
| 208 |
+
'model_state_dict': model.state_dict(),
|
| 209 |
+
'optimizer_state_dict': optimizer.state_dict(),
|
| 210 |
+
'scheduler_state_dict': scheduler.state_dict(),
|
| 211 |
+
'config': config.__dict__,
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
# Save checkpoint
|
| 215 |
+
if is_best:
|
| 216 |
+
filename = os.path.join(config.output_dir, f"{config.model_save_prefix}_best.pt")
|
| 217 |
+
else:
|
| 218 |
+
filename = os.path.join(config.output_dir, f"{config.model_save_prefix}_epoch_{epoch}.pt")
|
| 219 |
+
|
| 220 |
+
torch.save(checkpoint, filename)
|
| 221 |
+
print(f"Checkpoint saved to {filename}")
|
| 222 |
+
|
| 223 |
+
def main():
|
| 224 |
+
# Parse command line arguments
|
| 225 |
+
parser = argparse.ArgumentParser(description="Train a reasoning model")
|
| 226 |
+
parser.add_argument('--config', type=str, default=None, help="Path to config file")
|
| 227 |
+
parser.add_argument('--output_dir', type=str, default=None, help="Output directory for checkpoints")
|
| 228 |
+
parser.add_argument('--batch_size', type=int, default=None, help="Batch size")
|
| 229 |
+
parser.add_argument('--num_epochs', type=int, default=None, help="Number of epochs")
|
| 230 |
+
parser.add_argument('--learning_rate', type=float, default=None, help="Learning rate")
|
| 231 |
+
parser.add_argument('--fp16', action='store_true', help="Use mixed precision training")
|
| 232 |
+
args = parser.parse_args()
|
| 233 |
+
|
| 234 |
+
# Initialize config
|
| 235 |
+
if args.config:
|
| 236 |
+
config = Config.from_file(args.config)
|
| 237 |
+
else:
|
| 238 |
+
config = Config()
|
| 239 |
+
|
| 240 |
+
# Override config with command line arguments
|
| 241 |
+
if args.output_dir:
|
| 242 |
+
config.output_dir = args.output_dir
|
| 243 |
+
if args.batch_size:
|
| 244 |
+
config.batch_size = args.batch_size
|
| 245 |
+
if args.num_epochs:
|
| 246 |
+
config.num_epochs = args.num_epochs
|
| 247 |
+
if args.learning_rate:
|
| 248 |
+
config.learning_rate = args.learning_rate
|
| 249 |
+
if args.fp16:
|
| 250 |
+
config.fp16 = True
|
| 251 |
+
|
| 252 |
+
# Set random seed for reproducibility
|
| 253 |
+
torch.manual_seed(config.seed)
|
| 254 |
+
np.random.seed(config.seed)
|
| 255 |
+
if torch.cuda.is_available():
|
| 256 |
+
torch.cuda.manual_seed_all(config.seed)
|
| 257 |
+
|
| 258 |
+
# Create output directory
|
| 259 |
+
os.makedirs(config.output_dir, exist_ok=True)
|
| 260 |
+
|
| 261 |
+
# Save config
|
| 262 |
+
config.save(os.path.join(config.output_dir, "config.json"))
|
| 263 |
+
|
| 264 |
+
# Load data
|
| 265 |
+
print("Loading and preprocessing data...")
|
| 266 |
+
train_loader, val_loader, tokenizer = load_and_preprocess_data(config)
|
| 267 |
+
|
| 268 |
+
# Initialize model
|
| 269 |
+
print("Initializing model...")
|
| 270 |
+
# TODO: Replace with your model initialization
|
| 271 |
+
# model = create_transformer_model(
|
| 272 |
+
# vocab_size=config.vocab_size,
|
| 273 |
+
# d_model=config.d_model,
|
| 274 |
+
# nhead=config.nhead,
|
| 275 |
+
# num_layers=config.num_layers,
|
| 276 |
+
# dim_feedforward=config.dim_feedforward,
|
| 277 |
+
# dropout=config.dropout,
|
| 278 |
+
# max_seq_length=config.max_seq_length
|
| 279 |
+
# )
|
| 280 |
+
|
| 281 |
+
# For now, let's use a placeholder that will raise an error
|
| 282 |
+
class PlaceholderModel(nn.Module):
|
| 283 |
+
def __init__(self):
|
| 284 |
+
super().__init__()
|
| 285 |
+
self.loss_fn = nn.CrossEntropyLoss(ignore_index=tokenizer.pad_token_id)
|
| 286 |
+
|
| 287 |
+
def forward(self, input_ids, attention_mask, labels=None):
|
| 288 |
+
# This is a placeholder that will raise an error
|
| 289 |
+
# Replace with your actual model implementation
|
| 290 |
+
raise NotImplementedError(
|
| 291 |
+
"Please implement your transformer model and replace this placeholder. "
|
| 292 |
+
"See the TODO comment in the code for more details."
|
| 293 |
+
)
|
| 294 |
+
|
| 295 |
+
model = PlaceholderModel()
|
| 296 |
+
model = model.to(config.device)
|
| 297 |
+
|
| 298 |
+
# Initialize optimizer and scheduler
|
| 299 |
+
no_decay = ['bias', 'LayerNorm.weight']
|
| 300 |
+
optimizer_grouped_parameters = [
|
| 301 |
+
{
|
| 302 |
+
'params': [p for n, p in model.named_parameters() if not any(nd in n for nd in no_decay)],
|
| 303 |
+
'weight_decay': config.weight_decay,
|
| 304 |
+
},
|
| 305 |
+
{
|
| 306 |
+
'params': [p for n, p in model.named_parameters() if any(nd in n for nd in no_decay)],
|
| 307 |
+
'weight_decay': 0.0,
|
| 308 |
+
}
|
| 309 |
+
]
|
| 310 |
+
|
| 311 |
+
optimizer = AdamW(optimizer_grouped_parameters, lr=config.learning_rate)
|
| 312 |
+
|
| 313 |
+
# Calculate total training steps
|
| 314 |
+
total_steps = len(train_loader) * config.num_epochs // config.gradient_accumulation_steps
|
| 315 |
+
warmup_steps = int(total_steps * config.warmup_steps)
|
| 316 |
+
|
| 317 |
+
# Initialize learning rate scheduler
|
| 318 |
+
scheduler = get_linear_schedule_with_warmup(
|
| 319 |
+
optimizer,
|
| 320 |
+
num_warmup_steps=warmup_steps,
|
| 321 |
+
num_training_steps=total_steps
|
| 322 |
+
)
|
| 323 |
+
|
| 324 |
+
# Initialize gradient scaler for mixed precision training
|
| 325 |
+
scaler = GradScaler(enabled=config.fp16)
|
| 326 |
+
|
| 327 |
+
# Training loop
|
| 328 |
+
print("Starting training...")
|
| 329 |
+
best_val_loss = float('inf')
|
| 330 |
+
|
| 331 |
+
for epoch in range(config.num_epochs):
|
| 332 |
+
# Train for one epoch
|
| 333 |
+
train_loss = train_epoch(model, train_loader, optimizer, scheduler, scaler, config, epoch)
|
| 334 |
+
|
| 335 |
+
# Evaluate on validation set
|
| 336 |
+
val_loss = evaluate(model, val_loader, config)
|
| 337 |
+
|
| 338 |
+
print(f"Epoch {epoch + 1}/{config.num_epochs}:")
|
| 339 |
+
print(f" Train loss: {train_loss:.4f}")
|
| 340 |
+
print(f" Val loss: {val_loss:.4f}")
|
| 341 |
+
|
| 342 |
+
# Save checkpoint
|
| 343 |
+
save_checkpoint(model, optimizer, scheduler, epoch, config)
|
| 344 |
+
|
| 345 |
+
# Save best model
|
| 346 |
+
if val_loss < best_val_loss:
|
| 347 |
+
best_val_loss = val_loss
|
| 348 |
+
save_checkpoint(model, optimizer, scheduler, epoch, config, is_best=True)
|
| 349 |
+
|
| 350 |
+
print("Training complete!")
|
| 351 |
+
|
| 352 |
+
if __name__ == "__main__":
|
| 353 |
+
main()
|
exploler.py
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
| 2 |
+
from bs4 import BeautifulSoup
|
| 3 |
+
import json
|
| 4 |
+
import time
|
| 5 |
+
|
| 6 |
+
SERPAPI_KEY = "c3e3e8fd8d12ca55d8a8954a14bf827f2d4261ef55373b381661f23b1440a2af" # Replace with your SerpAPI key
|
| 7 |
+
|
| 8 |
+
def google_search(query, num_results=1000):
|
| 9 |
+
url = "https://serpapi.com/search"
|
| 10 |
+
params = {
|
| 11 |
+
"engine": "google",
|
| 12 |
+
"q": query,
|
| 13 |
+
"api_key": SERPAPI_KEY,
|
| 14 |
+
"num": num_results
|
| 15 |
+
}
|
| 16 |
+
resp = requests.get(url, params=params)
|
| 17 |
+
data = resp.json()
|
| 18 |
+
links = []
|
| 19 |
+
for result in data.get("organic_results", []):
|
| 20 |
+
link = result.get("link")
|
| 21 |
+
if link:
|
| 22 |
+
links.append(link)
|
| 23 |
+
return links
|
| 24 |
+
|
| 25 |
+
def scrape_page(url):
|
| 26 |
+
try:
|
| 27 |
+
resp = requests.get(url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})
|
| 28 |
+
soup = BeautifulSoup(resp.content, "html.parser")
|
| 29 |
+
text = soup.get_text(separator="\n", strip=True)
|
| 30 |
+
return text[:20000] # Limit to first 2000 chars for brevity
|
| 31 |
+
except Exception as e:
|
| 32 |
+
return f"[SCRAPE ERROR] {e}"
|
| 33 |
+
|
| 34 |
+
def scrape_topic_and_save(topic, filename="results.json"):
|
| 35 |
+
links = google_search(topic)
|
| 36 |
+
results = []
|
| 37 |
+
for url in links:
|
| 38 |
+
print(f"Scraping: {url}")
|
| 39 |
+
content = scrape_page(url)
|
| 40 |
+
results.append({"url": url, "content": content})
|
| 41 |
+
time.sleep(0)
|
| 42 |
+
with open(filename, "w", encoding="utf-8") as f:
|
| 43 |
+
json.dump(results, f, ensure_ascii=False, indent=2)
|
| 44 |
+
print(f"Saved {len(results)} results to {filename}")
|
| 45 |
+
|
| 46 |
+
if __name__ == "__main__":
|
| 47 |
+
topic = input("Enter topic to search: ")
|
| 48 |
+
scrape_topic_and_save(topic)
|
general_reasoning.py
ADDED
|
@@ -0,0 +1,761 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
import json
|
| 4 |
+
import os
|
| 5 |
+
import re
|
| 6 |
+
from typing import Dict, List, Tuple, Optional, Any
|
| 7 |
+
from dataclasses import dataclass
|
| 8 |
+
from enum import Enum
|
| 9 |
+
from openai import OpenAI
|
| 10 |
+
import logging
|
| 11 |
+
from transformer import Transformer, create_transformer_model, initialize_weights
|
| 12 |
+
|
| 13 |
+
# Configure logging
|
| 14 |
+
logging.basicConfig(level=logging.INFO)
|
| 15 |
+
logger = logging.getLogger(__name__)
|
| 16 |
+
|
| 17 |
+
class ReasoningType(Enum):
|
| 18 |
+
"""Types of reasoning approaches"""
|
| 19 |
+
DEDUCTIVE = "deductive" # General to specific
|
| 20 |
+
INDUCTIVE = "inductive" # Specific to general
|
| 21 |
+
ABDUCTIVE = "abductive" # Best explanation
|
| 22 |
+
ANALOGICAL = "analogical" # Pattern matching
|
| 23 |
+
CAUSAL = "causal" # Cause and effect
|
| 24 |
+
TEMPORAL = "temporal" # Time-based reasoning
|
| 25 |
+
SPATIAL = "spatial" # Space/location reasoning
|
| 26 |
+
LOGICAL = "logical" # Formal logic
|
| 27 |
+
CREATIVE = "creative" # Novel solutions
|
| 28 |
+
|
| 29 |
+
@dataclass
|
| 30 |
+
class ReasoningStep:
|
| 31 |
+
"""Individual step in reasoning process"""
|
| 32 |
+
step_id: int
|
| 33 |
+
reasoning_type: ReasoningType
|
| 34 |
+
premise: str
|
| 35 |
+
conclusion: str
|
| 36 |
+
confidence: float
|
| 37 |
+
evidence: List[str]
|
| 38 |
+
assumptions: List[str]
|
| 39 |
+
|
| 40 |
+
@dataclass
|
| 41 |
+
class KnowledgeNode:
|
| 42 |
+
"""Node in the knowledge graph"""
|
| 43 |
+
concept: str
|
| 44 |
+
properties: Dict[str, Any]
|
| 45 |
+
relationships: Dict[str, List[str]]
|
| 46 |
+
confidence: float
|
| 47 |
+
source: str
|
| 48 |
+
|
| 49 |
+
class GeneralReasoningEngine:
|
| 50 |
+
"""
|
| 51 |
+
General Reasoning Engine for AGI-like reasoning capabilities
|
| 52 |
+
Implements multiple reasoning strategies and knowledge integration
|
| 53 |
+
"""
|
| 54 |
+
|
| 55 |
+
def __init__(self,
|
| 56 |
+
openai_client: OpenAI = None,
|
| 57 |
+
device: str = "cuda" if torch.cuda.is_available() else "cpu"):
|
| 58 |
+
|
| 59 |
+
self.device = device
|
| 60 |
+
self.openai_client = openai_client
|
| 61 |
+
|
| 62 |
+
# Initialize reasoning neural networks
|
| 63 |
+
self.reasoning_transformer = create_transformer_model(
|
| 64 |
+
src_vocab_size=100000,
|
| 65 |
+
tgt_vocab_size=100000
|
| 66 |
+
).to(self.device)
|
| 67 |
+
initialize_weights(self.reasoning_transformer)
|
| 68 |
+
|
| 69 |
+
# Knowledge base and working memory
|
| 70 |
+
self.knowledge_graph = {}
|
| 71 |
+
self.working_memory = []
|
| 72 |
+
self.reasoning_history = []
|
| 73 |
+
|
| 74 |
+
# Reasoning strategies
|
| 75 |
+
self.reasoning_strategies = {
|
| 76 |
+
ReasoningType.DEDUCTIVE: self._deductive_reasoning,
|
| 77 |
+
ReasoningType.INDUCTIVE: self._inductive_reasoning,
|
| 78 |
+
ReasoningType.ABDUCTIVE: self._abductive_reasoning,
|
| 79 |
+
ReasoningType.ANALOGICAL: self._analogical_reasoning,
|
| 80 |
+
ReasoningType.CAUSAL: self._causal_reasoning,
|
| 81 |
+
ReasoningType.TEMPORAL: self._temporal_reasoning,
|
| 82 |
+
ReasoningType.SPATIAL: self._spatial_reasoning,
|
| 83 |
+
ReasoningType.LOGICAL: self._logical_reasoning,
|
| 84 |
+
ReasoningType.CREATIVE: self._creative_reasoning
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
# Meta-reasoning for strategy selection
|
| 88 |
+
self.strategy_weights = {strategy: 1.0 for strategy in ReasoningType}
|
| 89 |
+
|
| 90 |
+
# Initialize with basic knowledge
|
| 91 |
+
self._initialize_base_knowledge()
|
| 92 |
+
|
| 93 |
+
def _initialize_base_knowledge(self):
|
| 94 |
+
"""Initialize with fundamental knowledge concepts"""
|
| 95 |
+
base_concepts = [
|
| 96 |
+
("object", {"type": "entity", "properties": ["existence", "identity"]}),
|
| 97 |
+
("action", {"type": "process", "properties": ["causality", "temporality"]}),
|
| 98 |
+
("relationship", {"type": "connection", "properties": ["bidirectional", "typed"]}),
|
| 99 |
+
("pattern", {"type": "structure", "properties": ["repetition", "similarity"]}),
|
| 100 |
+
("goal", {"type": "objective", "properties": ["desirability", "achievability"]}),
|
| 101 |
+
("constraint", {"type": "limitation", "properties": ["boundary", "restriction"]}),
|
| 102 |
+
("context", {"type": "environment", "properties": ["situational", "influential"]})
|
| 103 |
+
]
|
| 104 |
+
|
| 105 |
+
for concept, properties in base_concepts:
|
| 106 |
+
self.add_knowledge(concept, properties, {}, 1.0, "base_initialization")
|
| 107 |
+
|
| 108 |
+
def add_knowledge(self, concept: str, properties: Dict, relationships: Dict,
|
| 109 |
+
confidence: float, source: str):
|
| 110 |
+
"""Add knowledge to the knowledge graph"""
|
| 111 |
+
node = KnowledgeNode(concept, properties, relationships, confidence, source)
|
| 112 |
+
self.knowledge_graph[concept] = node
|
| 113 |
+
logger.info(f"Added knowledge: {concept}")
|
| 114 |
+
|
| 115 |
+
def reason_about_problem(self, problem: str, context: Dict = None) -> Dict:
|
| 116 |
+
"""
|
| 117 |
+
Main reasoning function - analyzes problem and applies appropriate reasoning
|
| 118 |
+
"""
|
| 119 |
+
logger.info(f"Starting reasoning about: {problem}")
|
| 120 |
+
|
| 121 |
+
# Step 1: Problem analysis and decomposition
|
| 122 |
+
problem_analysis = self._analyze_problem(problem, context)
|
| 123 |
+
|
| 124 |
+
# Step 2: Select appropriate reasoning strategies
|
| 125 |
+
selected_strategies = self._select_reasoning_strategies(problem_analysis)
|
| 126 |
+
|
| 127 |
+
# Step 3: Apply reasoning strategies
|
| 128 |
+
reasoning_results = []
|
| 129 |
+
for strategy in selected_strategies:
|
| 130 |
+
result = self._apply_reasoning_strategy(strategy, problem, problem_analysis)
|
| 131 |
+
reasoning_results.append(result)
|
| 132 |
+
|
| 133 |
+
# Step 4: Integrate and synthesize results
|
| 134 |
+
final_reasoning = self._synthesize_reasoning(reasoning_results)
|
| 135 |
+
|
| 136 |
+
# Step 5: Generate solution and explanation
|
| 137 |
+
solution = self._generate_solution(problem, final_reasoning)
|
| 138 |
+
|
| 139 |
+
# Step 6: Update knowledge and learning
|
| 140 |
+
self._update_knowledge_from_reasoning(problem, solution, final_reasoning)
|
| 141 |
+
|
| 142 |
+
return {
|
| 143 |
+
'problem': problem,
|
| 144 |
+
'analysis': problem_analysis,
|
| 145 |
+
'strategies_used': [s.value for s in selected_strategies],
|
| 146 |
+
'reasoning_steps': final_reasoning,
|
| 147 |
+
'solution': solution,
|
| 148 |
+
'confidence': self._calculate_overall_confidence(final_reasoning)
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
def _analyze_problem(self, problem: str, context: Dict = None) -> Dict:
|
| 152 |
+
"""Analyze and decompose the problem"""
|
| 153 |
+
analysis = {
|
| 154 |
+
'problem_type': self._classify_problem_type(problem),
|
| 155 |
+
'key_concepts': self._extract_concepts(problem),
|
| 156 |
+
'constraints': self._identify_constraints(problem),
|
| 157 |
+
'goals': self._identify_goals(problem),
|
| 158 |
+
'context': context or {},
|
| 159 |
+
'complexity': self._assess_complexity(problem),
|
| 160 |
+
'domain': self._identify_domain(problem)
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
# Use neural network for deeper analysis if available
|
| 164 |
+
if self.openai_client:
|
| 165 |
+
enhanced_analysis = self._enhance_analysis_with_llm(problem, analysis)
|
| 166 |
+
analysis.update(enhanced_analysis)
|
| 167 |
+
|
| 168 |
+
return analysis
|
| 169 |
+
|
| 170 |
+
def _classify_problem_type(self, problem: str) -> str:
|
| 171 |
+
"""Classify the type of problem"""
|
| 172 |
+
problem_lower = problem.lower()
|
| 173 |
+
|
| 174 |
+
if any(word in problem_lower for word in ['create', 'build', 'design', 'generate']):
|
| 175 |
+
return 'creative'
|
| 176 |
+
elif any(word in problem_lower for word in ['analyze', 'understand', 'explain']):
|
| 177 |
+
return 'analytical'
|
| 178 |
+
elif any(word in problem_lower for word in ['solve', 'find', 'calculate']):
|
| 179 |
+
return 'problem_solving'
|
| 180 |
+
elif any(word in problem_lower for word in ['predict', 'forecast', 'estimate']):
|
| 181 |
+
return 'predictive'
|
| 182 |
+
elif any(word in problem_lower for word in ['optimize', 'improve', 'enhance']):
|
| 183 |
+
return 'optimization'
|
| 184 |
+
else:
|
| 185 |
+
return 'general'
|
| 186 |
+
|
| 187 |
+
def _extract_concepts(self, problem: str) -> List[str]:
|
| 188 |
+
"""Extract key concepts from the problem"""
|
| 189 |
+
# Simple keyword extraction (can be enhanced with NLP)
|
| 190 |
+
words = re.findall(r'\b[a-zA-Z]+\b', problem.lower())
|
| 191 |
+
|
| 192 |
+
# Filter for meaningful concepts
|
| 193 |
+
stopwords = {'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by'}
|
| 194 |
+
concepts = [word for word in words if word not in stopwords and len(word) > 2]
|
| 195 |
+
|
| 196 |
+
# Check against knowledge graph
|
| 197 |
+
known_concepts = [concept for concept in concepts if concept in self.knowledge_graph]
|
| 198 |
+
|
| 199 |
+
return list(set(concepts)), known_concepts
|
| 200 |
+
|
| 201 |
+
def _identify_constraints(self, problem: str) -> List[str]:
|
| 202 |
+
"""Identify constraints in the problem"""
|
| 203 |
+
constraint_indicators = ['must', 'cannot', 'should not', 'limited', 'only', 'within', 'without']
|
| 204 |
+
constraints = []
|
| 205 |
+
|
| 206 |
+
for indicator in constraint_indicators:
|
| 207 |
+
if indicator in problem.lower():
|
| 208 |
+
# Extract sentence containing constraint
|
| 209 |
+
sentences = problem.split('.')
|
| 210 |
+
for sentence in sentences:
|
| 211 |
+
if indicator in sentence.lower():
|
| 212 |
+
constraints.append(sentence.strip())
|
| 213 |
+
|
| 214 |
+
return constraints
|
| 215 |
+
|
| 216 |
+
def _identify_goals(self, problem: str) -> List[str]:
|
| 217 |
+
"""Identify goals in the problem"""
|
| 218 |
+
goal_indicators = ['want', 'need', 'goal', 'objective', 'aim', 'target', 'achieve']
|
| 219 |
+
goals = []
|
| 220 |
+
|
| 221 |
+
for indicator in goal_indicators:
|
| 222 |
+
if indicator in problem.lower():
|
| 223 |
+
sentences = problem.split('.')
|
| 224 |
+
for sentence in sentences:
|
| 225 |
+
if indicator in sentence.lower():
|
| 226 |
+
goals.append(sentence.strip())
|
| 227 |
+
|
| 228 |
+
return goals
|
| 229 |
+
|
| 230 |
+
def _assess_complexity(self, problem: str) -> str:
|
| 231 |
+
"""Assess problem complexity"""
|
| 232 |
+
word_count = len(problem.split())
|
| 233 |
+
concept_count = len(self._extract_concepts(problem)[0])
|
| 234 |
+
|
| 235 |
+
if word_count < 10 and concept_count < 3:
|
| 236 |
+
return 'simple'
|
| 237 |
+
elif word_count < 50 and concept_count < 10:
|
| 238 |
+
return 'moderate'
|
| 239 |
+
else:
|
| 240 |
+
return 'complex'
|
| 241 |
+
|
| 242 |
+
def _identify_domain(self, problem: str) -> str:
|
| 243 |
+
"""Identify the domain of the problem"""
|
| 244 |
+
domain_keywords = {
|
| 245 |
+
'technology': ['code', 'program', 'software', 'computer', 'algorithm'],
|
| 246 |
+
'science': ['experiment', 'hypothesis', 'theory', 'research', 'data'],
|
| 247 |
+
'business': ['profit', 'market', 'customer', 'revenue', 'strategy'],
|
| 248 |
+
'mathematics': ['equation', 'calculate', 'formula', 'number', 'solve'],
|
| 249 |
+
'creative': ['design', 'art', 'creative', 'innovative', 'original']
|
| 250 |
+
}
|
| 251 |
+
|
| 252 |
+
problem_lower = problem.lower()
|
| 253 |
+
for domain, keywords in domain_keywords.items():
|
| 254 |
+
if any(keyword in problem_lower for keyword in keywords):
|
| 255 |
+
return domain
|
| 256 |
+
|
| 257 |
+
return 'general'
|
| 258 |
+
|
| 259 |
+
def _select_reasoning_strategies(self, analysis: Dict) -> List[ReasoningType]:
|
| 260 |
+
"""Select appropriate reasoning strategies based on problem analysis"""
|
| 261 |
+
strategies = []
|
| 262 |
+
problem_type = analysis['problem_type']
|
| 263 |
+
domain = analysis['domain']
|
| 264 |
+
complexity = analysis['complexity']
|
| 265 |
+
|
| 266 |
+
# Strategy selection based on problem characteristics
|
| 267 |
+
if problem_type == 'creative':
|
| 268 |
+
strategies.extend([ReasoningType.CREATIVE, ReasoningType.ANALOGICAL])
|
| 269 |
+
elif problem_type == 'analytical':
|
| 270 |
+
strategies.extend([ReasoningType.DEDUCTIVE, ReasoningType.INDUCTIVE])
|
| 271 |
+
elif problem_type == 'problem_solving':
|
| 272 |
+
strategies.extend([ReasoningType.LOGICAL, ReasoningType.CAUSAL])
|
| 273 |
+
elif problem_type == 'predictive':
|
| 274 |
+
strategies.extend([ReasoningType.INDUCTIVE, ReasoningType.TEMPORAL])
|
| 275 |
+
|
| 276 |
+
# Add domain-specific strategies
|
| 277 |
+
if domain == 'technology':
|
| 278 |
+
strategies.append(ReasoningType.LOGICAL)
|
| 279 |
+
elif domain == 'science':
|
| 280 |
+
strategies.extend([ReasoningType.CAUSAL, ReasoningType.ABDUCTIVE])
|
| 281 |
+
|
| 282 |
+
# Ensure at least one strategy
|
| 283 |
+
if not strategies:
|
| 284 |
+
strategies = [ReasoningType.DEDUCTIVE, ReasoningType.LOGICAL]
|
| 285 |
+
|
| 286 |
+
return list(set(strategies))
|
| 287 |
+
|
| 288 |
+
def _apply_reasoning_strategy(self, strategy: ReasoningType, problem: str, analysis: Dict) -> ReasoningStep:
|
| 289 |
+
"""Apply a specific reasoning strategy"""
|
| 290 |
+
logger.info(f"Applying {strategy.value} reasoning")
|
| 291 |
+
|
| 292 |
+
if strategy in self.reasoning_strategies:
|
| 293 |
+
return self.reasoning_strategies[strategy](problem, analysis)
|
| 294 |
+
else:
|
| 295 |
+
return self._default_reasoning(problem, analysis)
|
| 296 |
+
|
| 297 |
+
def _deductive_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 298 |
+
"""Apply deductive reasoning (general to specific)"""
|
| 299 |
+
# Find general principles that apply to this problem
|
| 300 |
+
relevant_knowledge = self._find_relevant_knowledge(analysis['key_concepts'][0])
|
| 301 |
+
|
| 302 |
+
premise = f"General principle: {relevant_knowledge}"
|
| 303 |
+
conclusion = f"Applied to specific case: {problem}"
|
| 304 |
+
|
| 305 |
+
return ReasoningStep(
|
| 306 |
+
step_id=len(self.reasoning_history),
|
| 307 |
+
reasoning_type=ReasoningType.DEDUCTIVE,
|
| 308 |
+
premise=premise,
|
| 309 |
+
conclusion=conclusion,
|
| 310 |
+
confidence=0.8,
|
| 311 |
+
evidence=[relevant_knowledge],
|
| 312 |
+
assumptions=["General principle applies to specific case"]
|
| 313 |
+
)
|
| 314 |
+
|
| 315 |
+
def _inductive_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 316 |
+
"""Apply inductive reasoning (specific to general)"""
|
| 317 |
+
# Look for patterns in similar problems
|
| 318 |
+
patterns = self._find_patterns(analysis['key_concepts'][0])
|
| 319 |
+
|
| 320 |
+
premise = f"Observed patterns: {patterns}"
|
| 321 |
+
conclusion = f"General rule: Similar problems follow this pattern"
|
| 322 |
+
|
| 323 |
+
return ReasoningStep(
|
| 324 |
+
step_id=len(self.reasoning_history),
|
| 325 |
+
reasoning_type=ReasoningType.INDUCTIVE,
|
| 326 |
+
premise=premise,
|
| 327 |
+
conclusion=conclusion,
|
| 328 |
+
confidence=0.7,
|
| 329 |
+
evidence=patterns,
|
| 330 |
+
assumptions=["Past patterns predict future behavior"]
|
| 331 |
+
)
|
| 332 |
+
|
| 333 |
+
def _abductive_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 334 |
+
"""Apply abductive reasoning (best explanation)"""
|
| 335 |
+
# Find the most likely explanation
|
| 336 |
+
possible_explanations = self._generate_explanations(problem, analysis)
|
| 337 |
+
best_explanation = max(possible_explanations, key=lambda x: x.get('likelihood', 0))
|
| 338 |
+
|
| 339 |
+
premise = f"Observed: {problem}"
|
| 340 |
+
conclusion = f"Best explanation: {best_explanation['explanation']}"
|
| 341 |
+
|
| 342 |
+
return ReasoningStep(
|
| 343 |
+
step_id=len(self.reasoning_history),
|
| 344 |
+
reasoning_type=ReasoningType.ABDUCTIVE,
|
| 345 |
+
premise=premise,
|
| 346 |
+
conclusion=conclusion,
|
| 347 |
+
confidence=best_explanation.get('likelihood', 0.6),
|
| 348 |
+
evidence=[best_explanation['explanation']],
|
| 349 |
+
assumptions=["Most likely explanation is correct"]
|
| 350 |
+
)
|
| 351 |
+
|
| 352 |
+
def _analogical_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 353 |
+
"""Apply analogical reasoning (pattern matching)"""
|
| 354 |
+
# Find similar problems or situations
|
| 355 |
+
analogies = self._find_analogies(analysis['key_concepts'][0])
|
| 356 |
+
|
| 357 |
+
premise = f"Similar situation: {analogies}"
|
| 358 |
+
conclusion = f"By analogy: Apply similar solution approach"
|
| 359 |
+
|
| 360 |
+
return ReasoningStep(
|
| 361 |
+
step_id=len(self.reasoning_history),
|
| 362 |
+
reasoning_type=ReasoningType.ANALOGICAL,
|
| 363 |
+
premise=premise,
|
| 364 |
+
conclusion=conclusion,
|
| 365 |
+
confidence=0.7,
|
| 366 |
+
evidence=analogies,
|
| 367 |
+
assumptions=["Similar problems have similar solutions"]
|
| 368 |
+
)
|
| 369 |
+
|
| 370 |
+
def _causal_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 371 |
+
"""Apply causal reasoning (cause and effect)"""
|
| 372 |
+
# Identify cause-effect relationships
|
| 373 |
+
causes = self._identify_causes(problem, analysis)
|
| 374 |
+
effects = self._predict_effects(causes)
|
| 375 |
+
|
| 376 |
+
premise = f"Causes: {causes}"
|
| 377 |
+
conclusion = f"Expected effects: {effects}"
|
| 378 |
+
|
| 379 |
+
return ReasoningStep(
|
| 380 |
+
step_id=len(self.reasoning_history),
|
| 381 |
+
reasoning_type=ReasoningType.CAUSAL,
|
| 382 |
+
premise=premise,
|
| 383 |
+
conclusion=conclusion,
|
| 384 |
+
confidence=0.8,
|
| 385 |
+
evidence=causes + effects,
|
| 386 |
+
assumptions=["Causal relationships are stable"]
|
| 387 |
+
)
|
| 388 |
+
|
| 389 |
+
def _temporal_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 390 |
+
"""Apply temporal reasoning (time-based)"""
|
| 391 |
+
# Consider time-based aspects
|
| 392 |
+
temporal_aspects = self._analyze_temporal_aspects(problem)
|
| 393 |
+
|
| 394 |
+
premise = f"Temporal context: {temporal_aspects}"
|
| 395 |
+
conclusion = f"Time-based implications: Consider sequence and timing"
|
| 396 |
+
|
| 397 |
+
return ReasoningStep(
|
| 398 |
+
step_id=len(self.reasoning_history),
|
| 399 |
+
reasoning_type=ReasoningType.TEMPORAL,
|
| 400 |
+
premise=premise,
|
| 401 |
+
conclusion=conclusion,
|
| 402 |
+
confidence=0.7,
|
| 403 |
+
evidence=temporal_aspects,
|
| 404 |
+
assumptions=["Time sequence affects outcomes"]
|
| 405 |
+
)
|
| 406 |
+
|
| 407 |
+
def _spatial_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 408 |
+
"""Apply spatial reasoning (space/location)"""
|
| 409 |
+
# Consider spatial relationships
|
| 410 |
+
spatial_aspects = self._analyze_spatial_aspects(problem)
|
| 411 |
+
|
| 412 |
+
premise = f"Spatial context: {spatial_aspects}"
|
| 413 |
+
conclusion = f"Spatial implications: Consider location and arrangement"
|
| 414 |
+
|
| 415 |
+
return ReasoningStep(
|
| 416 |
+
step_id=len(self.reasoning_history),
|
| 417 |
+
reasoning_type=ReasoningType.SPATIAL,
|
| 418 |
+
premise=premise,
|
| 419 |
+
conclusion=conclusion,
|
| 420 |
+
confidence=0.6,
|
| 421 |
+
evidence=spatial_aspects,
|
| 422 |
+
assumptions=["Spatial arrangement affects function"]
|
| 423 |
+
)
|
| 424 |
+
|
| 425 |
+
def _logical_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 426 |
+
"""Apply logical reasoning (formal logic)"""
|
| 427 |
+
# Apply logical rules
|
| 428 |
+
logical_structure = self._analyze_logical_structure(problem)
|
| 429 |
+
|
| 430 |
+
premise = f"Logical structure: {logical_structure}"
|
| 431 |
+
conclusion = f"Logical conclusion: Apply formal reasoning rules"
|
| 432 |
+
|
| 433 |
+
return ReasoningStep(
|
| 434 |
+
step_id=len(self.reasoning_history),
|
| 435 |
+
reasoning_type=ReasoningType.LOGICAL,
|
| 436 |
+
premise=premise,
|
| 437 |
+
conclusion=conclusion,
|
| 438 |
+
confidence=0.9,
|
| 439 |
+
evidence=[logical_structure],
|
| 440 |
+
assumptions=["Logical rules are consistent"]
|
| 441 |
+
)
|
| 442 |
+
|
| 443 |
+
def _creative_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 444 |
+
"""Apply creative reasoning (novel solutions)"""
|
| 445 |
+
# Generate novel approaches
|
| 446 |
+
creative_ideas = self._generate_creative_ideas(problem, analysis)
|
| 447 |
+
|
| 448 |
+
premise = f"Creative exploration: {problem}"
|
| 449 |
+
conclusion = f"Novel approaches: {creative_ideas}"
|
| 450 |
+
|
| 451 |
+
return ReasoningStep(
|
| 452 |
+
step_id=len(self.reasoning_history),
|
| 453 |
+
reasoning_type=ReasoningType.CREATIVE,
|
| 454 |
+
premise=premise,
|
| 455 |
+
conclusion=conclusion,
|
| 456 |
+
confidence=0.6,
|
| 457 |
+
evidence=creative_ideas,
|
| 458 |
+
assumptions=["Novel approaches may be effective"]
|
| 459 |
+
)
|
| 460 |
+
|
| 461 |
+
def _default_reasoning(self, problem: str, analysis: Dict) -> ReasoningStep:
|
| 462 |
+
"""Default reasoning when no specific strategy applies"""
|
| 463 |
+
return ReasoningStep(
|
| 464 |
+
step_id=len(self.reasoning_history),
|
| 465 |
+
reasoning_type=ReasoningType.LOGICAL,
|
| 466 |
+
premise=f"Problem: {problem}",
|
| 467 |
+
conclusion="Apply general problem-solving approach",
|
| 468 |
+
confidence=0.5,
|
| 469 |
+
evidence=[problem],
|
| 470 |
+
assumptions=["General approach is applicable"]
|
| 471 |
+
)
|
| 472 |
+
|
| 473 |
+
def _synthesize_reasoning(self, reasoning_results: List[ReasoningStep]) -> List[ReasoningStep]:
|
| 474 |
+
"""Integrate and synthesize multiple reasoning results"""
|
| 475 |
+
# Weight results by confidence and strategy effectiveness
|
| 476 |
+
weighted_results = []
|
| 477 |
+
|
| 478 |
+
for result in reasoning_results:
|
| 479 |
+
weight = self.strategy_weights.get(result.reasoning_type, 1.0)
|
| 480 |
+
result.confidence *= weight
|
| 481 |
+
weighted_results.append(result)
|
| 482 |
+
|
| 483 |
+
# Sort by confidence
|
| 484 |
+
weighted_results.sort(key=lambda x: x.confidence, reverse=True)
|
| 485 |
+
|
| 486 |
+
# Update strategy weights based on performance
|
| 487 |
+
self._update_strategy_weights(weighted_results)
|
| 488 |
+
|
| 489 |
+
return weighted_results
|
| 490 |
+
|
| 491 |
+
def _generate_solution(self, problem: str, reasoning_steps: List[ReasoningStep]) -> Dict:
|
| 492 |
+
"""Generate final solution based on reasoning"""
|
| 493 |
+
if not reasoning_steps:
|
| 494 |
+
return {"solution": "No solution found", "confidence": 0.0}
|
| 495 |
+
|
| 496 |
+
# Combine insights from all reasoning steps
|
| 497 |
+
best_step = reasoning_steps[0]
|
| 498 |
+
all_conclusions = [step.conclusion for step in reasoning_steps]
|
| 499 |
+
|
| 500 |
+
solution = {
|
| 501 |
+
"primary_approach": best_step.conclusion,
|
| 502 |
+
"reasoning_type": best_step.reasoning_type.value,
|
| 503 |
+
"alternative_approaches": all_conclusions[1:3], # Top 3 alternatives
|
| 504 |
+
"confidence": best_step.confidence,
|
| 505 |
+
"supporting_evidence": best_step.evidence,
|
| 506 |
+
"assumptions": best_step.assumptions
|
| 507 |
+
}
|
| 508 |
+
|
| 509 |
+
# Enhance with LLM if available
|
| 510 |
+
if self.openai_client:
|
| 511 |
+
enhanced_solution = self._enhance_solution_with_llm(problem, solution)
|
| 512 |
+
solution.update(enhanced_solution)
|
| 513 |
+
|
| 514 |
+
return solution
|
| 515 |
+
|
| 516 |
+
def _enhance_analysis_with_llm(self, problem: str, analysis: Dict) -> Dict:
|
| 517 |
+
"""Enhance analysis using language model"""
|
| 518 |
+
prompt = f"""
|
| 519 |
+
Analyze this problem in depth:
|
| 520 |
+
Problem: {problem}
|
| 521 |
+
Current analysis: {analysis}
|
| 522 |
+
|
| 523 |
+
Provide enhanced analysis focusing on:
|
| 524 |
+
1. Hidden assumptions
|
| 525 |
+
2. Alternative perspectives
|
| 526 |
+
3. Potential complications
|
| 527 |
+
4. Key success factors
|
| 528 |
+
|
| 529 |
+
Return as structured analysis.
|
| 530 |
+
"""
|
| 531 |
+
|
| 532 |
+
try:
|
| 533 |
+
response = self.openai_client.chat.completions.create(
|
| 534 |
+
model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free",
|
| 535 |
+
messages=[{"role": "user", "content": prompt}],
|
| 536 |
+
max_tokens=800,
|
| 537 |
+
temperature=0.3
|
| 538 |
+
)
|
| 539 |
+
|
| 540 |
+
enhanced_text = response.choices[0].message.content.strip()
|
| 541 |
+
return {"enhanced_analysis": enhanced_text}
|
| 542 |
+
|
| 543 |
+
except Exception as e:
|
| 544 |
+
logger.error(f"LLM enhancement failed: {e}")
|
| 545 |
+
return {}
|
| 546 |
+
|
| 547 |
+
def _enhance_solution_with_llm(self, problem: str, solution: Dict) -> Dict:
|
| 548 |
+
"""Enhance solution using language model"""
|
| 549 |
+
prompt = f"""
|
| 550 |
+
Problem: {problem}
|
| 551 |
+
Current solution: {solution}
|
| 552 |
+
|
| 553 |
+
Enhance this solution by:
|
| 554 |
+
1. Adding implementation details
|
| 555 |
+
2. Identifying potential risks
|
| 556 |
+
3. Suggesting improvements
|
| 557 |
+
4. Providing step-by-step approach
|
| 558 |
+
|
| 559 |
+
Return enhanced solution.
|
| 560 |
+
"""
|
| 561 |
+
|
| 562 |
+
try:
|
| 563 |
+
response = self.openai_client.chat.completions.create(
|
| 564 |
+
model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free",
|
| 565 |
+
messages=[{"role": "user", "content": prompt}],
|
| 566 |
+
max_tokens=1000,
|
| 567 |
+
temperature=0.5
|
| 568 |
+
)
|
| 569 |
+
|
| 570 |
+
enhanced_text = response.choices[0].message.content.strip()
|
| 571 |
+
return {"detailed_solution": enhanced_text}
|
| 572 |
+
|
| 573 |
+
except Exception as e:
|
| 574 |
+
logger.error(f"Solution enhancement failed: {e}")
|
| 575 |
+
return {}
|
| 576 |
+
|
| 577 |
+
# Helper methods for reasoning strategies
|
| 578 |
+
def _find_relevant_knowledge(self, concepts: List[str]) -> str:
|
| 579 |
+
"""Find relevant knowledge from knowledge graph"""
|
| 580 |
+
relevant = []
|
| 581 |
+
for concept in concepts:
|
| 582 |
+
if concept in self.knowledge_graph:
|
| 583 |
+
node = self.knowledge_graph[concept]
|
| 584 |
+
relevant.append(f"{concept}: {node.properties}")
|
| 585 |
+
return str(relevant) if relevant else "No specific knowledge found"
|
| 586 |
+
|
| 587 |
+
def _find_patterns(self, concepts: List[str]) -> List[str]:
|
| 588 |
+
"""Find patterns in historical data"""
|
| 589 |
+
# Simplified pattern finding
|
| 590 |
+
patterns = []
|
| 591 |
+
for concept in concepts:
|
| 592 |
+
if concept in self.knowledge_graph:
|
| 593 |
+
patterns.append(f"Pattern for {concept}: recurring structure")
|
| 594 |
+
return patterns if patterns else ["No clear patterns identified"]
|
| 595 |
+
|
| 596 |
+
def _generate_explanations(self, problem: str, analysis: Dict) -> List[Dict]:
|
| 597 |
+
"""Generate possible explanations"""
|
| 598 |
+
explanations = [
|
| 599 |
+
{"explanation": "Direct causal relationship", "likelihood": 0.7},
|
| 600 |
+
{"explanation": "Complex system interaction", "likelihood": 0.6},
|
| 601 |
+
{"explanation": "Emergent behavior", "likelihood": 0.5}
|
| 602 |
+
]
|
| 603 |
+
return explanations
|
| 604 |
+
|
| 605 |
+
def _find_analogies(self, concepts: List[str]) -> List[str]:
|
| 606 |
+
"""Find analogous situations"""
|
| 607 |
+
analogies = []
|
| 608 |
+
for concept in concepts:
|
| 609 |
+
analogies.append(f"Similar to: {concept} in different context")
|
| 610 |
+
return analogies if analogies else ["No clear analogies found"]
|
| 611 |
+
|
| 612 |
+
def _identify_causes(self, problem: str, analysis: Dict) -> List[str]:
|
| 613 |
+
"""Identify potential causes"""
|
| 614 |
+
causes = []
|
| 615 |
+
for constraint in analysis.get('constraints', []):
|
| 616 |
+
causes.append(f"Constraint-based cause: {constraint}")
|
| 617 |
+
return causes if causes else ["Causes need investigation"]
|
| 618 |
+
|
| 619 |
+
def _predict_effects(self, causes: List[str]) -> List[str]:
|
| 620 |
+
"""Predict effects from causes"""
|
| 621 |
+
effects = []
|
| 622 |
+
for cause in causes:
|
| 623 |
+
effects.append(f"Effect of {cause}: downstream impact")
|
| 624 |
+
return effects
|
| 625 |
+
|
| 626 |
+
def _analyze_temporal_aspects(self, problem: str) -> List[str]:
|
| 627 |
+
"""Analyze temporal aspects"""
|
| 628 |
+
temporal_words = ['when', 'before', 'after', 'during', 'time', 'sequence']
|
| 629 |
+
aspects = []
|
| 630 |
+
for word in temporal_words:
|
| 631 |
+
if word in problem.lower():
|
| 632 |
+
aspects.append(f"Temporal aspect: {word}")
|
| 633 |
+
return aspects if aspects else ["No specific temporal aspects"]
|
| 634 |
+
|
| 635 |
+
def _analyze_spatial_aspects(self, problem: str) -> List[str]:
|
| 636 |
+
"""Analyze spatial aspects"""
|
| 637 |
+
spatial_words = ['where', 'location', 'position', 'place', 'space', 'distance']
|
| 638 |
+
aspects = []
|
| 639 |
+
for word in spatial_words:
|
| 640 |
+
if word in problem.lower():
|
| 641 |
+
aspects.append(f"Spatial aspect: {word}")
|
| 642 |
+
return aspects if aspects else ["No specific spatial aspects"]
|
| 643 |
+
|
| 644 |
+
def _analyze_logical_structure(self, problem: str) -> str:
|
| 645 |
+
"""Analyze logical structure"""
|
| 646 |
+
if 'if' in problem.lower() and 'then' in problem.lower():
|
| 647 |
+
return "Conditional logic structure"
|
| 648 |
+
elif any(word in problem.lower() for word in ['all', 'some', 'none']):
|
| 649 |
+
return "Quantified logic structure"
|
| 650 |
+
else:
|
| 651 |
+
return "General logical structure"
|
| 652 |
+
|
| 653 |
+
def _generate_creative_ideas(self, problem: str, analysis: Dict) -> List[str]:
|
| 654 |
+
"""Generate creative ideas"""
|
| 655 |
+
ideas = [
|
| 656 |
+
"Reverse the problem approach",
|
| 657 |
+
"Combine unrelated concepts",
|
| 658 |
+
"Question fundamental assumptions",
|
| 659 |
+
"Apply metaphorical thinking"
|
| 660 |
+
]
|
| 661 |
+
return ideas
|
| 662 |
+
|
| 663 |
+
def _update_strategy_weights(self, results: List[ReasoningStep]):
|
| 664 |
+
"""Update strategy weights based on performance"""
|
| 665 |
+
for result in results:
|
| 666 |
+
if result.confidence > 0.8:
|
| 667 |
+
self.strategy_weights[result.reasoning_type] *= 1.1
|
| 668 |
+
elif result.confidence < 0.4:
|
| 669 |
+
self.strategy_weights[result.reasoning_type] *= 0.9
|
| 670 |
+
|
| 671 |
+
def _calculate_overall_confidence(self, reasoning_steps: List[ReasoningStep]) -> float:
|
| 672 |
+
"""Calculate overall confidence in reasoning"""
|
| 673 |
+
if not reasoning_steps:
|
| 674 |
+
return 0.0
|
| 675 |
+
|
| 676 |
+
confidences = [step.confidence for step in reasoning_steps]
|
| 677 |
+
return sum(confidences) / len(confidences)
|
| 678 |
+
|
| 679 |
+
def _update_knowledge_from_reasoning(self, problem: str, solution: Dict, reasoning: List[ReasoningStep]):
|
| 680 |
+
"""Update knowledge base from reasoning experience"""
|
| 681 |
+
# Extract new knowledge from successful reasoning
|
| 682 |
+
if solution.get('confidence', 0) > 0.7:
|
| 683 |
+
new_concept = f"problem_solution_{len(self.knowledge_graph)}"
|
| 684 |
+
properties = {
|
| 685 |
+
"problem_type": solution.get('reasoning_type', 'unknown'),
|
| 686 |
+
"solution_approach": solution.get('primary_approach', ''),
|
| 687 |
+
"success_rate": solution.get('confidence', 0)
|
| 688 |
+
}
|
| 689 |
+
|
| 690 |
+
self.add_knowledge(new_concept, properties, {}, solution.get('confidence', 0), "reasoning_experience")
|
| 691 |
+
|
| 692 |
+
def get_reasoning_explanation(self, reasoning_result: Dict) -> str:
|
| 693 |
+
"""Generate human-readable explanation of reasoning process"""
|
| 694 |
+
explanation = f"""
|
| 695 |
+
REASONING ANALYSIS FOR: {reasoning_result['problem']}
|
| 696 |
+
|
| 697 |
+
Problem Analysis:
|
| 698 |
+
- Type: {reasoning_result['analysis']['problem_type']}
|
| 699 |
+
- Domain: {reasoning_result['analysis']['domain']}
|
| 700 |
+
- Complexity: {reasoning_result['analysis']['complexity']}
|
| 701 |
+
|
| 702 |
+
Reasoning Strategies Applied:
|
| 703 |
+
{', '.join(reasoning_result['strategies_used'])}
|
| 704 |
+
|
| 705 |
+
Key Reasoning Steps:
|
| 706 |
+
"""
|
| 707 |
+
|
| 708 |
+
for i, step in enumerate(reasoning_result['reasoning_steps'][:3], 1):
|
| 709 |
+
explanation += f"""
|
| 710 |
+
{i}. {step.reasoning_type.value.title()} Reasoning:
|
| 711 |
+
- Premise: {step.premise}
|
| 712 |
+
- Conclusion: {step.conclusion}
|
| 713 |
+
- Confidence: {step.confidence:.2f}
|
| 714 |
+
"""
|
| 715 |
+
|
| 716 |
+
explanation += f"""
|
| 717 |
+
|
| 718 |
+
Final Solution:
|
| 719 |
+
{reasoning_result['solution']['primary_approach']}
|
| 720 |
+
|
| 721 |
+
Overall Confidence: {reasoning_result['confidence']:.2f}
|
| 722 |
+
"""
|
| 723 |
+
|
| 724 |
+
return explanation
|
| 725 |
+
|
| 726 |
+
|
| 727 |
+
def create_general_reasoning_engine(openai_api_key: str = None) -> GeneralReasoningEngine:
|
| 728 |
+
"""Factory function to create reasoning engine"""
|
| 729 |
+
openai_client = None
|
| 730 |
+
if openai_api_key:
|
| 731 |
+
openai_client = OpenAI(
|
| 732 |
+
base_url="https://api.together.ai/",
|
| 733 |
+
api_key=openai_api_key
|
| 734 |
+
)
|
| 735 |
+
|
| 736 |
+
return GeneralReasoningEngine(openai_client=openai_client)
|
| 737 |
+
|
| 738 |
+
|
| 739 |
+
# Example usage
|
| 740 |
+
if __name__ == "__main__":
|
| 741 |
+
# Create reasoning engine
|
| 742 |
+
api_key = "afc478b561fbd2629f96f8f69041d780f3b9a94adcfe276f30818ee84a5e0358"
|
| 743 |
+
reasoning_engine = create_general_reasoning_engine(openai_api_key=api_key)
|
| 744 |
+
|
| 745 |
+
# Test problems
|
| 746 |
+
test_problems = [
|
| 747 |
+
"How can I optimize the performance of a machine learning model?",
|
| 748 |
+
"What's the best way to design a user interface for elderly users?",
|
| 749 |
+
"How do I solve the problem of declining team productivity?",
|
| 750 |
+
"What causes climate change and how can we address it?",
|
| 751 |
+
"How can I create a more efficient algorithm for sorting data?"
|
| 752 |
+
]
|
| 753 |
+
|
| 754 |
+
for problem in test_problems:
|
| 755 |
+
print(f"\n{'='*60}")
|
| 756 |
+
print(f"REASONING ABOUT: {problem}")
|
| 757 |
+
print('='*60)
|
| 758 |
+
|
| 759 |
+
result = reasoning_engine.reason_about_problem(problem)
|
| 760 |
+
explanation = reasoning_engine.get_reasoning_explanation(result)
|
| 761 |
+
print(explanation)
|
maintainer.py
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from openai import OpenAI
|
| 2 |
+
import aitech
|
| 3 |
+
import difflib
|
| 4 |
+
MODEL_NAME = "deepseek-ai/DeepSeek-R1-0528-tput"
|
| 5 |
+
|
| 6 |
+
client = OpenAI(
|
| 7 |
+
base_url="https://api.together.ai/",
|
| 8 |
+
api_key="afc478b561fbd2629f96f8f69041d780f3b9a94adcfe276f30818ee84a5e0358"
|
| 9 |
+
)
|
| 10 |
+
|
| 11 |
+
agent_reward = 0
|
| 12 |
+
|
| 13 |
+
f = open("aitech.py", "r")
|
| 14 |
+
code = f.read()
|
| 15 |
+
f.close()
|
| 16 |
+
|
| 17 |
+
def generate():
|
| 18 |
+
prompt = f"""your task is to create a python code for a self rewirting powerful ai agent that is having a recursive \
|
| 19 |
+
self improvement loop and can learn from its past action and mistakes and can make imporvements on those things also make the agent's code fully functional."""
|
| 20 |
+
response = client.chat.completions.create(
|
| 21 |
+
model=MODEL_NAME,
|
| 22 |
+
messages=[{"role": "user", "content": prompt}],
|
| 23 |
+
max_tokens=6000,
|
| 24 |
+
temperature=0.3,
|
| 25 |
+
)
|
| 26 |
+
return response.choices[0].message.content.strip()
|
| 27 |
+
|
| 28 |
+
big_model_code = generate()
|
| 29 |
+
similarity = difflib.SequenceMatcher(None, code, big_model_code).ratio()
|
| 30 |
+
|
| 31 |
+
if similarity >= 0.8:
|
| 32 |
+
agent_reward += 1
|
| 33 |
+
print(f"Rewarded! Similarity: {similarity:.2f}. Total reward: {agent_reward}")
|
| 34 |
+
else:
|
| 35 |
+
agent_reward -= 2
|
| 36 |
+
print(f"Penalized! Similarity: {similarity:.2f}. Total reward: {agent_reward}")
|
| 37 |
+
|
| 38 |
+
if code != big_model_code:
|
| 39 |
+
with open("aitech.py", "w") as f:
|
| 40 |
+
f.write(big_model_code)
|
neural_pipeline.py
ADDED
|
@@ -0,0 +1,445 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
import json
|
| 4 |
+
import os
|
| 5 |
+
from typing import Dict, List, Tuple, Optional
|
| 6 |
+
from transformer import Transformer, create_transformer_model, initialize_weights
|
| 7 |
+
from openai import OpenAI
|
| 8 |
+
import logging
|
| 9 |
+
|
| 10 |
+
# Configure logging
|
| 11 |
+
logging.basicConfig(level=logging.INFO)
|
| 12 |
+
logger = logging.getLogger(__name__)
|
| 13 |
+
|
| 14 |
+
class NeuralPipeline:
|
| 15 |
+
"""
|
| 16 |
+
Neural Pipeline for two-stage processing:
|
| 17 |
+
1. Logic Extraction: Input prompt -> Neural Network + Fine-tuned Model -> Extract logic/intent
|
| 18 |
+
2. Task Recognition: Logic/intent -> Neural Network -> Recognize specific task -> Route to expert
|
| 19 |
+
"""
|
| 20 |
+
|
| 21 |
+
def __init__(self,
|
| 22 |
+
transformer_config: Dict = None,
|
| 23 |
+
finetuned_model_path: str = None,
|
| 24 |
+
openai_client: OpenAI = None,
|
| 25 |
+
device: str = "cuda" if torch.cuda.is_available() else "cpu"):
|
| 26 |
+
|
| 27 |
+
self.device = device
|
| 28 |
+
self.openai_client = openai_client
|
| 29 |
+
|
| 30 |
+
# Initialize transformer model
|
| 31 |
+
self.transformer_config = transformer_config or {
|
| 32 |
+
'src_vocab_size': 50000,
|
| 33 |
+
'tgt_vocab_size': 50000,
|
| 34 |
+
'd_model': 512,
|
| 35 |
+
'num_heads': 8,
|
| 36 |
+
'num_layers': 6,
|
| 37 |
+
'd_ff': 2048,
|
| 38 |
+
'max_seq_length': 1024,
|
| 39 |
+
'dropout': 0.1
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
# Create transformer models for different stages
|
| 43 |
+
self.logic_extractor = create_transformer_model(
|
| 44 |
+
src_vocab_size=self.transformer_config['src_vocab_size'],
|
| 45 |
+
tgt_vocab_size=self.transformer_config['tgt_vocab_size']
|
| 46 |
+
).to(self.device)
|
| 47 |
+
|
| 48 |
+
self.task_recognizer = create_transformer_model(
|
| 49 |
+
src_vocab_size=self.transformer_config['src_vocab_size'],
|
| 50 |
+
tgt_vocab_size=self.transformer_config['tgt_vocab_size']
|
| 51 |
+
).to(self.device)
|
| 52 |
+
|
| 53 |
+
# Initialize weights
|
| 54 |
+
initialize_weights(self.logic_extractor)
|
| 55 |
+
initialize_weights(self.task_recognizer)
|
| 56 |
+
|
| 57 |
+
# Load fine-tuned model if provided
|
| 58 |
+
self.finetuned_model_path = finetuned_model_path
|
| 59 |
+
if finetuned_model_path and os.path.exists(finetuned_model_path):
|
| 60 |
+
self.load_finetuned_model(finetuned_model_path)
|
| 61 |
+
|
| 62 |
+
# Task routing configuration
|
| 63 |
+
self.task_experts = {
|
| 64 |
+
'code_generation': self._code_generation_expert,
|
| 65 |
+
'text_analysis': self._text_analysis_expert,
|
| 66 |
+
'problem_solving': self._problem_solving_expert,
|
| 67 |
+
'data_processing': self._data_processing_expert,
|
| 68 |
+
'web_scraping': self._web_scraping_expert,
|
| 69 |
+
'general_query': self._general_query_expert
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
# Vocabulary for tokenization (simplified)
|
| 73 |
+
self.vocab = self._create_vocabulary()
|
| 74 |
+
self.reverse_vocab = {v: k for k, v in self.vocab.items()}
|
| 75 |
+
|
| 76 |
+
def _create_vocabulary(self) -> Dict[str, int]:
|
| 77 |
+
"""Create a simple vocabulary for tokenization"""
|
| 78 |
+
# This is a simplified vocabulary - in practice, you'd use a proper tokenizer
|
| 79 |
+
vocab = {'<pad>': 0, '<unk>': 1, '<sos>': 2, '<eos>': 3}
|
| 80 |
+
|
| 81 |
+
# Add common words and tokens
|
| 82 |
+
common_words = [
|
| 83 |
+
'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for',
|
| 84 |
+
'of', 'with', 'by', 'from', 'up', 'about', 'into', 'through', 'during',
|
| 85 |
+
'before', 'after', 'above', 'below', 'between', 'among', 'this', 'that',
|
| 86 |
+
'these', 'those', 'i', 'you', 'he', 'she', 'it', 'we', 'they', 'me',
|
| 87 |
+
'him', 'her', 'us', 'them', 'my', 'your', 'his', 'her', 'its', 'our',
|
| 88 |
+
'their', 'what', 'which', 'who', 'when', 'where', 'why', 'how', 'is',
|
| 89 |
+
'are', 'was', 'were', 'be', 'been', 'being', 'have', 'has', 'had',
|
| 90 |
+
'do', 'does', 'did', 'will', 'would', 'could', 'should', 'may', 'might',
|
| 91 |
+
'must', 'can', 'code', 'function', 'class', 'method', 'variable', 'data',
|
| 92 |
+
'process', 'analyze', 'generate', 'create', 'solve', 'problem', 'task',
|
| 93 |
+
'web', 'scrape', 'search', 'find', 'get', 'set', 'run', 'execute'
|
| 94 |
+
]
|
| 95 |
+
|
| 96 |
+
for i, word in enumerate(common_words, start=4):
|
| 97 |
+
vocab[word] = i
|
| 98 |
+
|
| 99 |
+
return vocab
|
| 100 |
+
|
| 101 |
+
def tokenize(self, text: str) -> List[int]:
|
| 102 |
+
"""Simple tokenization - replace with proper tokenizer in production"""
|
| 103 |
+
words = text.lower().split()
|
| 104 |
+
tokens = [self.vocab.get('<sos>', 2)]
|
| 105 |
+
for word in words:
|
| 106 |
+
tokens.append(self.vocab.get(word, self.vocab.get('<unk>', 1)))
|
| 107 |
+
tokens.append(self.vocab.get('<eos>', 3))
|
| 108 |
+
return tokens
|
| 109 |
+
|
| 110 |
+
def detokenize(self, tokens: List[int]) -> str:
|
| 111 |
+
"""Convert tokens back to text"""
|
| 112 |
+
words = []
|
| 113 |
+
for token in tokens:
|
| 114 |
+
if token in [0, 2, 3]: # Skip pad, sos, eos
|
| 115 |
+
continue
|
| 116 |
+
word = self.reverse_vocab.get(token, '<unk>')
|
| 117 |
+
if word != '<unk>':
|
| 118 |
+
words.append(word)
|
| 119 |
+
return ' '.join(words)
|
| 120 |
+
|
| 121 |
+
def load_finetuned_model(self, model_path: str):
|
| 122 |
+
"""Load fine-tuned model weights"""
|
| 123 |
+
try:
|
| 124 |
+
checkpoint = torch.load(model_path, map_location=self.device)
|
| 125 |
+
if 'logic_extractor' in checkpoint:
|
| 126 |
+
self.logic_extractor.load_state_dict(checkpoint['logic_extractor'])
|
| 127 |
+
if 'task_recognizer' in checkpoint:
|
| 128 |
+
self.task_recognizer.load_state_dict(checkpoint['task_recognizer'])
|
| 129 |
+
logger.info(f"Fine-tuned model loaded from {model_path}")
|
| 130 |
+
except Exception as e:
|
| 131 |
+
logger.error(f"Failed to load fine-tuned model: {e}")
|
| 132 |
+
|
| 133 |
+
def save_model(self, save_path: str):
|
| 134 |
+
"""Save the current model state"""
|
| 135 |
+
checkpoint = {
|
| 136 |
+
'logic_extractor': self.logic_extractor.state_dict(),
|
| 137 |
+
'task_recognizer': self.task_recognizer.state_dict(),
|
| 138 |
+
'config': self.transformer_config
|
| 139 |
+
}
|
| 140 |
+
torch.save(checkpoint, save_path)
|
| 141 |
+
logger.info(f"Model saved to {save_path}")
|
| 142 |
+
|
| 143 |
+
def stage1_logic_extraction(self, prompt: str) -> str:
|
| 144 |
+
"""
|
| 145 |
+
Stage 1: Extract logic/intent from input prompt using neural network + fine-tuned model
|
| 146 |
+
"""
|
| 147 |
+
logger.info("Stage 1: Logic extraction started")
|
| 148 |
+
|
| 149 |
+
# Tokenize input
|
| 150 |
+
input_tokens = self.tokenize(prompt)
|
| 151 |
+
src_tensor = torch.tensor([input_tokens], dtype=torch.long).to(self.device)
|
| 152 |
+
|
| 153 |
+
# Pad to minimum length for transformer
|
| 154 |
+
min_len = 10
|
| 155 |
+
if src_tensor.size(1) < min_len:
|
| 156 |
+
padding = torch.zeros(1, min_len - src_tensor.size(1), dtype=torch.long).to(self.device)
|
| 157 |
+
src_tensor = torch.cat([src_tensor, padding], dim=1)
|
| 158 |
+
|
| 159 |
+
# Create target tensor for logic extraction
|
| 160 |
+
tgt_tensor = torch.tensor([[2] + [0] * (src_tensor.size(1) - 1)], dtype=torch.long).to(self.device)
|
| 161 |
+
|
| 162 |
+
# Run through logic extractor
|
| 163 |
+
self.logic_extractor.eval()
|
| 164 |
+
with torch.no_grad():
|
| 165 |
+
output = self.logic_extractor(src_tensor, tgt_tensor)
|
| 166 |
+
|
| 167 |
+
# Get the most likely tokens
|
| 168 |
+
predicted_tokens = torch.argmax(output, dim=-1).squeeze().tolist()
|
| 169 |
+
|
| 170 |
+
# Convert back to text
|
| 171 |
+
extracted_logic = self.detokenize(predicted_tokens)
|
| 172 |
+
|
| 173 |
+
# Enhance with fine-tuned model if available and OpenAI client is provided
|
| 174 |
+
if self.openai_client:
|
| 175 |
+
enhanced_logic = self._enhance_with_finetuned_model(prompt, extracted_logic)
|
| 176 |
+
logger.info(f"Logic extracted and enhanced: {enhanced_logic}")
|
| 177 |
+
return enhanced_logic
|
| 178 |
+
|
| 179 |
+
logger.info(f"Logic extracted: {extracted_logic}")
|
| 180 |
+
return extracted_logic
|
| 181 |
+
|
| 182 |
+
def _enhance_with_finetuned_model(self, original_prompt: str, neural_output: str) -> str:
|
| 183 |
+
"""Enhance neural network output with fine-tuned model"""
|
| 184 |
+
enhancement_prompt = f"""
|
| 185 |
+
Original user prompt: {original_prompt}
|
| 186 |
+
Neural network extracted logic: {neural_output}
|
| 187 |
+
|
| 188 |
+
Please refine and enhance the extracted logic to better capture the user's intent and requirements.
|
| 189 |
+
Focus on identifying the core task, required actions, and expected outcomes.
|
| 190 |
+
"""
|
| 191 |
+
|
| 192 |
+
try:
|
| 193 |
+
response = self.openai_client.chat.completions.create(
|
| 194 |
+
model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free",
|
| 195 |
+
messages=[{"role": "user", "content": enhancement_prompt}],
|
| 196 |
+
max_tokens=500,
|
| 197 |
+
temperature=0.3
|
| 198 |
+
)
|
| 199 |
+
return response.choices[0].message.content.strip()
|
| 200 |
+
except Exception as e:
|
| 201 |
+
logger.error(f"Fine-tuned model enhancement failed: {e}")
|
| 202 |
+
return neural_output
|
| 203 |
+
|
| 204 |
+
def stage2_task_recognition(self, logic: str) -> str:
|
| 205 |
+
"""
|
| 206 |
+
Stage 2: Recognize specific task from extracted logic using neural network
|
| 207 |
+
"""
|
| 208 |
+
logger.info("Stage 2: Task recognition started")
|
| 209 |
+
|
| 210 |
+
# Tokenize logic
|
| 211 |
+
logic_tokens = self.tokenize(logic)
|
| 212 |
+
src_tensor = torch.tensor([logic_tokens], dtype=torch.long).to(self.device)
|
| 213 |
+
|
| 214 |
+
# Pad to minimum length
|
| 215 |
+
min_len = 10
|
| 216 |
+
if src_tensor.size(1) < min_len:
|
| 217 |
+
padding = torch.zeros(1, min_len - src_tensor.size(1), dtype=torch.long).to(self.device)
|
| 218 |
+
src_tensor = torch.cat([src_tensor, padding], dim=1)
|
| 219 |
+
|
| 220 |
+
# Create target tensor for task recognition
|
| 221 |
+
tgt_tensor = torch.tensor([[2] + [0] * (src_tensor.size(1) - 1)], dtype=torch.long).to(self.device)
|
| 222 |
+
|
| 223 |
+
# Run through task recognizer
|
| 224 |
+
self.task_recognizer.eval()
|
| 225 |
+
with torch.no_grad():
|
| 226 |
+
output = self.task_recognizer(src_tensor, tgt_tensor)
|
| 227 |
+
|
| 228 |
+
# Get predicted tokens
|
| 229 |
+
predicted_tokens = torch.argmax(output, dim=-1).squeeze().tolist()
|
| 230 |
+
task_output = self.detokenize(predicted_tokens)
|
| 231 |
+
|
| 232 |
+
# Map to specific task category
|
| 233 |
+
recognized_task = self._map_to_task_category(logic, task_output)
|
| 234 |
+
logger.info(f"Task recognized: {recognized_task}")
|
| 235 |
+
|
| 236 |
+
return recognized_task
|
| 237 |
+
|
| 238 |
+
def _map_to_task_category(self, logic: str, neural_output: str) -> str:
|
| 239 |
+
"""Map neural network output to specific task categories"""
|
| 240 |
+
logic_lower = logic.lower()
|
| 241 |
+
neural_lower = neural_output.lower()
|
| 242 |
+
|
| 243 |
+
# Simple keyword-based mapping (can be enhanced with more sophisticated methods)
|
| 244 |
+
if any(keyword in logic_lower for keyword in ['code', 'function', 'class', 'program', 'script']):
|
| 245 |
+
return 'code_generation'
|
| 246 |
+
elif any(keyword in logic_lower for keyword in ['analyze', 'analysis', 'text', 'document']):
|
| 247 |
+
return 'text_analysis'
|
| 248 |
+
elif any(keyword in logic_lower for keyword in ['solve', 'problem', 'calculate', 'math']):
|
| 249 |
+
return 'problem_solving'
|
| 250 |
+
elif any(keyword in logic_lower for keyword in ['data', 'process', 'transform', 'clean']):
|
| 251 |
+
return 'data_processing'
|
| 252 |
+
elif any(keyword in logic_lower for keyword in ['web', 'scrape', 'crawl', 'extract']):
|
| 253 |
+
return 'web_scraping'
|
| 254 |
+
else:
|
| 255 |
+
return 'general_query'
|
| 256 |
+
|
| 257 |
+
def stage3_route_to_expert(self, task: str, logic: str, original_prompt: str) -> str:
|
| 258 |
+
"""
|
| 259 |
+
Stage 3: Route the recognized task to appropriate model expert
|
| 260 |
+
"""
|
| 261 |
+
logger.info(f"Stage 3: Routing to expert for task: {task}")
|
| 262 |
+
|
| 263 |
+
if task in self.task_experts:
|
| 264 |
+
return self.task_experts[task](logic, original_prompt)
|
| 265 |
+
else:
|
| 266 |
+
return self.task_experts['general_query'](logic, original_prompt)
|
| 267 |
+
|
| 268 |
+
def _code_generation_expert(self, logic: str, original_prompt: str) -> str:
|
| 269 |
+
"""Expert for code generation tasks"""
|
| 270 |
+
if not self.openai_client:
|
| 271 |
+
return "Code generation expert not available (OpenAI client not configured)"
|
| 272 |
+
|
| 273 |
+
expert_prompt = f"""
|
| 274 |
+
You are a code generation expert. Based on the extracted logic and original prompt, generate the requested code.
|
| 275 |
+
|
| 276 |
+
Extracted Logic: {logic}
|
| 277 |
+
Original Prompt: {original_prompt}
|
| 278 |
+
|
| 279 |
+
Please provide clean, well-commented, and functional code.
|
| 280 |
+
"""
|
| 281 |
+
|
| 282 |
+
return self._call_expert_model(expert_prompt)
|
| 283 |
+
|
| 284 |
+
def _text_analysis_expert(self, logic: str, original_prompt: str) -> str:
|
| 285 |
+
"""Expert for text analysis tasks"""
|
| 286 |
+
if not self.openai_client:
|
| 287 |
+
return "Text analysis expert not available (OpenAI client not configured)"
|
| 288 |
+
|
| 289 |
+
expert_prompt = f"""
|
| 290 |
+
You are a text analysis expert. Based on the extracted logic and original prompt, perform the requested analysis.
|
| 291 |
+
|
| 292 |
+
Extracted Logic: {logic}
|
| 293 |
+
Original Prompt: {original_prompt}
|
| 294 |
+
|
| 295 |
+
Please provide detailed analysis with insights and conclusions.
|
| 296 |
+
"""
|
| 297 |
+
|
| 298 |
+
return self._call_expert_model(expert_prompt)
|
| 299 |
+
|
| 300 |
+
def _problem_solving_expert(self, logic: str, original_prompt: str) -> str:
|
| 301 |
+
"""Expert for problem-solving tasks"""
|
| 302 |
+
if not self.openai_client:
|
| 303 |
+
return "Problem solving expert not available (OpenAI client not configured)"
|
| 304 |
+
|
| 305 |
+
expert_prompt = f"""
|
| 306 |
+
You are a problem-solving expert. Based on the extracted logic and original prompt, solve the given problem step by step.
|
| 307 |
+
|
| 308 |
+
Extracted Logic: {logic}
|
| 309 |
+
Original Prompt: {original_prompt}
|
| 310 |
+
|
| 311 |
+
Please provide a clear solution with step-by-step reasoning.
|
| 312 |
+
"""
|
| 313 |
+
|
| 314 |
+
return self._call_expert_model(expert_prompt)
|
| 315 |
+
|
| 316 |
+
def _data_processing_expert(self, logic: str, original_prompt: str) -> str:
|
| 317 |
+
"""Expert for data processing tasks"""
|
| 318 |
+
if not self.openai_client:
|
| 319 |
+
return "Data processing expert not available (OpenAI client not configured)"
|
| 320 |
+
|
| 321 |
+
expert_prompt = f"""
|
| 322 |
+
You are a data processing expert. Based on the extracted logic and original prompt, provide data processing solutions.
|
| 323 |
+
|
| 324 |
+
Extracted Logic: {logic}
|
| 325 |
+
Original Prompt: {original_prompt}
|
| 326 |
+
|
| 327 |
+
Please provide efficient data processing methods and code if needed.
|
| 328 |
+
"""
|
| 329 |
+
|
| 330 |
+
return self._call_expert_model(expert_prompt)
|
| 331 |
+
|
| 332 |
+
def _web_scraping_expert(self, logic: str, original_prompt: str) -> str:
|
| 333 |
+
"""Expert for web scraping tasks"""
|
| 334 |
+
if not self.openai_client:
|
| 335 |
+
return "Web scraping expert not available (OpenAI client not configured)"
|
| 336 |
+
|
| 337 |
+
expert_prompt = f"""
|
| 338 |
+
You are a web scraping expert. Based on the extracted logic and original prompt, provide web scraping solutions.
|
| 339 |
+
|
| 340 |
+
Extracted Logic: {logic}
|
| 341 |
+
Original Prompt: {original_prompt}
|
| 342 |
+
|
| 343 |
+
Please provide ethical web scraping methods and code with proper error handling.
|
| 344 |
+
"""
|
| 345 |
+
|
| 346 |
+
return self._call_expert_model(expert_prompt)
|
| 347 |
+
|
| 348 |
+
def _general_query_expert(self, logic: str, original_prompt: str) -> str:
|
| 349 |
+
"""Expert for general queries"""
|
| 350 |
+
if not self.openai_client:
|
| 351 |
+
return "General query expert not available (OpenAI client not configured)"
|
| 352 |
+
|
| 353 |
+
expert_prompt = f"""
|
| 354 |
+
You are a general knowledge expert. Based on the extracted logic and original prompt, provide a comprehensive response.
|
| 355 |
+
|
| 356 |
+
Extracted Logic: {logic}
|
| 357 |
+
Original Prompt: {original_prompt}
|
| 358 |
+
|
| 359 |
+
Please provide a helpful and informative response.
|
| 360 |
+
"""
|
| 361 |
+
|
| 362 |
+
return self._call_expert_model(expert_prompt)
|
| 363 |
+
|
| 364 |
+
def _call_expert_model(self, prompt: str) -> str:
|
| 365 |
+
"""Call the expert model (fine-tuned model via OpenAI API)"""
|
| 366 |
+
try:
|
| 367 |
+
response = self.openai_client.chat.completions.create(
|
| 368 |
+
model="meta-llama/Llama-3.3-70B-Instruct-Turbo-Free",
|
| 369 |
+
messages=[{"role": "user", "content": prompt}],
|
| 370 |
+
max_tokens=1500,
|
| 371 |
+
temperature=0.7
|
| 372 |
+
)
|
| 373 |
+
return response.choices[0].message.content.strip()
|
| 374 |
+
except Exception as e:
|
| 375 |
+
logger.error(f"Expert model call failed: {e}")
|
| 376 |
+
return f"Expert model unavailable. Error: {str(e)}"
|
| 377 |
+
|
| 378 |
+
def process_prompt(self, prompt: str) -> Dict[str, str]:
|
| 379 |
+
"""
|
| 380 |
+
Complete pipeline: Process input prompt through all three stages
|
| 381 |
+
"""
|
| 382 |
+
logger.info(f"Processing prompt: {prompt}")
|
| 383 |
+
|
| 384 |
+
# Stage 1: Logic Extraction
|
| 385 |
+
extracted_logic = self.stage1_logic_extraction(prompt)
|
| 386 |
+
|
| 387 |
+
# Stage 2: Task Recognition
|
| 388 |
+
recognized_task = self.stage2_task_recognition(extracted_logic)
|
| 389 |
+
|
| 390 |
+
# Stage 3: Route to Expert
|
| 391 |
+
expert_response = self.stage3_route_to_expert(recognized_task, extracted_logic, prompt)
|
| 392 |
+
|
| 393 |
+
result = {
|
| 394 |
+
'original_prompt': prompt,
|
| 395 |
+
'extracted_logic': extracted_logic,
|
| 396 |
+
'recognized_task': recognized_task,
|
| 397 |
+
'expert_response': expert_response
|
| 398 |
+
}
|
| 399 |
+
|
| 400 |
+
logger.info("Pipeline processing completed")
|
| 401 |
+
return result
|
| 402 |
+
|
| 403 |
+
|
| 404 |
+
def create_neural_pipeline(openai_api_key: str = None,
|
| 405 |
+
finetuned_model_path: str = None) -> NeuralPipeline:
|
| 406 |
+
"""
|
| 407 |
+
Factory function to create a neural pipeline with OpenAI client
|
| 408 |
+
"""
|
| 409 |
+
openai_client = None
|
| 410 |
+
if openai_api_key:
|
| 411 |
+
openai_client = OpenAI(
|
| 412 |
+
base_url="https://api.together.ai/",
|
| 413 |
+
api_key=openai_api_key
|
| 414 |
+
)
|
| 415 |
+
|
| 416 |
+
return NeuralPipeline(
|
| 417 |
+
openai_client=openai_client,
|
| 418 |
+
finetuned_model_path=finetuned_model_path
|
| 419 |
+
)
|
| 420 |
+
|
| 421 |
+
|
| 422 |
+
# Example usage
|
| 423 |
+
if __name__ == "__main__":
|
| 424 |
+
# Create pipeline
|
| 425 |
+
api_key = "afc478b561fbd2629f96f8f69041d780f3b9a94adcfe276f30818ee84a5e0358" # Your API key
|
| 426 |
+
pipeline = create_neural_pipeline(openai_api_key=api_key)
|
| 427 |
+
|
| 428 |
+
# Test prompts
|
| 429 |
+
test_prompts = [
|
| 430 |
+
"Create a Python function to calculate fibonacci numbers",
|
| 431 |
+
"Analyze the sentiment of customer reviews",
|
| 432 |
+
"Scrape product information from an e-commerce website",
|
| 433 |
+
"Process CSV data and generate summary statistics"
|
| 434 |
+
]
|
| 435 |
+
|
| 436 |
+
for prompt in test_prompts:
|
| 437 |
+
print(f"\n{'='*50}")
|
| 438 |
+
print(f"Testing: {prompt}")
|
| 439 |
+
print('='*50)
|
| 440 |
+
|
| 441 |
+
result = pipeline.process_prompt(prompt)
|
| 442 |
+
|
| 443 |
+
print(f"Extracted Logic: {result['extracted_logic']}")
|
| 444 |
+
print(f"Recognized Task: {result['recognized_task']}")
|
| 445 |
+
print(f"Expert Response: {result['expert_response'][:200]}...") # Truncated for display
|
transformer.py
ADDED
|
@@ -0,0 +1,247 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import torch
|
| 2 |
+
import torch.nn as nn
|
| 3 |
+
import torch.nn.functional as F
|
| 4 |
+
import math
|
| 5 |
+
import numpy as np
|
| 6 |
+
|
| 7 |
+
|
| 8 |
+
class MultiHeadAttention(nn.Module):
|
| 9 |
+
"""Multi-Head Attention mechanism"""
|
| 10 |
+
|
| 11 |
+
def __init__(self, d_model, num_heads):
|
| 12 |
+
super(MultiHeadAttention, self).__init__()
|
| 13 |
+
assert d_model % num_heads == 0
|
| 14 |
+
|
| 15 |
+
self.d_model = d_model
|
| 16 |
+
self.num_heads = num_heads
|
| 17 |
+
self.d_k = d_model // num_heads
|
| 18 |
+
|
| 19 |
+
self.W_q = nn.Linear(d_model, d_model)
|
| 20 |
+
self.W_k = nn.Linear(d_model, d_model)
|
| 21 |
+
self.W_v = nn.Linear(d_model, d_model)
|
| 22 |
+
self.W_o = nn.Linear(d_model, d_model)
|
| 23 |
+
|
| 24 |
+
def scaled_dot_product_attention(self, Q, K, V, mask=None):
|
| 25 |
+
attn_scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
|
| 26 |
+
if mask is not None:
|
| 27 |
+
attn_scores = attn_scores.masked_fill(mask == 0, -1e9)
|
| 28 |
+
attn_probs = torch.softmax(attn_scores, dim=-1)
|
| 29 |
+
output = torch.matmul(attn_probs, V)
|
| 30 |
+
return output
|
| 31 |
+
|
| 32 |
+
def forward(self, query, key, value, mask=None):
|
| 33 |
+
batch_size = query.size(0)
|
| 34 |
+
|
| 35 |
+
Q = self.W_q(query)
|
| 36 |
+
K = self.W_k(key)
|
| 37 |
+
V = self.W_v(value)
|
| 38 |
+
|
| 39 |
+
Q = Q.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
|
| 40 |
+
K = K.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
|
| 41 |
+
V = V.view(batch_size, -1, self.num_heads, self.d_k).transpose(1, 2)
|
| 42 |
+
|
| 43 |
+
attn_output = self.scaled_dot_product_attention(Q, K, V, mask)
|
| 44 |
+
|
| 45 |
+
attn_output = attn_output.transpose(1, 2).contiguous().view(
|
| 46 |
+
batch_size, -1, self.d_model)
|
| 47 |
+
|
| 48 |
+
output = self.W_o(attn_output)
|
| 49 |
+
return output
|
| 50 |
+
|
| 51 |
+
|
| 52 |
+
class PositionalEncoding(nn.Module):
|
| 53 |
+
"""Positional encoding for transformer"""
|
| 54 |
+
|
| 55 |
+
def __init__(self, d_model, max_seq_length=5000):
|
| 56 |
+
super(PositionalEncoding, self).__init__()
|
| 57 |
+
|
| 58 |
+
pe = torch.zeros(max_seq_length, d_model)
|
| 59 |
+
position = torch.arange(0, max_seq_length, dtype=torch.float).unsqueeze(1)
|
| 60 |
+
|
| 61 |
+
div_term = torch.exp(torch.arange(0, d_model, 2).float() *
|
| 62 |
+
-(math.log(10000.0) / d_model))
|
| 63 |
+
|
| 64 |
+
pe[:, 0::2] = torch.sin(position * div_term)
|
| 65 |
+
pe[:, 1::2] = torch.cos(position * div_term)
|
| 66 |
+
|
| 67 |
+
self.register_buffer('pe', pe.unsqueeze(0))
|
| 68 |
+
|
| 69 |
+
def forward(self, x):
|
| 70 |
+
return x + self.pe[:, :x.size(1)]
|
| 71 |
+
|
| 72 |
+
|
| 73 |
+
class FeedForward(nn.Module):
|
| 74 |
+
"""Position-wise Feed-Forward Network"""
|
| 75 |
+
|
| 76 |
+
def __init__(self, d_model, d_ff):
|
| 77 |
+
super(FeedForward, self).__init__()
|
| 78 |
+
self.linear1 = nn.Linear(d_model, d_ff)
|
| 79 |
+
self.linear2 = nn.Linear(d_ff, d_model)
|
| 80 |
+
self.relu = nn.ReLU()
|
| 81 |
+
|
| 82 |
+
def forward(self, x):
|
| 83 |
+
return self.linear2(self.relu(self.linear1(x)))
|
| 84 |
+
|
| 85 |
+
|
| 86 |
+
class EncoderLayer(nn.Module):
|
| 87 |
+
"""Single encoder layer with self-attention and feed-forward"""
|
| 88 |
+
|
| 89 |
+
def __init__(self, d_model, num_heads, d_ff, dropout):
|
| 90 |
+
super(EncoderLayer, self).__init__()
|
| 91 |
+
self.self_attn = MultiHeadAttention(d_model, num_heads)
|
| 92 |
+
self.feed_forward = FeedForward(d_model, d_ff)
|
| 93 |
+
self.norm1 = nn.LayerNorm(d_model)
|
| 94 |
+
self.norm2 = nn.LayerNorm(d_model)
|
| 95 |
+
self.dropout = nn.Dropout(dropout)
|
| 96 |
+
|
| 97 |
+
def forward(self, x, mask):
|
| 98 |
+
attn_output = self.self_attn(x, x, x, mask)
|
| 99 |
+
x = self.norm1(x + self.dropout(attn_output))
|
| 100 |
+
ff_output = self.feed_forward(x)
|
| 101 |
+
x = self.norm2(x + self.dropout(ff_output))
|
| 102 |
+
return x
|
| 103 |
+
|
| 104 |
+
|
| 105 |
+
class DecoderLayer(nn.Module):
|
| 106 |
+
"""Single decoder layer with self-attention, cross-attention and feed-forward"""
|
| 107 |
+
|
| 108 |
+
def __init__(self, d_model, num_heads, d_ff, dropout):
|
| 109 |
+
super(DecoderLayer, self).__init__()
|
| 110 |
+
self.self_attn = MultiHeadAttention(d_model, num_heads)
|
| 111 |
+
self.cross_attn = MultiHeadAttention(d_model, num_heads)
|
| 112 |
+
self.feed_forward = FeedForward(d_model, d_ff)
|
| 113 |
+
self.norm1 = nn.LayerNorm(d_model)
|
| 114 |
+
self.norm2 = nn.LayerNorm(d_model)
|
| 115 |
+
self.norm3 = nn.LayerNorm(d_model)
|
| 116 |
+
self.dropout = nn.Dropout(dropout)
|
| 117 |
+
|
| 118 |
+
def forward(self, x, enc_output, src_mask, tgt_mask):
|
| 119 |
+
attn_output = self.self_attn(x, x, x, tgt_mask)
|
| 120 |
+
x = self.norm1(x + self.dropout(attn_output))
|
| 121 |
+
attn_output = self.cross_attn(x, enc_output, enc_output, src_mask)
|
| 122 |
+
x = self.norm2(x + self.dropout(attn_output))
|
| 123 |
+
ff_output = self.feed_forward(x)
|
| 124 |
+
x = self.norm3(x + self.dropout(ff_output))
|
| 125 |
+
return x
|
| 126 |
+
|
| 127 |
+
|
| 128 |
+
class TransformerEncoder(nn.Module):
|
| 129 |
+
"""Stack of encoder layers"""
|
| 130 |
+
|
| 131 |
+
def __init__(self, vocab_size, d_model, num_heads, num_layers, d_ff, max_seq_length, dropout):
|
| 132 |
+
super(TransformerEncoder, self).__init__()
|
| 133 |
+
self.d_model = d_model
|
| 134 |
+
self.embedding = nn.Embedding(vocab_size, d_model)
|
| 135 |
+
self.positional_encoding = PositionalEncoding(d_model, max_seq_length)
|
| 136 |
+
self.layers = nn.ModuleList([EncoderLayer(d_model, num_heads, d_ff, dropout)
|
| 137 |
+
for _ in range(num_layers)])
|
| 138 |
+
self.dropout = nn.Dropout(dropout)
|
| 139 |
+
|
| 140 |
+
def forward(self, src, mask):
|
| 141 |
+
src_emb = self.embedding(src) * math.sqrt(self.d_model)
|
| 142 |
+
src_emb = self.positional_encoding(src_emb)
|
| 143 |
+
src_emb = self.dropout(src_emb)
|
| 144 |
+
|
| 145 |
+
for layer in self.layers:
|
| 146 |
+
src_emb = layer(src_emb, mask)
|
| 147 |
+
|
| 148 |
+
return src_emb
|
| 149 |
+
|
| 150 |
+
|
| 151 |
+
class TransformerDecoder(nn.Module):
|
| 152 |
+
"""Stack of decoder layers"""
|
| 153 |
+
|
| 154 |
+
def __init__(self, vocab_size, d_model, num_heads, num_layers, d_ff, max_seq_length, dropout):
|
| 155 |
+
super(TransformerDecoder, self).__init__()
|
| 156 |
+
self.d_model = d_model
|
| 157 |
+
self.embedding = nn.Embedding(vocab_size, d_model)
|
| 158 |
+
self.positional_encoding = PositionalEncoding(d_model, max_seq_length)
|
| 159 |
+
self.layers = nn.ModuleList([DecoderLayer(d_model, num_heads, d_ff, dropout)
|
| 160 |
+
for _ in range(num_layers)])
|
| 161 |
+
self.dropout = nn.Dropout(dropout)
|
| 162 |
+
|
| 163 |
+
def forward(self, tgt, enc_output, src_mask, tgt_mask):
|
| 164 |
+
tgt_emb = self.embedding(tgt) * math.sqrt(self.d_model)
|
| 165 |
+
tgt_emb = self.positional_encoding(tgt_emb)
|
| 166 |
+
tgt_emb = self.dropout(tgt_emb)
|
| 167 |
+
|
| 168 |
+
for layer in self.layers:
|
| 169 |
+
tgt_emb = layer(tgt_emb, enc_output, src_mask, tgt_mask)
|
| 170 |
+
|
| 171 |
+
return tgt_emb
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
class Transformer(nn.Module):
|
| 175 |
+
"""Complete Transformer model"""
|
| 176 |
+
|
| 177 |
+
def __init__(self, src_vocab_size, tgt_vocab_size, d_model=512, num_heads=8,
|
| 178 |
+
num_layers=6, d_ff=2048, max_seq_length=5000, dropout=0.1):
|
| 179 |
+
super(Transformer, self).__init__()
|
| 180 |
+
self.encoder = TransformerEncoder(src_vocab_size, d_model, num_heads,
|
| 181 |
+
num_layers, d_ff, max_seq_length, dropout)
|
| 182 |
+
self.decoder = TransformerDecoder(tgt_vocab_size, d_model, num_heads,
|
| 183 |
+
num_layers, d_ff, max_seq_length, dropout)
|
| 184 |
+
self.fc_out = nn.Linear(d_model, tgt_vocab_size)
|
| 185 |
+
self.dropout = nn.Dropout(dropout)
|
| 186 |
+
|
| 187 |
+
def generate_mask(self, src, tgt):
|
| 188 |
+
src_mask = (src != 0).unsqueeze(1).unsqueeze(2)
|
| 189 |
+
tgt_mask = (tgt != 0).unsqueeze(1).unsqueeze(3)
|
| 190 |
+
seq_length = tgt.size(1)
|
| 191 |
+
nopeak_mask = (1 - torch.triu(torch.ones(1, seq_length, seq_length), diagonal=1)).bool()
|
| 192 |
+
tgt_mask = tgt_mask & nopeak_mask
|
| 193 |
+
return src_mask, tgt_mask
|
| 194 |
+
|
| 195 |
+
def forward(self, src, tgt):
|
| 196 |
+
src_mask, tgt_mask = self.generate_mask(src, tgt)
|
| 197 |
+
enc_output = self.encoder(src, src_mask)
|
| 198 |
+
dec_output = self.decoder(tgt, enc_output, src_mask, tgt_mask)
|
| 199 |
+
output = self.fc_out(dec_output)
|
| 200 |
+
return output
|
| 201 |
+
|
| 202 |
+
|
| 203 |
+
# Example usage and utility functions
|
| 204 |
+
def create_transformer_model(src_vocab_size=10000, tgt_vocab_size=10000):
|
| 205 |
+
"""Create a transformer model with default parameters"""
|
| 206 |
+
model = Transformer(
|
| 207 |
+
src_vocab_size=src_vocab_size,
|
| 208 |
+
tgt_vocab_size=tgt_vocab_size,
|
| 209 |
+
d_model=512,
|
| 210 |
+
num_heads=8,
|
| 211 |
+
num_layers=6,
|
| 212 |
+
d_ff=2048,
|
| 213 |
+
max_seq_length=5000,
|
| 214 |
+
dropout=0.1
|
| 215 |
+
)
|
| 216 |
+
return model
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
def count_parameters(model):
|
| 220 |
+
"""Count the number of trainable parameters in the model"""
|
| 221 |
+
return sum(p.numel() for p in model.parameters() if p.requires_grad)
|
| 222 |
+
|
| 223 |
+
|
| 224 |
+
def initialize_weights(model):
|
| 225 |
+
"""Initialize model weights using Xavier initialization"""
|
| 226 |
+
for p in model.parameters():
|
| 227 |
+
if p.dim() > 1:
|
| 228 |
+
nn.init.xavier_uniform_(p)
|
| 229 |
+
|
| 230 |
+
|
| 231 |
+
if __name__ == "__main__":
|
| 232 |
+
# Example usage
|
| 233 |
+
model = create_transformer_model()
|
| 234 |
+
initialize_weights(model)
|
| 235 |
+
|
| 236 |
+
print(f"Model created with {count_parameters(model):,} trainable parameters")
|
| 237 |
+
|
| 238 |
+
# Example forward pass
|
| 239 |
+
batch_size = 2
|
| 240 |
+
src_seq_len = 10
|
| 241 |
+
tgt_seq_len = 8
|
| 242 |
+
|
| 243 |
+
src = torch.randint(1, 1000, (batch_size, src_seq_len))
|
| 244 |
+
tgt = torch.randint(1, 1000, (batch_size, tgt_seq_len))
|
| 245 |
+
|
| 246 |
+
output = model(src, tgt)
|
| 247 |
+
print(f"Output shape: {output.shape}") # Should be (batch_size, tgt_seq_len, tgt_vocab_size)
|