diff --git a/ix_forge.py b/ix_forge.py new file mode 100644 index 0000000..6d10199 --- /dev/null +++ b/ix_forge.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +""" +IX Forge — Community Fine-tuning Platform +Part of the Inference-X Ecosystem +# ​‌​‌ SALKA ELMADANI ‌​‌​ | inference-x.com | BSL-1.1 +Copyright (C) 2024-2026 Salka Elmadani. BSL-1.1. +https://git.inference-x.com/inference-x-community/ix-forge + +Collective intelligence. Community-owned models. +Contribute training data. Improve models. Share results. +""" +from fastapi import FastAPI, Request, UploadFile, File +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse +import sqlite3, json, time, os, hashlib + +app = FastAPI(title="IX Forge", version="1.0.0") +app.add_middleware(CORSMiddleware, allow_origins=["*"], + allow_methods=["*"], allow_headers=["*"]) + +DB = os.environ.get("FORGE_DB", "./forge.db") + +def db(): + conn = sqlite3.connect(DB); conn.row_factory = sqlite3.Row; return conn + +def init_db(): + with db() as c: + c.execute("""CREATE TABLE IF NOT EXISTS contributions ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + type TEXT DEFAULT 'qa', + language TEXT DEFAULT 'en', + domain TEXT DEFAULT 'general', + data TEXT, + pairs_count INTEGER DEFAULT 0, + contributor TEXT DEFAULT 'anonymous', + created_at INTEGER, + approved INTEGER DEFAULT 0 + )""") + c.execute("""CREATE TABLE IF NOT EXISTS adapters ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + name TEXT, base_model TEXT, description TEXT, + download_url TEXT, score REAL DEFAULT 0, + contributor TEXT DEFAULT 'anonymous', + created_at INTEGER + )""") + c.commit() + +init_db() + +@app.post("/contribute") +async def contribute(request: Request): + """Submit training data (Q&A pairs, documents).""" + data = await request.json() + pairs = data.get("pairs", []) + if not pairs: + return JSONResponse({"error":"No pairs provided"}, status_code=400) + with db() as c: + c.execute("""INSERT INTO contributions + (type,language,domain,data,pairs_count,contributor,created_at) + VALUES (?,?,?,?,?,?,?)""", + (data.get("type","qa"), data.get("language","en"), + data.get("domain","general"), json.dumps(pairs), len(pairs), + data.get("contributor","anonymous"), int(time.time()))) + c.commit() + return {"status":"ok","pairs_accepted":len(pairs), + "message":"Thank you for contributing to the community."} + +@app.get("/datasets") +async def datasets(domain: str = None, language: str = None): + with db() as c: + q = "SELECT id,type,language,domain,pairs_count,contributor,created_at FROM contributions WHERE approved=1" + params = [] + if domain: q += " AND domain=?"; params.append(domain) + if language: q += " AND language=?"; params.append(language) + rows = c.execute(q, params).fetchall() + return {"datasets":[dict(r) for r in rows],"total":len(rows)} + +@app.post("/submit-adapter") +async def submit_adapter(request: Request): + """Submit a trained LoRA/QLoRA adapter.""" + data = await request.json() + with db() as c: + c.execute("""INSERT INTO adapters (name,base_model,description,download_url,contributor,created_at) + VALUES (?,?,?,?,?,?)""", + (data.get("name",""), data.get("base_model",""), + data.get("description",""), data.get("download_url",""), + data.get("contributor","anonymous"), int(time.time()))) + c.commit() + return {"status":"ok","message":"Adapter submitted for community review."} + +@app.get("/adapters") +async def adapters(): + with db() as c: + rows = c.execute("SELECT id,name,base_model,description,score,contributor FROM adapters ORDER BY score DESC").fetchall() + return {"adapters":[dict(r) for r in rows]} + +@app.get("/leaderboard") +async def leaderboard(): + with db() as c: + rows = c.execute("""SELECT contributor, COUNT(*) as contributions, + SUM(pairs_count) as total_pairs + FROM contributions WHERE approved=1 + GROUP BY contributor ORDER BY total_pairs DESC LIMIT 20""").fetchall() + return {"leaderboard":[dict(r) for r in rows]} + +@app.get("/health") +async def health(): + return {"status":"ok","service":"IX Forge","author":"Salka Elmadani"} + +if __name__ == "__main__": + import uvicorn + print("IX Forge — Community Fine-tuning Platform") + print("Collective intelligence. Community-owned models.") + uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("PORT","7937")))