Skip to main content

trustformers_debug/
model_diagnostics_main.rs

1//! Model-level diagnostics and analysis tools.
2//!
3//! This module has been refactored into a modular architecture for better
4//! organization and maintainability. All previous functionality remains
5//! available through comprehensive re-exports to ensure backward compatibility.
6// reason: debug/profiling scaffolding — structs are constructed and their fields/methods
7// are retained for the data model, serialization completeness, and future consumers that
8// do not yet read every member. Consolidated from many item-level #[allow(dead_code)].
9#![allow(dead_code)]
10
11use crate::DebugConfig;
12use anyhow::Result;
13use serde::{Deserialize, Serialize};
14
15// Import all modular components directly from the model_diagnostics directory
16use crate::model_diagnostics::*;
17
18/// Main model diagnostics system that coordinates all diagnostic components.
19#[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    /// Create new model diagnostics system.
34    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    /// Record performance metrics.
49    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        // Process metrics for alerts
55        self.alert_manager.process_performance_metrics(&metrics)?;
56
57        Ok(())
58    }
59
60    /// Record architecture information.
61    pub fn record_architecture(&mut self, arch_info: ModelArchitectureInfo) {
62        self.architecture_analyzer.record_architecture(arch_info);
63    }
64
65    /// Record layer activation statistics.
66    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        // Process for alerts
71        self.alert_manager.process_layer_stats(&stats)?;
72
73        Ok(())
74    }
75
76    /// Record training dynamics.
77    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        // Process for alerts
82        self.alert_manager.process_training_dynamics(&dynamics)?;
83
84        Ok(())
85    }
86
87    /// Calculate overall model health score.
88    fn calculate_health_score(&self) -> f64 {
89        // Simple implementation - could be enhanced
90        let performance_score = 0.8; // Based on performance metrics
91        let architecture_score = 0.7; // Based on architecture analysis
92        let training_score = 0.9; // Based on training dynamics
93
94        (performance_score + architecture_score + training_score) / 3.0
95    }
96
97    /// Aggregate recommendations from all diagnostic components.
98    fn aggregate_recommendations(&self) -> Vec<String> {
99        let mut recommendations = Vec::new();
100
101        // Collect recommendations from architecture analyzer
102        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        // Collect recommendations from performance analyzer
109        let perf_summary = self.performance_analyzer.generate_performance_summary();
110        // Add performance-related recommendations based on metrics
111        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            // > 16GB
119            recommendations.push(
120                "[Performance] High memory usage detected - consider gradient checkpointing or smaller batch size"
121                    .to_string(),
122            );
123        }
124
125        // Collect recommendations from training analyzer
126        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        // Check for plateau conditions
144        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        // Check convergence status
154        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        // Add recommendations based on overfitting/underfitting indicators
176        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        // Collect recommendations from analytics engine
190        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        // Remove duplicates while preserving order
197        let mut seen = std::collections::HashSet::new();
198        recommendations.retain(|r| seen.insert(r.clone()));
199
200        recommendations
201    }
202
203    /// Get current step.
204    pub fn current_step(&self) -> usize {
205        self.current_step
206    }
207
208    /// Analyze current training dynamics.
209    pub fn analyze_training_dynamics(&self) -> TrainingDynamics {
210        self.training_analyzer.analyze_training_dynamics()
211    }
212
213    /// Increment step counter.
214    pub fn increment_step(&mut self) {
215        self.current_step += 1;
216    }
217
218    /// Start the diagnostics system.
219    pub async fn start(&mut self) -> Result<()> {
220        // Initialize all components
221        Ok(())
222    }
223
224    /// Generate comprehensive diagnostics report (async version).
225    pub async fn generate_report(&self) -> Result<ModelDiagnosticsReport> {
226        self.generate_report_sync()
227    }
228
229    /// Generate comprehensive diagnostics report (sync version).
230    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        // Generate auto-debugging analysis
237        let auto_debugging_results = None; // Simplified for now
238
239        // Generate analytics report
240        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/// Comprehensive model diagnostics report.
257#[derive(Debug, Clone, Serialize, Deserialize)]
258pub struct ModelDiagnosticsReport {
259    /// Current training step
260    pub current_step: usize,
261    /// Training dynamics analysis
262    pub training_dynamics: TrainingDynamics,
263    /// Performance summary
264    pub performance_summary: PerformanceSummary,
265    /// Architectural analysis results
266    pub architectural_analysis: Option<ArchitecturalAnalysis>,
267    /// Active diagnostic alerts
268    pub alerts: Vec<ModelDiagnosticAlert>,
269    /// Optimization recommendations
270    pub recommendations: Vec<String>,
271    /// Overall model health score
272    pub health_score: f64,
273    /// Auto-debugging results
274    pub auto_debugging_results: Option<DebuggingReport>,
275    /// Advanced analytics report
276    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}