#[ cfg( feature = "model_tuning" ) ]
mod private
{
use serde::{ Serialize, Deserialize };
use core::time::Duration;
use error_tools::untyped::Result;
use std::collections::HashMap;
#[ derive( Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize ) ]
pub enum TuningJobStatus
{
Pending,
Running,
Paused,
Completed,
Cancelled,
Failed,
}
#[ derive( Debug, Clone, PartialEq, Eq, Serialize, Deserialize ) ]
pub enum TuningMethod
{
FullFineTuning,
LoRA,
Adapter,
PrefixTuning,
PromptTuning,
PTuningV2,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub enum TrainingObjective
{
TextGeneration
{
max_length : usize,
temperature : f32,
top_p : f32,
},
Classification
{
num_classes : usize,
class_weights : Option< Vec< f32 > >,
},
QuestionAnswering
{
max_answer_length : usize,
impossible_answer_threshold : f32,
},
NamedEntityRecognition
{
entity_types : Vec< String >,
use_bio_tagging : bool,
},
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct HyperParameters
{
pub learning_rate : f32,
pub batch_size : usize,
pub max_epochs : usize,
pub warmup_steps : usize,
pub weight_decay : f32,
pub gradient_clip_norm : f32,
pub lora_rank : Option< u32 >,
pub lora_alpha : Option< f32 >,
pub lora_dropout : Option< f32 >,
pub target_modules : Vec< String >,
pub adapter_size : Option< usize >,
pub adapter_activation : Option< String >,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct TrainingProgress
{
pub current_epoch : usize,
pub total_epochs : usize,
pub current_step : usize,
pub steps_per_epoch : usize,
pub elapsed_time : Duration,
pub estimated_remaining : Option< Duration >,
pub metrics : HashMap< String, f32 >,
pub validation_metrics : Option< HashMap< String, f32 > >,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct ModelCheckpoint
{
pub id : String,
pub step : usize,
pub epoch : usize,
pub training_loss : f32,
pub validation_loss : f32,
pub created_at : std::time::SystemTime,
pub size_bytes : u64,
pub is_best : bool,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct ResourceUsage
{
pub gpu_memory_used_mb : u64,
pub gpu_utilization_percent : f32,
pub cpu_utilization_percent : f32,
pub memory_used_mb : u64,
pub disk_io_read_mb : u64,
pub disk_io_write_mb : u64,
pub network_io_read_mb : u64,
pub network_io_write_mb : u64,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct ModelEvaluation
{
pub perplexity : f32,
pub bleu_score : f32,
pub rouge_scores : HashMap< String, f32 >,
pub custom_metrics : HashMap< String, f32 >,
pub evaluated_at : std::time::SystemTime,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct ModelVersion
{
pub id : String,
pub name : String,
pub description : String,
pub base_model : String,
pub tuning_method : TuningMethod,
pub created_at : std::time::SystemTime,
pub size_bytes : u64,
pub performance_metrics : HashMap< String, f32 >,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct TrainingSample
{
pub input : String,
pub output : String,
pub metadata : Option< HashMap< String, serde_json::Value > >,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct ValidationResult
{
pub is_valid : bool,
pub total_samples : usize,
pub warnings : Vec< String >,
pub errors : Vec< String >,
pub statistics : HashMap< String, serde_json::Value >,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct DataUploadResult
{
pub data_id : String,
pub size_bytes : u64,
pub sample_count : usize,
pub uploaded_at : std::time::SystemTime,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct BenchmarkTaskResult
{
pub accuracy : f32,
pub latency_ms : f32,
pub throughput_tokens_per_sec : f32,
pub memory_usage_mb : u64,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct BenchmarkResults
{
pub tasks : HashMap< String, BenchmarkTaskResult >,
pub overall_score : f32,
pub benchmarked_at : std::time::SystemTime,
}
#[ derive( Debug, Clone, Serialize, Deserialize ) ]
pub struct ModelTuningConfig
{
pub model_name : String,
pub tuning_method : TuningMethod,
pub training_objective : TrainingObjective,
pub hyperparameters : HyperParameters,
pub validation_split : f32,
pub checkpoint_frequency : usize,
pub keep_best_checkpoints : usize,
pub early_stopping : bool,
pub early_stopping_patience : usize,
pub memory_optimization : bool,
pub gradient_checkpointing : bool,
pub mixed_precision : bool,
pub version_name : Option< String >,
pub version_description : Option< String >,
}
#[ derive( Debug, Clone ) ]
pub struct TrainingData
{
pub samples : Vec< TrainingSample >,
pub metadata : HashMap< String, serde_json::Value >,
}
#[ derive( Debug ) ]
pub struct DataPreprocessor
{
pub tokenizer_config : HashMap< String, serde_json::Value >,
pub normalization_config : HashMap< String, bool >,
}
#[ derive( Debug, Clone ) ]
pub struct ModelBenchmark
{
pub tasks : Vec< String >,
pub test_data_size : usize,
pub config : HashMap< String, serde_json::Value >,
}
#[ derive( Debug ) ]
pub struct ModelTuningJob
{
pub id : String,
pub config : ModelTuningConfig,
pub training_data : TrainingData,
pub validation_data : Option< TrainingData >,
pub status : TuningJobStatus,
pub created_at : std::time::SystemTime,
pub started_at : Option< std::time::SystemTime >,
pub completed_at : Option< std::time::SystemTime >,
pub latest_checkpoint_id : Option< String >,
pub progress : Option< TrainingProgress >,
pub resource_usage : Option< ResourceUsage >,
}
#[ derive( Debug, Default ) ]
pub struct ModelTuningConfigBuilder
{
model_name : Option< String >,
tuning_method : Option< TuningMethod >,
}
impl ModelTuningConfig
{
#[ inline ]
pub fn builder() -> ModelTuningConfigBuilder
{
ModelTuningConfigBuilder::new()
}
#[ inline ]
#[ must_use ]
pub fn default() -> Self
{
Self
{
model_name : "llama2".to_string(),
tuning_method : TuningMethod::FullFineTuning,
training_objective : TrainingObjective::TextGeneration
{
max_length : 512,
temperature : 0.7,
top_p : 0.9,
},
hyperparameters : HyperParameters::new(),
validation_split : 0.1,
checkpoint_frequency : 1000,
keep_best_checkpoints : 3,
early_stopping : true,
early_stopping_patience : 5,
memory_optimization : true,
gradient_checkpointing : false,
mixed_precision : false,
version_name : None,
version_description : None,
}
}
#[ inline ]
#[ must_use ]
pub fn with_model_name( mut self, name : &str ) -> Self
{
self.model_name = name.to_string();
self
}
}
impl ModelTuningConfigBuilder
{
#[ inline ]
#[ must_use ]
pub fn new() -> Self
{
Self::default()
}
#[ inline ]
#[ must_use ]
pub fn model_name( mut self, name : &str ) -> Self
{
self.model_name = Some( name.to_string() );
self
}
#[ inline ]
#[ must_use ]
pub fn tuning_method( mut self, method : TuningMethod ) -> Self
{
self.tuning_method = Some( method );
self
}
#[ inline ]
pub fn build( self ) -> Result< ModelTuningConfig >
{
Ok( ModelTuningConfig
{
model_name : self.model_name.unwrap_or( "llama2".to_string() ),
tuning_method : self.tuning_method.unwrap_or( TuningMethod::FullFineTuning ),
training_objective : TrainingObjective::TextGeneration
{
max_length : 512,
temperature : 0.7,
top_p : 0.9,
},
hyperparameters : HyperParameters::new(),
validation_split : 0.1,
checkpoint_frequency : 1000,
keep_best_checkpoints : 3,
early_stopping : true,
early_stopping_patience : 5,
memory_optimization : true,
gradient_checkpointing : false,
mixed_precision : false,
version_name : None,
version_description : None,
} )
}
}
impl TrainingData
{
#[ inline ]
#[ must_use ]
pub fn new() -> Self
{
Self
{
samples : Vec::new(),
metadata : HashMap::new(),
}
}
#[ inline ]
pub fn from_jsonl_file( _path : &str ) -> Result< Self >
{
Ok( Self::new() )
}
#[ inline ]
pub fn from_samples( samples : Vec< TrainingSample > ) -> Result< Self >
{
Ok( Self
{
samples,
metadata : HashMap::new(),
} )
}
#[ inline ]
pub fn from_text_file( _path : &str ) -> Result< Self >
{
Ok( Self::new() )
}
#[ inline ]
pub fn from_text( _text : &str ) -> Result< Self >
{
Ok( Self::new() )
}
#[ inline ]
pub fn add_sample( &mut self, _prompt : &str, _completion : &str )
{
}
#[ inline ]
pub fn add_validation_sample( &mut self, _prompt : &str, _completion : &str )
{
}
}
impl Default for TrainingData
{
#[ inline ]
fn default() -> Self
{
Self::new()
}
}
impl DataPreprocessor
{
#[ inline ]
#[ must_use ]
pub fn new() -> Self
{
Self
{
tokenizer_config : HashMap::new(),
normalization_config : HashMap::new(),
}
}
#[ inline ]
pub fn configure_tokenization( &mut self, _settings : HashMap< String, serde_json::Value > )
{
}
#[ inline ]
pub fn set_normalization( &mut self, _enabled : bool )
{
}
#[ inline ]
pub fn preprocess( &self, _data : &mut TrainingData ) -> Result< () >
{
Ok( () )
}
}
impl ModelBenchmark
{
#[ inline ]
#[ must_use ]
pub fn new() -> Self
{
Self
{
tasks : Vec::new(),
test_data_size : 1000,
config : HashMap::new(),
}
}
#[ inline ]
#[ must_use ]
pub fn add_task( mut self, task : &str ) -> Self
{
self.tasks.push( task.to_string() );
self
}
#[ inline ]
#[ must_use ]
pub fn test_data_size( mut self, size : usize ) -> Self
{
self.test_data_size = size;
self
}
}
impl HyperParameters
{
#[ inline ]
#[ must_use ]
pub fn new() -> Self
{
Self
{
learning_rate : 0.001,
batch_size : 32,
max_epochs : 10,
warmup_steps : 1000,
weight_decay : 0.01,
gradient_clip_norm : 1.0,
lora_rank : None,
lora_alpha : None,
lora_dropout : None,
target_modules : vec![ "query".to_string(), "value".to_string() ],
adapter_size : None,
adapter_activation : None,
}
}
#[ inline ]
pub fn set_learning_rate( &mut self, lr : f32 )
{
self.learning_rate = lr;
}
#[ inline ]
pub fn set_batch_size( &mut self, size : usize )
{
self.batch_size = size;
}
#[ inline ]
pub fn set_epochs( &mut self, epochs : usize )
{
self.max_epochs = epochs;
}
}
impl ModelTuningJob
{
#[ inline ]
pub fn model_id( &self ) -> &str
{
&self.config.model_name
}
#[ inline ]
#[ must_use ]
pub fn is_completed( &self ) -> bool
{
matches!( self.status, TuningJobStatus::Completed )
}
#[ inline ]
#[ must_use ]
pub fn progress_percentage( &self ) -> f32
{
self.progress.as_ref().map( | p |
if p.total_epochs > 0
{
( p.current_epoch as f32 / p.total_epochs as f32 ) * 100.0
}
else
{
0.0
}
).unwrap_or( 0.0 )
}
#[ inline ]
pub async fn wait_for_completion( &mut self ) -> Result< () >
{
tokio ::time::sleep( core::time::Duration::from_millis( 100 ) ).await;
self.status = TuningJobStatus::Completed;
self.completed_at = Some( std::time::SystemTime::now() );
Ok( () )
}
#[ inline ]
#[ must_use ]
pub fn get_resource_usage( &self ) -> Option< &ResourceUsage >
{
self.resource_usage.as_ref()
}
}
}
#[ cfg( feature = "model_tuning" ) ]
crate ::mod_interface!
{
exposed use private::TuningJobStatus;
exposed use private::TuningMethod;
exposed use private::TrainingObjective;
exposed use private::HyperParameters;
exposed use private::TrainingProgress;
exposed use private::ModelCheckpoint;
exposed use private::ResourceUsage;
exposed use private::ModelEvaluation;
exposed use private::ModelVersion;
exposed use private::TrainingSample;
exposed use private::ValidationResult;
exposed use private::DataUploadResult;
exposed use private::BenchmarkTaskResult;
exposed use private::BenchmarkResults;
exposed use private::ModelTuningConfig;
exposed use private::TrainingData;
exposed use private::DataPreprocessor;
exposed use private::ModelBenchmark;
exposed use private::ModelTuningJob;
exposed use private::ModelTuningConfigBuilder;
}