use std::fmt::Debug;
pub mod architecture;
pub mod strategies;
pub mod training;
pub use architecture::{
ActivationFunction, AttentionOptimization, FeedForwardNetwork, InputEmbedding, LayerNorm,
MultiHeadAttention, OutputProjectionLayer, PositionalEncoder, PositionalEncodingType,
TransformerLayer,
};
pub use strategies::{
GradientProcessingStrategy, GradientProcessor, LearningRateAdaptationStrategy,
LearningRateAdapter, MomentumIntegrator, MomentumStrategy, RegularizationStrategy,
TransformerRegularizer,
};
pub use training::{
CurriculumLearner, CurriculumStrategy, EvaluationStrategy, MetaLearningStrategy,
TransformerEvaluator, TransformerMetaLearner,
};
use scirs2_core::ndarray::{Array1, Array2};
use scirs2_core::numeric::Float;
use std::collections::{HashMap, VecDeque};
use super::{LearnedOptimizerConfig, MetaOptimizationStrategy};
use crate::error::{OptimError, Result};
#[derive(Debug, Clone)]
pub struct TransformerOptimizerConfig {
pub base_config: LearnedOptimizerConfig,
pub modeldim: usize,
pub numheads: usize,
pub ff_dim: usize,
pub num_layers: usize,
pub max_sequence_length: usize,
pub attention_dropout: f64,
pub ff_dropout: f64,
pub layer_norm_eps: f64,
pub pre_layer_norm: bool,
pub pos_encoding_type: PositionalEncodingType,
pub relative_position_bias: bool,
pub use_rope: bool,
pub gradient_checkpointing: bool,
pub attention_optimization: AttentionOptimization,
pub multi_scale_attention: bool,
pub cross_attention: bool,
pub memory_efficient: bool,
}
#[derive(Debug, Clone)]
pub struct TransformerNetwork<
T: Float
+ Debug
+ Default
+ Clone
+ std::iter::Sum
+ scirs2_core::ndarray::ScalarOperand
+ Send
+ Sync
+ 'static,
> {
input_embedding: InputEmbedding<T>,
layers: Vec<TransformerLayer<T>>,
output_projection: OutputProjectionLayer<T>,
output_layer_norm: LayerNorm<T>,
position_encoder: PositionalEncoder<T>,
config: TransformerOptimizerConfig,
}
#[derive(Debug)]
pub struct TransformerOptimizer<
T: Float
+ Debug
+ Default
+ Clone
+ std::iter::Sum
+ scirs2_core::ndarray::ScalarOperand
+ Send
+ Sync
+ 'static,
> {
config: TransformerOptimizerConfig,
transformer_network: TransformerNetwork<T>,
gradient_processor: GradientProcessor<T>,
lr_adapter: LearningRateAdapter<T>,
momentum_integrator: MomentumIntegrator<T>,
regularizer: TransformerRegularizer<T>,
meta_learner: TransformerMetaLearner<T>,
curriculum_learner: CurriculumLearner<T>,
evaluator: TransformerEvaluator<T>,
sequence_buffer: SequenceBuffer<T>,
metrics: TransformerOptimizerMetrics,
step_count: usize,
rng: scirs2_core::random::CoreRandom,
}
#[derive(Debug, Clone)]
pub struct SequenceBuffer<
T: Float + Debug + scirs2_core::ndarray::ScalarOperand + Send + Sync + 'static,
> {
gradient_sequences: VecDeque<Array1<T>>,
parameter_sequences: VecDeque<Array1<T>>,
loss_sequences: VecDeque<T>,
lr_sequences: VecDeque<T>,
capacity: usize,
}
#[derive(Debug, Clone)]
pub struct TransformerOptimizerMetrics {
total_steps: usize,
convergence_history: Vec<f64>,
attention_stats: HashMap<String, f64>,
strategy_stats: HashMap<String, f64>,
performance_comparisons: HashMap<String, f64>,
}
impl<
T: Float
+ Debug
+ Default
+ Clone
+ std::iter::Sum
+ scirs2_core::ndarray::ScalarOperand
+ Send
+ Sync
+ 'static,
> TransformerNetwork<T>
{
pub fn new(config: &TransformerOptimizerConfig) -> Result<Self> {
let input_embedding = InputEmbedding::new(config.modeldim, config.modeldim)?;
let mut layers = Vec::new();
for _ in 0..config.num_layers {
let mut rng = scirs2_core::random::thread_rng();
layers.push(TransformerLayer::new(config, &mut rng)?);
}
let output_projection = OutputProjectionLayer::new(config.modeldim, config.modeldim)?;
let output_layer_norm = LayerNorm::new(config.modeldim);
let position_encoder = PositionalEncoder::new(config)?;
Ok(Self {
input_embedding,
layers,
output_projection,
output_layer_norm,
position_encoder,
config: config.clone(),
})
}
pub fn forward(&mut self, input: &Array2<T>) -> Result<Array2<T>> {
let mut x = self.input_embedding.forward(input)?;
x = self.position_encoder.encode(&x)?;
for layer in &mut self.layers {
x = layer.forward(&x)?;
}
x = self.output_layer_norm.forward(&x)?;
let output = self.output_projection.forward(&x)?;
Ok(output)
}
pub fn get_attention_patterns(&self) -> Vec<Option<&scirs2_core::ndarray::Array3<T>>> {
self.layers
.iter()
.map(|layer| layer.get_attention_patterns())
.collect()
}
}
impl<
T: Float
+ Debug
+ Default
+ Clone
+ std::iter::Sum
+ scirs2_core::ndarray::ScalarOperand
+ Send
+ Sync
+ 'static,
> TransformerOptimizer<T>
{
pub fn new(config: TransformerOptimizerConfig) -> Result<Self> {
let transformer_network = TransformerNetwork::new(&config)?;
let gradient_processor = GradientProcessor::new(GradientProcessingStrategy::Adaptive);
let lr_adapter = LearningRateAdapter::new(
LearningRateAdaptationStrategy::TransformerPredicted,
scirs2_core::numeric::NumCast::from(0.001).unwrap_or_else(|| T::zero()),
);
let momentum_integrator = MomentumIntegrator::new(MomentumStrategy::TransformerPredicted);
let regularizer = TransformerRegularizer::new(RegularizationStrategy::Adaptive);
let meta_learner = TransformerMetaLearner::new(MetaLearningStrategy::GradientBased)?;
let curriculum_learner = CurriculumLearner::new(CurriculumStrategy::Adaptive)?;
let evaluator = TransformerEvaluator::new(EvaluationStrategy::Comprehensive)?;
let sequence_buffer = SequenceBuffer::new(1000);
let metrics = TransformerOptimizerMetrics::new();
Ok(Self {
config,
transformer_network,
gradient_processor,
lr_adapter,
momentum_integrator,
regularizer,
meta_learner,
curriculum_learner,
evaluator,
sequence_buffer,
metrics,
step_count: 0,
rng: scirs2_core::random::thread_rng(),
})
}
pub fn step(
&mut self,
parameters: &mut HashMap<String, Array2<T>>,
gradients: &mut HashMap<String, Array2<T>>,
loss: T,
) -> Result<T> {
self.step_count += 1;
for (param_name, gradient) in gradients.iter_mut() {
let flat_gradient = gradient.iter().cloned().collect::<Vec<_>>();
let gradient_array = Array1::from_vec(flat_gradient);
let processed_gradient = self.gradient_processor.process_gradients(&gradient_array)?;
let current_lr = self
.lr_adapter
.update_learning_rate(Some(loss), Some(&processed_gradient))?;
let momentum_gradient = self.momentum_integrator.integrate_momentum(
&processed_gradient,
None, )?;
let mut param_map = HashMap::new();
if let Some(param_values) = parameters.get(param_name) {
param_map.insert(param_name.clone(), param_values.clone());
}
let mut grad_map = HashMap::new();
grad_map.insert(param_name.clone(), gradient.clone());
let _reg_loss = self.regularizer.apply_regularization(
¶m_map,
&mut grad_map,
None, )?;
self.sequence_buffer.add_gradient(momentum_gradient);
}
self.sequence_buffer.add_loss(loss);
self.sequence_buffer
.add_learning_rate(self.lr_adapter.current_learning_rate());
let task_id = "current_task"; self.curriculum_learner
.update_curriculum(task_id, loss, self.step_count)?;
self.metrics
.update_step(loss.to_f64().unwrap_or(0.0), self.step_count);
Ok(loss)
}
pub fn get_statistics(&self) -> HashMap<String, f64> {
let mut stats = HashMap::new();
stats.insert("step_count".to_string(), self.step_count as f64);
stats.insert(
"current_lr".to_string(),
self.lr_adapter
.current_learning_rate()
.to_f64()
.unwrap_or(0.0),
);
let grad_stats = self.gradient_processor.statistics();
stats.insert(
"mean_gradient_magnitude".to_string(),
grad_stats.mean_magnitude().to_f64().unwrap_or(0.0),
);
stats.insert(
"gradient_sparsity".to_string(),
grad_stats.sparsity().to_f64().unwrap_or(0.0),
);
let momentum_stats = self.momentum_integrator.statistics();
stats.insert(
"momentum_magnitude".to_string(),
momentum_stats
.avg_momentum_magnitude
.to_f64()
.unwrap_or(0.0),
);
let curriculum_stats = self.curriculum_learner.get_curriculum_statistics();
for (key, value) in curriculum_stats {
stats.insert(format!("curriculum_{}", key), value.to_f64().unwrap_or(0.0));
}
stats
}
pub fn reset(&mut self) -> Result<()> {
self.step_count = 0;
self.gradient_processor.reset();
self.lr_adapter.reset();
self.momentum_integrator.reset();
self.regularizer.reset();
self.meta_learner.reset();
self.curriculum_learner.reset();
self.evaluator.reset();
self.sequence_buffer.clear();
self.metrics = TransformerOptimizerMetrics::new();
Ok(())
}
}
impl<
T: Float
+ Debug
+ Default
+ Clone
+ scirs2_core::ndarray::ScalarOperand
+ Send
+ Sync
+ 'static,
> SequenceBuffer<T>
{
pub fn new(capacity: usize) -> Self {
Self {
gradient_sequences: VecDeque::new(),
parameter_sequences: VecDeque::new(),
loss_sequences: VecDeque::new(),
lr_sequences: VecDeque::new(),
capacity,
}
}
pub fn add_gradient(&mut self, gradient: Array1<T>) {
self.gradient_sequences.push_back(gradient);
if self.gradient_sequences.len() > self.capacity {
self.gradient_sequences.pop_front();
}
}
pub fn add_loss(&mut self, loss: T) {
self.loss_sequences.push_back(loss);
if self.loss_sequences.len() > self.capacity {
self.loss_sequences.pop_front();
}
}
pub fn add_learning_rate(&mut self, lr: T) {
self.lr_sequences.push_back(lr);
if self.lr_sequences.len() > self.capacity {
self.lr_sequences.pop_front();
}
}
pub fn clear(&mut self) {
self.gradient_sequences.clear();
self.parameter_sequences.clear();
self.loss_sequences.clear();
self.lr_sequences.clear();
}
pub fn get_recent_gradients(&self, count: usize) -> Vec<&Array1<T>> {
self.gradient_sequences.iter().rev().take(count).collect()
}
}
impl Default for TransformerOptimizerMetrics {
fn default() -> Self {
Self::new()
}
}
impl TransformerOptimizerMetrics {
pub fn new() -> Self {
Self {
total_steps: 0,
convergence_history: Vec::new(),
attention_stats: HashMap::new(),
strategy_stats: HashMap::new(),
performance_comparisons: HashMap::new(),
}
}
pub fn update_step(&mut self, loss: f64, step: usize) {
self.total_steps = step;
self.convergence_history.push(loss);
if self.convergence_history.len() > 10000 {
self.convergence_history.remove(0);
}
}
}