File size: 8,719 Bytes
26d6e68
 
 
 
 
 
8dd60ea
26d6e68
 
 
 
3c5f7cb
26d6e68
 
 
c5a77e0
e216b1a
 
 
 
 
d660875
e216b1a
 
26d6e68
 
 
 
 
 
 
 
 
e216b1a
bb6f38a
e216b1a
3c5f7cb
26d6e68
 
 
 
 
 
 
e216b1a
 
 
 
 
 
 
 
26d6e68
 
 
 
 
 
 
 
e216b1a
 
26d6e68
 
3c5f7cb
26d6e68
 
 
e216b1a
26d6e68
 
 
e216b1a
26d6e68
 
 
e216b1a
 
26d6e68
 
e216b1a
 
 
 
 
 
 
 
26d6e68
 
 
 
 
 
 
 
 
 
e216b1a
143e9f4
26d6e68
 
e216b1a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f6d9192
 
 
 
5cd151e
f6d9192
e216b1a
 
f6d9192
e216b1a
 
 
26d6e68
 
 
 
143e9f4
26d6e68
 
e216b1a
 
143e9f4
 
 
 
 
 
26d6e68
 
3c5f7cb
00bfd8c
 
3c5f7cb
 
 
 
 
 
 
26d6e68
 
 
 
 
 
e216b1a
 
 
 
 
 
 
 
 
 
 
 
 
26d6e68
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>YAML Config Generator</title>
    <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
    <div class="container">
        <h1>YAML Config Generator</h1>
        <p style="font-weight: bold">Credit: mlabonne</p>
        <form id="configForm">
            <div>
                <label for="totalLayers">Total Layers:</label>
                <input type="number" id="totalLayers" name="totalLayers" required placeholder="Total number of layers (e.g. 126)">
            </div>
            <div class="checkbox-container">
                <label for="autoRangeSize">Auto Range Size:</label>
                <input type="checkbox" id="autoRangeSize" name="autoRangeSize">
            </div>
            <div id="range-size-input" style="display: block;">
                <label for="rangeSize">Range Size:</label>
                <input type="number" id="rangeSize" name="rangeSize" placeholder="Range size (e.g. 42)">
            </div>
            <div>
                <label for="nbParameters">Number of Parameters (B):</label>
                <input type="number" id="nbParameters" name="nbParameters" step="0.01" required placeholder="Number of parameters in the model (e.g. 410.0)">
            </div>
            <div>
                <label for="model">Model:</label>
                <input type="text" id="model" name="model" required placeholder="Model name (e.g. meta-llama/Meta-Llama-3.1-405B-Instruct)">
            </div>
            <div class="checkbox-container" id="god-mode">
                <label for="doWhatISay">Do what I say:</label>
                <input type="checkbox" id="doWhatISay" name="doWhatISay">
            </div>
            <button type="submit">Generate Config</button>
        </form>
        <div id="error" style="display: none;"></div>
        <div id="result" style="display: none;">
            <h2>Results:</h2>
            <p id="newSize"></p>
            <p id="newParam"></p>
            <div id="yaml-config-section" style="display: none;">
                <h3>YAML Config:</h3>
                <pre id="yamlOutput"></pre>
            </div>
        </div>
        <div id="possible-range-sizes" style="display: none;">
            <h2>Possible Range Sizes:</h2>
            <ul id="possible-range-sizes-list"></ul>
        </div>
    </div>

    <script>
        document.getElementById('configForm').addEventListener('submit', function(e) {
            e.preventDefault();
            
            const totalLayers = parseInt(document.getElementById('totalLayers').value);
            const autoRangeSize = document.getElementById('autoRangeSize').checked;
            const rangeSize = autoRangeSize? null : parseInt(document.getElementById('rangeSize').value);
            const nbParameters = parseFloat(document.getElementById('nbParameters').value);
            const model = document.getElementById('model').value;
            const doWhatISay = document.getElementById('doWhatISay').checked;

            const errorDiv = document.getElementById('error');
            const resultDiv = document.getElementById('result');
            const possibleRangeSizesDiv = document.getElementById('possible-range-sizes');
            errorDiv.innerHTML = '';
            errorDiv.style.display = 'none';
            resultDiv.style.display = 'none';
            possibleRangeSizesDiv.style.display = 'none';

            const errors = [];

            if (isNaN(totalLayers) || totalLayers <= 0 ||!Number.isInteger(totalLayers)) {
                errors.push("Total Layers must be a positive integer.");
            }

            if (!autoRangeSize) {
                if (isNaN(rangeSize) || rangeSize <= 0 ||!Number.isInteger(rangeSize)) {
                    errors.push("Range Size must be a positive integer.");
                }

                if (rangeSize > totalLayers) {
                    errors.push("Range Size cannot be greater than Total Layers.");
                }
            }

            if (isNaN(nbParameters) || nbParameters <= 0) {
                errors.push("Number of Parameters must be a positive number.");
            }

            if (model.trim() === "") {
                errors.push("Model name cannot be empty.");
            }

            if (!doWhatISay && totalLayers % (autoRangeSize? calculatePossibleRangeSize(totalLayers, doWhatISay)[0] : rangeSize)!== 0) {
                errors.push("There are layers left after the main loop.");
            }

            if (errors.length > 0) {
                errorDiv.innerHTML = errors.join('<br>');
                errorDiv.style.display = 'block';
                return;
            }

            if (autoRangeSize) {
                const possibleRangeSizes = calculatePossibleRangeSize(totalLayers, doWhatISay);
                const possibleRangeSizesList = document.getElementById('possible-range-sizes-list');
                possibleRangeSizesList.innerHTML = '';
                possibleRangeSizes.forEach(size => {
                    const listItem = document.createElement('li');
                    const link = document.createElement('a');
                    link.textContent = `${size}`;
                    link.className = 'clickable';
                    link.addEventListener('click', function() {
                        generateConfig(totalLayers, size, nbParameters, model, doWhatISay);
                        possibleRangeSizesDiv.style.display = 'none';
                    });
                    listItem.appendChild(link);
                    possibleRangeSizesList.appendChild(listItem);
                });
                possibleRangeSizesDiv.style.display = 'block';
            } else {
                generateConfig(totalLayers, rangeSize, nbParameters, model, doWhatISay);
            }
        });

        function calculatePossibleRangeSize(num) {
            const divisors = [];
            for (let i = 1; i <= num; i++) {
                const quotient = num / i;
                if (Number.isInteger(quotient) || (quotient % 0.5 === 0 && !Number.isInteger(quotient))) {
                    divisors.push(i);
                }
            }
            return divisors.sort((a, b) => a - b);
        }

        function generateConfig(totalLayers, rangeSize, nbParameters, model, doWhatISay) {
            let newSize = totalLayers + totalLayers - rangeSize;
            let newParam = (nbParameters / totalLayers) * newSize;

            let yamlStr = "slices:\n";
            
            for (let i = 0; i <= totalLayers - rangeSize; i += rangeSize / 2) {
                let start = i;
                if (!doWhatISay &&!Number.isInteger(start)) {
                    console.error("The layer range contains non integer");
                } else {
                    let end = Math.min(start + rangeSize, totalLayers);
                    yamlStr += `- sources:\n`;
                    yamlStr += `  - layer_range: [${start}, ${end}]\n`;
                    yamlStr += `    model: ${model}\n`;
                }
            }

            // Check if there are remaining layers
            const quotient = totalLayers / rangeSize; 
            if (Number.isInteger(quotient) || !(quotient % 0.5 === 0 && !Number.isInteger(quotient))) {
                let start = totalLayers - (totalLayers % rangeSize);
                let end = totalLayers;
                yamlStr += `- sources:\n`;
                yamlStr += `  - layer_range: [${start}, ${end}]\n`;
                yamlStr += `    model: ${model}\n`;
            }

            yamlStr += "merge_method: passthrough\n";
            yamlStr += "dtype: bfloat16\n";

            document.getElementById('newSize').textContent = `New size = ${newSize} layers`;
            document.getElementById('newParam').textContent = `New parameters = ${newParam.toFixed(2)}B`;
            document.getElementById('yamlOutput').textContent = yamlStr;
            document.getElementById('yaml-config-section').style.display = 'block';
            document.getElementById('result').style.display = 'block';
        }

        document.getElementById('autoRangeSize').addEventListener('change', function() {
            if (this.checked) {
                document.getElementById('range-size-input').style.display = 'none';
				document.getElementById('god-mode').style.display = 'none';
            } else {
                document.getElementById('range-size-input').style.display = 'block';
				document.getElementById('god-mode').style.display = 'flex';

            }
        });
    </script>
</body>
</html>