Skip to content

Commit

Permalink
Merge pull request #48 from SkywardAI/training-page-dev
Browse files Browse the repository at this point in the history
bring out new training page design
  • Loading branch information
cbh778899 authored Jul 21, 2024
2 parents 04d5688 + ba89443 commit 661d165
Show file tree
Hide file tree
Showing 10 changed files with 547 additions and 80 deletions.
4 changes: 4 additions & 0 deletions components/training-page/faq-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default function loadFAQPage(main) {
main.innerHTML = '';
return null;
}
99 changes: 54 additions & 45 deletions components/training-page/index.js
Original file line number Diff line number Diff line change
@@ -1,54 +1,63 @@
const dataset_options = []
const model_options = []
const settings = {
output_dir: "WANDB_NAME",
evaluation_strategy: "steps",
do_eval: true,
optim: "adamw_8bit",
per_device_train_batch_size: 8,
gradient_accumulation_steps: 2,
per_device_eval_batch_size: 8,
log_level: "debug",
logging_steps: 100,
learning_rate: 8e-6,
eval_steps: 100,
save_steps: 100,
save_strategy: "epoch",
num_train_epochs: 1,
warmup_ratio: 0.1,
lr_scheduler_type: "linear",
beta: 0.1,
max_length: 1024,
report_to: "wandb",
run_name: 'WANDB_NAME'
// const dataset_options = []
// const model_options = []

import loadFAQPage from "./faq-page.js";
import loadParametersPage from "./parameters-page.js";
import loadTrainingVisualizationPage from "./training-visualization-page.js";

const pages = [
{index: 'parameters', title: 'Start Training'},
{index: 'training-visualization', title: 'Training Visualization'},
{index: 'faq', title: 'FAQ'},
]

let training_page_main, current_page = '';

function switchPage(page) {
if(current_page === page) return;
switch(page) {
case 'parameters':
loadParametersPage(training_page_main);
break;
case 'faq':
loadFAQPage(training_page_main);
break;
case 'training-visualization':
loadTrainingVisualizationPage(training_page_main);
break;
default: return;
}

current_page && document.getElementById(`training-tab-${current_page}`).classList.remove('selected');
document.getElementById(`training-tab-${page}`).classList.add('selected');
current_page = page;
}

export default function createTrainingPage() {

document.getElementById("main").innerHTML = `
<div class='training-main'>
<div class='title'>Training</div>
<div class='option-set'>
<div class='option-name'>Dataset Name:</div>
<select id='select-dataset'>
${dataset_options.map(e=>`<option value='${e}'>${e}</option>`).join('')}
</select>
<div class='api-key'>WANDB_API_KEY</div>
</div>
<div class='option-set'>
<div class='option-name'>Model Name:</div>
<select id='select-model'>
${model_options.map(e=>`<option value='${e}'>${e}</option>`).join('')}
</select>
<div class='api-key'>HUGGINGFACE_API_KEY</div>
</div>
<textarea class='show-json-setting' rows="15" cols="20">
{
${Array.from(Object.entries(settings)).map(([k, v])=>`"${k}": ${isNaN(+v)?`"${v}"`:v}`).join(',\n ')}
}
</textarea>
<div class='save-btn clickable'>Save</div>
<div id='training-tabs'></div>
<div id='training-page-main'></div>
</div>`

training_page_main = document.getElementById('training-page-main');

const tabs = document.getElementById('training-tabs');
pages.forEach(page => {
const tab = document.createElement('div');
tab.className = 'tab clickable';
tab.id = `training-tab-${page.index}`
tab.textContent = page.title;
tab.onclick = () => {
switchPage(page.index);
}
tabs.appendChild(tab);
})


const loaded_page = current_page;
current_page = '';

switchPage(loaded_page || pages[0].index);
return null;
}
207 changes: 207 additions & 0 deletions components/training-page/parameters-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
import createDialog from "../../tools/dialog.js";
import showMessage from "../../tools/message.js"

const settings = {
output_dir: "WANDB_NAME",
evaluation_strategy: "steps",
do_eval: true,
optim: "adamw_8bit",
per_device_train_batch_size: 8,
gradient_accumulation_steps: 2,
per_device_eval_batch_size: 8,
log_level: "debug",
logging_steps: 100,
learning_rate: 8e-6,
eval_steps: 100,
save_steps: 100,
save_strategy: "epoch",
num_train_epochs: 1,
warmup_ratio: 0.1,
lr_scheduler_type: "linear",
beta: 0.1,
max_length: 1024,
report_to: "wandb",
run_name: 'WANDB_NAME'
}

const setting_value_type = {};
for(const key in settings) setting_value_type[key] = typeof settings[key];

// TODO: load settings from local

const [ advanced_settings_dialog, controller ] = createDialog();
let main_form, init = false;

export default function loadParametersPage(main) {
main.innerHTML = `
<form id='training-params'>
<section class='token'>
<div>
<div class='title'>Huggingface Token</div>
<input type='text' autocomplete="off" name='huggingface-token'>
</div>
<div>
<div class='title'>Wandb Token</div>
<input type='text' autocomplete="off" name='wandb-token'>
</div>
</section>
<section class='model'>
<div>
<div class='title'>Select Base Model</div>
<select class='clickable' name='select-model'>
<option value='default model'>Default Model</option>
</select>
</div>
<div>
<div class='title'>Select Dataset</div>
<select class='clickable' name='select-dataset'>
<option value='default dataset'>Default Dataset</option>
</select>
</div>
</section>
<section class='params'>
<div>
<div class='title'>Some Random Setting 1</div>
<select class='clickable' name='random-setting-1'>
<option value='default option'>Default Option</option>
</select>
</div>
<div>
<div class='title'>Some Random Setting 2</div>
<input type='text'>
</div>
<div>
<div class='title'>Some Random Setting 3</div>
<input type='text'>
</div>
<div>
<div class='title'>Some Random Setting 4</div>
<select class='clickable' name='random-setting-1'>
<option value='option 1'>Option 1</option>
<option value='option 2'>Option 2</option>
<option value='option 3'>Option 3</option>
</select>
</div>
<div>
<div class='title'>Some Random Setting 5</div>
<input type='text'>
</div>
<div id='advanced-setting' class='advanced clickable'>
<div class='title'>Advanced Settings</div>
</div>
</section>
<section class='function'>
<button class='clickable' type='button' id='save-btn'>Save</button>
<button class='clickable' type='submit'>Start Training</button>
</section>
</form>`

main_form = document.getElementById('training-params');
main_form.onsubmit = startTraining;

document.getElementById('save-btn').onclick = () => {
console.log(getEntryValues());
}

createAdvancedSettingPage();
document.getElementById('advanced-setting').onclick = controller.showModal;

return null;
}

function createAdvancedSettingPage() {
if(init) return;

const table = document.createElement('table');
table.innerHTML =
`<thead>
<tr>
<th scope='col'>Key</th>
<th scope='col'>Value</th>
</tr>
</thead>`

const tbody = document.createElement('tbody');
for(const key in settings) {
const value = settings[key];
tbody.appendChild(createAdvancedSettingRow(setting_value_type[key], key, value))
}
table.appendChild(tbody);

const dialog_main = document.createElement('div');
dialog_main.className = 'advanced-setting-table';
dialog_main.onclick = evt => evt.stopPropagation();
dialog_main.appendChild(table);

advanced_settings_dialog.appendChild(dialog_main);

init = true;
}

function createAdvancedSettingRow(type, key, value) {
const row = document.createElement('tr');
row.innerHTML = `<td>${key}</td>`;

const column = document.createElement('td');

const input = document.createElement('input');
if(type === 'boolean') {
const show_value = document.createElement('div');
show_value.className = 'show-boolean-value';
show_value.textContent = value;

input.type = 'checkbox';
input.className = 'clickable'
input.checked = value;
input.onchange = evt => {
const value = evt.target.checked;
show_value.textContent = value;
settings[key] = value;
showMessage(`"${key}" set to ${value}`);
}
column.appendChild(show_value);
} else {
input.type = 'text';
input.value = value;
input.onchange = evt => {
const value = settingValueParser(type, evt.target.value);
if(value === null) {
showMessage(`The entry "${key}" must be type of ${type}!`, { type:'warn' })
evt.target.value = settings[key]
return;
}
settings[key] = value;
evt.target.value = value;
showMessage(`"${key}" set to ${value}`);
}
}

column.appendChild(input);
row.appendChild(column);
return row;
}

function getEntryValues() {
const values = {
"huggingface-token": main_form["huggingface-token"].value,
"wandb-token": main_form["wandb-token"].value,
"select-model": main_form["select-model"].value,
"select-dataset": main_form["select-dataset"].value,
};

return values;

}

function startTraining(evt) {
evt.preventDefault();
}

function settingValueParser(type, value) {
if(type === 'number') {
value = +value;
return isNaN(value) ? null : value;
} else {
return value || null;
}
}
4 changes: 4 additions & 0 deletions components/training-page/training-visualization-page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export default function loadTrainingVisualizationPage(main) {
main.innerHTML = '';
return null;
}
3 changes: 0 additions & 3 deletions styles/account_page.css
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@
bottom: 5px;
background-color: transparent;
}
.input-details-main .account-field-container input:focus {
outline: none;
}

.password-eye-icon {
position: absolute;
Expand Down
2 changes: 0 additions & 2 deletions styles/chat_page.css
Original file line number Diff line number Diff line change
Expand Up @@ -347,13 +347,11 @@
#chat-page #chat-main #submit-chat input {
position: absolute;
width: 100%;
box-sizing: border-box;
border: 1px solid gray;
height: 100%;
border-radius: 10px;
padding: 0px var(--send-section-size) 0px 15px;
}
#chat-page #chat-main #submit-chat input:focus { outline: none; }

#chat-page #chat-main #submit-chat .right-button {
position: absolute;
Expand Down
2 changes: 1 addition & 1 deletion styles/chat_settings.css
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@
.chat-settings .setting-section input[type="text"],
.chat-settings .setting-section select {
height: var(--input-height);
box-sizing: border-box;
border-radius: 5px;
padding: 0px 10px;
border: 1px solid gray;
width: 100%;
background-color: white;
}

.chat-settings .setting-section input[type="text"]:focus,
.chat-settings .setting-section select:focus {
outline: none;
Expand Down
8 changes: 8 additions & 0 deletions styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,14 @@ div {
box-sizing: border-box;
}

input[type="text"],
input[type="password"] {
box-sizing: border-box;
}
input:focus {
outline: none;
}

svg {
display: block;
}
Expand Down
Loading

0 comments on commit 661d165

Please sign in to comment.