====== Generare dati sintetici per rizzo-pii ====== ===== 1. Cosa sono i dati sintetici e perché sono importanti ===== I **dati sintetici** sono dati generati da un modello (in questo caso un LLM) che ne riproducono struttura, linguaggio e distribuzione, ma **non contengono informazioni reali**. Qui si tratta di esempi "PII" in prosa legale italiana: testi con etichette **BIO** esatte e **checksum matematicamente validi** per codice fiscale, partita IVA e IBAN — ma nessun dato personale vero. Perché sono importanti: * **Privacy per costruzione** — il modello impara a riconoscere gli identificativi senza che alcuna PII reale entri nel dataset o attraversi la rete (GDPR). * **Corpus per addestramento e validazione** — ''rizzo-pii:0.3B'' viene addestrato e testato su **22 categorie di dati personali**, inclusi identificativi specifici del diritto italiano (CF, PIVA, dati catastali) che nessun modello open copre. * **Contributo community senza rischi** — chiunque può generare nuovi esempi sul proprio hardware e proporne una **Pull Request** sul dataset; un maintainer la revisiona prima del merge. * **Testo davvero nuovo ad ogni esecuzione** — con la propria chiave API (o il proprio modello locale) l'LLM scrive **nuovi template legali a ogni run** (prosa diversa, temperatura alta) e il codice vi inietta i dati: ogni contributore produce contenuto nuovo, non solo nuovi valori sugli stessi template. Il principio del progetto è: **"LLM autore, codice etichettatore"** — l'LLM scrive solo la prosa con segnaposto; il codice inietta i valori, le etichette BIO esatte e i checksum validi. ===== 2. Il progetto: rizzo-pii ===== **Local, reversible PII anonymization for Italian legal text** — //use frontier models without giving up your data.// - rizzo-pii è uno strumento locale basato su ''rizzo-pii:0.3B'', un modello di token-classification **italiano-first** (backbone mmBERT/ModernBERT, ~0.3B parametri, ~0.5 GB di RAM, CPU-friendly) che rileva **22 categorie di dati personali**, inclusi gli identificativi del diritto italiano: **codice fiscale**, **partita IVA**, **dati catastali**. - Il funzionamento: **anonimizza localmente** il documento → sostituisce i dati con **placeholder** salvati in un **dizionario locale reversibile** → invia solo i placeholder al **frontier LLM** in cloud (ChatGPT / Claude / Gemini) → **ripristina localmente** i valori originali dalla risposta. - L'obiettivo: poter usare i modelli frontier su documenti sensibili **senza che i dati reali lascino mai il dispositivo**, anche per chi è vincolato dal GDPR. - I destinatari: studi legali, commercialisti, notarai e chiunque lavori su documenti contenenti PII senza volerli esporre a server che non controlla (log, cache, retention, data breach). **Le due modalità di anonimizzazione** * **Reversibile** (workflow base): i valori originali restano nel dizionario locale e il documento può essere **ripristinato in qualsiasi momento** al dato precedente. * **Irreversibile**: i dati vengono sostituiti **senza conservare i mezzi di ripristino** — non si può tornare indietro. Utile quando il documento va condiviso, pubblicato o archiviato senza alcuna possibilità di re-identificazione (e senza conservare localmente il dizionario). I dati sintetici che genero alimentano il dataset community del progetto: **''rizzoaiacademy/anonimizzazione-testi-italiano''** su Hugging Face. ===== 3. Hardware e modello per la generazione ===== ^ Componente ^ Scelta ^ | GPU | **NVIDIA GeForce RTX 3090** (24 GB VRAM) | | Motore di inference | **llama.cpp**, server in modalità OpenAI-compatibile | | Modello | ''Qwen3.8-27B-GSQ-RCO-IQ3_S-mtp'' (variante quantizzata, MTP) | Un modello ~27B in quantizzazione a 3 bit sta comodo nei 24 GB della 3090 e viene servito in locale: **nessuna chiave API, nessun prompt che lascia la macchina** — coerente con un progetto sulla privacy. ===== 4. Mini guida: contribuire da casa ===== ==== Prerequisiti ==== * Python 3.x con ''pip'' * Account **Hugging Face** con token (''hf auth login'' oppure ''HF_TOKEN'') * GPU locale con llama.cpp (nel mio caso la 3090) — oppure una chiave **Gemini** ([[https://aistudio.google.com/apikey|aistudio.google.com/apikey]]) ==== 1. Clona il repository ==== git clone https://github.com/Rizzo-AI-Academy/rizzo-pii cd rizzo-pii ==== 2. Ambiente virtuale e dipendenze ==== python -m venv .venv source .venv/bin/activate # Windows: .venv\Scripts\activate pip install -r requirements.txt # include huggingface_hub; per i dati NON serve torch ==== 3. Avvia llama.cpp con il modello ==== llama-server -m Qwen3.8-27B-GSQ-RCO-IQ3_S-mtp.gguf --port 8080 Va bene qualsiasi endpoint OpenAI-compatibile: llama.cpp, Ollama, vLLM, LM Studio. ==== 4. Imposta le variabili d'ambiente (da non committare) ==== export HF_TOKEN="hf_xxx" export LLM_BASE_URL="http://localhost:8080/v1" export LLM_MODEL="Qwen3.8-27B-GSQ-RCO-IQ3_S-mtp" export OPENAI_MODEL="Qwen3.8-27B-GSQ-RCO-IQ3_S-mtp" export MODEL="Qwen3.8-27B-GSQ-RCO-IQ3_S-mtp" Se usi Gemini al posto del modello locale: ''export GEMINI_API_KEY=...'' (PowerShell: ''$env:GEMINI_API_KEY=...''). ==== 5. Prova locale senza caricare nulla ==== python src/data_pipeline/contribute_dataset.py --n 300 --handle iltuonome --no-upload Controlla l'output (distribuzione dei tag) prima del batch vero. ==== 6. Genera il batch e apri la Pull Request ==== python src/data_pipeline/contribute_dataset.py --n 5000 --handle iltuonome \ --per-type 3 --boost ORG=6 IBAN=4 CF=4 CATASTO=3 DOCID=3 * ''--per-type N'' — quanti **nuovi** template per tipo di documento far scrivere all'LLM (default 2) * ''--boost TAG=N'' — rinforza i tag più deboli del dataset * ''--no-upload'' — solo locale, per vedere cosa verrebbe inviato * ''--offline'' — usa solo i template built-in (dati meno "nuovi": da evitare se si può) Lo script apre una **Pull Request** sul dataset ''rizzoaiacademy/anonimizzazione-testi-italiano''; un maintainer la revisiona prima del merge. Scritto da ugo formattato in docuwiki syntax da ai.