mirror of
https://github.com/hanzoai/datastore.git
synced 2026-09-26 13:55:07 +00:00
149 lines
6.9 KiB
HTML
149 lines
6.9 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Merge Selector Lab</title>
|
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
|
|
<script src="https://d3js.org/d3.v7.min.js"></script>
|
|
<style>
|
|
#trainButton {
|
|
width: 100%;
|
|
position: relative;
|
|
overflow: hidden;
|
|
color: white;
|
|
background-color: #007bff;
|
|
border: none;
|
|
}
|
|
#trainButton .progress-fill {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
height: 100%;
|
|
background-color: rgba(255, 255, 255, 0.3); /* Transparent overlay */
|
|
width: 0;
|
|
transition: width 0.1s linear; /* Smooth progress */
|
|
}
|
|
#downloadButton {
|
|
display: none;
|
|
margin-top: 1rem;
|
|
width: 100%;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container-fluid">
|
|
<form id="param-form" class="p-3">
|
|
<div class="row">
|
|
<div class="form-group col-md-4">
|
|
<label for="minPartSize">Min part size:</label>
|
|
<input type="text" class="form-control form-control-sm" id="minPartSize" placeholder="Minimum size" value="64KB">
|
|
</div>
|
|
<div class="form-group col-md-4">
|
|
<label for="maxPartSize">Max part size:</label>
|
|
<input type="text" class="form-control form-control-sm" id="maxPartSize" placeholder="Maximum size" value="256GB">
|
|
</div>
|
|
<div class="form-group col-md-4">
|
|
<label for="maxWorkers">Max workers:</label>
|
|
<input type="text" class="form-control form-control-sm" id="maxWorkers" placeholder="Maximum workers" value="32768">
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="form-group col-md-4">
|
|
<label for="partsStep">Part size step:</label>
|
|
<input type="text" class="form-control form-control-sm" id="partsStep" placeholder="Power of 2 exponent" value="0.25">
|
|
</div>
|
|
<div class="form-group col-md-4">
|
|
<label for="workersStep">Workers step:</label>
|
|
<input type="text" class="form-control form-control-sm" id="workersStep" placeholder="Power of 2 exponent" value="0.25">
|
|
</div>
|
|
</div>
|
|
<div class="row mt-3">
|
|
<div class="col">
|
|
<button type="button" class="btn btn-primary" id="trainButton">
|
|
<span id="trainButtonText">Train</span>
|
|
<div class="progress-fill"></div>
|
|
</button>
|
|
<button type="button" class="btn btn-success" id="downloadButton">Download</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
|
|
<script type="module">
|
|
import { MergeTree } from './MergeTree.js';
|
|
import { SimulationContainer } from './SimulationContainer.js';
|
|
import { sequenceInserter } from './sequenceInserter.js';
|
|
import { floatLayerMerges } from './floatLayerMerges.js';
|
|
import { subgradientMethod } from './gradientDescent.js';
|
|
import { mergeModel } from './mergeModel.js';
|
|
import { ModelSolver } from './ModelSolver.js';
|
|
import { delayMs, parseHumanReadableSize } from './util.js';
|
|
|
|
function readSize(name) {
|
|
return parseHumanReadableSize(document.getElementById(name).value);
|
|
}
|
|
|
|
function readParams() {
|
|
let params = {
|
|
minPartSize: readSize('minPartSize'),
|
|
maxPartSize: readSize('maxPartSize'),
|
|
maxWorkers: readSize('maxWorkers'),
|
|
partsStep: readSize('partsStep'),
|
|
workersStep: readSize('workersStep'),
|
|
};
|
|
console.log("PARAMS", params);
|
|
return params;
|
|
}
|
|
|
|
document.getElementById('trainButton').addEventListener('click', async () => {
|
|
const trainButton = document.getElementById('trainButton');
|
|
const progressFill = trainButton.querySelector('.progress-fill');
|
|
const trainButtonText = document.getElementById('trainButtonText');
|
|
const downloadButton = document.getElementById('downloadButton');
|
|
|
|
trainButton.disabled = true;
|
|
trainButtonText.textContent = 'Training...';
|
|
progressFill.style.width = '0%';
|
|
downloadButton.style.display = 'none';
|
|
|
|
const { minPartSize, maxPartSize, maxWorkers, partsStep, workersStep } = readParams();
|
|
|
|
let solver = new ModelSolver(mergeModel);
|
|
await solver.train(minPartSize, maxPartSize, maxWorkers, partsStep, workersStep, subgradientMethod,
|
|
async function onProgress({progress, runs_done, runs_total}) {
|
|
// Update progress bar (button background)
|
|
progressFill.style.width = `${progress}%`;
|
|
trainButtonText.textContent = `Training: ${progress}% — ${runs_done}/${runs_total}`;
|
|
await delayMs(1);
|
|
});
|
|
console.log(solver.data);
|
|
|
|
trainButtonText.textContent = 'Train Again';
|
|
trainButton.disabled = false;
|
|
|
|
// Show the download button
|
|
downloadButton.style.display = 'block';
|
|
|
|
// Set up download functionality
|
|
downloadButton.addEventListener('click', () => {
|
|
const data = solver.serializeData();
|
|
const blob = new Blob([data], { type: 'application/json' });
|
|
const url = URL.createObjectURL(blob);
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
let params = [
|
|
document.getElementById('minPartSize').value,
|
|
document.getElementById('maxPartSize').value,
|
|
document.getElementById('maxWorkers').value,
|
|
'x' + (1.0 / +document.getElementById('partsStep').value),
|
|
'x' + (1.0 / +document.getElementById('workersStep').value),
|
|
];
|
|
link.download = `solver-${params.join('_')}.json`;
|
|
link.click();
|
|
URL.revokeObjectURL(url);
|
|
}, { once: true });
|
|
});
|
|
</script>
|
|
</body>
|
|
</html>
|