trustformers_debug/
model_diagnostics_main.rs1#![allow(dead_code)]
10
11use crate::DebugConfig;
12use anyhow::Result;
13use serde::{Deserialize, Serialize};
14
15use crate::model_diagnostics::*;
17
18#[derive(Debug)]
20pub struct ModelDiagnostics {
21 config: DebugConfig,
22 performance_analyzer: PerformanceAnalyzer,
23 architecture_analyzer: ArchitectureAnalyzer,
24 training_analyzer: TrainingDynamicsAnalyzer,
25 layer_analyzer: LayerAnalyzer,
26 alert_manager: AlertManager,
27 auto_debugger: AutoDebugger,
28 analytics_engine: AdvancedAnalytics,
29 current_step: usize,
30}
31
32impl ModelDiagnostics {
33 pub fn new(config: &DebugConfig) -> Self {
35 Self {
36 config: config.clone(),
37 performance_analyzer: PerformanceAnalyzer::new(),
38 architecture_analyzer: ArchitectureAnalyzer::new(),
39 training_analyzer: TrainingDynamicsAnalyzer::new(),
40 layer_analyzer: LayerAnalyzer::new(),
41 alert_manager: AlertManager::new(),
42 auto_debugger: AutoDebugger::new(),
43 analytics_engine: AdvancedAnalytics::new(),
44 current_step: 0,
45 }
46 }
47
48 pub fn record_performance(&mut self, metrics: ModelPerformanceMetrics) -> Result<()> {
50 self.performance_analyzer.record_metrics(metrics.clone());
51 self.auto_debugger.record_performance_metrics(metrics.clone());
52 self.analytics_engine.record_performance_metrics(&metrics);
53
54 self.alert_manager.process_performance_metrics(&metrics)?;
56
57 Ok(())
58 }
59
60 pub fn record_architecture(&mut self, arch_info: ModelArchitectureInfo) {
62 self.architecture_analyzer.record_architecture(arch_info);
63 }
64
65 pub fn record_layer_stats(&mut self, stats: LayerActivationStats) -> Result<()> {
67 self.layer_analyzer.record_layer_stats(stats.clone());
68 self.auto_debugger.record_layer_stats(stats.clone());
69
70 self.alert_manager.process_layer_stats(&stats)?;
72
73 Ok(())
74 }
75
76 pub fn record_training_dynamics(&mut self, dynamics: TrainingDynamics) -> Result<()> {
78 self.training_analyzer.record_training_dynamics(dynamics.clone());
79 self.auto_debugger.record_training_dynamics(dynamics.clone());
80
81 self.alert_manager.process_training_dynamics(&dynamics)?;
83
84 Ok(())
85 }
86
87 fn calculate_health_score(&self) -> f64 {
89 let performance_score = 0.8; let architecture_score = 0.7; let training_score = 0.9; (performance_score + architecture_score + training_score) / 3.0
95 }
96
97 fn aggregate_recommendations(&self) -> Vec<String> {
99 let mut recommendations = Vec::new();
100
101 if let Ok(arch_analysis) = self.architecture_analyzer.analyze_architecture() {
103 for recommendation in arch_analysis.recommendations {
104 recommendations.push(format!("[Architecture] {}", recommendation));
105 }
106 }
107
108 let perf_summary = self.performance_analyzer.generate_performance_summary();
110 if perf_summary.current_loss > perf_summary.best_loss * 1.5 {
112 recommendations.push(
113 "[Performance] Current loss significantly higher than best - check for training instability"
114 .to_string(),
115 );
116 }
117 if perf_summary.peak_memory_mb > 16384.0 {
118 recommendations.push(
120 "[Performance] High memory usage detected - consider gradient checkpointing or smaller batch size"
121 .to_string(),
122 );
123 }
124
125 let training_dynamics = self.training_analyzer.analyze_training_dynamics();
127 match training_dynamics.training_stability {
128 TrainingStability::Unstable => {
129 recommendations.push(
130 "[Training] Training stability issues detected - consider reducing learning rate or applying gradient clipping"
131 .to_string(),
132 );
133 },
134 TrainingStability::Unknown => {
135 recommendations.push(
136 "[Training] Collect more training metrics for better stability assessment"
137 .to_string(),
138 );
139 },
140 _ => {},
141 }
142
143 if let Some(plateau) = &training_dynamics.plateau_detection {
145 if plateau.duration_steps > 100 {
146 recommendations.push(
147 "[Training] Training plateau detected - consider learning rate adjustment or early stopping"
148 .to_string(),
149 );
150 }
151 }
152
153 match training_dynamics.convergence_status {
155 ConvergenceStatus::Diverging => {
156 recommendations.push(
157 "[Training] Model is diverging - reduce learning rate immediately".to_string(),
158 );
159 },
160 ConvergenceStatus::Plateau => {
161 recommendations.push(
162 "[Training] Training has reached a plateau - consider changing optimization strategy or early stopping"
163 .to_string(),
164 );
165 },
166 ConvergenceStatus::Oscillating => {
167 recommendations.push(
168 "[Training] Training is oscillating - reduce learning rate or increase batch size"
169 .to_string(),
170 );
171 },
172 _ => {},
173 }
174
175 if !training_dynamics.overfitting_indicators.is_empty() {
177 recommendations.push(
178 "[Training] Overfitting detected - consider regularization, dropout, or early stopping"
179 .to_string(),
180 );
181 }
182 if !training_dynamics.underfitting_indicators.is_empty() {
183 recommendations.push(
184 "[Training] Underfitting detected - consider increasing model capacity or training longer"
185 .to_string(),
186 );
187 }
188
189 if let Ok(analytics_report) = self.analytics_engine.generate_analytics_report() {
191 for recommendation in analytics_report.recommendations {
192 recommendations.push(format!("[Analytics] {}", recommendation));
193 }
194 }
195
196 let mut seen = std::collections::HashSet::new();
198 recommendations.retain(|r| seen.insert(r.clone()));
199
200 recommendations
201 }
202
203 pub fn current_step(&self) -> usize {
205 self.current_step
206 }
207
208 pub fn analyze_training_dynamics(&self) -> TrainingDynamics {
210 self.training_analyzer.analyze_training_dynamics()
211 }
212
213 pub fn increment_step(&mut self) {
215 self.current_step += 1;
216 }
217
218 pub async fn start(&mut self) -> Result<()> {
220 Ok(())
222 }
223
224 pub async fn generate_report(&self) -> Result<ModelDiagnosticsReport> {
226 self.generate_report_sync()
227 }
228
229 pub fn generate_report_sync(&self) -> Result<ModelDiagnosticsReport> {
231 let performance_summary = self.performance_analyzer.generate_performance_summary();
232 let architectural_analysis = self.architecture_analyzer.analyze_architecture().ok();
233 let training_dynamics = self.training_analyzer.analyze_training_dynamics();
234 let alerts = self.alert_manager.get_active_alerts().to_vec();
235
236 let auto_debugging_results = None; let analytics_report = self.analytics_engine.generate_analytics_report().ok();
241
242 Ok(ModelDiagnosticsReport {
243 current_step: self.current_step,
244 training_dynamics,
245 performance_summary,
246 architectural_analysis,
247 alerts: alerts.into_iter().map(|a| a.alert).collect(),
248 recommendations: self.aggregate_recommendations(),
249 health_score: self.calculate_health_score(),
250 auto_debugging_results,
251 analytics_report,
252 })
253 }
254}
255
256#[derive(Debug, Clone, Serialize, Deserialize)]
258pub struct ModelDiagnosticsReport {
259 pub current_step: usize,
261 pub training_dynamics: TrainingDynamics,
263 pub performance_summary: PerformanceSummary,
265 pub architectural_analysis: Option<ArchitecturalAnalysis>,
267 pub alerts: Vec<ModelDiagnosticAlert>,
269 pub recommendations: Vec<String>,
271 pub health_score: f64,
273 pub auto_debugging_results: Option<DebuggingReport>,
275 pub analytics_report: Option<AnalyticsReport>,
277}
278
279impl Default for ModelDiagnosticsReport {
280 fn default() -> Self {
281 Self {
282 current_step: 0,
283 training_dynamics: TrainingDynamics {
284 convergence_status: ConvergenceStatus::Unknown,
285 training_stability: TrainingStability::Unknown,
286 learning_efficiency: 0.0,
287 overfitting_indicators: Vec::new(),
288 underfitting_indicators: Vec::new(),
289 plateau_detection: None,
290 },
291 performance_summary: PerformanceSummary::default(),
292 architectural_analysis: None,
293 alerts: Vec::new(),
294 recommendations: Vec::new(),
295 health_score: 0.0,
296 auto_debugging_results: None,
297 analytics_report: None,
298 }
299 }
300}