Delete plots
Browse files- plots/.gitignore +0 -74
- plots/404.html +0 -33
- plots/README.md +0 -90
- plots/code.js +0 -550
- plots/data.json +0 -0
- plots/index.html +0 -72
- plots/style.css +0 -258
plots/.gitignore
DELETED
|
@@ -1,74 +0,0 @@
|
|
| 1 |
-
# Logs
|
| 2 |
-
logs
|
| 3 |
-
*.log
|
| 4 |
-
npm-debug.log*
|
| 5 |
-
yarn-debug.log*
|
| 6 |
-
yarn-error.log*
|
| 7 |
-
firebase-debug.log*
|
| 8 |
-
firebase-debug.*.log*
|
| 9 |
-
|
| 10 |
-
# Firebase cache
|
| 11 |
-
.firebase/
|
| 12 |
-
|
| 13 |
-
# Firebase config
|
| 14 |
-
|
| 15 |
-
# Uncomment this if you'd like others to create their own Firebase project.
|
| 16 |
-
# For a team working on the same Firebase project(s), it is recommended to leave
|
| 17 |
-
# it commented so all members can deploy to the same project(s) in .firebaserc.
|
| 18 |
-
# .firebaserc
|
| 19 |
-
|
| 20 |
-
# Runtime data
|
| 21 |
-
pids
|
| 22 |
-
*.pid
|
| 23 |
-
*.seed
|
| 24 |
-
*.pid.lock
|
| 25 |
-
|
| 26 |
-
# Directory for instrumented libs generated by jscoverage/JSCover
|
| 27 |
-
lib-cov
|
| 28 |
-
|
| 29 |
-
# Coverage directory used by tools like istanbul
|
| 30 |
-
coverage
|
| 31 |
-
|
| 32 |
-
# nyc test coverage
|
| 33 |
-
.nyc_output
|
| 34 |
-
|
| 35 |
-
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
| 36 |
-
.grunt
|
| 37 |
-
|
| 38 |
-
# Bower dependency directory (https://bower.io/)
|
| 39 |
-
bower_components
|
| 40 |
-
|
| 41 |
-
# node-waf configuration
|
| 42 |
-
.lock-wscript
|
| 43 |
-
|
| 44 |
-
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
| 45 |
-
build/Release
|
| 46 |
-
|
| 47 |
-
# Dependency directories
|
| 48 |
-
node_modules/
|
| 49 |
-
|
| 50 |
-
# Optional npm cache directory
|
| 51 |
-
.npm
|
| 52 |
-
|
| 53 |
-
# Optional eslint cache
|
| 54 |
-
.eslintcache
|
| 55 |
-
|
| 56 |
-
# Optional REPL history
|
| 57 |
-
.node_repl_history
|
| 58 |
-
|
| 59 |
-
# Output of 'npm pack'
|
| 60 |
-
*.tgz
|
| 61 |
-
|
| 62 |
-
# Yarn Integrity file
|
| 63 |
-
.yarn-integrity
|
| 64 |
-
|
| 65 |
-
# dotenv environment variables file
|
| 66 |
-
.env
|
| 67 |
-
|
| 68 |
-
# dataconnect generated files
|
| 69 |
-
.dataconnect
|
| 70 |
-
|
| 71 |
-
# firebase files
|
| 72 |
-
|
| 73 |
-
.firebaserc
|
| 74 |
-
firebase.json
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plots/404.html
DELETED
|
@@ -1,33 +0,0 @@
|
|
| 1 |
-
<!DOCTYPE html>
|
| 2 |
-
<html>
|
| 3 |
-
<head>
|
| 4 |
-
<meta charset="utf-8">
|
| 5 |
-
<meta name="viewport" content="width=device-width, initial-scale=1">
|
| 6 |
-
<title>Page Not Found</title>
|
| 7 |
-
|
| 8 |
-
<style media="screen">
|
| 9 |
-
body { background: #ECEFF1; color: rgba(0,0,0,0.87); font-family: Roboto, Helvetica, Arial, sans-serif; margin: 0; padding: 0; }
|
| 10 |
-
#message { background: white; max-width: 360px; margin: 100px auto 16px; padding: 32px 24px 16px; border-radius: 3px; }
|
| 11 |
-
#message h3 { color: #888; font-weight: normal; font-size: 16px; margin: 16px 0 12px; }
|
| 12 |
-
#message h2 { color: #ffa100; font-weight: bold; font-size: 16px; margin: 0 0 8px; }
|
| 13 |
-
#message h1 { font-size: 22px; font-weight: 300; color: rgba(0,0,0,0.6); margin: 0 0 16px;}
|
| 14 |
-
#message p { line-height: 140%; margin: 16px 0 24px; font-size: 14px; }
|
| 15 |
-
#message a { display: block; text-align: center; background: #039be5; text-transform: uppercase; text-decoration: none; color: white; padding: 16px; border-radius: 4px; }
|
| 16 |
-
#message, #message a { box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24); }
|
| 17 |
-
#load { color: rgba(0,0,0,0.4); text-align: center; font-size: 13px; }
|
| 18 |
-
@media (max-width: 600px) {
|
| 19 |
-
body, #message { margin-top: 0; background: white; box-shadow: none; }
|
| 20 |
-
body { border-top: 16px solid #ffa100; }
|
| 21 |
-
}
|
| 22 |
-
</style>
|
| 23 |
-
</head>
|
| 24 |
-
<body>
|
| 25 |
-
<div id="message">
|
| 26 |
-
<h2>404</h2>
|
| 27 |
-
<h1>Page Not Found</h1>
|
| 28 |
-
<p>The specified file was not found on this website. Please check the URL for mistakes and try again.</p>
|
| 29 |
-
<h3>Why am I seeing this?</h3>
|
| 30 |
-
<p>This page was generated by the Firebase Command-Line Interface. To modify it, edit the <code>404.html</code> file in your project's configured <code>public</code> directory.</p>
|
| 31 |
-
</div>
|
| 32 |
-
</body>
|
| 33 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plots/README.md
DELETED
|
@@ -1,90 +0,0 @@
|
|
| 1 |
-
# 🚀 Pico Training Metrics Dashboard
|
| 2 |
-
|
| 3 |
-
A beautiful, interactive web dashboard for visualizing training progress across all your Pico model runs.
|
| 4 |
-
|
| 5 |
-
## ✨ Features
|
| 6 |
-
|
| 7 |
-
- **📈 Training Loss Visualization**: Track loss curves over time for all runs
|
| 8 |
-
- **🎯 Learning Rate Schedules**: Monitor LR progression and warmup patterns
|
| 9 |
-
- **📊 Paloma Evaluation**: View perplexity metrics during training
|
| 10 |
-
- **🔄 Combined View**: See all metrics together for easy comparison
|
| 11 |
-
- **🎨 Interactive Charts**: Built with Chart.js for smooth interactions
|
| 12 |
-
- **📱 Responsive Design**: Works on desktop and mobile devices
|
| 13 |
-
- **⚙️ Run Comparison**: Compare different model configurations side-by-side
|
| 14 |
-
|
| 15 |
-
## �� Quick Start
|
| 16 |
-
|
| 17 |
-
1. **Generate Data**: First, run the data generation script to parse your training logs:
|
| 18 |
-
```bash
|
| 19 |
-
python scripts/generate_data.py
|
| 20 |
-
```
|
| 21 |
-
|
| 22 |
-
2. **View the Dashboard**: Open `index.html` in your web browser
|
| 23 |
-
3. **Select Runs**: Use the dropdown to view specific runs or all runs together
|
| 24 |
-
4. **Toggle Metrics**: Check/uncheck boxes to show/hide different metric types
|
| 25 |
-
5. **Explore Charts**: Hover over data points for detailed information
|
| 26 |
-
|
| 27 |
-
## 📁 Files
|
| 28 |
-
|
| 29 |
-
- `index.html` - Main dashboard interface
|
| 30 |
-
- `style.css` - Modern, responsive styling
|
| 31 |
-
- `code.js` - Interactive chart functionality
|
| 32 |
-
- `data.json` - Training metrics data (auto-generated from logs)
|
| 33 |
-
|
| 34 |
-
## 🔧 Data Source
|
| 35 |
-
|
| 36 |
-
The dashboard automatically extracts training metrics from:
|
| 37 |
-
- Training loss at each step
|
| 38 |
-
- Learning rate progression
|
| 39 |
-
- Paloma evaluation results
|
| 40 |
-
- Model configuration parameters
|
| 41 |
-
|
| 42 |
-
## 🔄 Updating Data
|
| 43 |
-
|
| 44 |
-
To refresh the dashboard with new training data:
|
| 45 |
-
1. **Run new training sessions** - logs will be saved to `runs/*/logs/`
|
| 46 |
-
2. **Generate updated data.json**:
|
| 47 |
-
```bash
|
| 48 |
-
python scripts/generate_data.py
|
| 49 |
-
```
|
| 50 |
-
3. **Refresh the dashboard** - new runs will appear automatically
|
| 51 |
-
|
| 52 |
-
## 🎨 Chart Types
|
| 53 |
-
|
| 54 |
-
1. **Training Loss**: Line charts showing loss reduction over time
|
| 55 |
-
2. **Learning Rate**: Logarithmic scale for LR schedule visualization
|
| 56 |
-
3. **Evaluation**: Paloma perplexity metrics during training
|
| 57 |
-
4. **Combined**: All metrics on one chart for easy comparison
|
| 58 |
-
|
| 59 |
-
## 💡 Usage Tips
|
| 60 |
-
|
| 61 |
-
- **Compare Runs**: Select "All Runs" to see how different configurations perform
|
| 62 |
-
- **Zoom In**: Use the chart zoom features to focus on specific training phases
|
| 63 |
-
- **Export**: Right-click charts to save as images
|
| 64 |
-
- **Mobile**: Dashboard is fully responsive for mobile devices
|
| 65 |
-
|
| 66 |
-
## 🎯 Key Metrics Tracked
|
| 67 |
-
|
| 68 |
-
- **Training Loss**: Primary performance indicator
|
| 69 |
-
- **Learning Rate**: Schedule adherence and warmup progress
|
| 70 |
-
- **Paloma Perplexity**: Model evaluation quality
|
| 71 |
-
- **Inf/NaN Counts**: Training stability monitoring
|
| 72 |
-
- **Model Config**: Architecture and hyperparameter details
|
| 73 |
-
|
| 74 |
-
## 🌟 Design Features
|
| 75 |
-
|
| 76 |
-
- **Modern UI**: Clean, professional interface
|
| 77 |
-
- **Color Coding**: Distinct colors for each model run
|
| 78 |
-
- **Responsive Layout**: Adapts to different screen sizes
|
| 79 |
-
- **Interactive Elements**: Hover effects and smooth animations
|
| 80 |
-
- **Professional Typography**: Easy-to-read fonts and spacing
|
| 81 |
-
|
| 82 |
-
## 📚 Documentation
|
| 83 |
-
|
| 84 |
-
For more details on generating the data.json file, see:
|
| 85 |
-
- `scripts/README.md` - Complete script documentation
|
| 86 |
-
- `scripts/generate_data.py` - The data generation script
|
| 87 |
-
|
| 88 |
-
---
|
| 89 |
-
|
| 90 |
-
Built with ❤️ for the Pico Language Model training community
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plots/code.js
DELETED
|
@@ -1,550 +0,0 @@
|
|
| 1 |
-
// Global variables
|
| 2 |
-
let trainingData = null;
|
| 3 |
-
let charts = {};
|
| 4 |
-
|
| 5 |
-
// Color palette for different runs
|
| 6 |
-
const colors = [
|
| 7 |
-
'#667eea', '#764ba2', '#f093fb', '#f5576c', '#4facfe', '#00f2fe',
|
| 8 |
-
'#43e97b', '#38f9d7', '#fa7093', '#fee140', '#a8edea', '#fed6e3'
|
| 9 |
-
];
|
| 10 |
-
|
| 11 |
-
// Initialize the dashboard
|
| 12 |
-
document.addEventListener('DOMContentLoaded', function() {
|
| 13 |
-
loadData();
|
| 14 |
-
setupEventListeners();
|
| 15 |
-
});
|
| 16 |
-
|
| 17 |
-
// Load training data from JSON file
|
| 18 |
-
async function loadData() {
|
| 19 |
-
try {
|
| 20 |
-
const response = await fetch('data.json');
|
| 21 |
-
trainingData = await response.json();
|
| 22 |
-
|
| 23 |
-
// Merge continuation logs from the same model run
|
| 24 |
-
mergeContinuationLogs();
|
| 25 |
-
|
| 26 |
-
populateRunSelector();
|
| 27 |
-
createCharts();
|
| 28 |
-
updateRunSummary();
|
| 29 |
-
updateConfigDetails();
|
| 30 |
-
|
| 31 |
-
console.log('Data loaded and merged successfully:', trainingData);
|
| 32 |
-
} catch (error) {
|
| 33 |
-
console.error('Error loading data:', error);
|
| 34 |
-
document.body.innerHTML = '<div class="loading">Error loading training data. Please check the console for details.</div>';
|
| 35 |
-
}
|
| 36 |
-
}
|
| 37 |
-
|
| 38 |
-
// Merge continuation logs from the same model run
|
| 39 |
-
function mergeContinuationLogs() {
|
| 40 |
-
const runGroups = {};
|
| 41 |
-
|
| 42 |
-
// Group runs by base model name
|
| 43 |
-
trainingData.runs.forEach(run => {
|
| 44 |
-
const baseName = run.run_name;
|
| 45 |
-
if (!runGroups[baseName]) {
|
| 46 |
-
runGroups[baseName] = [];
|
| 47 |
-
}
|
| 48 |
-
runGroups[baseName].push(run);
|
| 49 |
-
});
|
| 50 |
-
|
| 51 |
-
// Merge runs with the same base name
|
| 52 |
-
const mergedRuns = [];
|
| 53 |
-
|
| 54 |
-
Object.entries(runGroups).forEach(([baseName, runs]) => {
|
| 55 |
-
if (runs.length === 1) {
|
| 56 |
-
// Single run, no merging needed
|
| 57 |
-
mergedRuns.push(runs[0]);
|
| 58 |
-
} else {
|
| 59 |
-
// Multiple runs to merge
|
| 60 |
-
console.log(`Merging ${runs.length} continuation logs for ${baseName}`);
|
| 61 |
-
|
| 62 |
-
const mergedRun = {
|
| 63 |
-
run_name: baseName,
|
| 64 |
-
log_files: runs.map(r => r.log_file),
|
| 65 |
-
training_metrics: [],
|
| 66 |
-
evaluation_results: [],
|
| 67 |
-
config: runs[0].config || {}
|
| 68 |
-
};
|
| 69 |
-
|
| 70 |
-
// Merge training metrics (they should be continuous)
|
| 71 |
-
runs.forEach(run => {
|
| 72 |
-
if (run.training_metrics) {
|
| 73 |
-
mergedRun.training_metrics.push(...run.training_metrics);
|
| 74 |
-
}
|
| 75 |
-
});
|
| 76 |
-
|
| 77 |
-
// Merge evaluation results (they should be continuous)
|
| 78 |
-
runs.forEach(run => {
|
| 79 |
-
if (run.evaluation_results) {
|
| 80 |
-
mergedRun.evaluation_results.push(...run.evaluation_results);
|
| 81 |
-
}
|
| 82 |
-
});
|
| 83 |
-
|
| 84 |
-
// Sort by step number to ensure proper ordering
|
| 85 |
-
mergedRun.training_metrics.sort((a, b) => a.step - b.step);
|
| 86 |
-
mergedRun.evaluation_results.sort((a, b) => a.step - b.step);
|
| 87 |
-
|
| 88 |
-
// Remove duplicates based on step number
|
| 89 |
-
mergedRun.training_metrics = mergedRun.training_metrics.filter((metric, index, self) =>
|
| 90 |
-
index === 0 || metric.step !== self[index - 1].step
|
| 91 |
-
);
|
| 92 |
-
mergedRun.evaluation_results = mergedRun.evaluation_results.filter((result, index, self) =>
|
| 93 |
-
index === 0 || result.step !== self[index - 1].step
|
| 94 |
-
);
|
| 95 |
-
|
| 96 |
-
console.log(`Merged ${baseName}: ${mergedRun.training_metrics.length} training points, ${mergedRun.evaluation_results.length} eval points`);
|
| 97 |
-
mergedRuns.push(mergedRun);
|
| 98 |
-
}
|
| 99 |
-
});
|
| 100 |
-
|
| 101 |
-
trainingData.runs = mergedRuns;
|
| 102 |
-
}
|
| 103 |
-
|
| 104 |
-
// Setup event listeners for controls
|
| 105 |
-
function setupEventListeners() {
|
| 106 |
-
document.getElementById('runSelect').addEventListener('change', function() {
|
| 107 |
-
updateCharts();
|
| 108 |
-
updateRunSummary();
|
| 109 |
-
updateConfigDetails();
|
| 110 |
-
});
|
| 111 |
-
document.getElementById('showTraining').addEventListener('change', updateCharts);
|
| 112 |
-
document.getElementById('showLearningRate').addEventListener('change', updateCharts);
|
| 113 |
-
document.getElementById('showEvaluation').addEventListener('change', updateCharts);
|
| 114 |
-
}
|
| 115 |
-
|
| 116 |
-
// Populate run selector dropdown
|
| 117 |
-
function populateRunSelector() {
|
| 118 |
-
const select = document.getElementById('runSelect');
|
| 119 |
-
const runs = trainingData.runs;
|
| 120 |
-
|
| 121 |
-
// Clear existing options
|
| 122 |
-
select.innerHTML = '<option value="all">All Runs</option>';
|
| 123 |
-
|
| 124 |
-
runs.forEach((run, index) => {
|
| 125 |
-
const option = document.createElement('option');
|
| 126 |
-
option.value = index;
|
| 127 |
-
option.textContent = run.run_name;
|
| 128 |
-
select.appendChild(option);
|
| 129 |
-
});
|
| 130 |
-
}
|
| 131 |
-
|
| 132 |
-
// Create all charts
|
| 133 |
-
function createCharts() {
|
| 134 |
-
createLossChart();
|
| 135 |
-
createLRChart();
|
| 136 |
-
createEvalChart();
|
| 137 |
-
createCombinedChart();
|
| 138 |
-
}
|
| 139 |
-
|
| 140 |
-
// Create training loss chart
|
| 141 |
-
function createLossChart() {
|
| 142 |
-
const ctx = document.getElementById('lossChart').getContext('2d');
|
| 143 |
-
|
| 144 |
-
charts.loss = new Chart(ctx, {
|
| 145 |
-
type: 'line',
|
| 146 |
-
data: getChartData('loss'),
|
| 147 |
-
options: {
|
| 148 |
-
responsive: true,
|
| 149 |
-
maintainAspectRatio: false,
|
| 150 |
-
plugins: {
|
| 151 |
-
title: {
|
| 152 |
-
display: true,
|
| 153 |
-
text: 'Training Loss Over Time'
|
| 154 |
-
},
|
| 155 |
-
legend: {
|
| 156 |
-
position: 'top'
|
| 157 |
-
}
|
| 158 |
-
},
|
| 159 |
-
scales: {
|
| 160 |
-
x: {
|
| 161 |
-
type: 'linear',
|
| 162 |
-
title: {
|
| 163 |
-
display: true,
|
| 164 |
-
text: 'Training Step'
|
| 165 |
-
}
|
| 166 |
-
},
|
| 167 |
-
y: {
|
| 168 |
-
title: {
|
| 169 |
-
display: true,
|
| 170 |
-
text: 'Loss'
|
| 171 |
-
},
|
| 172 |
-
beginAtZero: false
|
| 173 |
-
}
|
| 174 |
-
},
|
| 175 |
-
interaction: {
|
| 176 |
-
intersect: false,
|
| 177 |
-
mode: 'index'
|
| 178 |
-
}
|
| 179 |
-
}
|
| 180 |
-
});
|
| 181 |
-
}
|
| 182 |
-
|
| 183 |
-
// Create learning rate chart
|
| 184 |
-
function createLRChart() {
|
| 185 |
-
const ctx = document.getElementById('lrChart').getContext('2d');
|
| 186 |
-
|
| 187 |
-
charts.lr = new Chart(ctx, {
|
| 188 |
-
type: 'line',
|
| 189 |
-
data: getChartData('lr'),
|
| 190 |
-
options: {
|
| 191 |
-
responsive: true,
|
| 192 |
-
maintainAspectRatio: false,
|
| 193 |
-
plugins: {
|
| 194 |
-
title: {
|
| 195 |
-
display: true,
|
| 196 |
-
text: 'Learning Rate Schedule'
|
| 197 |
-
},
|
| 198 |
-
legend: {
|
| 199 |
-
position: 'top'
|
| 200 |
-
}
|
| 201 |
-
},
|
| 202 |
-
scales: {
|
| 203 |
-
x: {
|
| 204 |
-
type: 'linear',
|
| 205 |
-
title: {
|
| 206 |
-
display: true,
|
| 207 |
-
text: 'Training Step'
|
| 208 |
-
}
|
| 209 |
-
},
|
| 210 |
-
y: {
|
| 211 |
-
title: {
|
| 212 |
-
display: true,
|
| 213 |
-
text: 'Learning Rate'
|
| 214 |
-
},
|
| 215 |
-
type: 'logarithmic'
|
| 216 |
-
}
|
| 217 |
-
},
|
| 218 |
-
interaction: {
|
| 219 |
-
intersect: false,
|
| 220 |
-
mode: 'index'
|
| 221 |
-
}
|
| 222 |
-
}
|
| 223 |
-
});
|
| 224 |
-
}
|
| 225 |
-
|
| 226 |
-
// Create evaluation chart
|
| 227 |
-
function createEvalChart() {
|
| 228 |
-
const ctx = document.getElementById('evalChart').getContext('2d');
|
| 229 |
-
|
| 230 |
-
charts.eval = new Chart(ctx, {
|
| 231 |
-
type: 'line',
|
| 232 |
-
data: getChartData('eval'),
|
| 233 |
-
options: {
|
| 234 |
-
responsive: true,
|
| 235 |
-
maintainAspectRatio: false,
|
| 236 |
-
plugins: {
|
| 237 |
-
title: {
|
| 238 |
-
display: true,
|
| 239 |
-
text: 'Paloma Evaluation Metrics'
|
| 240 |
-
},
|
| 241 |
-
legend: {
|
| 242 |
-
position: 'top'
|
| 243 |
-
}
|
| 244 |
-
},
|
| 245 |
-
scales: {
|
| 246 |
-
x: {
|
| 247 |
-
type: 'linear',
|
| 248 |
-
title: {
|
| 249 |
-
display: true,
|
| 250 |
-
text: 'Training Step'
|
| 251 |
-
}
|
| 252 |
-
},
|
| 253 |
-
y: {
|
| 254 |
-
title: {
|
| 255 |
-
display: true,
|
| 256 |
-
text: 'Perplexity'
|
| 257 |
-
},
|
| 258 |
-
type: 'logarithmic'
|
| 259 |
-
}
|
| 260 |
-
},
|
| 261 |
-
interaction: {
|
| 262 |
-
intersect: false,
|
| 263 |
-
mode: 'index'
|
| 264 |
-
}
|
| 265 |
-
}
|
| 266 |
-
});
|
| 267 |
-
}
|
| 268 |
-
|
| 269 |
-
// Create combined chart
|
| 270 |
-
function createCombinedChart() {
|
| 271 |
-
const ctx = document.getElementById('combinedChart').getContext('2d');
|
| 272 |
-
|
| 273 |
-
charts.combined = new Chart(ctx, {
|
| 274 |
-
type: 'line',
|
| 275 |
-
data: getCombinedChartData(),
|
| 276 |
-
options: {
|
| 277 |
-
responsive: true,
|
| 278 |
-
maintainAspectRatio: false,
|
| 279 |
-
plugins: {
|
| 280 |
-
title: {
|
| 281 |
-
display: true,
|
| 282 |
-
text: 'Combined Training Metrics'
|
| 283 |
-
},
|
| 284 |
-
legend: {
|
| 285 |
-
position: 'top'
|
| 286 |
-
}
|
| 287 |
-
},
|
| 288 |
-
scales: {
|
| 289 |
-
x: {
|
| 290 |
-
type: 'linear',
|
| 291 |
-
title: {
|
| 292 |
-
display: true,
|
| 293 |
-
text: 'Training Step'
|
| 294 |
-
}
|
| 295 |
-
},
|
| 296 |
-
y: {
|
| 297 |
-
title: {
|
| 298 |
-
display: true,
|
| 299 |
-
text: 'Value'
|
| 300 |
-
}
|
| 301 |
-
}
|
| 302 |
-
},
|
| 303 |
-
interaction: {
|
| 304 |
-
intersect: false,
|
| 305 |
-
mode: 'index'
|
| 306 |
-
}
|
| 307 |
-
}
|
| 308 |
-
});
|
| 309 |
-
}
|
| 310 |
-
|
| 311 |
-
// Get chart data for specific metric type
|
| 312 |
-
function getChartData(metricType) {
|
| 313 |
-
const selectedRun = document.getElementById('runSelect').value;
|
| 314 |
-
const runs = selectedRun === 'all' ? trainingData.runs : [trainingData.runs[selectedRun]];
|
| 315 |
-
|
| 316 |
-
const datasets = [];
|
| 317 |
-
|
| 318 |
-
console.log(`Getting ${metricType} data for ${runs.length} runs:`, runs.map(r => r.run_name));
|
| 319 |
-
|
| 320 |
-
runs.forEach((run, runIndex) => {
|
| 321 |
-
const color = colors[runIndex % colors.length];
|
| 322 |
-
|
| 323 |
-
if (metricType === 'loss') {
|
| 324 |
-
if (run.training_metrics && run.training_metrics.length > 0) {
|
| 325 |
-
const data = run.training_metrics.map(m => ({ x: m.step, y: m.loss }));
|
| 326 |
-
console.log(`Loss data for ${run.run_name}:`, data.slice(0, 5), '...', data.slice(-5));
|
| 327 |
-
datasets.push({
|
| 328 |
-
label: run.run_name,
|
| 329 |
-
data: data,
|
| 330 |
-
borderColor: color,
|
| 331 |
-
backgroundColor: color + '20',
|
| 332 |
-
borderWidth: 2,
|
| 333 |
-
fill: false,
|
| 334 |
-
tension: 0.1
|
| 335 |
-
});
|
| 336 |
-
}
|
| 337 |
-
} else if (metricType === 'lr') {
|
| 338 |
-
if (run.training_metrics && run.training_metrics.length > 0) {
|
| 339 |
-
const data = run.training_metrics.map(m => ({ x: m.step, y: m.learning_rate }));
|
| 340 |
-
console.log(`LR data for ${run.run_name}:`, data.slice(0, 5), '...', data.slice(-5));
|
| 341 |
-
datasets.push({
|
| 342 |
-
label: run.run_name,
|
| 343 |
-
data: data,
|
| 344 |
-
borderColor: color,
|
| 345 |
-
backgroundColor: color + '20',
|
| 346 |
-
borderWidth: 2,
|
| 347 |
-
fill: false,
|
| 348 |
-
tension: 0.1
|
| 349 |
-
});
|
| 350 |
-
}
|
| 351 |
-
} else if (metricType === 'eval') {
|
| 352 |
-
if (run.evaluation_results && run.evaluation_results.length > 0) {
|
| 353 |
-
const data = run.evaluation_results.map(m => ({ x: m.step, y: m.paloma }));
|
| 354 |
-
console.log(`Eval data for ${run.run_name}:`, data.slice(0, 5), '...', data.slice(-5));
|
| 355 |
-
datasets.push({
|
| 356 |
-
label: run.run_name,
|
| 357 |
-
data: data,
|
| 358 |
-
borderColor: color,
|
| 359 |
-
backgroundColor: color + '20',
|
| 360 |
-
borderWidth: 2,
|
| 361 |
-
fill: false,
|
| 362 |
-
tension: 0.1
|
| 363 |
-
});
|
| 364 |
-
}
|
| 365 |
-
}
|
| 366 |
-
});
|
| 367 |
-
|
| 368 |
-
console.log(`Final ${metricType} datasets:`, datasets);
|
| 369 |
-
return { datasets };
|
| 370 |
-
}
|
| 371 |
-
|
| 372 |
-
// Get combined chart data
|
| 373 |
-
function getCombinedChartData() {
|
| 374 |
-
const selectedRun = document.getElementById('runSelect').value;
|
| 375 |
-
const runs = selectedRun === 'all' ? trainingData.runs : [trainingData.runs[selectedRun]];
|
| 376 |
-
|
| 377 |
-
const datasets = [];
|
| 378 |
-
|
| 379 |
-
runs.forEach((run, runIndex) => {
|
| 380 |
-
const color = colors[runIndex % colors.length];
|
| 381 |
-
|
| 382 |
-
// Training loss
|
| 383 |
-
if (run.training_metrics && run.training_metrics.length > 0) {
|
| 384 |
-
datasets.push({
|
| 385 |
-
label: `${run.run_name} - Loss`,
|
| 386 |
-
data: run.training_metrics.map(m => ({ x: m.step, y: m.loss })),
|
| 387 |
-
borderColor: color,
|
| 388 |
-
backgroundColor: color + '20',
|
| 389 |
-
borderWidth: 2,
|
| 390 |
-
fill: false,
|
| 391 |
-
tension: 0.1
|
| 392 |
-
});
|
| 393 |
-
}
|
| 394 |
-
|
| 395 |
-
// Learning rate (scaled)
|
| 396 |
-
if (run.training_metrics && run.training_metrics.length > 0) {
|
| 397 |
-
const maxLR = Math.max(...run.training_metrics.map(m => m.learning_rate));
|
| 398 |
-
const maxLoss = Math.max(...run.training_metrics.map(m => m.loss));
|
| 399 |
-
const scaleFactor = maxLoss / maxLR;
|
| 400 |
-
|
| 401 |
-
datasets.push({
|
| 402 |
-
label: `${run.run_name} - LR (scaled)`,
|
| 403 |
-
data: run.training_metrics.map(m => ({ x: m.step, y: m.learning_rate * scaleFactor })),
|
| 404 |
-
borderColor: color + '80',
|
| 405 |
-
backgroundColor: color + '10',
|
| 406 |
-
borderWidth: 1,
|
| 407 |
-
fill: false,
|
| 408 |
-
tension: 0.1
|
| 409 |
-
});
|
| 410 |
-
}
|
| 411 |
-
});
|
| 412 |
-
|
| 413 |
-
return { datasets };
|
| 414 |
-
}
|
| 415 |
-
|
| 416 |
-
// Update all charts based on current selection
|
| 417 |
-
function updateCharts() {
|
| 418 |
-
if (charts.loss) {
|
| 419 |
-
charts.loss.data = getChartData('loss');
|
| 420 |
-
charts.loss.update();
|
| 421 |
-
}
|
| 422 |
-
|
| 423 |
-
if (charts.lr) {
|
| 424 |
-
charts.lr.data = getChartData('lr');
|
| 425 |
-
charts.lr.update();
|
| 426 |
-
}
|
| 427 |
-
|
| 428 |
-
if (charts.eval) {
|
| 429 |
-
charts.eval.data = getChartData('eval');
|
| 430 |
-
charts.eval.update();
|
| 431 |
-
}
|
| 432 |
-
|
| 433 |
-
if (charts.combined) {
|
| 434 |
-
charts.combined.data = getCombinedChartData();
|
| 435 |
-
charts.combined.update();
|
| 436 |
-
}
|
| 437 |
-
}
|
| 438 |
-
|
| 439 |
-
// Update run summary section
|
| 440 |
-
function updateRunSummary() {
|
| 441 |
-
const container = document.getElementById('runSummary');
|
| 442 |
-
const selectedRun = document.getElementById('runSelect').value;
|
| 443 |
-
const runs = selectedRun === 'all' ? trainingData.runs : [trainingData.runs[selectedRun]];
|
| 444 |
-
|
| 445 |
-
let html = '<div class="run-grid">';
|
| 446 |
-
|
| 447 |
-
runs.forEach(run => {
|
| 448 |
-
const trainingPoints = run.training_metrics ? run.training_metrics.length : 0;
|
| 449 |
-
const evalPoints = run.evaluation_results ? run.evaluation_results.length : 0;
|
| 450 |
-
|
| 451 |
-
let finalLoss = 'N/A';
|
| 452 |
-
let finalLR = 'N/A';
|
| 453 |
-
let finalPaloma = 'N/A';
|
| 454 |
-
let stepRange = 'N/A';
|
| 455 |
-
|
| 456 |
-
if (run.training_metrics && run.training_metrics.length > 0) {
|
| 457 |
-
const first = run.training_metrics[0];
|
| 458 |
-
const last = run.training_metrics[run.training_metrics.length - 1];
|
| 459 |
-
finalLoss = last.loss.toFixed(4);
|
| 460 |
-
finalLR = last.learning_rate.toExponential(2);
|
| 461 |
-
stepRange = `${first.step} → ${last.step}`;
|
| 462 |
-
}
|
| 463 |
-
|
| 464 |
-
if (run.evaluation_results && run.evaluation_results.length > 0) {
|
| 465 |
-
const last = run.evaluation_results[run.evaluation_results.length - 1];
|
| 466 |
-
if (isFinite(last.paloma)) {
|
| 467 |
-
finalPaloma = last.paloma.toExponential(2);
|
| 468 |
-
} else {
|
| 469 |
-
finalPaloma = '∞';
|
| 470 |
-
}
|
| 471 |
-
}
|
| 472 |
-
|
| 473 |
-
const logFiles = run.log_files ? run.log_files.join(', ') : run.log_file;
|
| 474 |
-
|
| 475 |
-
html += `
|
| 476 |
-
<div class="run-card">
|
| 477 |
-
<h4>${run.run_name}</h4>
|
| 478 |
-
<p><strong>Logs:</strong> ${logFiles}</p>
|
| 479 |
-
<div class="metric">
|
| 480 |
-
<span>Step Range:</span>
|
| 481 |
-
<span class="value">${stepRange}</span>
|
| 482 |
-
</div>
|
| 483 |
-
<div class="metric">
|
| 484 |
-
<span>Training Points:</span>
|
| 485 |
-
<span class="value">${trainingPoints}</span>
|
| 486 |
-
</div>
|
| 487 |
-
<div class="metric">
|
| 488 |
-
<span>Evaluation Points:</span>
|
| 489 |
-
<span class="value">${evalPoints}</span>
|
| 490 |
-
</div>
|
| 491 |
-
<div class="metric">
|
| 492 |
-
<span>Final Loss:</span>
|
| 493 |
-
<span class="value">${finalLoss}</span>
|
| 494 |
-
</div>
|
| 495 |
-
<div class="metric">
|
| 496 |
-
<span>Final LR:</span>
|
| 497 |
-
<span class="value">${finalLR}</span>
|
| 498 |
-
</div>
|
| 499 |
-
<div class="metric">
|
| 500 |
-
<span>Final Paloma:</span>
|
| 501 |
-
<span class="value">${finalPaloma}</span>
|
| 502 |
-
</div>
|
| 503 |
-
</div>
|
| 504 |
-
`;
|
| 505 |
-
});
|
| 506 |
-
|
| 507 |
-
html += '</div>';
|
| 508 |
-
container.innerHTML = html;
|
| 509 |
-
}
|
| 510 |
-
|
| 511 |
-
// Update configuration details section
|
| 512 |
-
function updateConfigDetails() {
|
| 513 |
-
const container = document.getElementById('configDetails');
|
| 514 |
-
const selectedRun = document.getElementById('runSelect').value;
|
| 515 |
-
const runs = selectedRun === 'all' ? trainingData.runs : [trainingData.runs[selectedRun]];
|
| 516 |
-
|
| 517 |
-
let html = '<div class="config-grid">';
|
| 518 |
-
|
| 519 |
-
// Get unique config keys
|
| 520 |
-
const allKeys = new Set();
|
| 521 |
-
runs.forEach(run => {
|
| 522 |
-
if (run.config) {
|
| 523 |
-
Object.keys(run.config).forEach(key => allKeys.add(key));
|
| 524 |
-
}
|
| 525 |
-
});
|
| 526 |
-
|
| 527 |
-
allKeys.forEach(key => {
|
| 528 |
-
const values = runs.map(run => run.config && run.config[key] !== undefined ? run.config[key] : 'N/A');
|
| 529 |
-
const uniqueValues = [...new Set(values)];
|
| 530 |
-
const displayValue = uniqueValues.length === 1 ? uniqueValues[0] : `${uniqueValues.join(' / ')}`;
|
| 531 |
-
|
| 532 |
-
html += `
|
| 533 |
-
<div class="config-item">
|
| 534 |
-
<div class="label">${key.replace(/_/g, ' ').toUpperCase()}</div>
|
| 535 |
-
<div class="value">${displayValue}</div>
|
| 536 |
-
</div>
|
| 537 |
-
`;
|
| 538 |
-
});
|
| 539 |
-
|
| 540 |
-
html += '</div>';
|
| 541 |
-
container.innerHTML = html;
|
| 542 |
-
}
|
| 543 |
-
|
| 544 |
-
// Utility function to format large numbers
|
| 545 |
-
function formatNumber(num) {
|
| 546 |
-
if (num >= 1e9) return (num / 1e9).toFixed(2) + 'B';
|
| 547 |
-
if (num >= 1e6) return (num / 1e6).toFixed(2) + 'M';
|
| 548 |
-
if (num >= 1e3) return (num / 1e3).toFixed(2) + 'K';
|
| 549 |
-
return num.toString();
|
| 550 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plots/data.json
DELETED
|
The diff for this file is too large to render.
See raw diff
|
|
|
plots/index.html
DELETED
|
@@ -1,72 +0,0 @@
|
|
| 1 |
-
<!DOCTYPE html>
|
| 2 |
-
<html lang="en">
|
| 3 |
-
<head>
|
| 4 |
-
<meta charset="UTF-8">
|
| 5 |
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
-
<title>Pico Training Metrics Dashboard</title>
|
| 7 |
-
<link rel="stylesheet" href="style.css">
|
| 8 |
-
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
| 9 |
-
</head>
|
| 10 |
-
<body>
|
| 11 |
-
<div class="container">
|
| 12 |
-
<header>
|
| 13 |
-
<h1>🚀 Pico Training Metrics Dashboard</h1>
|
| 14 |
-
<p>Real-time visualization of training progress across all model runs</p>
|
| 15 |
-
</header>
|
| 16 |
-
|
| 17 |
-
<div class="controls">
|
| 18 |
-
<div class="run-selector">
|
| 19 |
-
<label for="runSelect">Select Run:</label>
|
| 20 |
-
<select id="runSelect">
|
| 21 |
-
<option value="all">All Runs</option>
|
| 22 |
-
</select>
|
| 23 |
-
</div>
|
| 24 |
-
<div class="metric-toggle">
|
| 25 |
-
<label>
|
| 26 |
-
<input type="checkbox" id="showTraining" checked> Training Loss
|
| 27 |
-
</label>
|
| 28 |
-
<label>
|
| 29 |
-
<input type="checkbox" id="showLearningRate" checked> Learning Rate
|
| 30 |
-
</label>
|
| 31 |
-
<label>
|
| 32 |
-
<input type="checkbox" id="showEvaluation" checked> Paloma Evaluation
|
| 33 |
-
</label>
|
| 34 |
-
</div>
|
| 35 |
-
</div>
|
| 36 |
-
|
| 37 |
-
<div class="charts-container">
|
| 38 |
-
<div class="chart-card">
|
| 39 |
-
<h3>📈 Training Loss Over Time</h3>
|
| 40 |
-
<canvas id="lossChart"></canvas>
|
| 41 |
-
</div>
|
| 42 |
-
|
| 43 |
-
<div class="chart-card">
|
| 44 |
-
<h3>🎯 Learning Rate Schedule</h3>
|
| 45 |
-
<canvas id="lrChart"></canvas>
|
| 46 |
-
</div>
|
| 47 |
-
|
| 48 |
-
<div class="chart-card">
|
| 49 |
-
<h3>📊 Paloma Evaluation Metrics</h3>
|
| 50 |
-
<canvas id="evalChart"></canvas>
|
| 51 |
-
</div>
|
| 52 |
-
|
| 53 |
-
<div class="chart-card">
|
| 54 |
-
<h3>🔄 Combined View</h3>
|
| 55 |
-
<canvas id="combinedChart"></canvas>
|
| 56 |
-
</div>
|
| 57 |
-
</div>
|
| 58 |
-
|
| 59 |
-
<div class="run-summary">
|
| 60 |
-
<h3>📋 Run Summary</h3>
|
| 61 |
-
<div id="runSummary"></div>
|
| 62 |
-
</div>
|
| 63 |
-
|
| 64 |
-
<div class="config-details">
|
| 65 |
-
<h3>⚙️ Model Configuration</h3>
|
| 66 |
-
<div id="configDetails"></div>
|
| 67 |
-
</div>
|
| 68 |
-
</div>
|
| 69 |
-
|
| 70 |
-
<script src="code.js"></script>
|
| 71 |
-
</body>
|
| 72 |
-
</html>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
plots/style.css
DELETED
|
@@ -1,258 +0,0 @@
|
|
| 1 |
-
* {
|
| 2 |
-
margin: 0;
|
| 3 |
-
padding: 0;
|
| 4 |
-
box-sizing: border-box;
|
| 5 |
-
}
|
| 6 |
-
|
| 7 |
-
body {
|
| 8 |
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
| 9 |
-
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 10 |
-
min-height: 100vh;
|
| 11 |
-
color: #333;
|
| 12 |
-
}
|
| 13 |
-
|
| 14 |
-
.container {
|
| 15 |
-
max-width: 1400px;
|
| 16 |
-
margin: 0 auto;
|
| 17 |
-
padding: 20px;
|
| 18 |
-
}
|
| 19 |
-
|
| 20 |
-
header {
|
| 21 |
-
text-align: center;
|
| 22 |
-
margin-bottom: 30px;
|
| 23 |
-
color: white;
|
| 24 |
-
}
|
| 25 |
-
|
| 26 |
-
header h1 {
|
| 27 |
-
font-size: 2.5rem;
|
| 28 |
-
margin-bottom: 10px;
|
| 29 |
-
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
|
| 30 |
-
}
|
| 31 |
-
|
| 32 |
-
header p {
|
| 33 |
-
font-size: 1.1rem;
|
| 34 |
-
opacity: 0.9;
|
| 35 |
-
}
|
| 36 |
-
|
| 37 |
-
.controls {
|
| 38 |
-
background: white;
|
| 39 |
-
padding: 20px;
|
| 40 |
-
border-radius: 12px;
|
| 41 |
-
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
| 42 |
-
margin-bottom: 30px;
|
| 43 |
-
display: flex;
|
| 44 |
-
justify-content: space-between;
|
| 45 |
-
align-items: center;
|
| 46 |
-
flex-wrap: wrap;
|
| 47 |
-
gap: 20px;
|
| 48 |
-
}
|
| 49 |
-
|
| 50 |
-
.run-selector select {
|
| 51 |
-
padding: 8px 16px;
|
| 52 |
-
border: 2px solid #e1e5e9;
|
| 53 |
-
border-radius: 8px;
|
| 54 |
-
font-size: 14px;
|
| 55 |
-
background: white;
|
| 56 |
-
cursor: pointer;
|
| 57 |
-
transition: border-color 0.3s ease;
|
| 58 |
-
}
|
| 59 |
-
|
| 60 |
-
.run-selector select:focus {
|
| 61 |
-
outline: none;
|
| 62 |
-
border-color: #667eea;
|
| 63 |
-
}
|
| 64 |
-
|
| 65 |
-
.metric-toggle {
|
| 66 |
-
display: flex;
|
| 67 |
-
gap: 20px;
|
| 68 |
-
flex-wrap: wrap;
|
| 69 |
-
}
|
| 70 |
-
|
| 71 |
-
.metric-toggle label {
|
| 72 |
-
display: flex;
|
| 73 |
-
align-items: center;
|
| 74 |
-
gap: 8px;
|
| 75 |
-
cursor: pointer;
|
| 76 |
-
font-weight: 500;
|
| 77 |
-
color: #555;
|
| 78 |
-
}
|
| 79 |
-
|
| 80 |
-
.metric-toggle input[type="checkbox"] {
|
| 81 |
-
width: 18px;
|
| 82 |
-
height: 18px;
|
| 83 |
-
accent-color: #667eea;
|
| 84 |
-
}
|
| 85 |
-
|
| 86 |
-
.charts-container {
|
| 87 |
-
display: grid;
|
| 88 |
-
grid-template-columns: repeat(auto-fit, minmax(600px, 1fr));
|
| 89 |
-
gap: 30px;
|
| 90 |
-
margin-bottom: 30px;
|
| 91 |
-
}
|
| 92 |
-
|
| 93 |
-
.chart-card {
|
| 94 |
-
background: white;
|
| 95 |
-
padding: 25px;
|
| 96 |
-
border-radius: 12px;
|
| 97 |
-
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
| 98 |
-
transition: transform 0.3s ease, box-shadow 0.3s ease;
|
| 99 |
-
}
|
| 100 |
-
|
| 101 |
-
.chart-card:hover {
|
| 102 |
-
transform: translateY(-5px);
|
| 103 |
-
box-shadow: 0 12px 40px rgba(0,0,0,0.15);
|
| 104 |
-
}
|
| 105 |
-
|
| 106 |
-
.chart-card h3 {
|
| 107 |
-
margin-bottom: 20px;
|
| 108 |
-
color: #333;
|
| 109 |
-
font-size: 1.2rem;
|
| 110 |
-
display: flex;
|
| 111 |
-
align-items: center;
|
| 112 |
-
gap: 8px;
|
| 113 |
-
}
|
| 114 |
-
|
| 115 |
-
.chart-card canvas {
|
| 116 |
-
max-height: 400px;
|
| 117 |
-
width: 100% !important;
|
| 118 |
-
}
|
| 119 |
-
|
| 120 |
-
.run-summary, .config-details {
|
| 121 |
-
background: white;
|
| 122 |
-
padding: 25px;
|
| 123 |
-
border-radius: 12px;
|
| 124 |
-
box-shadow: 0 8px 32px rgba(0,0,0,0.1);
|
| 125 |
-
margin-bottom: 30px;
|
| 126 |
-
}
|
| 127 |
-
|
| 128 |
-
.run-summary h3, .config-details h3 {
|
| 129 |
-
margin-bottom: 20px;
|
| 130 |
-
color: #333;
|
| 131 |
-
font-size: 1.2rem;
|
| 132 |
-
display: flex;
|
| 133 |
-
align-items: center;
|
| 134 |
-
gap: 8px;
|
| 135 |
-
}
|
| 136 |
-
|
| 137 |
-
.run-grid {
|
| 138 |
-
display: grid;
|
| 139 |
-
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
| 140 |
-
gap: 20px;
|
| 141 |
-
}
|
| 142 |
-
|
| 143 |
-
.run-card {
|
| 144 |
-
background: #f8f9fa;
|
| 145 |
-
padding: 20px;
|
| 146 |
-
border-radius: 8px;
|
| 147 |
-
border-left: 4px solid #667eea;
|
| 148 |
-
}
|
| 149 |
-
|
| 150 |
-
.run-card h4 {
|
| 151 |
-
color: #667eea;
|
| 152 |
-
margin-bottom: 10px;
|
| 153 |
-
font-size: 1.1rem;
|
| 154 |
-
}
|
| 155 |
-
|
| 156 |
-
.run-card p {
|
| 157 |
-
margin-bottom: 8px;
|
| 158 |
-
color: #666;
|
| 159 |
-
font-size: 0.9rem;
|
| 160 |
-
}
|
| 161 |
-
|
| 162 |
-
.run-card .metric {
|
| 163 |
-
display: flex;
|
| 164 |
-
justify-content: space-between;
|
| 165 |
-
margin-bottom: 5px;
|
| 166 |
-
}
|
| 167 |
-
|
| 168 |
-
.run-card .metric .value {
|
| 169 |
-
font-weight: 600;
|
| 170 |
-
color: #333;
|
| 171 |
-
}
|
| 172 |
-
|
| 173 |
-
.config-grid {
|
| 174 |
-
display: grid;
|
| 175 |
-
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
| 176 |
-
gap: 15px;
|
| 177 |
-
}
|
| 178 |
-
|
| 179 |
-
.config-item {
|
| 180 |
-
background: #f8f9fa;
|
| 181 |
-
padding: 15px;
|
| 182 |
-
border-radius: 8px;
|
| 183 |
-
text-align: center;
|
| 184 |
-
}
|
| 185 |
-
|
| 186 |
-
.config-item .label {
|
| 187 |
-
font-size: 0.8rem;
|
| 188 |
-
color: #666;
|
| 189 |
-
text-transform: uppercase;
|
| 190 |
-
letter-spacing: 0.5px;
|
| 191 |
-
margin-bottom: 5px;
|
| 192 |
-
}
|
| 193 |
-
|
| 194 |
-
.config-item .value {
|
| 195 |
-
font-size: 1.2rem;
|
| 196 |
-
font-weight: 600;
|
| 197 |
-
color: #333;
|
| 198 |
-
}
|
| 199 |
-
|
| 200 |
-
@media (max-width: 768px) {
|
| 201 |
-
.container {
|
| 202 |
-
padding: 15px;
|
| 203 |
-
}
|
| 204 |
-
|
| 205 |
-
header h1 {
|
| 206 |
-
font-size: 2rem;
|
| 207 |
-
}
|
| 208 |
-
|
| 209 |
-
.controls {
|
| 210 |
-
flex-direction: column;
|
| 211 |
-
align-items: stretch;
|
| 212 |
-
}
|
| 213 |
-
|
| 214 |
-
.charts-container {
|
| 215 |
-
grid-template-columns: 1fr;
|
| 216 |
-
}
|
| 217 |
-
|
| 218 |
-
.chart-card {
|
| 219 |
-
padding: 20px;
|
| 220 |
-
}
|
| 221 |
-
|
| 222 |
-
.run-grid, .config-grid {
|
| 223 |
-
grid-template-columns: 1fr;
|
| 224 |
-
}
|
| 225 |
-
}
|
| 226 |
-
|
| 227 |
-
/* Chart.js customizations */
|
| 228 |
-
.chartjs-tooltip {
|
| 229 |
-
background: rgba(0,0,0,0.8) !important;
|
| 230 |
-
color: white !important;
|
| 231 |
-
border-radius: 8px !important;
|
| 232 |
-
padding: 10px !important;
|
| 233 |
-
font-size: 12px !important;
|
| 234 |
-
}
|
| 235 |
-
|
| 236 |
-
/* Loading state */
|
| 237 |
-
.loading {
|
| 238 |
-
text-align: center;
|
| 239 |
-
padding: 40px;
|
| 240 |
-
color: #666;
|
| 241 |
-
}
|
| 242 |
-
|
| 243 |
-
.loading::after {
|
| 244 |
-
content: '';
|
| 245 |
-
display: inline-block;
|
| 246 |
-
width: 20px;
|
| 247 |
-
height: 20px;
|
| 248 |
-
border: 3px solid #f3f3f3;
|
| 249 |
-
border-top: 3px solid #667eea;
|
| 250 |
-
border-radius: 50%;
|
| 251 |
-
animation: spin 1s linear infinite;
|
| 252 |
-
margin-left: 10px;
|
| 253 |
-
}
|
| 254 |
-
|
| 255 |
-
@keyframes spin {
|
| 256 |
-
0% { transform: rotate(0deg); }
|
| 257 |
-
100% { transform: rotate(360deg); }
|
| 258 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|