Kleinpuki2 commited on
Commit
f2f562e
·
verified ·
1 Parent(s): 603f4e3

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +82 -0
  2. requirements.txt +7 -0
  3. templates/index.html +86 -0
app.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import json
4
+ import uuid
5
+ from fastapi import FastAPI, Request, HTTPException, Depends
6
+ from fastapi.responses import HTMLResponse, JSONResponse
7
+ from fastapi.staticfiles import StaticFiles
8
+ from fastapi.templating import Jinja2Templates
9
+ from model import MiniTransformer, BPETokenizer
10
+
11
+ app = FastAPI()
12
+ templates = Jinja2Templates(directory="templates")
13
+
14
+ # --- MODEL SETUP ---
15
+ DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
16
+ MODEL_PATH = "madgames_gpt2_stable.pth" # Wird beim Deployment geladen
17
+ tokenizer = BPETokenizer()
18
+
19
+ # Lädt das Modell (Dummy-Check falls Datei noch nicht da)
20
+ model = None
21
+ if os.path.exists(MODEL_PATH):
22
+ ckpt = torch.load(MODEL_PATH, map_location=DEVICE, weights_only=False)
23
+ config = ckpt["config"]
24
+ model = MiniTransformer(
25
+ vocab_size=config["vocab_size"],
26
+ emb_dim=config["emb_dim"],
27
+ n_layers=config["n_layers"],
28
+ n_heads=config["n_heads"],
29
+ ctx_len=config["ctx_len"]
30
+ ).to(DEVICE)
31
+ model.load_state_dict(ckpt["model_state"])
32
+ model.eval()
33
+
34
+ # --- KEY MANAGEMENT ---
35
+ KEYS_FILE = "api_keys.json"
36
+
37
+ def load_keys():
38
+ if not os.path.exists(KEYS_FILE): return {}
39
+ with open(KEYS_FILE, "r") as f: return json.load(f)
40
+
41
+ def save_keys(keys):
42
+ with open(KEYS_FILE, "w") as f: json.dump(keys, f)
43
+
44
+ # --- ROUTES ---
45
+ @app.get("/", response_class=HTMLResponse)
46
+ async def dashboard(request: Request):
47
+ return templates.TemplateResponse("index.html", {"request": request})
48
+
49
+ @app.post("/generate_key")
50
+ async def create_key():
51
+ new_key = f"MG-{uuid.uuid4().hex[:12].upper()}"
52
+ keys = load_keys()
53
+ keys[new_key] = {"created": str(torch.utils.data.dataloader.default_collate), "uses": 0}
54
+ save_keys(keys)
55
+ return {"key": new_key}
56
+
57
+ @app.post("/predict")
58
+ async def predict(request: Request):
59
+ data = await request.json()
60
+ api_key = request.headers.get("X-API-Key")
61
+
62
+ keys = load_keys()
63
+ if api_key not in keys:
64
+ raise HTTPException(status_code=403, detail="Ungültiger API-Key")
65
+
66
+ prompt = data.get("prompt", "")
67
+ if not model or not prompt:
68
+ return {"response": "Server bereit, aber Modell oder Prompt fehlt."}
69
+
70
+ # Generierung (stark vereinfacht für Demo)
71
+ tokens = torch.tensor(tokenizer.encode(prompt)).unsqueeze(0).to(DEVICE)
72
+ with torch.no_grad():
73
+ out = model.generate(tokens, max_new_tokens=100)[0].tolist()
74
+
75
+ keys[api_key]["uses"] += 1
76
+ save_keys(keys)
77
+
78
+ return {"response": tokenizer.decode(out)}
79
+
80
+ if __name__ == "__main__":
81
+ import uvicorn
82
+ uvicorn.run(app, host="0.0.0.0", port=7860)
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ torch
4
+ numpy
5
+ python-multipart
6
+ jinja2
7
+ aiofiles
templates/index.html ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="de">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>MadGames AI | API Dashboard</title>
7
+ <style>
8
+ :root {
9
+ --accent: #ff6b00;
10
+ --bg: #0a0a0c;
11
+ --glass: rgba(255, 255, 255, 0.03);
12
+ --border: rgba(255, 255, 255, 0.08);
13
+ }
14
+ body {
15
+ font-family: 'Inter', system-ui, sans-serif;
16
+ background: var(--bg);
17
+ color: #fff;
18
+ display: flex;
19
+ align-items: center;
20
+ justify-content: center;
21
+ height: 100vh;
22
+ margin: 0;
23
+ background-image: radial-gradient(circle at 50% 50%, #1a1a20 0%, #0a0a0c 100%);
24
+ }
25
+ .dashboard-card {
26
+ background: var(--glass);
27
+ backdrop-filter: blur(20px);
28
+ border: 1px solid var(--border);
29
+ padding: 3rem;
30
+ border-radius: 24px;
31
+ text-align: center;
32
+ max-width: 450px;
33
+ width: 90%;
34
+ box-shadow: 0 20px 50px rgba(0,0,0,0.5);
35
+ }
36
+ h1 { font-size: 2rem; color: var(--accent); margin-bottom: 0.5rem; }
37
+ p { color: #888; margin-bottom: 2.5rem; }
38
+ .key-display {
39
+ background: rgba(0,0,0,0.3);
40
+ padding: 1rem;
41
+ border-radius: 12px;
42
+ border: 1px dashed var(--accent);
43
+ font-family: monospace;
44
+ font-size: 1.2rem;
45
+ margin-bottom: 2rem;
46
+ display: none;
47
+ color: var(--accent);
48
+ }
49
+ button {
50
+ background: var(--accent);
51
+ color: #fff;
52
+ border: none;
53
+ padding: 1rem 2rem;
54
+ border-radius: 12px;
55
+ font-weight: 600;
56
+ font-size: 1rem;
57
+ cursor: pointer;
58
+ transition: transform 0.2s, box-shadow 0.2s;
59
+ }
60
+ button:hover { transform: translateY(-2px); box-shadow: 0 5px 15px rgba(255,107,0,0.4); }
61
+ .footer { margin-top: 2rem; font-size: 0.8rem; color: #444; }
62
+ </style>
63
+ </head>
64
+ <body>
65
+ <div class="dashboard-card">
66
+ <h1>MadGames API</h1>
67
+ <p>Verwalte deine API-Keys für das MadGamesAI Sprachmodell.</p>
68
+
69
+ <div id="key-result" class="key-display"></div>
70
+
71
+ <button onclick="generateKey()">Neuen API-Key erstellen</button>
72
+
73
+ <div class="footer">MadGames AI Engine &bull; Private Space Instance</div>
74
+ </div>
75
+
76
+ <script>
77
+ async function generateKey() {
78
+ const res = await fetch('/generate_key', { method: 'POST' });
79
+ const data = await res.json();
80
+ const el = document.getElementById('key-result');
81
+ el.innerText = data.key;
82
+ el.style.display = 'block';
83
+ }
84
+ </script>
85
+ </body>
86
+ </html>