|
3 | 3 |
|
4 | 4 | <head> |
5 | 5 | <meta charset="UTF-8"> |
6 | | - <title>LLM Query</title> |
| 6 | + <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| 7 | + <title>BitNet 1-Bit LLM Query Interface</title> |
7 | 8 | <script src="/socket.io/socket.io.js"></script> |
8 | 9 | <style> |
| 10 | + body { |
| 11 | + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| 12 | + margin: 0; |
| 13 | + padding: 0; |
| 14 | + background-color: #f4f4f9; |
| 15 | + display: flex; |
| 16 | + justify-content: center; |
| 17 | + align-items: center; |
| 18 | + height: 100vh; |
| 19 | + } |
| 20 | + |
| 21 | + .container { |
| 22 | + display: flex; |
| 23 | + max-width: 1200px; |
| 24 | + width: 100%; |
| 25 | + background-color: #fff; |
| 26 | + border-radius: 8px; |
| 27 | + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); |
| 28 | + overflow: hidden; |
| 29 | + } |
| 30 | + |
| 31 | + .left-section { |
| 32 | + flex: 1; |
| 33 | + padding: 20px; |
| 34 | + background-color: white; |
| 35 | + color: black; |
| 36 | + display: flex; |
| 37 | + flex-direction: column; |
| 38 | + justify-content: space-between; |
| 39 | + box-sizing: border-box; |
| 40 | + } |
| 41 | + |
| 42 | + .left-section h2 { |
| 43 | + margin-bottom: 20px; |
| 44 | + font-size: 1.5rem; |
| 45 | + } |
| 46 | + |
| 47 | + .input-group { |
| 48 | + margin-bottom: 15px; |
| 49 | + } |
| 50 | + |
| 51 | + .input-group label { |
| 52 | + display: block; |
| 53 | + font-size: 0.9rem; |
| 54 | + margin-bottom: 8px; |
| 55 | + } |
| 56 | + |
| 57 | + .input-group input, |
| 58 | + .input-group textarea { |
| 59 | + width: 100%; |
| 60 | + padding: 10px; |
| 61 | + border-radius: 4px; |
| 62 | + font-size: 0.95rem; |
| 63 | + box-sizing: border-box; |
| 64 | + } |
| 65 | + |
| 66 | + input[type="number"], |
| 67 | + textarea { |
| 68 | + width: 100%; |
| 69 | + border: 1px solid #ccc; |
| 70 | + border-radius: 4px; |
| 71 | + box-sizing: border-box; |
| 72 | + } |
| 73 | + |
| 74 | + input[type="number"]:focus, |
| 75 | + textarea:focus { |
| 76 | + border-color: #238a95; |
| 77 | + outline: none; |
| 78 | + box-shadow: 0 0 5px rgba(35, 138, 149, 0.5); |
| 79 | + } |
| 80 | + |
| 81 | + input[type="number"]::placeholder, |
| 82 | + textarea::placeholder { |
| 83 | + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| 84 | + } |
| 85 | + |
| 86 | + .input-group textarea { |
| 87 | + resize: none; |
| 88 | + } |
| 89 | + |
| 90 | + .button-group { |
| 91 | + margin-top: 20px; |
| 92 | + margin: auto; |
| 93 | + } |
| 94 | + |
| 95 | + .button-group button { |
| 96 | + padding: 10px 20px; |
| 97 | + background-color: #238a95; |
| 98 | + border: none; |
| 99 | + color: white; |
| 100 | + cursor: pointer; |
| 101 | + border-radius: 4px; |
| 102 | + font-size: 1rem; |
| 103 | + transition: background-color 0.3s, transform 0.2s; |
| 104 | + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| 105 | + } |
| 106 | + |
| 107 | + .button-group button:hover { |
| 108 | + background-color: #1e7a84; |
| 109 | + transform: scale(1.05); |
| 110 | + } |
| 111 | + |
| 112 | + .right-section { |
| 113 | + flex: 2; |
| 114 | + padding: 20px; |
| 115 | + background-color: #ffffff; |
| 116 | + border-left: 2px solid #dbdbdb; |
| 117 | + box-sizing: border-box; |
| 118 | + } |
| 119 | + |
| 120 | + .right-section h2 { |
| 121 | + margin-bottom: 20px; |
| 122 | + } |
| 123 | + |
9 | 124 | #response { |
10 | | - width: 70%; |
| 125 | + height: 430px; |
11 | 126 | border: 1px solid #dbdbdb; |
12 | 127 | border-radius: 4px; |
13 | | - padding: 20px; |
14 | | - height: 450px; |
15 | | - overflow-y: scroll; |
| 128 | + padding: 10px; |
| 129 | + overflow-y: auto; |
| 130 | + font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; |
| 131 | + background-color: #f5f4f459; |
| 132 | + font-size: 0.95rem; |
| 133 | + } |
| 134 | + |
| 135 | + /* Responsive design */ |
| 136 | + @media screen and (max-width: 768px) { |
| 137 | + .container { |
| 138 | + flex-direction: column; |
| 139 | + } |
| 140 | + |
| 141 | + .right-section { |
| 142 | + border-left: none; |
| 143 | + border-top: 2px solid #dbdbdb; |
| 144 | + } |
16 | 145 | } |
17 | 146 | </style> |
18 | 147 | </head> |
19 | 148 |
|
20 | 149 | <body> |
21 | | - <h1>LLM Query</h1> |
22 | | - <textarea id="query" rows="4" cols="50"></textarea><br> |
23 | | - <button onclick="sendQuery()">Send</button> |
24 | | - <h2>Response:</h2> |
25 | | - <div id="response"></div> |
| 150 | + <div class="container"> |
| 151 | + <div class="left-section"> |
| 152 | + <h2>Command Options</h2> |
| 153 | + <div class="input-group"> |
| 154 | + <label for="tokens">Number of tokens to predict</label> |
| 155 | + <input type="number" id="tokens" min="0" placeholder="Enter number of tokens"> |
| 156 | + </div> |
| 157 | + <div class="input-group"> |
| 158 | + <label for="threads">Number of threads to use</label> |
| 159 | + <input type="number" id="threads" min="0" placeholder="Enter number of threads"> |
| 160 | + </div> |
| 161 | + <div class="input-group"> |
| 162 | + <label for="context-size">Size of the prompt context</label> |
| 163 | + <input type="number" id="context-size" min="0" placeholder="Enter context size"> |
| 164 | + </div> |
| 165 | + <div class="input-group"> |
| 166 | + <label for="temperature">Temperature, a hyperparameter that controls the randomness of the generated |
| 167 | + text</label> |
| 168 | + <input type="number" min="0" id="temperature" placeholder="Enter temperature value"> |
| 169 | + </div> |
| 170 | + <div class="input-group"> |
| 171 | + <label for="prompt">Prompt</label> |
| 172 | + <textarea id="prompt" rows="4" min="0" placeholder="Enter your prompt"></textarea> |
| 173 | + </div> |
| 174 | + <div class="button-group"> |
| 175 | + <button onclick="sendQuery()">Send Query</button> |
| 176 | + </div> |
| 177 | + </div> |
| 178 | + <div class="right-section"> |
| 179 | + <h2>Response</h2> |
| 180 | + <div id="response"></div> |
| 181 | + </div> |
| 182 | + </div> |
26 | 183 |
|
27 | 184 | <script> |
28 | 185 | const socket = io(); |
29 | 186 |
|
30 | 187 | function sendQuery() { |
31 | | - const query = document.getElementById('query').value; |
32 | | - document.getElementById('response').innerText = ''; // Clear previous response |
33 | | - socket.emit('query', query); |
| 188 | + const tokens = document.getElementById('tokens').value; |
| 189 | + const threads = document.getElementById('threads').value; |
| 190 | + const contextSize = document.getElementById('context-size').value; |
| 191 | + const temperature = document.getElementById('temperature').value; |
| 192 | + const prompt = document.getElementById('prompt').value; |
| 193 | + |
| 194 | + if (!prompt) { |
| 195 | + return alert('There is no prompt to send!'); |
| 196 | + } |
| 197 | + |
| 198 | + let args = ''; |
| 199 | + |
| 200 | + if (tokens && !isNaN(tokens) && tokens > -1) { |
| 201 | + args += ` -n ${tokens}`; |
| 202 | + } |
| 203 | + |
| 204 | + if (threads && !isNaN(threads) && threads > -1) { |
| 205 | + args += ` -t ${threads}`; |
| 206 | + } |
| 207 | + |
| 208 | + if (contextSize && !isNaN(contextSize) && contextSize > -1) { |
| 209 | + args += ` -c ${contextSize}`; |
| 210 | + } |
| 211 | + |
| 212 | + if (temperature && !isNaN(temperature) && temperature > -1) { |
| 213 | + args += ` -temp ${temperature}`; |
| 214 | + } |
| 215 | + |
| 216 | + // Clear previous response |
| 217 | + document.getElementById('response').innerText = ''; |
| 218 | + |
| 219 | + // Emit query with all parameters |
| 220 | + socket.emit('query', { query: prompt, args }); |
34 | 221 | } |
35 | 222 |
|
36 | 223 | socket.on('response', function (word) { |
37 | | - // Append each word to the response div |
38 | 224 | const responseDiv = document.getElementById('response'); |
39 | 225 | responseDiv.innerText += word + ' '; |
40 | | - |
| 226 | + // Scroll to the bottom of the response div |
41 | 227 | responseDiv.scrollTop = responseDiv.scrollHeight; |
42 | 228 | }); |
43 | 229 | </script> |
|
0 commit comments