amewebstudio commited on
Commit
5fe4d99
·
verified ·
1 Parent(s): 69f2e41

cognitive core loading framework

Browse files
Files changed (6) hide show
  1. README.md +161 -5
  2. __init__.py +86 -0
  3. cognitive_base.py +272 -0
  4. cognitive_checkpoint.py +298 -0
  5. cognitive_training.py +372 -0
  6. cognitive_utils.py +282 -0
README.md CHANGED
@@ -1,5 +1,161 @@
1
- ---
2
- license: other
3
- license_name: proprietary
4
- license_link: LICENSE
5
- ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # COGNITIVE-CORE Framework
2
+
3
+ > Standard universel pour les architectures cognitives d'Ame Web Studio
4
+
5
+ ## 🏗️ Structure
6
+
7
+ ```
8
+ cognitive-core/
9
+ ├── __init__.py # Exports du package
10
+ ├── cognitive_base.py # Classes de base (Config, Modules, PreTrainedModel)
11
+ ├── cognitive_checkpoint.py # Chargement/sauvegarde avec remappage auto
12
+ ├── cognitive_utils.py # Utilitaires (device, mémoire, tokens)
13
+ └── README.md # Cette documentation
14
+ ```
15
+
16
+ ## 🚀 Installation
17
+
18
+ ```python
19
+ # Ajouter à votre modèle
20
+ import sys
21
+ sys.path.append("/path/to/standardisation")
22
+
23
+ from cognitive_core import (
24
+ CognitiveConfig,
25
+ CognitivePreTrainedModel,
26
+ setup_environment,
27
+ get_device
28
+ )
29
+ ```
30
+
31
+ ## 📖 Guide d'Utilisation
32
+
33
+ ### 1. Créer une Configuration
34
+
35
+ ```python
36
+ from cognitive_core import CognitiveConfig
37
+
38
+ class MyModelConfig(CognitiveConfig):
39
+ model_type = "my_cognitive_model"
40
+
41
+ def __init__(
42
+ self,
43
+ vocab_size: int = 50000,
44
+ # ... vos paramètres
45
+ **kwargs
46
+ ):
47
+ super().__init__(**kwargs)
48
+ self.vocab_size = vocab_size
49
+ ```
50
+
51
+ ### 2. Créer un Modèle Cognitif
52
+
53
+ ```python
54
+ from cognitive_core import CognitivePreTrainedModel, CognitiveModule
55
+ import torch.nn as nn
56
+
57
+ class MyMemoryModule(CognitiveModule):
58
+ def __init__(self, config):
59
+ super().__init__(config)
60
+ self.memory = nn.Parameter(torch.randn(1000, config.d_model))
61
+
62
+ def forward(self, x, **kwargs):
63
+ # Votre logique
64
+ return {"output": x, "memory_used": True}
65
+
66
+ def reset_state(self):
67
+ pass
68
+
69
+ class MyModel(CognitivePreTrainedModel):
70
+ config_class = MyModelConfig
71
+
72
+ def __init__(self, config):
73
+ super().__init__(config)
74
+ self.embeddings = nn.Embedding(config.vocab_size, config.d_model)
75
+ self.memory = MyMemoryModule(config)
76
+ self.lm_head = nn.Linear(config.d_model, config.vocab_size)
77
+ self.post_init()
78
+
79
+ def forward(self, input_ids, **kwargs):
80
+ x = self.embeddings(input_ids)
81
+ mem_out = self.memory(x)
82
+ logits = self.lm_head(mem_out["output"])
83
+ return logits
84
+ ```
85
+
86
+ ### 3. Chargement Automatique
87
+
88
+ Le framework gère automatiquement:
89
+ - ✅ Remappage des clés (avec/sans préfixe `model.`)
90
+ - ✅ Validation du checkpoint
91
+ - ✅ Compatibilité HuggingFace
92
+
93
+ ```python
94
+ from cognitive_core import load_cognitive_checkpoint
95
+
96
+ # Charger un checkpoint personnalisé
97
+ info = load_cognitive_checkpoint(model, "path/to/checkpoint.pt", verbose=True)
98
+ print(f"Clés chargées: {info['validation']['matched_keys']}")
99
+ ```
100
+
101
+ ### 4. Configuration Environnement (Kaggle/Colab)
102
+
103
+ ```python
104
+ from cognitive_core import setup_environment, get_device, get_hf_token
105
+
106
+ # Configure cache HuggingFace dans répertoire accessible
107
+ cache_dir = setup_environment()
108
+
109
+ # Détection automatique GPU/CPU
110
+ device = get_device()
111
+
112
+ # Récupérer token HuggingFace
113
+ token = get_hf_token()
114
+ ```
115
+
116
+ ## 🔧 Modules Disponibles
117
+
118
+ | Module | Description |
119
+ |--------|-------------|
120
+ | `CognitiveConfig` | Configuration de base héritant de PretrainedConfig |
121
+ | `CognitiveModule` | Interface abstraite pour modules cognitifs |
122
+ | `MemoryModule` | Interface pour modules de mémoire (store/retrieve) |
123
+ | `TemporalModule` | Interface pour modules temporels (predict) |
124
+ | `WorldModelModule` | Interface pour modèles du monde (update/imagine) |
125
+ | `CognitivePreTrainedModel` | Modèle HuggingFace avec remappage auto |
126
+
127
+ ## 🎯 Cas d'Usage
128
+
129
+ ### Vision Cognitive
130
+ ```python
131
+ class CognitiveViTConfig(CognitiveConfig):
132
+ model_type = "cognitive_vit"
133
+ # ... config vision
134
+ ```
135
+
136
+ ### World Model
137
+ ```python
138
+ class CognitiveWorldConfig(CognitiveConfig):
139
+ model_type = "cognitive_world"
140
+ # ... config world model
141
+ ```
142
+
143
+ ### Multimodal
144
+ ```python
145
+ class CognitiveMultimodalConfig(CognitiveConfig):
146
+ model_type = "cognitive_multimodal"
147
+ vision_enabled = True
148
+ audio_enabled = True
149
+ ```
150
+
151
+ ## 📊 Garanties du Standard
152
+
153
+ - ✅ **Intégrité des poids** - Aucun poids réinitialisé silencieusement
154
+ - ✅ **Compatibilité HuggingFace** - AutoModel fonctionne nativement
155
+ - ✅ **Portabilité** - Kaggle, Colab, Local sans modification
156
+ - ✅ **Extensibilité** - Ajouter vos modules facilement
157
+
158
+ ## 📄 Licence
159
+
160
+ **PROPRIETARY - ALL RIGHTS RESERVED**
161
+ Copyright © 2026 Mike Amega (Logo) - Ame Web Studio
__init__.py ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ COGNITIVE-CORE Framework
3
+ ========================
4
+
5
+ Universal template for Ame Web Studio's cognitive AI architectures.
6
+ Provides standardized loading, checkpoint management, and utilities
7
+ for vision, language, world model, and multimodal cognitive systems.
8
+
9
+ Copyright © 2026 Mike Amega (Logo) - Ame Web Studio
10
+ License: Proprietary - All Rights Reserved
11
+ """
12
+
13
+ from .cognitive_base import (
14
+ CognitiveConfig,
15
+ CognitiveModule,
16
+ MemoryModule,
17
+ TemporalModule,
18
+ WorldModelModule,
19
+ CognitivePreTrainedModel,
20
+ register_cognitive_model,
21
+ )
22
+
23
+ from .cognitive_checkpoint import (
24
+ remap_checkpoint_keys,
25
+ validate_checkpoint,
26
+ save_cognitive_checkpoint,
27
+ load_cognitive_checkpoint,
28
+ )
29
+
30
+ from .cognitive_utils import (
31
+ setup_environment,
32
+ get_device,
33
+ get_optimal_dtype,
34
+ get_memory_info,
35
+ clear_memory,
36
+ estimate_model_memory,
37
+ print_model_info,
38
+ print_training_progress,
39
+ get_hf_token,
40
+ )
41
+
42
+ from .cognitive_training import (
43
+ CognitiveTrainingConfig,
44
+ CognitiveTrainer,
45
+ prepare_dataset,
46
+ create_instruction_dataset,
47
+ quick_train,
48
+ CognitiveStateCallback,
49
+ )
50
+
51
+ __version__ = "1.0.0"
52
+ __author__ = "Mike Amega"
53
+ __license__ = "Proprietary"
54
+
55
+ __all__ = [
56
+ # Base classes
57
+ "CognitiveConfig",
58
+ "CognitiveModule",
59
+ "MemoryModule",
60
+ "TemporalModule",
61
+ "WorldModelModule",
62
+ "CognitivePreTrainedModel",
63
+ "register_cognitive_model",
64
+ # Checkpoint
65
+ "remap_checkpoint_keys",
66
+ "validate_checkpoint",
67
+ "save_cognitive_checkpoint",
68
+ "load_cognitive_checkpoint",
69
+ # Utils
70
+ "setup_environment",
71
+ "get_device",
72
+ "get_optimal_dtype",
73
+ "get_memory_info",
74
+ "clear_memory",
75
+ "estimate_model_memory",
76
+ "print_model_info",
77
+ "print_training_progress",
78
+ "get_hf_token",
79
+ # Training
80
+ "CognitiveTrainingConfig",
81
+ "CognitiveTrainer",
82
+ "prepare_dataset",
83
+ "create_instruction_dataset",
84
+ "quick_train",
85
+ "CognitiveStateCallback",
86
+ ]
cognitive_base.py ADDED
@@ -0,0 +1,272 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ COGNITIVE-CORE: Base Classes for Cognitive Architectures
3
+ =========================================================
4
+
5
+ This module provides the foundational classes for building cognitive AI models
6
+ that follow the Ame Web Studio standard. All cognitive models (vision, language,
7
+ world model, multimodal) should inherit from these base classes.
8
+
9
+ Copyright © 2026 Mike Amega (Logo) - Ame Web Studio
10
+ License: Proprietary - All Rights Reserved
11
+ """
12
+
13
+ import torch
14
+ import torch.nn as nn
15
+ from typing import Dict, List, Optional, Any, Tuple
16
+ from abc import ABC, abstractmethod
17
+
18
+ from transformers import PreTrainedModel, PretrainedConfig
19
+
20
+
21
+ # ==============================================================================
22
+ # CONFIGURATION DE BASE
23
+ # ==============================================================================
24
+
25
+
26
+ class CognitiveConfig(PretrainedConfig):
27
+ """
28
+ Configuration de base pour tous les modèles cognitifs.
29
+
30
+ Tous les modèles cognitifs (vision, language, world, multimodal) doivent
31
+ hériter de cette configuration pour garantir la compatibilité.
32
+ """
33
+
34
+ model_type = "cognitive"
35
+
36
+ def __init__(
37
+ self,
38
+ # Dimensions de base
39
+ d_model: int = 512,
40
+ d_ff: int = 2048,
41
+ n_layers: int = 12,
42
+ n_heads: int = 8,
43
+ dropout: float = 0.1,
44
+ # Modules cognitifs (peuvent être activés/désactivés)
45
+ use_memory: bool = True,
46
+ use_temporal: bool = True,
47
+ use_synaptic: bool = True,
48
+ use_dream: bool = True,
49
+ use_world_model: bool = True,
50
+ use_neurogenesis: bool = True,
51
+ # Mémoire
52
+ memory_size: int = 8192,
53
+ short_term_dim: int = 512,
54
+ long_term_dim: int = 256,
55
+ # États internes
56
+ internal_state_dim: int = 128,
57
+ latent_state_dim: int = 768,
58
+ # Meta
59
+ version: str = "1.0",
60
+ author: str = "Mike Amega",
61
+ license: str = "Proprietary",
62
+ **kwargs,
63
+ ):
64
+ super().__init__(**kwargs)
65
+
66
+ # Dimensions
67
+ self.d_model = d_model
68
+ self.hidden_size = d_model # Alias HuggingFace
69
+ self.d_ff = d_ff
70
+ self.n_layers = n_layers
71
+ self.n_heads = n_heads
72
+ self.dropout = dropout
73
+
74
+ # Modules cognitifs
75
+ self.use_memory = use_memory
76
+ self.use_temporal = use_temporal
77
+ self.use_synaptic = use_synaptic
78
+ self.use_dream = use_dream
79
+ self.use_world_model = use_world_model
80
+ self.use_neurogenesis = use_neurogenesis
81
+
82
+ # Mémoire
83
+ self.memory_size = memory_size
84
+ self.short_term_dim = short_term_dim
85
+ self.long_term_dim = long_term_dim
86
+
87
+ # États
88
+ self.internal_state_dim = internal_state_dim
89
+ self.latent_state_dim = latent_state_dim
90
+
91
+ # Meta
92
+ self.version = version
93
+ self.author = author
94
+ self.license = license
95
+
96
+ @property
97
+ def head_dim(self) -> int:
98
+ return self.d_model // self.n_heads
99
+
100
+
101
+ # ==============================================================================
102
+ # MODULES COGNITIFS ABSTRAITS
103
+ # ==============================================================================
104
+
105
+
106
+ class CognitiveModule(nn.Module, ABC):
107
+ """
108
+ Classe de base abstraite pour tous les modules cognitifs.
109
+
110
+ Chaque module cognitif doit implémenter:
111
+ - forward(): traitement principal
112
+ - reset_state(): réinitialisation des états internes
113
+ - get_state(): récupérer l'état courant
114
+ """
115
+
116
+ def __init__(self, config: CognitiveConfig):
117
+ super().__init__()
118
+ self.config = config
119
+
120
+ @abstractmethod
121
+ def forward(self, x: torch.Tensor, **kwargs) -> Dict[str, Any]:
122
+ """Traitement principal du module."""
123
+ pass
124
+
125
+ @abstractmethod
126
+ def reset_state(self):
127
+ """Réinitialiser les états internes du module."""
128
+ pass
129
+
130
+ def get_state(self) -> Dict[str, torch.Tensor]:
131
+ """Récupérer l'état courant (pour sauvegarde/debug)."""
132
+ return {}
133
+
134
+
135
+ class MemoryModule(CognitiveModule):
136
+ """Interface pour les modules de mémoire."""
137
+
138
+ @abstractmethod
139
+ def store(self, key: torch.Tensor, value: torch.Tensor):
140
+ """Stocker une information en mémoire."""
141
+ pass
142
+
143
+ @abstractmethod
144
+ def retrieve(self, query: torch.Tensor, k: int = 1) -> torch.Tensor:
145
+ """Récupérer les k informations les plus pertinentes."""
146
+ pass
147
+
148
+
149
+ class TemporalModule(CognitiveModule):
150
+ """Interface pour les modules temporels/prédictifs."""
151
+
152
+ @abstractmethod
153
+ def predict(self, state: torch.Tensor, horizon: int = 1) -> torch.Tensor:
154
+ """Prédire l'état futur à l'horizon donné."""
155
+ pass
156
+
157
+
158
+ class WorldModelModule(CognitiveModule):
159
+ """Interface pour les modèles du monde."""
160
+
161
+ @abstractmethod
162
+ def update(self, observation: torch.Tensor) -> Dict[str, float]:
163
+ """Mettre à jour le modèle du monde avec une observation."""
164
+ pass
165
+
166
+ @abstractmethod
167
+ def imagine(self, action: torch.Tensor) -> torch.Tensor:
168
+ """Imaginer l'effet d'une action."""
169
+ pass
170
+
171
+
172
+ # ==============================================================================
173
+ # MODÈLE COGNITIF DE BASE
174
+ # ==============================================================================
175
+
176
+
177
+ class CognitivePreTrainedModel(PreTrainedModel):
178
+ """
179
+ Classe de base pour tous les modèles cognitifs HuggingFace-compatibles.
180
+
181
+ Fournit:
182
+ - Remappage automatique des clés de checkpoint
183
+ - Gestion des modules cognitifs optionnels
184
+ - Méthodes d'initialisation standardisées
185
+ """
186
+
187
+ config_class = CognitiveConfig
188
+ base_model_prefix = "cognitive"
189
+ supports_gradient_checkpointing = False # Incompatible avec architecture cognitive
190
+
191
+ # Clés à ignorer lors du chargement (buffers dynamiques)
192
+ _keys_to_ignore_on_load_missing = [
193
+ r".*\.state$",
194
+ r".*\.history$",
195
+ r".*\.buffer$",
196
+ r".*rope\..*_cache",
197
+ r".*rope\.inv_freq",
198
+ ]
199
+
200
+ def _init_weights(self, module):
201
+ """Initialisation standard des poids."""
202
+ if isinstance(module, nn.Linear):
203
+ torch.nn.init.normal_(module.weight, mean=0.0, std=0.02)
204
+ if module.bias is not None:
205
+ torch.nn.init.zeros_(module.bias)
206
+ elif isinstance(module, nn.Embedding):
207
+ torch.nn.init.normal_(module.weight, mean=0.0, std=0.02)
208
+
209
+ def _load_from_state_dict(
210
+ self,
211
+ state_dict,
212
+ prefix,
213
+ local_metadata,
214
+ strict,
215
+ missing_keys,
216
+ unexpected_keys,
217
+ error_msgs,
218
+ ):
219
+ """
220
+ Remappage automatique des clés de checkpoint.
221
+
222
+ Gère les différences de préfixes entre formats de checkpoint
223
+ (ex: avec/sans 'model.' prefix).
224
+ """
225
+ from .cognitive_checkpoint import remap_checkpoint_keys
226
+
227
+ # Remapper les clés si nécessaire
228
+ remapped = remap_checkpoint_keys(state_dict, self.state_dict())
229
+
230
+ # Appeler l'implémentation parent
231
+ super()._load_from_state_dict(
232
+ remapped,
233
+ prefix,
234
+ local_metadata,
235
+ strict,
236
+ missing_keys,
237
+ unexpected_keys,
238
+ error_msgs,
239
+ )
240
+
241
+ def get_cognitive_state(self) -> Dict[str, Any]:
242
+ """Récupérer l'état de tous les modules cognitifs."""
243
+ state = {}
244
+ for name, module in self.named_modules():
245
+ if isinstance(module, CognitiveModule):
246
+ state[name] = module.get_state()
247
+ return state
248
+
249
+ def reset_cognitive_state(self):
250
+ """Réinitialiser l'état de tous les modules cognitifs."""
251
+ for module in self.modules():
252
+ if isinstance(module, CognitiveModule):
253
+ module.reset_state()
254
+
255
+
256
+ # ==============================================================================
257
+ # UTILITAIRES D'ENREGISTREMENT AUTO
258
+ # ==============================================================================
259
+
260
+
261
+ def register_cognitive_model(config_class, model_class):
262
+ """
263
+ Enregistrer un modèle cognitif pour utilisation avec AutoModel.
264
+
265
+ Usage:
266
+ register_cognitive_model(MyConfig, MyModel)
267
+ # Puis: AutoModelForCausalLM.from_pretrained(..., trust_remote_code=True)
268
+ """
269
+ from transformers import AutoConfig, AutoModel
270
+
271
+ AutoConfig.register(config_class.model_type, config_class)
272
+ AutoModel.register(config_class, model_class)
cognitive_checkpoint.py ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ COGNITIVE-CORE: Checkpoint Loading & Key Remapping
3
+ ===================================================
4
+
5
+ This module provides robust checkpoint loading with automatic key remapping
6
+ to handle different checkpoint formats (with/without 'model.' prefix, etc.)
7
+
8
+ Copyright © 2026 Mike Amega (Logo) - Ame Web Studio
9
+ License: Proprietary - All Rights Reserved
10
+ """
11
+
12
+ import re
13
+ from typing import Dict, Set, Optional
14
+ import torch
15
+
16
+
17
+ def remap_checkpoint_keys(
18
+ checkpoint_state_dict: Dict[str, torch.Tensor],
19
+ model_state_dict: Dict[str, torch.Tensor],
20
+ verbose: bool = False,
21
+ ) -> Dict[str, torch.Tensor]:
22
+ """
23
+ Remappe automatiquement les clés du checkpoint pour correspondre au modèle.
24
+
25
+ Gère les scénarios suivants:
26
+ 1. Checkpoint a préfixe 'model.' mais modèle n'en a pas → retirer préfixe
27
+ 2. Checkpoint n'a pas préfixe 'model.' mais modèle en a → ajouter préfixe
28
+ 3. Autres préfixes personnalisés
29
+
30
+ Args:
31
+ checkpoint_state_dict: État du checkpoint chargé
32
+ model_state_dict: État du modèle cible
33
+ verbose: Afficher les détails du remappage
34
+
35
+ Returns:
36
+ Dict remappé compatible avec le modèle
37
+ """
38
+ model_keys = set(model_state_dict.keys())
39
+ checkpoint_keys = set(checkpoint_state_dict.keys())
40
+
41
+ # Vérifier si le checkpoint correspond déjà
42
+ matching = model_keys & checkpoint_keys
43
+ if len(matching) >= len(checkpoint_keys) * 0.9:
44
+ if verbose:
45
+ print(
46
+ f"✅ Checkpoint compatible: {len(matching)}/{len(checkpoint_keys)} clés correspondent"
47
+ )
48
+ return checkpoint_state_dict
49
+
50
+ # Tester différentes stratégies de remappage
51
+ strategies = [
52
+ ("remove_model_prefix", _remove_prefix, "model."),
53
+ ("add_model_prefix", _add_prefix, "model."),
54
+ ("remove_backbone_prefix", _remove_prefix, "backbone."),
55
+ ("remove_encoder_prefix", _remove_prefix, "encoder."),
56
+ ]
57
+
58
+ best_strategy = None
59
+ best_match_count = len(matching)
60
+ best_result = checkpoint_state_dict
61
+
62
+ for name, func, prefix in strategies:
63
+ remapped = func(checkpoint_state_dict, prefix)
64
+ match_count = len(model_keys & set(remapped.keys()))
65
+
66
+ if match_count > best_match_count:
67
+ best_match_count = match_count
68
+ best_strategy = name
69
+ best_result = remapped
70
+
71
+ if verbose and best_strategy:
72
+ print(f"🔄 Stratégie appliquée: {best_strategy}")
73
+ print(f" Clés correspondantes: {best_match_count}/{len(checkpoint_keys)}")
74
+
75
+ # Fallback: mapper intelligemment clé par clé
76
+ if best_match_count < len(checkpoint_keys) * 0.5:
77
+ best_result = _smart_key_mapping(checkpoint_state_dict, model_keys)
78
+ if verbose:
79
+ final_match = len(model_keys & set(best_result.keys()))
80
+ print(
81
+ f"🧠 Remappage intelligent: {final_match}/{len(checkpoint_keys)} clés"
82
+ )
83
+
84
+ return best_result
85
+
86
+
87
+ def _remove_prefix(state_dict: Dict, prefix: str) -> Dict:
88
+ """Retirer un préfixe de toutes les clés."""
89
+ return {
90
+ (k[len(prefix) :] if k.startswith(prefix) else k): v
91
+ for k, v in state_dict.items()
92
+ }
93
+
94
+
95
+ def _add_prefix(state_dict: Dict, prefix: str) -> Dict:
96
+ """Ajouter un préfixe à toutes les clés."""
97
+ return {f"{prefix}{k}": v for k, v in state_dict.items()}
98
+
99
+
100
+ def _smart_key_mapping(
101
+ checkpoint_dict: Dict[str, torch.Tensor], model_keys: Set[str]
102
+ ) -> Dict[str, torch.Tensor]:
103
+ """
104
+ Mapping intelligent clé par clé basé sur les suffixes et patterns.
105
+ """
106
+ result = {}
107
+ model_keys_list = list(model_keys)
108
+
109
+ for ckpt_key, value in checkpoint_dict.items():
110
+ # Correspondance exacte
111
+ if ckpt_key in model_keys:
112
+ result[ckpt_key] = value
113
+ continue
114
+
115
+ # Essayer avec préfixe 'model.'
116
+ with_prefix = f"model.{ckpt_key}"
117
+ if with_prefix in model_keys:
118
+ result[with_prefix] = value
119
+ continue
120
+
121
+ # Essayer sans préfixe 'model.'
122
+ if ckpt_key.startswith("model."):
123
+ without_prefix = ckpt_key[6:]
124
+ if without_prefix in model_keys:
125
+ result[without_prefix] = value
126
+ continue
127
+
128
+ # Chercher par suffixe (ex: ".weight", ".bias")
129
+ ckpt_suffix = ckpt_key.split(".")[-1]
130
+ ckpt_base = ".".join(ckpt_key.split(".")[:-1])
131
+
132
+ for model_key in model_keys_list:
133
+ if model_key.endswith(ckpt_suffix):
134
+ model_base = ".".join(model_key.split(".")[:-1])
135
+ # Vérifier similarité structurelle
136
+ if _keys_similar(ckpt_base, model_base):
137
+ result[model_key] = value
138
+ break
139
+ else:
140
+ # Garder la clé originale (sera ignorée si pas dans modèle)
141
+ result[ckpt_key] = value
142
+
143
+ return result
144
+
145
+
146
+ def _keys_similar(key1: str, key2: str) -> bool:
147
+ """Vérifier si deux clés sont structurellement similaires."""
148
+ parts1 = key1.split(".")
149
+ parts2 = key2.split(".")
150
+
151
+ # Même nombre de parties
152
+ if len(parts1) != len(parts2):
153
+ return False
154
+
155
+ # Comparer chaque partie (ignorer les préfixes comme 'model')
156
+ matches = sum(
157
+ 1 for p1, p2 in zip(parts1, parts2) if p1 == p2 or p1.isdigit() and p2.isdigit()
158
+ )
159
+ return matches >= len(parts1) * 0.7
160
+
161
+
162
+ def validate_checkpoint(
163
+ checkpoint_state_dict: Dict[str, torch.Tensor],
164
+ model_state_dict: Dict[str, torch.Tensor],
165
+ strict: bool = False,
166
+ ) -> Dict[str, any]:
167
+ """
168
+ Valider qu'un checkpoint est compatible avec un modèle.
169
+
170
+ Returns:
171
+ Dict avec:
172
+ - valid: bool
173
+ - missing_keys: clés manquantes dans checkpoint
174
+ - unexpected_keys: clés inattendues dans checkpoint
175
+ - size_mismatches: clés avec tailles incompatibles
176
+ """
177
+ model_keys = set(model_state_dict.keys())
178
+ ckpt_keys = set(checkpoint_state_dict.keys())
179
+
180
+ missing = model_keys - ckpt_keys
181
+ unexpected = ckpt_keys - model_keys
182
+
183
+ # Vérifier les tailles
184
+ size_mismatches = []
185
+ for key in model_keys & ckpt_keys:
186
+ model_shape = model_state_dict[key].shape
187
+ ckpt_shape = checkpoint_state_dict[key].shape
188
+ if model_shape != ckpt_shape:
189
+ size_mismatches.append(
190
+ {"key": key, "model_shape": model_shape, "checkpoint_shape": ckpt_shape}
191
+ )
192
+
193
+ valid = len(missing) == 0 and len(size_mismatches) == 0
194
+ if not strict:
195
+ valid = len(size_mismatches) == 0 and len(missing) < len(model_keys) * 0.1
196
+
197
+ return {
198
+ "valid": valid,
199
+ "missing_keys": list(missing),
200
+ "unexpected_keys": list(unexpected),
201
+ "size_mismatches": size_mismatches,
202
+ "matched_keys": len(model_keys & ckpt_keys),
203
+ "total_model_keys": len(model_keys),
204
+ }
205
+
206
+
207
+ def save_cognitive_checkpoint(
208
+ model,
209
+ path: str,
210
+ include_optimizer: bool = False,
211
+ optimizer=None,
212
+ extra_state: Optional[Dict] = None,
213
+ ):
214
+ """
215
+ Sauvegarder un checkpoint de modèle cognitif.
216
+
217
+ Args:
218
+ model: Le modèle à sauvegarder
219
+ path: Chemin de sauvegarde
220
+ include_optimizer: Inclure l'état de l'optimiseur
221
+ optimizer: L'optimiseur (si include_optimizer=True)
222
+ extra_state: État additionnel à sauvegarder
223
+ """
224
+ checkpoint = {
225
+ "model_state_dict": model.state_dict(),
226
+ "config": model.config.to_dict() if hasattr(model, "config") else {},
227
+ }
228
+
229
+ if include_optimizer and optimizer is not None:
230
+ checkpoint["optimizer_state_dict"] = optimizer.state_dict()
231
+
232
+ # Sauvegarder l'état cognitif si disponible
233
+ if hasattr(model, "get_cognitive_state"):
234
+ checkpoint["cognitive_state"] = model.get_cognitive_state()
235
+
236
+ if extra_state:
237
+ checkpoint["extra_state"] = extra_state
238
+
239
+ torch.save(checkpoint, path)
240
+ print(f"✅ Checkpoint sauvegardé: {path}")
241
+
242
+
243
+ def load_cognitive_checkpoint(
244
+ model, path: str, strict: bool = False, verbose: bool = True
245
+ ) -> Dict:
246
+ """
247
+ Charger un checkpoint dans un modèle cognitif avec remappage automatique.
248
+
249
+ Args:
250
+ model: Le modèle cible
251
+ path: Chemin du checkpoint
252
+ strict: Mode strict (erreur si clés manquantes)
253
+ verbose: Afficher les détails
254
+
255
+ Returns:
256
+ Dict avec informations de chargement
257
+ """
258
+ checkpoint = torch.load(path, map_location="cpu")
259
+
260
+ # Extraire le state_dict
261
+ if "model_state_dict" in checkpoint:
262
+ state_dict = checkpoint["model_state_dict"]
263
+ elif "state_dict" in checkpoint:
264
+ state_dict = checkpoint["state_dict"]
265
+ else:
266
+ state_dict = checkpoint
267
+
268
+ # Remapper les clés
269
+ remapped = remap_checkpoint_keys(state_dict, model.state_dict(), verbose=verbose)
270
+
271
+ # Valider
272
+ validation = validate_checkpoint(remapped, model.state_dict(), strict=strict)
273
+
274
+ if verbose:
275
+ print(
276
+ f"📊 Clés chargées: {validation['matched_keys']}/{validation['total_model_keys']}"
277
+ )
278
+ if validation["missing_keys"]:
279
+ print(f"⚠️ Clés manquantes: {len(validation['missing_keys'])}")
280
+ if validation["size_mismatches"]:
281
+ print(f"⚠️ Tailles incompatibles: {len(validation['size_mismatches'])}")
282
+
283
+ # Charger avec ignore_mismatched_sizes pour robustesse
284
+ model.load_state_dict(remapped, strict=False)
285
+
286
+ # Restaurer l'état cognitif si disponible
287
+ if "cognitive_state" in checkpoint and hasattr(model, "reset_cognitive_state"):
288
+ # L'état cognitif est généralement réinitialisé, pas restauré
289
+ pass
290
+
291
+ if verbose:
292
+ print("✅ Checkpoint chargé avec succès")
293
+
294
+ return {
295
+ "validation": validation,
296
+ "config": checkpoint.get("config", {}),
297
+ "extra_state": checkpoint.get("extra_state", {}),
298
+ }
cognitive_training.py ADDED
@@ -0,0 +1,372 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ COGNITIVE-CORE: Training Utilities
3
+ ====================================
4
+
5
+ Standardized training utilities for cognitive models, including:
6
+ - Training configurations
7
+ - Trainer wrappers
8
+ - Dataset preparation helpers
9
+ - Progress tracking
10
+
11
+ Copyright © 2026 Mike Amega (Logo) - Ame Web Studio
12
+ License: Proprietary - All Rights Reserved
13
+ """
14
+
15
+ import os
16
+ import torch
17
+ import torch.nn as nn
18
+ from typing import Dict, List, Optional, Any, Callable
19
+ from dataclasses import dataclass, field
20
+
21
+
22
+ # ==============================================================================
23
+ # CONFIGURATION D'ENTRAÎNEMENT
24
+ # ==============================================================================
25
+
26
+
27
+ @dataclass
28
+ class CognitiveTrainingConfig:
29
+ """
30
+ Configuration standard pour l'entraînement de modèles cognitifs.
31
+ """
32
+
33
+ # Output
34
+ output_dir: str = "./cognitive-output"
35
+
36
+ # Training params
37
+ num_epochs: int = 1
38
+ batch_size: int = 1
39
+ gradient_accumulation_steps: int = 8
40
+ learning_rate: float = 1e-5
41
+ warmup_steps: int = 100
42
+ weight_decay: float = 0.01
43
+ max_grad_norm: float = 1.0
44
+
45
+ # Sequence
46
+ max_seq_len: int = 2048 # IMPORTANT: >= 2048 pour modules cognitifs
47
+
48
+ # Precision
49
+ use_fp16: bool = True
50
+ use_bf16: bool = False
51
+
52
+ # Logging
53
+ logging_steps: int = 10
54
+ save_steps: int = 200
55
+ save_total_limit: int = 2
56
+
57
+ # Hub
58
+ push_to_hub: bool = False
59
+ hub_model_id: Optional[str] = None
60
+ hub_private: bool = True
61
+
62
+ # Device
63
+ device: Optional[str] = None # auto-detected if None
64
+
65
+ def __post_init__(self):
66
+ os.makedirs(self.output_dir, exist_ok=True)
67
+
68
+
69
+ # ==============================================================================
70
+ # PRÉPARATION DES DONNÉES
71
+ # ==============================================================================
72
+
73
+
74
+ def prepare_dataset(
75
+ dataset,
76
+ tokenizer,
77
+ text_column: str = "text",
78
+ max_length: int = 2048,
79
+ num_proc: int = 4,
80
+ ):
81
+ """
82
+ Prépare un dataset pour l'entraînement d'un modèle cognitif.
83
+
84
+ Args:
85
+ dataset: Dataset HuggingFace
86
+ tokenizer: Tokenizer du modèle
87
+ text_column: Nom de la colonne contenant le texte
88
+ max_length: Longueur maximale des séquences
89
+ num_proc: Nombre de processus pour le mapping
90
+
91
+ Returns:
92
+ Dataset tokenisé prêt pour l'entraînement
93
+ """
94
+
95
+ def tokenize_function(examples):
96
+ texts = examples[text_column]
97
+ if not isinstance(texts, list):
98
+ texts = [texts]
99
+
100
+ return tokenizer(
101
+ texts,
102
+ truncation=True,
103
+ padding="max_length",
104
+ max_length=max_length,
105
+ return_tensors=None,
106
+ )
107
+
108
+ # Supprimer les colonnes originales
109
+ columns_to_remove = dataset.column_names
110
+ if isinstance(columns_to_remove, dict):
111
+ columns_to_remove = columns_to_remove.get("train", [])
112
+
113
+ tokenized = dataset.map(
114
+ tokenize_function,
115
+ batched=True,
116
+ num_proc=num_proc,
117
+ remove_columns=columns_to_remove,
118
+ )
119
+
120
+ tokenized.set_format(type="torch")
121
+ return tokenized
122
+
123
+
124
+ def create_instruction_dataset(
125
+ examples: List[Dict[str, str]],
126
+ tokenizer,
127
+ max_length: int = 2048,
128
+ instruction_template: str = "### Instruction:\n{instruction}\n\n### Response:\n{response}",
129
+ ):
130
+ """
131
+ Crée un dataset d'instructions à partir d'exemples.
132
+
133
+ Args:
134
+ examples: Liste de dicts avec 'instruction' et 'response'
135
+ tokenizer: Tokenizer du modèle
136
+ max_length: Longueur maximale
137
+ instruction_template: Template de formatage
138
+
139
+ Returns:
140
+ Dataset tokenisé
141
+ """
142
+ from datasets import Dataset
143
+
144
+ formatted = []
145
+ for ex in examples:
146
+ text = instruction_template.format(
147
+ instruction=ex.get("instruction", ""), response=ex.get("response", "")
148
+ )
149
+ formatted.append({"text": text})
150
+
151
+ dataset = Dataset.from_list(formatted)
152
+ return prepare_dataset(dataset, tokenizer, "text", max_length)
153
+
154
+
155
+ # ==============================================================================
156
+ # TRAINER WRAPPER
157
+ # ==============================================================================
158
+
159
+
160
+ class CognitiveTrainer:
161
+ """
162
+ Trainer simplifié pour modèles cognitifs.
163
+
164
+ Wrapper autour du Trainer HuggingFace avec configuration optimisée
165
+ pour les architectures cognitives.
166
+ """
167
+
168
+ def __init__(
169
+ self,
170
+ model,
171
+ tokenizer,
172
+ train_dataset,
173
+ config: CognitiveTrainingConfig,
174
+ eval_dataset=None,
175
+ callbacks: Optional[List] = None,
176
+ ):
177
+ self.model = model
178
+ self.tokenizer = tokenizer
179
+ self.train_dataset = train_dataset
180
+ self.eval_dataset = eval_dataset
181
+ self.config = config
182
+ self.callbacks = callbacks or []
183
+
184
+ # Configurer tokenizer
185
+ if tokenizer.pad_token is None:
186
+ tokenizer.pad_token = tokenizer.eos_token
187
+
188
+ self._setup_trainer()
189
+
190
+ def _setup_trainer(self):
191
+ """Configure le Trainer HuggingFace."""
192
+ from transformers import (
193
+ Trainer,
194
+ TrainingArguments,
195
+ DataCollatorForLanguageModeling,
196
+ )
197
+
198
+ # Déterminer device
199
+ if self.config.device:
200
+ device = self.config.device
201
+ elif torch.cuda.is_available():
202
+ device = "cuda"
203
+ else:
204
+ device = "cpu"
205
+
206
+ # Arguments d'entraînement
207
+ training_args = TrainingArguments(
208
+ output_dir=self.config.output_dir,
209
+ overwrite_output_dir=True,
210
+ num_train_epochs=self.config.num_epochs,
211
+ per_device_train_batch_size=self.config.batch_size,
212
+ gradient_accumulation_steps=self.config.gradient_accumulation_steps,
213
+ learning_rate=self.config.learning_rate,
214
+ warmup_steps=self.config.warmup_steps,
215
+ weight_decay=self.config.weight_decay,
216
+ max_grad_norm=self.config.max_grad_norm,
217
+ logging_steps=self.config.logging_steps,
218
+ save_steps=self.config.save_steps,
219
+ save_total_limit=self.config.save_total_limit,
220
+ fp16=self.config.use_fp16 and device == "cuda",
221
+ bf16=self.config.use_bf16 and device == "cuda",
222
+ push_to_hub=self.config.push_to_hub,
223
+ hub_model_id=self.config.hub_model_id,
224
+ hub_private_repo=self.config.hub_private,
225
+ report_to="none",
226
+ remove_unused_columns=False,
227
+ dataloader_num_workers=0, # Évite problèmes sur certains environnements
228
+ )
229
+
230
+ # Data collator
231
+ data_collator = DataCollatorForLanguageModeling(
232
+ tokenizer=self.tokenizer, mlm=False
233
+ )
234
+
235
+ # Créer le trainer
236
+ self.trainer = Trainer(
237
+ model=self.model,
238
+ args=training_args,
239
+ train_dataset=self.train_dataset,
240
+ eval_dataset=self.eval_dataset,
241
+ data_collator=data_collator,
242
+ tokenizer=self.tokenizer,
243
+ callbacks=self.callbacks,
244
+ )
245
+
246
+ def train(self, resume_from_checkpoint: Optional[str] = None):
247
+ """
248
+ Lance l'entraînement.
249
+
250
+ Args:
251
+ resume_from_checkpoint: Chemin pour reprendre l'entraînement
252
+
253
+ Returns:
254
+ Résultats de l'entraînement
255
+ """
256
+ print("\n🚀 ENTRAÎNEMENT COGNITIF")
257
+ print("=" * 60)
258
+
259
+ try:
260
+ result = self.trainer.train(resume_from_checkpoint=resume_from_checkpoint)
261
+ print("=" * 60)
262
+ print("✅ Entraînement terminé!")
263
+ return result
264
+ except Exception as e:
265
+ print(f"❌ Erreur: {e}")
266
+ import traceback
267
+
268
+ traceback.print_exc()
269
+ return None
270
+
271
+ def save(self, output_dir: Optional[str] = None):
272
+ """Sauvegarde le modèle et tokenizer."""
273
+ save_dir = output_dir or self.config.output_dir
274
+ self.trainer.save_model(save_dir)
275
+ self.tokenizer.save_pretrained(save_dir)
276
+ print(f"💾 Modèle sauvegardé: {save_dir}")
277
+
278
+ def push_to_hub(self, repo_id: Optional[str] = None):
279
+ """Push le modèle vers HuggingFace Hub."""
280
+ if repo_id:
281
+ self.config.hub_model_id = repo_id
282
+
283
+ try:
284
+ self.trainer.push_to_hub()
285
+ print(f"📤 Modèle pushé: {self.config.hub_model_id}")
286
+ except Exception as e:
287
+ print(f"⚠️ Erreur push: {e}")
288
+
289
+
290
+ # ==============================================================================
291
+ # CALLBACKS PERSONNALISÉS
292
+ # ==============================================================================
293
+
294
+
295
+ class CognitiveStateCallback:
296
+ """
297
+ Callback pour monitorer l'état des modules cognitifs pendant l'entraînement.
298
+ """
299
+
300
+ def __init__(self, log_every: int = 100):
301
+ self.log_every = log_every
302
+ self.step = 0
303
+
304
+ def on_step_end(self, args, state, control, model=None, **kwargs):
305
+ self.step += 1
306
+
307
+ if self.step % self.log_every == 0 and model is not None:
308
+ if hasattr(model, "get_cognitive_state"):
309
+ cog_state = model.get_cognitive_state()
310
+ print(f"\n📊 État cognitif (step {self.step}):")
311
+ for name, state_dict in cog_state.items():
312
+ if state_dict:
313
+ print(f" {name}: {len(state_dict)} buffers")
314
+
315
+
316
+ # ==============================================================================
317
+ # QUICK TRAIN FUNCTION
318
+ # ==============================================================================
319
+
320
+
321
+ def quick_train(
322
+ model,
323
+ tokenizer,
324
+ texts: List[str],
325
+ output_dir: str = "./quick-train-output",
326
+ num_epochs: int = 1,
327
+ max_seq_len: int = 2048,
328
+ learning_rate: float = 1e-5,
329
+ push_to_hub: bool = False,
330
+ hub_model_id: Optional[str] = None,
331
+ ):
332
+ """
333
+ Entraînement rapide avec configuration minimale.
334
+
335
+ Args:
336
+ model: Modèle à entraîner
337
+ tokenizer: Tokenizer
338
+ texts: Liste de textes d'entraînement
339
+ output_dir: Répertoire de sortie
340
+ num_epochs: Nombre d'époques
341
+ max_seq_len: Longueur max des séquences
342
+ learning_rate: Taux d'apprentissage
343
+ push_to_hub: Pusher vers HuggingFace
344
+ hub_model_id: ID du repo HuggingFace
345
+
346
+ Returns:
347
+ Résultats de l'entraînement
348
+ """
349
+ from datasets import Dataset
350
+
351
+ # Créer dataset
352
+ dataset = Dataset.from_dict({"text": texts})
353
+ tokenized = prepare_dataset(dataset, tokenizer, "text", max_seq_len)
354
+
355
+ # Config
356
+ config = CognitiveTrainingConfig(
357
+ output_dir=output_dir,
358
+ num_epochs=num_epochs,
359
+ max_seq_len=max_seq_len,
360
+ learning_rate=learning_rate,
361
+ push_to_hub=push_to_hub,
362
+ hub_model_id=hub_model_id,
363
+ )
364
+
365
+ # Trainer
366
+ trainer = CognitiveTrainer(model, tokenizer, tokenized, config)
367
+ result = trainer.train()
368
+
369
+ if result:
370
+ trainer.save()
371
+
372
+ return result
cognitive_utils.py ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ COGNITIVE-CORE: Utility Functions
3
+ ==================================
4
+
5
+ Common utilities for cognitive model development, including:
6
+ - Environment setup for Kaggle/Colab
7
+ - Device detection
8
+ - Memory optimization helpers
9
+ - Logging utilities
10
+
11
+ Copyright © 2026 Mike Amega (Logo) - Ame Web Studio
12
+ License: Proprietary - All Rights Reserved
13
+ """
14
+
15
+ import os
16
+ import sys
17
+ import torch
18
+ import warnings
19
+ from typing import Optional, Dict, Any
20
+
21
+
22
+ # ==============================================================================
23
+ # ENVIRONNEMENT & CACHE
24
+ # ==============================================================================
25
+
26
+
27
+ def setup_environment(cache_dir: Optional[str] = None) -> str:
28
+ """
29
+ Configure l'environnement pour Kaggle/Colab/Local.
30
+
31
+ Résout les problèmes de:
32
+ - Read-only file system sur Kaggle
33
+ - Chemins de cache HuggingFace
34
+
35
+ Args:
36
+ cache_dir: Répertoire cache personnalisé (optionnel)
37
+
38
+ Returns:
39
+ Chemin du répertoire cache configuré
40
+ """
41
+ if cache_dir is None:
42
+ # Détecter l'environnement
43
+ if os.path.exists("/kaggle"):
44
+ cache_dir = "/kaggle/working/.cache"
45
+ elif os.path.exists("/content"): # Colab
46
+ cache_dir = "/content/.cache"
47
+ else:
48
+ cache_dir = os.path.expanduser("~/.cache/cognitive")
49
+
50
+ # Créer le répertoire
51
+ os.makedirs(cache_dir, exist_ok=True)
52
+ os.makedirs(os.path.join(cache_dir, "datasets"), exist_ok=True)
53
+
54
+ # Configurer les variables d'environnement
55
+ os.environ["HF_HOME"] = cache_dir
56
+ os.environ["TRANSFORMERS_CACHE"] = cache_dir
57
+ os.environ["HF_DATASETS_CACHE"] = os.path.join(cache_dir, "datasets")
58
+
59
+ # Désactiver les warnings non critiques
60
+ warnings.filterwarnings("ignore", category=FutureWarning)
61
+ warnings.filterwarnings("ignore", category=UserWarning, module="transformers")
62
+
63
+ return cache_dir
64
+
65
+
66
+ def get_device(prefer_gpu: bool = True) -> torch.device:
67
+ """
68
+ Détecte et retourne le meilleur device disponible.
69
+
70
+ Args:
71
+ prefer_gpu: Préférer GPU si disponible
72
+
73
+ Returns:
74
+ torch.device configuré
75
+ """
76
+ if prefer_gpu and torch.cuda.is_available():
77
+ device = torch.device("cuda")
78
+ gpu_name = torch.cuda.get_device_name(0)
79
+ gpu_mem = torch.cuda.get_device_properties(0).total_memory / 1e9
80
+ print(f"🔧 GPU: {gpu_name} ({gpu_mem:.1f} GB)")
81
+ elif (
82
+ prefer_gpu
83
+ and hasattr(torch.backends, "mps")
84
+ and torch.backends.mps.is_available()
85
+ ):
86
+ device = torch.device("mps")
87
+ print("🔧 Apple MPS")
88
+ else:
89
+ device = torch.device("cpu")
90
+ print("🔧 CPU")
91
+
92
+ return device
93
+
94
+
95
+ def get_optimal_dtype(device: torch.device) -> torch.dtype:
96
+ """
97
+ Retourne le dtype optimal pour le device.
98
+
99
+ Args:
100
+ device: Le device cible
101
+
102
+ Returns:
103
+ torch.dtype optimal (float16 pour GPU, float32 pour CPU)
104
+ """
105
+ if device.type == "cuda":
106
+ # Vérifier support BF16
107
+ if torch.cuda.is_bf16_supported():
108
+ return torch.bfloat16
109
+ return torch.float16
110
+ return torch.float32
111
+
112
+
113
+ # ==============================================================================
114
+ # MÉMOIRE & OPTIMISATION
115
+ # ==============================================================================
116
+
117
+
118
+ def get_memory_info() -> Dict[str, float]:
119
+ """
120
+ Retourne les informations mémoire (GPU si disponible).
121
+
122
+ Returns:
123
+ Dict avec allocated, reserved, free en GB
124
+ """
125
+ if torch.cuda.is_available():
126
+ allocated = torch.cuda.memory_allocated() / 1e9
127
+ reserved = torch.cuda.memory_reserved() / 1e9
128
+ total = torch.cuda.get_device_properties(0).total_memory / 1e9
129
+ return {
130
+ "allocated_gb": allocated,
131
+ "reserved_gb": reserved,
132
+ "free_gb": total - allocated,
133
+ "total_gb": total,
134
+ }
135
+ return {"allocated_gb": 0, "reserved_gb": 0, "free_gb": 0, "total_gb": 0}
136
+
137
+
138
+ def clear_memory():
139
+ """Libère la mémoire GPU si possible."""
140
+ if torch.cuda.is_available():
141
+ torch.cuda.empty_cache()
142
+ torch.cuda.synchronize()
143
+
144
+
145
+ def estimate_model_memory(model, dtype: torch.dtype = torch.float32) -> float:
146
+ """
147
+ Estime la mémoire nécessaire pour un modèle.
148
+
149
+ Args:
150
+ model: Le modèle PyTorch
151
+ dtype: Le dtype utilisé
152
+
153
+ Returns:
154
+ Estimation en GB
155
+ """
156
+ param_bytes = sum(p.numel() * p.element_size() for p in model.parameters())
157
+ buffer_bytes = sum(b.numel() * b.element_size() for b in model.buffers())
158
+
159
+ # Facteur pour activations (estimation: 2x les paramètres)
160
+ activation_factor = 2.0
161
+
162
+ total_bytes = (param_bytes + buffer_bytes) * activation_factor
163
+
164
+ # Ajuster selon dtype
165
+ if dtype in (torch.float16, torch.bfloat16):
166
+ total_bytes *= 0.5
167
+
168
+ return total_bytes / 1e9
169
+
170
+
171
+ # ==============================================================================
172
+ # LOGGING & AFFICHAGE
173
+ # ==============================================================================
174
+
175
+
176
+ def print_model_info(model, show_params: bool = True):
177
+ """
178
+ Affiche les informations du modèle.
179
+
180
+ Args:
181
+ model: Le modèle à analyser
182
+ show_params: Afficher le détail des paramètres
183
+ """
184
+ total_params = sum(p.numel() for p in model.parameters())
185
+ trainable_params = sum(p.numel() for p in model.parameters() if p.requires_grad)
186
+
187
+ print(f"\n📊 MODÈLE: {model.__class__.__name__}")
188
+ print(f" Total paramètres: {total_params:,}")
189
+ print(f" Paramètres entraînables: {trainable_params:,}")
190
+ print(f" Mémoire estimée: {estimate_model_memory(model):.2f} GB")
191
+
192
+ if show_params and hasattr(model, "config"):
193
+ print(f"\n Configuration:")
194
+ for key in ["d_model", "n_layers", "n_heads", "vocab_size"]:
195
+ if hasattr(model.config, key):
196
+ print(f" - {key}: {getattr(model.config, key)}")
197
+
198
+
199
+ def print_training_progress(
200
+ step: int,
201
+ total_steps: int,
202
+ loss: float,
203
+ lr: Optional[float] = None,
204
+ extras: Optional[Dict[str, float]] = None,
205
+ ):
206
+ """
207
+ Affiche la progression d'entraînement.
208
+
209
+ Args:
210
+ step: Étape actuelle
211
+ total_steps: Nombre total d'étapes
212
+ loss: Valeur de la loss
213
+ lr: Learning rate actuel
214
+ extras: Métriques additionnelles
215
+ """
216
+ progress = step / total_steps * 100
217
+ msg = f"[{step:>6}/{total_steps}] ({progress:>5.1f}%) | Loss: {loss:.4f}"
218
+
219
+ if lr is not None:
220
+ msg += f" | LR: {lr:.2e}"
221
+
222
+ if extras:
223
+ for key, val in extras.items():
224
+ msg += f" | {key}: {val:.4f}"
225
+
226
+ print(msg)
227
+
228
+
229
+ # ==============================================================================
230
+ # TOKEN HUGGINGFACE
231
+ # ==============================================================================
232
+
233
+
234
+ def get_hf_token() -> Optional[str]:
235
+ """
236
+ Récupère le token HuggingFace depuis différentes sources.
237
+
238
+ Ordre de recherche:
239
+ 1. Variable d'environnement HF_TOKEN
240
+ 2. Secrets Kaggle
241
+ 3. Secrets Colab
242
+ 4. Token local HuggingFace CLI
243
+
244
+ Returns:
245
+ Token ou None si non trouvé
246
+ """
247
+ # Env var
248
+ token = os.environ.get("HF_TOKEN")
249
+ if token:
250
+ return token
251
+
252
+ # Kaggle
253
+ try:
254
+ from kaggle_secrets import UserSecretsClient
255
+
256
+ token = UserSecretsClient().get_secret("HF_TOKEN")
257
+ if token:
258
+ return token
259
+ except Exception:
260
+ pass
261
+
262
+ # Colab
263
+ try:
264
+ from google.colab import userdata
265
+
266
+ token = userdata.get("HF_TOKEN")
267
+ if token:
268
+ return token
269
+ except Exception:
270
+ pass
271
+
272
+ # Local HuggingFace CLI
273
+ try:
274
+ from huggingface_hub import HfFolder
275
+
276
+ token = HfFolder.get_token()
277
+ if token:
278
+ return token
279
+ except Exception:
280
+ pass
281
+
282
+ return None