Apprentissage Fédéré (FL)
Le Savitri Network intègre un système d'Apprentissage Fédéré en chaîne pour l'entraînement décentralisé de modèles d'IA. Les contrats FL gèrent l'enregistrement des modèles, les sessions d'entraînement, la soumission des mises à jour, la distribution des récompenses et la gouvernance.
Architecture
Governance (proposals + voting)
│
▼
Model Registry
│ register model, assign roles, version tracking
▼
Job Lifecycle
│ create round → open → submit updates → seal → finalize
▼
Reward Pool
│ Merkle-proof reward claims
▼
Trainers + Aggregators
Registre de Modèles
Les modèles sont enregistrés en chaîne avec des métadonnées, une gestion des versions et un contrôle d'accès basé sur les rôles.
Enregistrement de Modèle
// Register a new model
FlModelRegistry::register_model(
&mut storage,
&db,
&creator, // [u8; 32] - model creator address
"sentiment-v1", // model name
"ipfs://Qm.../meta", // metadata URI
"MIT", // license URI
"ipfs://Qm.../weights", // initial weights URI
&mut events,
Some(&mut gas),
)?;
Gestion des Versions de Modèles
Les modèles ont des chaînes de versions immuables. Chaque nouvelle version référence son parent :
v1 (initial) → v2 (fine-tuned) → v3 (production)
Les métadonnées de version comprennent :
metadata_uri: Description de l'architecture du modèleweights_uri: Emplacement des poids entraînésaggregator: Adresse qui a produit cette versionparent_version: Lien vers la version précédente
Contrôle d'Accès Basé sur les Rôles (RBAC)
| Rôle | Permissions |
|---|---|
Creator | Enregistrer des modèles, gérer les versions, définir les politiques |
Viewer | Lire les métadonnées et les versions des modèles |
Trainer | Soumettre des mises à jour d'entraînement aux sessions |
Aggregator | Agréger les mises à jour, finaliser les sessions, produire des versions |
L'accès des entraîneurs est contrôlé via une liste d'autorisation/blocage par modèle.
Gestion des Politiques
Chaque modèle dispose de politiques configurables :
| Politique | Description |
|---|---|
access_policy_hash | Qui peut accéder aux données du modèle |
reward_policy_hash | Comment les récompenses sont distribuées |
max_trainers | Nombre maximal d'entraîneurs simultanés |
aggregator_whitelist | Agrégateurs approuvés |
Cycle de Vie des Tâches
L'entraînement FL est organisé en sessions avec un cycle de vie défini :
Planned → Open → Sealed → Finalized
↘ Aborted (via governance)
États d'une Session
| État | Description | Actions Autorisées |
|---|---|---|
Planned | Session créée, n'acceptant pas encore de mises à jour | Ouvrir |
Open | Accepte les mises à jour des entraîneurs | Soumettre une mise à jour, Sceller |
Sealed | Plus de mises à jour, agrégation en cours | Finaliser, Abandonner |
Finalized | Récompenses distribuées, session terminée | Réclamer les récompenses |
Aborted | Session annulée via la gouvernance | Aucune |
Créer une Session
FlJobLifecycle::create_round(
&mut storage,
&db,
&creator,
&model_id, // [u8; 32]
round_id, // u64
reward_pool_amount, // u128
&mut events,
Some(&mut gas),
)?;
Soumettre une Mise à Jour d'Entraînement
Les entraîneurs soumettent des mises à jour de modèle pendant la phase Ouverte :
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),
)?;
Protection contre la rediffusion : chaque entraîneur dispose d'un nonce par session qui doit être strictement croissant.
Sceller et Finaliser
// Seal round (stop accepting updates)
FlJobLifecycle::seal_round(&mut storage, &db, &aggregator, &model_id, round_id, ...)?;
// Finalize round (distribute rewards)
FlJobLifecycle::finalize_round(
&mut storage, &db, &aggregator, &model_id, round_id,
&merkle_root, // reward distribution Merkle root
&new_weights_uri, // aggregated model weights
...
)?;
Réclamer les Récompenses
Les entraîneurs réclament leurs récompenses avec des preuves de Merkle :
FlJobLifecycle::claim_reward(
&mut storage, &db, &trainer, &model_id, round_id,
amount, // reward amount
&merkle_proof, // proof of inclusion in reward distribution
...
)?;
Frais de Trésor
Un pourcentage configurable (fee_treasury_bps, max 10000 = 100 %) est déduit du pool de récompenses pour le trésor du réseau. Le calcul utilise l'arithmétique à virgule fixe pour éviter les erreurs d'arrondi.
Propositions de Gouvernance FL
Actions de gouvernance spécifiques au FL :
SetFlPolicy
Proposer des modifications aux paramètres FL :
ProposalAction::SetFlPolicy {
fee_treasury_bps: 500, // 5% treasury fee
max_models: 100, // max registered models
aggregator_whitelist: vec!["addr1", "addr2"],
}
Validation : fee_treasury_bps <= 10000, max_models > 0, liste blanche non vide.
ApproveFlModel
Approuver un modèle pour une utilisation en production :
ProposalAction::ApproveFlModel {
model_id: "abc123...64hex", // 32-byte hex model ID
}
AbortFlRound
Abandon d'urgence d'une session d'entraînement active :
ProposalAction::AbortFlRound {
model_id: "abc123...64hex",
round_id: 5,
}
Validation : round_id > 0, model_id de 32 octets valide.
Disposition du Stockage
Les contrats FL utilisent des emplacements de stockage à partir de 100 :
| Plage d'Emplacement | Utilisation |
|---|---|
| 100+ | Métadonnées du modèle |
| 200+ | Chaînes de versions |
| 300+ | État de la session |
| 400+ | Soumissions de mises à jour |
| 500+ | Pools de récompenses |
| 600+ | Mappages de rôles |
Intégration via le SDK
use savitri_sdk::{TransactionBuilder, GovernanceAction};
// Create FL governance proposal
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)?;