Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -13,12 +13,12 @@ import urllib.parse
|
|
| 13 |
import re
|
| 14 |
|
| 15 |
# --- 1. INITIALIZE FASTAPI API ---
|
| 16 |
-
app = FastAPI(title="Orbit SpaceStar Multi-Version Backend API", version="0.
|
| 17 |
|
| 18 |
-
# Zorg dat je website (frontend) met deze backend
|
| 19 |
app.add_middleware(
|
| 20 |
CORSMiddleware,
|
| 21 |
-
allow_origins=["*"],
|
| 22 |
allow_credentials=True,
|
| 23 |
allow_methods=["*"],
|
| 24 |
allow_headers=["*"],
|
|
@@ -112,15 +112,23 @@ class OrbitTransformer(nn.Module):
|
|
| 112 |
logits = self.lm_head(x)
|
| 113 |
return logits, None
|
| 114 |
|
| 115 |
-
def generate(self, idx, max_new_tokens, tokenizer, temperature=0.
|
| 116 |
-
|
| 117 |
end_token_id = tokenizer.token_to_id("<|end|>")
|
|
|
|
| 118 |
|
| 119 |
for _ in range(max_new_tokens):
|
| 120 |
idx_cond = idx[:, -self.block_size:]
|
| 121 |
logits, _ = self(idx_cond)
|
| 122 |
logits = logits[:, -1, :] / temperature
|
| 123 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 124 |
if top_k is not None:
|
| 125 |
v, _ = torch.topk(logits, min(top_k, logits.size(-1)))
|
| 126 |
logits[logits < v[:, [-1]]] = float('-inf')
|
|
@@ -128,10 +136,9 @@ class OrbitTransformer(nn.Module):
|
|
| 128 |
probs = F.softmax(logits, dim=-1)
|
| 129 |
idx_next = torch.multinomial(probs, num_samples=1)
|
| 130 |
|
| 131 |
-
# Voeg toe aan de reeks
|
| 132 |
idx = torch.cat((idx, idx_next), dim=1)
|
| 133 |
|
| 134 |
-
#
|
| 135 |
if end_token_id is not None and idx_next.item() == end_token_id:
|
| 136 |
break
|
| 137 |
|
|
@@ -181,20 +188,20 @@ def get_model_and_tokenizer(version: str):
|
|
| 181 |
else:
|
| 182 |
raise HTTPException(status_code=404, detail=f"Bestanden niet gevonden: {e}")
|
| 183 |
|
| 184 |
-
# --- 5. INTERNET SEARCH ENGINE (
|
| 185 |
def fetch_internet_context(query: str) -> str:
|
| 186 |
-
"""Haalt info op via DuckDuckGo, maar ALLEEN
|
| 187 |
q_lower = query.lower().strip()
|
| 188 |
|
| 189 |
-
#
|
| 190 |
-
triggers = ["zoek", "wat is", "wie is", "hoe werkt", "search", "what is", "who is", "tell me about"]
|
| 191 |
-
|
| 192 |
needs_internet = any(q_lower.startswith(t) for t in triggers)
|
| 193 |
-
|
| 194 |
-
|
|
|
|
|
|
|
| 195 |
|
| 196 |
try:
|
| 197 |
-
# Haal de triggerwoorden eraf voor een schonere zoekopdracht
|
| 198 |
clean_q = q_lower
|
| 199 |
for t in triggers:
|
| 200 |
if clean_q.startswith(t):
|
|
@@ -214,7 +221,7 @@ def fetch_internet_context(query: str) -> str:
|
|
| 214 |
abstract = item["Text"]
|
| 215 |
break
|
| 216 |
if abstract:
|
| 217 |
-
return abstract[:
|
| 218 |
except Exception as e:
|
| 219 |
print(f"📡 API fout: {e}")
|
| 220 |
return ""
|
|
@@ -223,8 +230,8 @@ def fetch_internet_context(query: str) -> str:
|
|
| 223 |
class ChatRequest(BaseModel):
|
| 224 |
prompt: str
|
| 225 |
version: str = "0.02"
|
| 226 |
-
temperature: float = 0.
|
| 227 |
-
max_tokens: int =
|
| 228 |
|
| 229 |
@app.get("/")
|
| 230 |
def home():
|
|
@@ -234,22 +241,19 @@ def home():
|
|
| 234 |
def chat(request: ChatRequest):
|
| 235 |
model, tokenizer = get_model_and_tokenizer(request.version)
|
| 236 |
|
| 237 |
-
#
|
| 238 |
internet_info = fetch_internet_context(request.prompt)
|
| 239 |
|
| 240 |
think_html_block = ""
|
| 241 |
|
| 242 |
-
#
|
| 243 |
if internet_info:
|
| 244 |
-
# Dit genereren we direct voor jouw frontend <denk> UI, super mooi!
|
| 245 |
think_html_block = f"<denk>Internet uplink succesvol.\nGezocht op: '{request.prompt}'\nGevonden info: {internet_info}</denk>\n"
|
| 246 |
-
|
| 247 |
-
# Dit geven we aan de AI in de achtergrond, zodat we geen woorden meer in zijn mond leggen
|
| 248 |
-
formatted_prompt = f"<|user|>\n[Verborgen Context: {internet_info}]\n{request.prompt}\n<|assistant|>\n"
|
| 249 |
else:
|
| 250 |
formatted_prompt = f"<|user|>\n{request.prompt}\n<|assistant|>\n"
|
| 251 |
|
| 252 |
-
# Tokenizen
|
| 253 |
context = torch.tensor([tokenizer.encode(formatted_prompt).ids], dtype=torch.long, device=DEVICE)
|
| 254 |
|
| 255 |
with torch.no_grad():
|
|
@@ -258,23 +262,33 @@ def chat(request: ChatRequest):
|
|
| 258 |
max_new_tokens=request.max_tokens,
|
| 259 |
tokenizer=tokenizer,
|
| 260 |
temperature=request.temperature,
|
| 261 |
-
top_k=
|
| 262 |
)[0]
|
| 263 |
full_output = tokenizer.decode(generated_tokens.tolist(), skip_special_tokens=False)
|
| 264 |
|
| 265 |
-
#
|
| 266 |
generated_text = full_output.replace(formatted_prompt, "").replace("<|end|>", "").strip()
|
| 267 |
|
| 268 |
-
#
|
| 269 |
-
|
| 270 |
-
|
| 271 |
-
|
|
|
|
|
|
|
| 272 |
if len(parts) >= 3:
|
| 273 |
internal_thought = parts[0].strip()
|
| 274 |
actual_speech = parts[1] + parts[2]
|
| 275 |
-
generated_text = f"<denk>Interne
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 276 |
|
| 277 |
-
# Plak het internet-denkblok aan het
|
| 278 |
final_response = think_html_block + generated_text
|
| 279 |
|
| 280 |
return {
|
|
|
|
| 13 |
import re
|
| 14 |
|
| 15 |
# --- 1. INITIALIZE FASTAPI API ---
|
| 16 |
+
app = FastAPI(title="Orbit SpaceStar Multi-Version Backend API", version="0.03_Super")
|
| 17 |
|
| 18 |
+
# Zorg dat je website (frontend) vlekkeloos mag praten met deze backend
|
| 19 |
app.add_middleware(
|
| 20 |
CORSMiddleware,
|
| 21 |
+
allow_origins=["*"],
|
| 22 |
allow_credentials=True,
|
| 23 |
allow_methods=["*"],
|
| 24 |
allow_headers=["*"],
|
|
|
|
| 112 |
logits = self.lm_head(x)
|
| 113 |
return logits, None
|
| 114 |
|
| 115 |
+
def generate(self, idx, max_new_tokens, tokenizer, temperature=0.5, top_k=30):
|
| 116 |
+
"""Geüpgradede generatie met een keiharde herhalingsrem (Repetition Penalty)"""
|
| 117 |
end_token_id = tokenizer.token_to_id("<|end|>")
|
| 118 |
+
repetition_penalty = 1.3 # Strafpunten voor tokens die hij al gebruikt heeft (voorkomt loops!)
|
| 119 |
|
| 120 |
for _ in range(max_new_tokens):
|
| 121 |
idx_cond = idx[:, -self.block_size:]
|
| 122 |
logits, _ = self(idx_cond)
|
| 123 |
logits = logits[:, -1, :] / temperature
|
| 124 |
|
| 125 |
+
# REPETITION PENALTY: Als het model een token herhaalt, maken we de kans erop kleiner!
|
| 126 |
+
for token_id in set(idx[0].tolist()):
|
| 127 |
+
if logits[0, token_id] > 0:
|
| 128 |
+
logits[0, token_id] /= repetition_penalty
|
| 129 |
+
else:
|
| 130 |
+
logits[0, token_id] *= repetition_penalty
|
| 131 |
+
|
| 132 |
if top_k is not None:
|
| 133 |
v, _ = torch.topk(logits, min(top_k, logits.size(-1)))
|
| 134 |
logits[logits < v[:, [-1]]] = float('-inf')
|
|
|
|
| 136 |
probs = F.softmax(logits, dim=-1)
|
| 137 |
idx_next = torch.multinomial(probs, num_samples=1)
|
| 138 |
|
|
|
|
| 139 |
idx = torch.cat((idx, idx_next), dim=1)
|
| 140 |
|
| 141 |
+
# KEIHARDE STOP-TOKEN CHECK: Meteen kappen als hij klaar is!
|
| 142 |
if end_token_id is not None and idx_next.item() == end_token_id:
|
| 143 |
break
|
| 144 |
|
|
|
|
| 188 |
else:
|
| 189 |
raise HTTPException(status_code=404, detail=f"Bestanden niet gevonden: {e}")
|
| 190 |
|
| 191 |
+
# --- 5. INTERNET SEARCH ENGINE (STRENGER AFGESTELD) ---
|
| 192 |
def fetch_internet_context(query: str) -> str:
|
| 193 |
+
"""Haalt info op via DuckDuckGo, maar ALLEEN bij duidelijke zoek-prompts."""
|
| 194 |
q_lower = query.lower().strip()
|
| 195 |
|
| 196 |
+
# Alleen zoeken als het echt een vraag is die begint met deze woorden
|
| 197 |
+
triggers = ["zoek naar", "wat is", "wie is", "hoe werkt", "search for", "what is", "who is", "tell me about"]
|
|
|
|
| 198 |
needs_internet = any(q_lower.startswith(t) for t in triggers)
|
| 199 |
+
|
| 200 |
+
# Extra handrem: als de prompt super kort is (zoals "HI" of "ramen"), NOOIT internet gebruiken!
|
| 201 |
+
if not needs_internet or len(q_lower) <= 4:
|
| 202 |
+
return ""
|
| 203 |
|
| 204 |
try:
|
|
|
|
| 205 |
clean_q = q_lower
|
| 206 |
for t in triggers:
|
| 207 |
if clean_q.startswith(t):
|
|
|
|
| 221 |
abstract = item["Text"]
|
| 222 |
break
|
| 223 |
if abstract:
|
| 224 |
+
return abstract[:180].strip()
|
| 225 |
except Exception as e:
|
| 226 |
print(f"📡 API fout: {e}")
|
| 227 |
return ""
|
|
|
|
| 230 |
class ChatRequest(BaseModel):
|
| 231 |
prompt: str
|
| 232 |
version: str = "0.02"
|
| 233 |
+
temperature: float = 0.5 # Iets lager gezet voor meer stabiliteit en minder hallucinaties
|
| 234 |
+
max_tokens: int = 150 # Iets korter gezet zodat hij niet te lang door-rabbelt
|
| 235 |
|
| 236 |
@app.get("/")
|
| 237 |
def home():
|
|
|
|
| 241 |
def chat(request: ChatRequest):
|
| 242 |
model, tokenizer = get_model_and_tokenizer(request.version)
|
| 243 |
|
| 244 |
+
# Internet check (negeert "HI")
|
| 245 |
internet_info = fetch_internet_context(request.prompt)
|
| 246 |
|
| 247 |
think_html_block = ""
|
| 248 |
|
| 249 |
+
# Bouw de nette chat-prompt
|
| 250 |
if internet_info:
|
|
|
|
| 251 |
think_html_block = f"<denk>Internet uplink succesvol.\nGezocht op: '{request.prompt}'\nGevonden info: {internet_info}</denk>\n"
|
| 252 |
+
formatted_prompt = f"<|user|>\n[Context: {internet_info}]\n{request.prompt}\n<|assistant|>\n"
|
|
|
|
|
|
|
| 253 |
else:
|
| 254 |
formatted_prompt = f"<|user|>\n{request.prompt}\n<|assistant|>\n"
|
| 255 |
|
| 256 |
+
# Tokenizen en sturen naar de GPU/CPU
|
| 257 |
context = torch.tensor([tokenizer.encode(formatted_prompt).ids], dtype=torch.long, device=DEVICE)
|
| 258 |
|
| 259 |
with torch.no_grad():
|
|
|
|
| 262 |
max_new_tokens=request.max_tokens,
|
| 263 |
tokenizer=tokenizer,
|
| 264 |
temperature=request.temperature,
|
| 265 |
+
top_k=30
|
| 266 |
)[0]
|
| 267 |
full_output = tokenizer.decode(generated_tokens.tolist(), skip_special_tokens=False)
|
| 268 |
|
| 269 |
+
# Sloop de prompt-tekst uit het uiteindelijke antwoord
|
| 270 |
generated_text = full_output.replace(formatted_prompt, "").replace("<|end|>", "").strip()
|
| 271 |
|
| 272 |
+
# --- DE ULTIEME ORBIT-SPACESTAR RETREATING & CLEANING FILTER ---
|
| 273 |
+
# Sloop alle rare achtergrond-gedachten eruit en forceer zijn naam!
|
| 274 |
+
|
| 275 |
+
# 1. Herken interne hersenspinsels en stop ze in jouw vette frontend <denk> blok!
|
| 276 |
+
if any(trigger in generated_text for trigger in ["Discuss ramen", "User greets", "User asks", "Provide the basic", "Analyze the"]):
|
| 277 |
+
parts = re.split(r'(Hello!|Hi!|I am|I think|To print|Based on)', generated_text, maxsplit=1)
|
| 278 |
if len(parts) >= 3:
|
| 279 |
internal_thought = parts[0].strip()
|
| 280 |
actual_speech = parts[1] + parts[2]
|
| 281 |
+
generated_text = f"<denk>Interne model-analyse:\n{internal_thought}</denk>\n{actual_speech}"
|
| 282 |
+
|
| 283 |
+
# 2. KEIHARDE KORRECTIE: Hij is NIET Orbit Ultra, hij is Orbit-SpaceStar!
|
| 284 |
+
generated_text = generated_text.replace("Orbit Ultra", "Orbit-SpaceStar")
|
| 285 |
+
|
| 286 |
+
# 3. Voorkom dubbele loops op je scherm (als hij twee keer dezelfde vraag aan zichzelf stelt, knippen we hem af)
|
| 287 |
+
if "What is the Python command" in generated_text:
|
| 288 |
+
sub_parts = generated_text.split("What is the Python command")
|
| 289 |
+
generated_text = sub_parts[0].strip()
|
| 290 |
|
| 291 |
+
# Plak het internet-denkblok (als dat er is) aan het antwoord vast
|
| 292 |
final_response = think_html_block + generated_text
|
| 293 |
|
| 294 |
return {
|