GenerAI / export_dataset.py
amogaddy's picture
Upload export_dataset.py with huggingface_hub
8344211 verified
Raw
History Blame Contribute Delete
4.51 kB
"""
export_dataset.py
=================
Esporta tutti i dati da ChromaDB + seed_italian.py in formato JSONL
compatibile con HuggingFace (ChatML / SFTTrainer).
Output: dataset.jsonl (pronto per AutoTrain o finetune.py)
Uso:
python export_dataset.py
python export_dataset.py --out mio_dataset.jsonl --min-chars 50
"""
import argparse
import json
import os
import sys
from pathlib import Path
SYSTEM_PROMPT = (
"Sei GenerAI, un assistente AI specializzato in lingua italiana. "
"Rispondi in modo chiaro, preciso e sempre in italiano."
)
def _row(question: str, answer: str) -> dict:
"""Formato ChatML — compatibile con SFTTrainer e HF AutoTrain."""
return {
"messages": [
{"role": "system", "content": SYSTEM_PROMPT},
{"role": "user", "content": question.strip()},
{"role": "assistant", "content": answer.strip()},
]
}
def load_from_seed() -> list[dict]:
"""Carica le regole di grammatica da seed_italian.py."""
from seed_italian import GRAMMAR_SEED
rows = [_row(item["q"], item["a"]) for item in GRAMMAR_SEED]
print(f"[seed] {len(rows)} esempi caricati da seed_italian.py")
return rows
def load_from_chromadb(min_chars: int = 80) -> list[dict]:
"""Carica i documenti archiviati da ChromaDB (domande web salvate)."""
try:
import chromadb
from chromadb.utils.embedding_functions import SentenceTransformerEmbeddingFunction
except ImportError:
print("[chromadb] chromadb non installato — saltato.")
return []
db_path = "./database"
if not os.path.exists(db_path):
print("[chromadb] Nessun database trovato — saltato.")
return []
ef = SentenceTransformerEmbeddingFunction(
model_name="paraphrase-multilingual-MiniLM-L12-v2"
)
client = chromadb.PersistentClient(path=db_path)
try:
col = client.get_collection(name="generai", embedding_function=ef)
except Exception:
print("[chromadb] Collezione 'generai' non trovata — saltato.")
return []
total = col.count()
if total == 0:
print("[chromadb] Database vuoto — saltato.")
return []
results = col.get(include=["metadatas"], limit=total)
rows = []
skipped = 0
for meta in results["metadatas"]:
source = meta.get("source", "")
if source == "grammatica_italiana":
continue # già in seed, evita duplicati
q = meta.get("query", "").strip()
a = meta.get("answer", "").strip()
if not q or not a or len(a) < min_chars:
skipped += 1
continue
rows.append(_row(q, a))
print(f"[chromadb] {len(rows)} esempi caricati ({skipped} saltati per qualità).")
return rows
def deduplicate(rows: list[dict]) -> list[dict]:
seen = set()
out = []
for row in rows:
key = row["messages"][1]["content"][:80].lower()
if key not in seen:
seen.add(key)
out.append(row)
return out
def main():
parser = argparse.ArgumentParser(description="Esporta dataset per HuggingFace fine-tuning")
parser.add_argument("--out", default="dataset.jsonl", help="File di output (default: dataset.jsonl)")
parser.add_argument("--min-chars", type=int, default=80, help="Lunghezza minima risposta (default: 80)")
parser.add_argument("--no-seed", action="store_true", help="Non includere seed_italian.py")
parser.add_argument("--no-db", action="store_true", help="Non includere ChromaDB")
args = parser.parse_args()
rows = []
if not args.no_seed:
rows += load_from_seed()
if not args.no_db:
rows += load_from_chromadb(min_chars=args.min_chars)
rows = deduplicate(rows)
if not rows:
print("❌ Nessun dato trovato. Aggiungi dati alla KB prima di esportare.")
sys.exit(1)
out_path = Path(args.out)
with open(out_path, "w", encoding="utf-8") as f:
for row in rows:
f.write(json.dumps(row, ensure_ascii=False) + "\n")
print(f"\n✅ Dataset esportato: {out_path.resolve()}")
print(f" Totale esempi : {len(rows)}")
print(f" Formato : ChatML (messages: system/user/assistant)")
print(f"\nProssimo passo:")
print(f" → Fine-tuning locale : python finetune.py --dataset {args.out}")
print(f" → HuggingFace AutoTrain: carica {args.out} su https://huggingface.co/autotrain")
if __name__ == "__main__":
main()