"""Loopback-only demonstration server; intentionally not a production API."""
import json
from http.server import BaseHTTPRequestHandler, HTTPServer
from .model import generate
PAGE = '''
DiffuThink · laboratoire de débruitage
MODÈLE ENTRAÎNÉ LOCALEMENT · DIFFUSION DISCRÈTE SIMPLIFIÉE
DiffuThink
Du texte masqué à une phrase reconstruite, étape par étape.
Ce que vous observez
Le Transformer regarde les deux côtés des trous. Il prédit les octets manquants et fixe les plus confiants à chaque passage. Le contexte visible reste inchangé.
Démonstrateur sur une grammaire anglaise synthétique. Pas un assistant conversationnel. Une phrase plausible ne prouve pas une compréhension générale. Température 0 : choix déterministe des octets.
'''
def serve(model, checkpoint, port):
class Handler(BaseHTTPRequestHandler):
def respond(self, status, body, content_type="application/json; charset=utf-8"):
raw = body.encode("utf-8")
self.send_response(status)
self.send_header("Content-Type", content_type)
self.send_header("Content-Length", str(len(raw)))
self.end_headers()
self.wfile.write(raw)
def do_GET(self):
if self.path == "/":
self.respond(200, PAGE, "text/html; charset=utf-8")
elif self.path == "/api/info":
self.respond(200, json.dumps({"parameters": sum(p.numel() for p in model.parameters()), "training_step": checkpoint["step"], "max_bytes": model.config.max_length}))
else:
self.respond(404, '{"error":"Not found"}')
def do_POST(self):
if self.path != "/api/generate":
self.respond(404, '{"error":"Not found"}')
return
try:
length = int(self.headers.get("Content-Length", "0"))
if not 0 < length <= 8192:
raise ValueError("Request size must be 1..8192 bytes")
args = json.loads(self.rfile.read(length))
if not isinstance(args, dict) or not isinstance(args.get("template"), str):
raise ValueError("template must be a string")
steps = int(args.get("steps", 12))
temperature = float(args.get("temperature", 0))
if not 1 <= steps <= 64 or not 0 <= temperature <= 2:
raise ValueError("steps: 1..64; temperature: 0..2")
self.respond(200, json.dumps(generate(model, args["template"], steps, temperature, int(args.get("seed", 42)))))
except (ValueError, TypeError, OverflowError) as exc:
self.respond(400, json.dumps({"error": str(exc)}))
server = HTTPServer(("127.0.0.1", port), Handler)
print(f"DiffuThink: http://127.0.0.1:{port}", flush=True)
try:
server.serve_forever()
except KeyboardInterrupt:
pass
finally:
server.server_close()