Initial commit
This commit is contained in:
parent
6458c6f52e
commit
7fda3e863a
114
ix_forge.py
Normal file
114
ix_forge.py
Normal file
@ -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")))
|
||||
Loading…
Reference in New Issue
Block a user