Auto calculate range size for easier calculation
Browse files- index.html +113 -35
index.html
CHANGED
@@ -14,7 +14,7 @@
|
|
14 |
align-items: center;
|
15 |
min-height: 100vh;
|
16 |
}
|
17 |
-
|
18 |
background-color: #f9f9f9;
|
19 |
padding: 20px;
|
20 |
border-radius: 8px;
|
@@ -34,7 +34,8 @@
|
|
34 |
label {
|
35 |
font-weight: bold;
|
36 |
margin-bottom: 5px;
|
37 |
-
display: block;
|
|
|
38 |
}
|
39 |
input {
|
40 |
width: 100%;
|
@@ -52,11 +53,6 @@
|
|
52 |
cursor: pointer;
|
53 |
font-weight: bold;
|
54 |
}
|
55 |
-
.checkbox-container {
|
56 |
-
display: flex;
|
57 |
-
align-items: center;
|
58 |
-
white-space: nowrap;
|
59 |
-
}
|
60 |
button:hover {
|
61 |
background-color: #2563eb;
|
62 |
}
|
@@ -75,6 +71,24 @@
|
|
75 |
white-space: pre-wrap;
|
76 |
word-wrap: break-word;
|
77 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
78 |
</style>
|
79 |
</head>
|
80 |
<body>
|
@@ -82,13 +96,17 @@
|
|
82 |
<h1>YAML Config Generator</h1>
|
83 |
<p style="font-weight: bold">Credit: mlabonne</p>
|
84 |
<form id="configForm">
|
85 |
-
<div>
|
86 |
-
<label for="rangeSize">Range Size:</label>
|
87 |
-
<input type="number" id="rangeSize" name="rangeSize" required placeholder="Range size (e.g. 42)">
|
88 |
-
</div>
|
89 |
<div>
|
90 |
<label for="totalLayers">Total Layers:</label>
|
91 |
-
<input type="number" id="totalLayers" name="totalLayers" required placeholder="Total number of layers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
</div>
|
93 |
<div>
|
94 |
<label for="nbParameters">Number of Parameters (B):</label>
|
@@ -98,9 +116,9 @@
|
|
98 |
<label for="model">Model:</label>
|
99 |
<input type="text" id="model" name="model" required placeholder="Model name (e.g. meta-llama/Meta-Llama-3.1-405B-Instruct)">
|
100 |
</div>
|
101 |
-
<div class="checkbox-container">
|
102 |
<label for="doWhatISay">Do what I say:</label>
|
103 |
-
<input
|
104 |
</div>
|
105 |
<button type="submit">Generate Config</button>
|
106 |
</form>
|
@@ -109,8 +127,14 @@
|
|
109 |
<h2>Results:</h2>
|
110 |
<p id="newSize"></p>
|
111 |
<p id="newParam"></p>
|
112 |
-
<
|
113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
</div>
|
115 |
</div>
|
116 |
|
@@ -118,44 +142,91 @@
|
|
118 |
document.getElementById('configForm').addEventListener('submit', function(e) {
|
119 |
e.preventDefault();
|
120 |
|
121 |
-
const rangeSize = parseInt(document.getElementById('rangeSize').value);
|
122 |
const totalLayers = parseInt(document.getElementById('totalLayers').value);
|
|
|
|
|
123 |
const nbParameters = parseFloat(document.getElementById('nbParameters').value);
|
124 |
const model = document.getElementById('model').value;
|
125 |
const doWhatISay = document.getElementById('doWhatISay').checked;
|
126 |
|
127 |
const errorDiv = document.getElementById('error');
|
128 |
const resultDiv = document.getElementById('result');
|
|
|
129 |
errorDiv.innerHTML = '';
|
130 |
errorDiv.style.display = 'none';
|
131 |
resultDiv.style.display = 'none';
|
|
|
132 |
|
133 |
const errors = [];
|
134 |
|
135 |
-
if (isNaN(
|
136 |
-
errors.push("
|
137 |
}
|
138 |
|
139 |
-
if (
|
140 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
141 |
}
|
142 |
|
143 |
if (isNaN(nbParameters) || nbParameters <= 0) {
|
144 |
errors.push("Number of Parameters must be a positive number.");
|
145 |
}
|
146 |
|
147 |
-
if (rangeSize > totalLayers) {
|
148 |
-
errors.push("Range Size cannot be greater than Total Layers.");
|
149 |
-
}
|
150 |
-
|
151 |
if (model.trim() === "") {
|
152 |
errors.push("Model name cannot be empty.");
|
153 |
}
|
154 |
|
155 |
-
if (!doWhatISay && totalLayers % rangeSize
|
156 |
errors.push("There are layers left after the main loop.");
|
157 |
}
|
158 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
159 |
let newSize = totalLayers + totalLayers - rangeSize;
|
160 |
let newParam = (nbParameters / totalLayers) * newSize;
|
161 |
|
@@ -163,8 +234,8 @@
|
|
163 |
|
164 |
for (let i = 0; i <= totalLayers - rangeSize; i += rangeSize / 2) {
|
165 |
let start = i;
|
166 |
-
if (!doWhatISay
|
167 |
-
|
168 |
} else {
|
169 |
let end = Math.min(start + rangeSize, totalLayers);
|
170 |
yamlStr += `- sources:\n`;
|
@@ -174,7 +245,7 @@
|
|
174 |
}
|
175 |
|
176 |
// Check if there are remaining layers
|
177 |
-
if (totalLayers % rangeSize
|
178 |
let start = totalLayers - (totalLayers % rangeSize);
|
179 |
let end = totalLayers;
|
180 |
yamlStr += `- sources:\n`;
|
@@ -182,18 +253,25 @@
|
|
182 |
yamlStr += ` model: ${model}\n`;
|
183 |
}
|
184 |
|
185 |
-
if (errors.length > 0) {
|
186 |
-
errorDiv.innerHTML = errors.join('<br>');
|
187 |
-
errorDiv.style.display = 'block';
|
188 |
-
return;
|
189 |
-
}
|
190 |
yamlStr += "merge_method: passthrough\n";
|
191 |
yamlStr += "dtype: bfloat16\n";
|
192 |
|
193 |
document.getElementById('newSize').textContent = `New size = ${newSize} layers`;
|
194 |
document.getElementById('newParam').textContent = `New parameters = ${newParam.toFixed(2)}B`;
|
195 |
document.getElementById('yamlOutput').textContent = yamlStr;
|
196 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
197 |
});
|
198 |
</script>
|
199 |
</body>
|
|
|
14 |
align-items: center;
|
15 |
min-height: 100vh;
|
16 |
}
|
17 |
+
.container {
|
18 |
background-color: #f9f9f9;
|
19 |
padding: 20px;
|
20 |
border-radius: 8px;
|
|
|
34 |
label {
|
35 |
font-weight: bold;
|
36 |
margin-bottom: 5px;
|
37 |
+
display: inline-block;
|
38 |
+
vertical-align: middle;
|
39 |
}
|
40 |
input {
|
41 |
width: 100%;
|
|
|
53 |
cursor: pointer;
|
54 |
font-weight: bold;
|
55 |
}
|
|
|
|
|
|
|
|
|
|
|
56 |
button:hover {
|
57 |
background-color: #2563eb;
|
58 |
}
|
|
|
71 |
white-space: pre-wrap;
|
72 |
word-wrap: break-word;
|
73 |
}
|
74 |
+
#possible-range-sizes {
|
75 |
+
margin-top: 20px;
|
76 |
+
}
|
77 |
+
.clickable {
|
78 |
+
cursor: pointer;
|
79 |
+
color: #3b82f6;
|
80 |
+
text-decoration: underline;
|
81 |
+
}
|
82 |
+
.checkbox-container {
|
83 |
+
display: flex;
|
84 |
+
align-items: center;
|
85 |
+
}
|
86 |
+
|
87 |
+
.checkbox-container label {
|
88 |
+
flex: 1;
|
89 |
+
white-space: nowrap;
|
90 |
+
margin-right: 10px;
|
91 |
+
}
|
92 |
</style>
|
93 |
</head>
|
94 |
<body>
|
|
|
96 |
<h1>YAML Config Generator</h1>
|
97 |
<p style="font-weight: bold">Credit: mlabonne</p>
|
98 |
<form id="configForm">
|
|
|
|
|
|
|
|
|
99 |
<div>
|
100 |
<label for="totalLayers">Total Layers:</label>
|
101 |
+
<input type="number" id="totalLayers" name="totalLayers" required placeholder="Total number of layers">
|
102 |
+
</div>
|
103 |
+
<div class="checkbox-container">
|
104 |
+
<label for="autoRangeSize">Auto Range Size:</label>
|
105 |
+
<input type="checkbox" id="autoRangeSize" name="autoRangeSize">
|
106 |
+
</div>
|
107 |
+
<div id="range-size-input" style="display: none;">
|
108 |
+
<label for="rangeSize">Range Size:</label>
|
109 |
+
<input type="number" id="rangeSize" name="rangeSize" placeholder="Range size (e.g. 42)">
|
110 |
</div>
|
111 |
<div>
|
112 |
<label for="nbParameters">Number of Parameters (B):</label>
|
|
|
116 |
<label for="model">Model:</label>
|
117 |
<input type="text" id="model" name="model" required placeholder="Model name (e.g. meta-llama/Meta-Llama-3.1-405B-Instruct)">
|
118 |
</div>
|
119 |
+
<div class="checkbox-container" id="god-mode">
|
120 |
<label for="doWhatISay">Do what I say:</label>
|
121 |
+
<input type="checkbox" id="doWhatISay" name="doWhatISay">
|
122 |
</div>
|
123 |
<button type="submit">Generate Config</button>
|
124 |
</form>
|
|
|
127 |
<h2>Results:</h2>
|
128 |
<p id="newSize"></p>
|
129 |
<p id="newParam"></p>
|
130 |
+
<div id="yaml-config-section" style="display: none;">
|
131 |
+
<h3>YAML Config:</h3>
|
132 |
+
<pre id="yamlOutput"></pre>
|
133 |
+
</div>
|
134 |
+
</div>
|
135 |
+
<div id="possible-range-sizes" style="display: none;">
|
136 |
+
<h2>Possible Range Sizes:</h2>
|
137 |
+
<ul id="possible-range-sizes-list"></ul>
|
138 |
</div>
|
139 |
</div>
|
140 |
|
|
|
142 |
document.getElementById('configForm').addEventListener('submit', function(e) {
|
143 |
e.preventDefault();
|
144 |
|
|
|
145 |
const totalLayers = parseInt(document.getElementById('totalLayers').value);
|
146 |
+
const autoRangeSize = document.getElementById('autoRangeSize').checked;
|
147 |
+
const rangeSize = autoRangeSize? null : parseInt(document.getElementById('rangeSize').value);
|
148 |
const nbParameters = parseFloat(document.getElementById('nbParameters').value);
|
149 |
const model = document.getElementById('model').value;
|
150 |
const doWhatISay = document.getElementById('doWhatISay').checked;
|
151 |
|
152 |
const errorDiv = document.getElementById('error');
|
153 |
const resultDiv = document.getElementById('result');
|
154 |
+
const possibleRangeSizesDiv = document.getElementById('possible-range-sizes');
|
155 |
errorDiv.innerHTML = '';
|
156 |
errorDiv.style.display = 'none';
|
157 |
resultDiv.style.display = 'none';
|
158 |
+
possibleRangeSizesDiv.style.display = 'none';
|
159 |
|
160 |
const errors = [];
|
161 |
|
162 |
+
if (isNaN(totalLayers) || totalLayers <= 0 ||!Number.isInteger(totalLayers)) {
|
163 |
+
errors.push("Total Layers must be a positive integer.");
|
164 |
}
|
165 |
|
166 |
+
if (!autoRangeSize) {
|
167 |
+
if (isNaN(rangeSize) || rangeSize <= 0 ||!Number.isInteger(rangeSize)) {
|
168 |
+
errors.push("Range Size must be a positive integer.");
|
169 |
+
}
|
170 |
+
|
171 |
+
if (rangeSize > totalLayers) {
|
172 |
+
errors.push("Range Size cannot be greater than Total Layers.");
|
173 |
+
}
|
174 |
}
|
175 |
|
176 |
if (isNaN(nbParameters) || nbParameters <= 0) {
|
177 |
errors.push("Number of Parameters must be a positive number.");
|
178 |
}
|
179 |
|
|
|
|
|
|
|
|
|
180 |
if (model.trim() === "") {
|
181 |
errors.push("Model name cannot be empty.");
|
182 |
}
|
183 |
|
184 |
+
if (!doWhatISay && totalLayers % (autoRangeSize? calculatePossibleRangeSize(totalLayers, doWhatISay)[0] : rangeSize)!== 0) {
|
185 |
errors.push("There are layers left after the main loop.");
|
186 |
}
|
187 |
|
188 |
+
if (errors.length > 0) {
|
189 |
+
errorDiv.innerHTML = errors.join('<br>');
|
190 |
+
errorDiv.style.display = 'block';
|
191 |
+
return;
|
192 |
+
}
|
193 |
+
|
194 |
+
if (autoRangeSize) {
|
195 |
+
const possibleRangeSizes = calculatePossibleRangeSize(totalLayers, doWhatISay);
|
196 |
+
const possibleRangeSizesList = document.getElementById('possible-range-sizes-list');
|
197 |
+
possibleRangeSizesList.innerHTML = '';
|
198 |
+
possibleRangeSizes.forEach(size => {
|
199 |
+
const listItem = document.createElement('li');
|
200 |
+
const link = document.createElement('a');
|
201 |
+
link.textContent = `${size}`;
|
202 |
+
link.className = 'clickable';
|
203 |
+
link.addEventListener('click', function() {
|
204 |
+
generateConfig(totalLayers, size, nbParameters, model, doWhatISay);
|
205 |
+
possibleRangeSizesDiv.style.display = 'none';
|
206 |
+
});
|
207 |
+
listItem.appendChild(link);
|
208 |
+
possibleRangeSizesList.appendChild(listItem);
|
209 |
+
});
|
210 |
+
possibleRangeSizesDiv.style.display = 'block';
|
211 |
+
} else {
|
212 |
+
generateConfig(totalLayers, rangeSize, nbParameters, model, doWhatISay);
|
213 |
+
}
|
214 |
+
});
|
215 |
+
|
216 |
+
function calculatePossibleRangeSize(totalLayers, doWhatISay) {
|
217 |
+
const possibleRangeSizes = [];
|
218 |
+
for (let rangeSize = 1; rangeSize <= totalLayers; rangeSize++) {
|
219 |
+
if (totalLayers % rangeSize === 0) {
|
220 |
+
if (!doWhatISay && rangeSize % 2!== 0) {
|
221 |
+
continue; // skip odd range sizes if doWhatISay is false
|
222 |
+
}
|
223 |
+
possibleRangeSizes.push(rangeSize);
|
224 |
+
}
|
225 |
+
}
|
226 |
+
return possibleRangeSizes;
|
227 |
+
}
|
228 |
+
|
229 |
+
function generateConfig(totalLayers, rangeSize, nbParameters, model, doWhatISay) {
|
230 |
let newSize = totalLayers + totalLayers - rangeSize;
|
231 |
let newParam = (nbParameters / totalLayers) * newSize;
|
232 |
|
|
|
234 |
|
235 |
for (let i = 0; i <= totalLayers - rangeSize; i += rangeSize / 2) {
|
236 |
let start = i;
|
237 |
+
if (!doWhatISay &&!Number.isInteger(start)) {
|
238 |
+
console.error("The layer range contains non integer");
|
239 |
} else {
|
240 |
let end = Math.min(start + rangeSize, totalLayers);
|
241 |
yamlStr += `- sources:\n`;
|
|
|
245 |
}
|
246 |
|
247 |
// Check if there are remaining layers
|
248 |
+
if (totalLayers % rangeSize!== 0) {
|
249 |
let start = totalLayers - (totalLayers % rangeSize);
|
250 |
let end = totalLayers;
|
251 |
yamlStr += `- sources:\n`;
|
|
|
253 |
yamlStr += ` model: ${model}\n`;
|
254 |
}
|
255 |
|
|
|
|
|
|
|
|
|
|
|
256 |
yamlStr += "merge_method: passthrough\n";
|
257 |
yamlStr += "dtype: bfloat16\n";
|
258 |
|
259 |
document.getElementById('newSize').textContent = `New size = ${newSize} layers`;
|
260 |
document.getElementById('newParam').textContent = `New parameters = ${newParam.toFixed(2)}B`;
|
261 |
document.getElementById('yamlOutput').textContent = yamlStr;
|
262 |
+
document.getElementById('yaml-config-section').style.display = 'block';
|
263 |
+
document.getElementById('result').style.display = 'block';
|
264 |
+
}
|
265 |
+
|
266 |
+
document.getElementById('autoRangeSize').addEventListener('change', function() {
|
267 |
+
if (this.checked) {
|
268 |
+
document.getElementById('range-size-input').style.display = 'none';
|
269 |
+
document.getElementById('god-mode').style.display = 'none';
|
270 |
+
} else {
|
271 |
+
document.getElementById('range-size-input').style.display = 'block';
|
272 |
+
document.getElementById('god-mode').style.display = 'flex';
|
273 |
+
|
274 |
+
}
|
275 |
});
|
276 |
</script>
|
277 |
</body>
|