mrdbourke's picture
Update index.html
b638f8e verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ML Model Memory Calculator</title>
<style>
:root {
--primary-color: #4a6fa5;
--secondary-color: #166088;
--accent-color: #4fc3a1;
--background-color: #f8f9fa;
--card-color: #ffffff;
--text-color: #333333;
--light-gray: #f0f0f0;
--border-color: #dee2e6;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
line-height: 1.6;
color: var(--text-color);
background-color: var(--background-color);
margin: 0;
padding: 20px;
}
.container {
max-width: 900px;
margin: 0 auto;
padding: 20px;
background-color: var(--card-color);
border-radius: 8px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
h1 {
color: var(--primary-color);
text-align: center;
margin-bottom: 20px;
}
.input-section {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 30px;
background-color: var(--light-gray);
padding: 20px;
border-radius: 8px;
}
.input-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
align-items: center;
}
label {
font-weight: 600;
min-width: 180px;
}
input {
flex: 1;
padding: 10px;
border: 1px solid var(--border-color);
border-radius: 4px;
font-size: 16px;
}
.buttons {
display: flex;
gap: 10px;
margin-top: 10px;
}
button {
padding: 10px 20px;
background-color: var(--primary-color);
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
transition: background-color 0.2s;
}
button:hover {
background-color: var(--secondary-color);
}
.preset-buttons {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-top: 15px;
}
.preset-button {
background-color: var(--accent-color);
padding: 8px 12px;
font-size: 14px;
}
.preset-button:hover {
background-color: #3da58a;
}
#results-container {
margin-top: 20px;
overflow-x: auto;
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 10px;
table-layout: fixed;
}
th, td {
padding: 12px 15px;
text-align: left;
border-bottom: 1px solid var(--border-color);
}
th {
background-color: var(--primary-color);
color: white;
position: sticky;
top: 0;
}
tr:nth-child(even) {
background-color: var(--light-gray);
}
.tooltip {
position: relative;
display: inline-block;
cursor: help;
margin-left: 5px;
}
.tooltip .tooltiptext {
visibility: hidden;
width: 280px;
background-color: #555;
color: #fff;
text-align: left;
border-radius: 6px;
padding: 8px;
position: absolute;
z-index: 1;
bottom: 125%;
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.3s;
font-size: 14px;
}
.tooltip:hover .tooltiptext {
visibility: visible;
opacity: 1;
}
.model-size {
font-size: 18px;
font-weight: bold;
text-align: center;
margin: 15px 0;
color: var(--secondary-color);
}
@media (max-width: 768px) {
.input-group {
flex-direction: column;
align-items: flex-start;
}
input {
width: 100%;
}
.buttons {
flex-direction: column;
}
}
footer {
text-align: center;
margin-top: 30px;
font-size: 14px;
color: #6c757d;
}
</style>
</head>
<body>
<div class="container">
<h1>ML Model Memory Calculator</h1>
<div class="input-section">
<div class="input-group">
<label for="parameters">Number of Parameters:</label>
<input type="text" id="parameters" placeholder="e.g., 7000000000 for 7B">
<div class="tooltip">
<span class="tooltiptext">Enter the total number of parameters in your model. For example, use 7000000000 for a 7B parameter model.</span>
</div>
</div>
<div class="buttons">
<button id="calculate-btn">Calculate</button>
<button id="clear-btn">Clear</button>
</div>
<div class="preset-buttons">
<span>Presets: </span>
<button class="preset-button" data-value="200000000">200M</button>
<button class="preset-button" data-value="500000000">500M</button>
<button class="preset-button" data-value="1000000000">1B</button>
<button class="preset-button" data-value="2000000000">2B</button>
<button class="preset-button" data-value="7000000000">7B</button>
<button class="preset-button" data-value="13000000000">13B</button>
<button class="preset-button" data-value="34000000000">34B</button>
<button class="preset-button" data-value="70000000000">70B</button>
<button class="preset-button" data-value="175000000000">175B</button>
</div>
</div>
<div id="model-size" class="model-size"></div>
<div id="results-container">
<table id="results-table">
<thead>
<tr>
<th>Precision</th>
<th>Bytes/Param</th>
<th>Memory</th>
<th>MB</th>
<th>GB</th>
<th>TB</th>
</tr>
</thead>
<tbody id="results-body">
<!-- Results will be populated here -->
</tbody>
</table>
</div>
<footer>
<p>A simple tool to estimate the memory requirements for ML models of different sizes and precision types.</p>
</footer>
</div>
<script>
// Model memory calculation function
function calculateModelMemory(numParameters) {
// Define bytes per parameter for each precision type
const precisionTypes = {
"float32": 4,
"float16": 2,
"bfloat16": 2,
"int8": 1,
"int4": 0.5,
"int2": 0.25,
"int1": 0.125
};
const results = {};
// Calculate memory for each precision type
for (const [precision, bytesPerParam] of Object.entries(precisionTypes)) {
const totalBytes = numParameters * bytesPerParam;
results[precision] = {
"bytesPerParam": bytesPerParam,
"bytes": totalBytes,
"KB": totalBytes / 1024,
"MB": totalBytes / (1024**2),
"GB": totalBytes / (1024**3),
"TB": totalBytes / (1024**4)
};
}
// Add human-readable summary for each precision type
for (const precision in precisionTypes) {
const memoryValues = results[precision];
let summary;
if (memoryValues.TB >= 1) {
summary = `${memoryValues.TB.toFixed(2)} TB (${memoryValues.GB.toFixed(2)} GB)`;
} else if (memoryValues.GB >= 1) {
summary = `${memoryValues.GB.toFixed(2)} GB (${memoryValues.MB.toFixed(2)} MB)`;
} else if (memoryValues.MB >= 1) {
summary = `${memoryValues.MB.toFixed(2)} MB (${memoryValues.KB.toFixed(2)} KB)`;
} else {
summary = `${memoryValues.KB.toFixed(2)} KB (${memoryValues.bytes.toFixed(2)} bytes)`;
}
results[precision].summary = summary;
}
// Add model size in billions for reference
results.modelSize = `${(numParameters/1e9).toFixed(2)}B parameters`;
return results;
}
// Format numbers with commas
function formatNumber(num) {
return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
// Calculate and display results
function calculateAndDisplay() {
const parametersInput = document.getElementById('parameters').value.trim();
const modelSizeElement = document.getElementById('model-size');
const resultsBody = document.getElementById('results-body');
// Clear previous results
resultsBody.innerHTML = '';
modelSizeElement.innerHTML = '';
// Validate input
if (!parametersInput) {
alert('Please enter the number of parameters.');
return;
}
// Parse and normalize input (remove commas)
const numParameters = parseFloat(parametersInput.replace(/,/g, ''));
if (isNaN(numParameters) || numParameters <= 0) {
alert('Please enter a valid positive number for parameters.');
return;
}
// Calculate memory requirements
const results = calculateModelMemory(numParameters);
// Display model size with both millions and billions
const sizeInBillions = numParameters / 1e9;
const sizeInMillions = numParameters / 1e6;
modelSizeElement.textContent = `Showing requirements for a ${sizeInBillions.toFixed(2)}B (${sizeInMillions.toFixed(2)}M) parameter model`;
// Sort precision types by size (largest first)
const precisionOrder = [
'float32', 'float16', 'bfloat16', 'int8', 'int4', 'int2', 'int1'
];
// Populate results table
precisionOrder.forEach(precision => {
const data = results[precision];
const row = document.createElement('tr');
row.innerHTML = `
<td>${precision}</td>
<td>${data.bytesPerParam} bytes</td>
<td>${data.summary}</td>
<td>${data.MB.toFixed(2)}</td>
<td>${data.GB.toFixed(2)}</td>
<td>${data.TB.toFixed(2)}</td>
`;
resultsBody.appendChild(row);
});
}
// Event listeners
document.getElementById('calculate-btn').addEventListener('click', calculateAndDisplay);
document.getElementById('clear-btn').addEventListener('click', () => {
document.getElementById('parameters').value = '';
document.getElementById('results-body').innerHTML = '';
document.getElementById('model-size').innerHTML = '';
});
// Add event listeners to preset buttons
document.querySelectorAll('.preset-button').forEach(button => {
button.addEventListener('click', () => {
document.getElementById('parameters').value = button.dataset.value;
calculateAndDisplay();
});
});
// Allow Enter key to trigger calculation
document.getElementById('parameters').addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
calculateAndDisplay();
}
});
// Prevent non-numeric input (but allow some special characters)
document.getElementById('parameters').addEventListener('input', (e) => {
const input = e.target;
input.value = input.value.replace(/[^0-9.,eE+-]/g, '');
});
</script>
</body>
</html>