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        // Auto-debugging is an async analysis (`AutoDebugger::analyze`); this
237        // is the SYNC report path, so it carries none. Use
238        // `generate_report()` for a report that includes it.
239        let auto_debugging_results = None;
240
241        // Generate analytics report
242        let analytics_report = self.analytics_engine.generate_analytics_report().ok();
243
244        Ok(ModelDiagnosticsReport {
245            current_step: self.current_step,
246            training_dynamics,
247            performance_summary,
248            architectural_analysis,
249            alerts: alerts.into_iter().map(|a| a.alert).collect(),
250            recommendations: self.aggregate_recommendations(),
251            health_score: self.calculate_health_score(),
252            auto_debugging_results,
253            analytics_report,
254        })
255    }
256}
257
258/// Comprehensive model diagnostics report.
259#[derive(Debug, Clone, Serialize, Deserialize)]
260pub struct ModelDiagnosticsReport {
261    /// Current training step
262    pub current_step: usize,
263    /// Training dynamics analysis
264    pub training_dynamics: TrainingDynamics,
265    /// Performance summary
266    pub performance_summary: PerformanceSummary,
267    /// Architectural analysis results
268    pub architectural_analysis: Option<ArchitecturalAnalysis>,
269    /// Active diagnostic alerts
270    pub alerts: Vec<ModelDiagnosticAlert>,
271    /// Optimization recommendations
272    pub recommendations: Vec<String>,
273    /// Overall model health score
274    pub health_score: f64,
275    /// Auto-debugging results
276    pub auto_debugging_results: Option<DebuggingReport>,
277    /// Advanced analytics report
278    pub analytics_report: Option<AnalyticsReport>,
279}
280
281impl Default for ModelDiagnosticsReport {
282    fn default() -> Self {
283        Self {
284            current_step: 0,
285            training_dynamics: TrainingDynamics {
286                convergence_status: ConvergenceStatus::Unknown,
287                training_stability: TrainingStability::Unknown,
288                learning_efficiency: 0.0,
289                overfitting_indicators: Vec::new(),
290                underfitting_indicators: Vec::new(),
291                plateau_detection: None,
292            },
293            performance_summary: PerformanceSummary::default(),
294            architectural_analysis: None,
295            alerts: Vec::new(),
296            recommendations: Vec::new(),
297            health_score: 0.0,
298            auto_debugging_results: None,
299            analytics_report: None,
300        }
301    }
302}