Fixing CUDA errors
This commit is contained in:
parent
f21e9b433e
commit
5f74b2c64c
1
.gitignore
vendored
1
.gitignore
vendored
@ -175,3 +175,4 @@ cython_debug/
|
||||
/data/memory/dreams.json
|
||||
data/memory/brainmap.json
|
||||
/data/memory/vocab.json
|
||||
data/memory/book_progress.json
|
||||
|
@ -5,6 +5,7 @@ from model.memory import load_dreams
|
||||
from model.tokenizer import Tokenizer
|
||||
from model.abstraction import cluster_vocab
|
||||
from model.memory import load_dreams
|
||||
from model.scheduler import get_time_until_next_action, get_next_action_label
|
||||
from context.context import load_context
|
||||
import json
|
||||
import os
|
||||
@ -37,13 +38,16 @@ def index():
|
||||
top_dreams = dreams[:5]
|
||||
memory_size = len(load_context())
|
||||
loss_data = load_loss_data()
|
||||
remaining = max(0, int(next_cycle_time - time.time()))
|
||||
next_cycle = get_time_until_next_action()
|
||||
next_action_label = get_next_action_label()
|
||||
|
||||
return render_template("index.html",
|
||||
vocab_size=len(tokenizer.vocab),
|
||||
top_dreams=top_dreams,
|
||||
memory_size=memory_size,
|
||||
loss_data=loss_data,
|
||||
next_cycle=remaining)
|
||||
next_cycle=next_cycle,
|
||||
next_action_label=next_action_label)
|
||||
|
||||
|
||||
@app.route("/growth")
|
||||
|
@ -2,6 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="refresh" content="60">
|
||||
<title>Ruby's Brain Map</title>
|
||||
<script src="https://cdn.jsdelivr.net/npm/force-graph"></script>
|
||||
<style>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="refresh" content="30">
|
||||
<title>Ruby's Dashboard</title>
|
||||
<style>
|
||||
body {
|
||||
@ -27,24 +28,38 @@
|
||||
border-top: 1px solid #333;
|
||||
margin: 20px 0;
|
||||
}
|
||||
.entry {
|
||||
margin-bottom: 15px;
|
||||
padding-bottom: 10px;
|
||||
border-bottom: 1px solid #333;
|
||||
}
|
||||
.nav {
|
||||
background-color: #1e1e1e;
|
||||
padding: 10px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.nav a {
|
||||
color: #e0e0e0;
|
||||
margin-right: 20px;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body>
|
||||
|
||||
<div class="nav">
|
||||
<a href="/">🏠 Home</a>
|
||||
<a href="/journal">📓 Journal</a>
|
||||
<a href="/concepts">🧠 Concepts</a>
|
||||
<a href="/brainmap">🕸️ Brain Map</a>
|
||||
<a href="/growth">📈 Growth</a>
|
||||
<a href="/dreams">💬 Dreams</a>
|
||||
</div>
|
||||
<div class="nav">
|
||||
<a href="/">🏠 Home</a>
|
||||
<a href="/journal">📓 Journal</a>
|
||||
<a href="/concepts">🧠 Concepts</a>
|
||||
<a href="/brainmap">🕸️ Brain Map</a>
|
||||
<a href="/growth">📈 Growth</a>
|
||||
<a href="/dreams">💬 Dreams</a>
|
||||
</div>
|
||||
|
||||
<h1>Ruby is Running 🧠</h1>
|
||||
|
||||
<div class="section">
|
||||
<h2>⏳ Next Cycle Countdown</h2>
|
||||
<h2>⏳ Next Cycle</h2>
|
||||
<p><strong>Next:</strong> {{ next_action_label }}</p>
|
||||
<p id="countdown">{{ next_cycle }} seconds</p>
|
||||
</div>
|
||||
|
||||
|
25
main.py
25
main.py
@ -8,8 +8,10 @@ from model.brain import generate_response
|
||||
from model.cleanup import full_cleanup
|
||||
from model.dream_replay import replay_dreams
|
||||
from model.rehearsal import simulate_conversation
|
||||
from model.scheduler import set_next_action
|
||||
from reader.reader import read_books_forever
|
||||
from dashboard.dashboard import run_dashboard
|
||||
import threading
|
||||
|
||||
load_dotenv()
|
||||
TOKEN = os.getenv("DISCORD_TOKEN")
|
||||
@ -43,27 +45,38 @@ threading.Thread(target=run_dashboard, daemon=True).start()
|
||||
async def background_cleanup_loop():
|
||||
while True:
|
||||
full_cleanup()
|
||||
set_next_action(300, "Cleaning up")
|
||||
await asyncio.sleep(300) # 5 minutes
|
||||
|
||||
|
||||
async def dream_replay_loop():
|
||||
while True:
|
||||
replay_dreams()
|
||||
set_next_action(900, "Dreaming new dreams")
|
||||
await asyncio.sleep(900) # Replay every 15 minutes
|
||||
|
||||
|
||||
async def rehearsal_loop():
|
||||
while True:
|
||||
simulate_conversation()
|
||||
set_next_action(1200, "Practicing Conversations")
|
||||
await asyncio.sleep(1200) # Every 20 minutes
|
||||
|
||||
|
||||
# Launch background tasks
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(read_books_forever()) # Book reader task
|
||||
loop.create_task(background_cleanup_loop())
|
||||
loop.create_task(dream_replay_loop())
|
||||
loop.create_task(rehearsal_loop())
|
||||
# Start Ruby's Brain Loops in a separate thread
|
||||
def start_brain_loops():
|
||||
loop = asyncio.new_event_loop()
|
||||
asyncio.set_event_loop(loop)
|
||||
|
||||
loop.create_task(read_books_forever())
|
||||
loop.create_task(dream_replay_loop())
|
||||
loop.create_task(background_cleanup_loop())
|
||||
loop.create_task(rehearsal_loop())
|
||||
|
||||
loop.run_forever()
|
||||
|
||||
|
||||
threading.Thread(target=start_brain_loops, daemon=True).start()
|
||||
|
||||
# Launch Discord bot (blocking)
|
||||
client.run(TOKEN)
|
||||
|
@ -1,9 +1,12 @@
|
||||
import random
|
||||
from model.memory import load_dreams
|
||||
from model.trainer import train_on_message
|
||||
from model.dynamic_expand import expand_model_if_needed
|
||||
|
||||
|
||||
def replay_dreams():
|
||||
expand_model_if_needed()
|
||||
|
||||
dreams = load_dreams()
|
||||
if not dreams:
|
||||
return
|
||||
|
@ -6,18 +6,17 @@ optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
|
||||
|
||||
|
||||
def get_optimizer():
|
||||
global optimizer
|
||||
return optimizer
|
||||
|
||||
|
||||
def expand_model_if_needed():
|
||||
global model, optimizer
|
||||
|
||||
current_vocab_size = len(tokenizer.vocab) + 10 # Buffer
|
||||
current_vocab_size = len(tokenizer.vocab) + 10
|
||||
old_vocab_size = model.head.out_features
|
||||
|
||||
if current_vocab_size <= old_vocab_size:
|
||||
return
|
||||
return # No expansion needed
|
||||
|
||||
print(f"Expanding model from {old_vocab_size} -> {current_vocab_size}")
|
||||
|
||||
@ -31,6 +30,6 @@ def expand_model_if_needed():
|
||||
param.copy_(old_state[name])
|
||||
|
||||
model = new_model
|
||||
opt = get_optimizer()
|
||||
optimizer = torch.optim.Adam(model.parameters(), lr=1e-4)
|
||||
|
||||
print("Model expanded and optimizer rebuilt.")
|
||||
print("Expansion complete.")
|
||||
|
@ -1,13 +1,18 @@
|
||||
import torch
|
||||
from model.brain import model, tokenizer, DEVICE
|
||||
from model.trainer import train_on_message
|
||||
from model.dynamic_expand import expand_model_if_needed
|
||||
|
||||
|
||||
def simulate_conversation():
|
||||
seed = torch.randint(0, tokenizer.next_id, (1, 5), device=DEVICE)
|
||||
output = model(seed)
|
||||
preds = torch.argmax(output, dim=-1).squeeze().tolist()
|
||||
expand_model_if_needed()
|
||||
|
||||
model.eval()
|
||||
seed = torch.randint(0, tokenizer.next_id, (1, 5), device=DEVICE)
|
||||
seed = seed[:, -128:] # Safety clamp
|
||||
output = model(seed)
|
||||
|
||||
preds = torch.argmax(output, dim=-1).squeeze().tolist()
|
||||
if isinstance(preds, int):
|
||||
preds = [preds]
|
||||
|
||||
|
19
model/scheduler.py
Normal file
19
model/scheduler.py
Normal file
@ -0,0 +1,19 @@
|
||||
import time
|
||||
|
||||
_next_action_time = time.time() + 60 # default 1 minute from now
|
||||
_next_action_label = "Waiting"
|
||||
|
||||
|
||||
def set_next_action(seconds_from_now: int, label: str = "Thinking"):
|
||||
global _next_action_time, _next_action_label
|
||||
_next_action_time = time.time() + seconds_from_now
|
||||
_next_action_label = label
|
||||
|
||||
|
||||
def get_time_until_next_action() -> int:
|
||||
remaining = int(_next_action_time - time.time())
|
||||
return max(0, remaining)
|
||||
|
||||
|
||||
def get_next_action_label() -> str:
|
||||
return _next_action_label
|
@ -1,9 +1,8 @@
|
||||
import torch
|
||||
import time
|
||||
from model.brain_state import model, tokenizer, DEVICE,loss_fn
|
||||
from context.context import add_to_context, get_recent_context
|
||||
from model.dynamic_expand import expand_model_if_needed, get_optimizer
|
||||
from model.brainmap import update_brainmap
|
||||
from model.brain_state import model, tokenizer, DEVICE, loss_fn
|
||||
from context.context import add_to_context, get_recent_context
|
||||
|
||||
LOSS_FILE = "data/logs/loss.log"
|
||||
|
||||
@ -15,6 +14,7 @@ def log_loss(value: float):
|
||||
|
||||
def train_on_message(text: str):
|
||||
expand_model_if_needed()
|
||||
|
||||
model.train()
|
||||
context_texts = get_recent_context(3)
|
||||
augmented_text = " ".join(context_texts + [text])
|
||||
@ -23,16 +23,23 @@ def train_on_message(text: str):
|
||||
if len(tokens) < 2:
|
||||
return
|
||||
|
||||
tokens = tokens[:128]
|
||||
words = tokenizer.detokenize(tokens).split()
|
||||
update_brainmap(words)
|
||||
# ✋ Clamp to model's known vocab
|
||||
max_token_id = model.head.out_features - 1
|
||||
tokens = [t for t in tokens if t <= max_token_id]
|
||||
|
||||
if len(tokens) < 2:
|
||||
return # after filtering, too short to train
|
||||
|
||||
tokens = tokens[:128] # safety clamp
|
||||
input_tensor = torch.tensor(tokens[:-1], dtype=torch.long, device=DEVICE).unsqueeze(0)
|
||||
target_tensor = torch.tensor(tokens[1:], dtype=torch.long, device=DEVICE).unsqueeze(0)
|
||||
|
||||
opt = get_optimizer()
|
||||
|
||||
output = model(input_tensor)
|
||||
|
||||
loss = loss_fn(output.view(-1, output.size(-1)), target_tensor.view(-1))
|
||||
|
||||
opt = get_optimizer()
|
||||
opt.zero_grad()
|
||||
loss.backward()
|
||||
opt.step()
|
||||
|
@ -1,7 +1,9 @@
|
||||
import os
|
||||
import asyncio
|
||||
from model.trainer import train_on_message
|
||||
from model.scheduler import set_next_action
|
||||
from reader.filter import is_valid_line
|
||||
import json
|
||||
|
||||
BOOK_DIR = "data/books"
|
||||
PROGRESS_FILE = "data/memory/book_progress.json"
|
||||
@ -45,4 +47,5 @@ async def read_books_forever():
|
||||
|
||||
if is_valid_line(line):
|
||||
train_on_message(line)
|
||||
set_next_action(READ_DELAY, "Reading")
|
||||
await asyncio.sleep(READ_DELAY)
|
||||
|
Loading…
x
Reference in New Issue
Block a user