Federated Learning (FL)
Savitri Network include un sistema di Federated Learning on-chain per l'addestramento decentralizzato di modelli AI. I contract FL gestiscono la registrazione dei modelli, i round di addestramento, l'invio degli aggiornamenti, la distribuzione delle ricompense e la governance.
Architettura
Governance (proposte + votazione)
│
▼
Registry Modelli
│ registra modello, assegna ruoli, tracciamento versioni
▼
Ciclo di Vita dei Job
│ crea round → apri → invia aggiornamenti → sigilla → finalizza
▼
Pool di Ricompense
│ reclamo ricompense con prova Merkle
▼
Trainer + Aggregatori
Registry dei Modelli
I modelli vengono registrati on-chain con metadati, versioning e controllo degli accessi basato sui ruoli.
Registrazione del Modello
// Registra un nuovo modello
FlModelRegistry::register_model(
&mut storage,
&db,
&creator, // [u8; 32] - indirizzo del creatore del modello
"sentiment-v1", // nome del modello
"ipfs://Qm.../meta", // URI metadati
"MIT", // URI licenza
"ipfs://Qm.../weights", // URI pesi iniziali
&mut events,
Some(&mut gas),
)?;
Versionamento del Modello
I modelli hanno catene di versioni immutabili. Ogni nuova versione fa riferimento alla versione precedente:
v1 (iniziale) → v2 (fine-tuned) → v3 (produzione)
I metadati della versione includono:
metadata_uri: Descrizione dell'architettura del modelloweights_uri: Posizione dei pesi addestratiaggregator: Indirizzo che ha prodotto questa versioneparent_version: Collegamento alla versione precedente
Controllo Accessi Basato su Ruoli (RBAC)
| Ruolo | Permessi |
|---|---|
Creator | Registra modelli, gestisce versioni, imposta policy |
Viewer | Legge metadati e versioni del modello |
Trainer | Invia aggiornamenti di addestramento ai round |
Aggregator | Aggrega aggiornamenti, finalizza round, produce versioni |
L'accesso dei Trainer è controllato tramite allowlist/denylist per modello.
Gestione delle Policy
Ogni modello ha policy configurabili:
| Policy | Descrizione |
|---|---|
access_policy_hash | Chi può accedere ai dati del modello |
reward_policy_hash | Come vengono distribuite le ricompense |
max_trainers | Numero massimo di trainer concorrenti |
aggregator_whitelist | Aggregatori approvati |
Ciclo di Vita dei Job
L'addestramento FL è organizzato in round con un ciclo di vita definito:
Pianificato → Aperto → Sigillato → Finalizzato
↘ Interrotto (tramite governance)
Stati del Round
| Stato | Descrizione | Azioni Consentite |
|---|---|---|
Planned | Round creato, non ancora in attesa di aggiornamenti | Apri |
Open | In attesa di aggiornamenti dai trainer | Invia aggiornamento, Sigilla |
Sealed | Nessun altro aggiornamento, aggregazione in corso | Finalizza, Interrompi |
Finalized | Ricompense distribuite, round completato | Reclama ricompense |
Aborted | Round annullato tramite governance | Nessuna |
Creazione di un Round
FlJobLifecycle::create_round(
&mut storage,
&db,
&creator,
&model_id, // [u8; 32]
round_id, // u64
reward_pool_amount, // u128
&mut events,
Some(&mut gas),
)?;
Invio dell'Aggiornamento di Addestramento
I trainer inviano aggiornamenti del modello durante la fase Aperta:
FlJobLifecycle::submit_update(
&mut storage,
&db,
&trainer, // [u8; 32]
&model_id,
round_id,
&update_data, // training update bytes
nonce, // replay protection
&mut events,
Some(&mut gas),
)?;
Protezione dal replay: ogni trainer ha un nonce per round che deve essere strettamente crescente.
Sigillatura e Finalizzazione
// Sigilla il round (smetti di accettare aggiornamenti)
FlJobLifecycle::seal_round(&mut storage, &db, &aggregator, &model_id, round_id, ...)?;
// Finalizza il round (distribuisci le ricompense)
FlJobLifecycle::finalize_round(
&mut storage, &db, &aggregator, &model_id, round_id,
&merkle_root, // reward distribution Merkle root
&new_weights_uri, // aggregated model weights
...
)?;
Reclamo delle Ricompense
I trainer reclamano le ricompense con prove Merkle:
FlJobLifecycle::claim_reward(
&mut storage, &db, &trainer, &model_id, round_id,
amount, // reward amount
&merkle_proof, // proof of inclusion in reward distribution
...
)?;
Commissione del Tesoro
Una percentuale configurabile (fee_treasury_bps, massimo 10000 = 100%) viene detratta dal pool di ricompense per il tesoro della rete. Il calcolo utilizza l'aritmetica a virgola fissa per prevenire errori di arrotondamento.
Proposte di Governance FL
Azioni di governance specifiche per FL:
SetFlPolicy
Proponi modifiche ai parametri FL:
ProposalAction::SetFlPolicy {
fee_treasury_bps: 500, // 5% treasury fee
max_models: 100, // max registered models
aggregator_whitelist: vec!["addr1", "addr2"],
}
Validazione: fee_treasury_bps <= 10000, max_models > 0, whitelist non vuota.
ApproveFlModel
Approva un modello per l'uso in produzione:
ProposalAction::ApproveFlModel {
model_id: "abc123...64hex", // 32-byte hex model ID
}
AbortFlRound
Interruzione di emergenza di un round di addestramento attivo:
ProposalAction::AbortFlRound {
model_id: "abc123...64hex",
round_id: 5,
}
Validazione: round_id > 0, model_id valido di 32 byte.
Layout dello Storage
I contract FL utilizzano slot di storage a partire da 100:
| Intervallo Slot | Scopo |
|---|---|
| 100+ | Metadati del modello |
| 200+ | Catene di versioni |
| 300+ | Stato del round |
| 400+ | Invii aggiornamenti |
| 500+ | Pool di ricompense |
| 600+ | Mapping dei ruoli |
Integrazione tramite SDK
use savitri_sdk::{TransactionBuilder, GovernanceAction};
// Crea proposta di governance FL
let tx = TransactionBuilder::new()
.create_fl_proposal(
"governance_contract_address",
"Approve sentiment model v2",
"Production-ready model with 95% accuracy",
604800, // 7-day voting period
)
.nonce(nonce)
.fee(5_000_000_000_000_000)
.build_and_sign(&wallet)?;