import React, { useEffect, useRef, useState } from 'react'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { TrainingStatus } from '../types'; import { CheckCircle, Activity, Clock } from 'lucide-react'; import { Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis, } from 'recharts'; interface MonitoringStatsProps { trainingStatus: TrainingStatus; getProgressPercentage: () => number; formatTime: (seconds: number) => string; } interface LossPoint { step: number; loss: number; } interface LrPoint { step: number; lr: number; } const HISTORY_CAP = 200; const MonitoringStats: React.FC = ({ trainingStatus, getProgressPercentage, formatTime, }) => { const [lossHistory, setLossHistory] = useState([]); const [lrHistory, setLrHistory] = useState([]); const lastStepRef = useRef(0); // Append new metric points as they arrive; reset when a new run starts // (current_step resets back to 0). useEffect(() => { const step = trainingStatus.current_step; if (step < lastStepRef.current) { setLossHistory([]); setLrHistory([]); } lastStepRef.current = step; if (step > 0 && trainingStatus.current_loss != null) { const loss = trainingStatus.current_loss; setLossHistory((prev) => { const last = prev[prev.length - 1]; if (last && last.step === step) return prev; return [...prev, { step, loss }].slice(-HISTORY_CAP); }); } if (step > 0 && trainingStatus.current_lr != null) { const lr = trainingStatus.current_lr; setLrHistory((prev) => { const last = prev[prev.length - 1]; if (last && last.step === step) return prev; return [...prev, { step, lr }].slice(-HISTORY_CAP); }); } }, [trainingStatus.current_step, trainingStatus.current_loss, trainingStatus.current_lr]); const progress = getProgressPercentage(); // Until tqdm fires its first progress line, total_steps is 0 — show // "Training starting…" instead of a misleading 0/0 0% reading. const isStarting = trainingStatus.training_active && trainingStatus.total_steps === 0; const stepLabel = isStarting ? 'Training starting…' : `${trainingStatus.current_step.toLocaleString()} / ${trainingStatus.total_steps.toLocaleString()}`; const etaLabel = trainingStatus.eta_seconds != null ? formatTime(trainingStatus.eta_seconds) : '—'; return (

Progress

{stepLabel}
ETA {etaLabel}
{isStarting ? 'warming up…' : `${progress.toFixed(1)}%`}
Loss{' '} ({trainingStatus.current_loss?.toFixed(4) ?? '—'})
{lossHistory.length === 0 ? (
Waiting for first metric tick…
) : ( v.toFixed(4)} /> )}
Learning Rate{' '} ({trainingStatus.current_lr?.toExponential(2) ?? '—'})
{lrHistory.length === 0 ? (
Waiting for first metric tick…
) : ( v.toExponential(0)} /> v.toExponential(2)} /> )}
); }; export default MonitoringStats;