|
from typing import Any |
|
|
|
from nbconvert import HTMLExporter |
|
|
|
from utils.create_info_files import create_hf_card |
|
from utils.notebook_generator import * |
|
from utils.components_creator import * |
|
|
|
finetuning_notebook = "Finetuning_NoteBook" |
|
|
|
notebook = None |
|
|
|
css = """ |
|
.container { |
|
align-items: center; |
|
justify-content: center; |
|
} |
|
.center_text { |
|
text-align: center; |
|
} |
|
|
|
.a_custom { |
|
border-radius: var(--button-large-radius); |
|
padding: var(--button-large-padding); |
|
font-weight: var(--button-large-text-weight); |
|
font-size: var(--button-large-text-size); |
|
border: var(--button-border-width) solid var(--button-primary-border-color); |
|
background: var(--button-primary-background-fill); |
|
color: var(--button-primary-text-color); |
|
justify-content: center; |
|
align-items: center; |
|
transition: var(--button-transition); |
|
box-shadow: var(--button-shadow); |
|
text-align: center |
|
} |
|
.a_custom a { |
|
text-decoration: none; |
|
color: white; |
|
} |
|
""" |
|
|
|
|
|
def centered_column(): |
|
return gr.Column(elem_classes=["container"]) |
|
|
|
|
|
def should_login_to_hf_model(model_id: str): |
|
return model_id == gemma.name or model_id == llama.name |
|
|
|
|
|
def change_model_selection(model_id): |
|
if model_id == gemma.name: |
|
gr.Warning(""" |
|
Access Gemma: |
|
|
|
To load Gemma from Hugging Face, youโre required to review and agree to Googleโs usage license. |
|
""") |
|
if model_id == llama.name: |
|
gr.Warning(""" |
|
Access Llama 2: |
|
|
|
To load Llama 2 from Hugging Face, youโre required to review and agree to Metaโs usage license. |
|
""") |
|
|
|
for m in models: |
|
if m.name == model_id: |
|
return gr.Dropdown(choices=m.versions, interactive=True, |
|
visible=True, info=f"Select the version of the model {m.name} you wish to use.") |
|
return None |
|
|
|
|
|
def check_valid_input(value): |
|
if isinstance(value, str): |
|
return value and value.strip() |
|
if isinstance(value, list): |
|
return len(value) > 0 |
|
return not None |
|
|
|
|
|
def get_dataset(dataset_path): |
|
for d in ft_datasets: |
|
if d.path == dataset_path: |
|
return d |
|
return None |
|
|
|
|
|
def get_value(components: dict[Component, Any], elem_id: str) -> Any: |
|
for component, val in components.items(): |
|
if component.elem_id == elem_id: |
|
return val |
|
return None |
|
|
|
|
|
def preview_notebook(): |
|
html_exporter = HTMLExporter() |
|
global notebook |
|
(body, resources) = html_exporter.from_notebook_node(notebook) |
|
|
|
html_path = f"{finetuning_notebook}.html" |
|
with open(html_path, 'w') as f: |
|
f.write(body) |
|
|
|
return f'<iframe src="file={html_path}" width="100%" height="250px"></iframe>' |
|
|
|
|
|
def generate_code(components: dict[Component, Any]): |
|
global notebook |
|
notebook = nbf.v4.new_notebook() |
|
create_install_libraries_cells(notebook['cells']) |
|
flash_attention_value = get_value(components, FLASH_ATTENTION_ID) |
|
if flash_attention_value: |
|
create_install_flash_attention(notebook['cells']) |
|
|
|
dataset_value = get_value(components, DATASET_SELECTION_ID) |
|
seed_value = get_value(components, DATASET_SHUFFLING_SEED) |
|
if not check_valid_input(dataset_value): |
|
gr.Warning("No dataset is selected") |
|
else: |
|
create_datasets_cells(notebook['cells'], get_dataset(dataset_value), seed_value) |
|
|
|
model_value = get_value(components, MODEL_SELECTION_ID) |
|
should_login = should_login_to_hf_model(model_value) |
|
|
|
version_value = "" |
|
if not check_valid_input(model_value): |
|
gr.Warning("No model is selected!") |
|
else: |
|
version_value = get_value(components, MODEL_VERSION_SELECTION_ID) |
|
if not check_valid_input(version_value): |
|
gr.Warning("No version of the model is selected") |
|
else: |
|
if should_login: |
|
create_login_hf_cells(notebook['cells'], should_login=True, model_name=model_value) |
|
|
|
load_in_4bit = get_value(components, LOAD_IN_4_BIT_ID) |
|
bnb_4bit_use_double_quant = get_value(components, BNB_4BIT_USE_DOUBLE_QUANT) |
|
bnb_4bit_quant_type = get_value(components, BNB_4BIT_QUANT_TYPE) |
|
bnb_4bit_compute_dtype = get_value(components, BNB_4BIT_COMPUTE_DTYPE) |
|
pad_side = get_value(components, PAD_SIDE_ID) |
|
pad_value = get_value(components, PAD_VALUE_ID) |
|
create_model_cells(notebook['cells'], model_id=model_value, version=version_value, |
|
flash_attention=flash_attention_value, pad_value=pad_value, |
|
pad_side=pad_side, load_in_4bit=load_in_4bit, |
|
bnb_4bit_use_double_quant=bnb_4bit_use_double_quant, |
|
bnb_4bit_quant_type=bnb_4bit_quant_type, bnb_4bit_compute_dtype=bnb_4bit_compute_dtype) |
|
|
|
r_value = get_value(components, LORA_R_ID) |
|
alpha_value = get_value(components, LORA_ALPHA_ID) |
|
dropout_value = get_value(components, LORA_DROPOUT_ID) |
|
bias_value = get_value(components, LORA_BIAS_ID) |
|
create_lora_config_cells(notebook['cells'], r_value, alpha_value, dropout_value, bias_value) |
|
|
|
epochs = get_value(components, NUM_TRAIN_EPOCHS_ID) |
|
max_steps = get_value(components, MAX_STEPS_ID) |
|
logging_steps = get_value(components, LOGGING_STEPS_ID) |
|
per_device_train_batch_size = get_value(components, PER_DEVICE_TRAIN_BATCH_SIZE) |
|
save_strategy = get_value(components, SAVE_STRATEGY_ID) |
|
gradient_accumulation_steps = get_value(components, GRADIENT_ACCUMULATION_STEPS_ID) |
|
gradient_checkpointing = get_value(components, GRADIENT_CHECKPOINTING_ID) |
|
learning_rate = get_value(components, LEARNING_RATE_ID) |
|
max_grad_norm = get_value(components, MAX_GRAD_NORM_ID) |
|
warmup_ratio = get_value(components, WARMUP_RATIO_ID) |
|
lr_scheduler_type = get_value(components, LR_SCHEDULER_TYPE_ID) |
|
output_dir = get_value(components, OUTPUT_DIR_ID) |
|
|
|
report_to = get_value(components, REPORT_TO_ID) |
|
|
|
if not check_valid_input(output_dir): |
|
gr.Warning("No output_dir is given") |
|
|
|
create_training_args_cells(notebook['cells'], epochs=epochs, max_steps=max_steps, logging_steps=logging_steps, |
|
per_device_train_batch_size=per_device_train_batch_size, save_strategy=save_strategy, |
|
gradient_accumulation_steps=gradient_accumulation_steps, |
|
gradient_checkpointing=gradient_checkpointing, learning_rate=learning_rate, |
|
max_grad_norm=max_grad_norm, warmup_ratio=warmup_ratio, |
|
lr_scheduler_type=lr_scheduler_type, output_dir=output_dir, report_to=report_to, |
|
seed=seed_value) |
|
|
|
max_seq_length = get_value(components, MAX_SEQ_LENGTH_ID) |
|
packing = get_value(components, PACKING_ID) |
|
create_sft_trainer_cells(notebook['cells'], max_seq_length, packing) |
|
|
|
push_to_hub = get_value(components, PUSH_TO_HUB_ID) |
|
|
|
create_start_training_cells(notebook['cells'], epochs, max_steps, push_to_hub, output_dir) |
|
|
|
create_free_gpu_cells(notebook['cells']) |
|
|
|
create_merge_lora_cells(notebook['cells'], output_dir) |
|
|
|
merge_model_cells(notebook['cells'], output_dir) |
|
|
|
create_readme = get_value(components, README_ID) |
|
if create_readme: |
|
create_hf_card(notebook['cells'], name=output_dir, base_model_name=model_value, |
|
base_model_version=version_value, |
|
dataset_name=dataset_value, output_dir=output_dir, report_to=report_to) |
|
|
|
if push_to_hub: |
|
if not should_login: |
|
create_login_hf_cells(notebook['cells']) |
|
push_to_hub_cells(notebook['cells'], output_dir) |
|
|
|
file_name = f"{finetuning_notebook}.ipynb" |
|
|
|
with open(file_name, 'w') as f: |
|
nbf.write(notebook, f) |
|
|
|
return gr.Button( |
|
visible=True), f'''<div class="a_custom"><a href="file={file_name}" download={file_name}> |
|
๐พ๏ธ Download {finetuning_notebook}.ipynb</a> </div> ''', "<div></div>" |
|
|
|
|
|
with gr.Blocks(css=css, theme=gr.themes.Soft(text_size='lg', font=["monospace"], |
|
primary_hue=gr.themes.colors.blue)) as demo: |
|
gr.Label("UI-Guided LLM FineTuning Jupyter Notebook Generator ๐ ๏ธ๐ง ", show_label=False) |
|
gr.Markdown( |
|
'Generating a **Jupyter Notebook file (.ipynb)** ๐โ๏ธ for **finetuning** a Large Language Model (**LLM**) ' |
|
'๐๏ธ๐ง on a chosen dataset and configured parameters, guided by an intuitive User Interface (UI) ๐๐ป.', |
|
elem_classes=["center_text"]) |
|
|
|
all_components: Set[Component] = set() |
|
|
|
gr.HTML("<h2 style='text-align: center;'>LLM ๐ง </h2>") |
|
with gr.Row(): |
|
model_selection = gr.Dropdown( |
|
[model.name for model in models], |
|
elem_id=MODEL_SELECTION_ID, |
|
label="Select a Large Language Model (LLM)", |
|
info="Select a Large Language Model (LLM) to finetune using the SFTTrainer." |
|
) |
|
version_selection = gr.Dropdown( |
|
choices=[], label="Select a Model Version ๐", info="", visible=False, elem_id=MODEL_VERSION_SELECTION_ID |
|
) |
|
all_components.add(model_selection) |
|
all_components.add(version_selection) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>Dataset ๐</h2>") |
|
with gr.Row(): |
|
all_components.update(add_dataset_components()) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>โก Flash Attention โก</h2>") |
|
with gr.Row(): |
|
flash_attention = gr.Checkbox(value=True, label="Enable Flash Attention", interactive=True, |
|
elem_id=FLASH_ATTENTION_ID, |
|
info="Flash Attention is a technique that reduces the memory and runtime costs " |
|
"associated with " |
|
"the attention layer in a model. For more details, please refer to the " |
|
"Flash Attention " |
|
"repository on GitHub.") |
|
all_components.add(flash_attention) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>Quantization</h2>") |
|
with gr.Row(): |
|
with centered_column(): |
|
all_components.update(add_quantization_components()) |
|
with centered_column(): |
|
all_components.update(add_quantization_components1()) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>Tokenizer Configuration</h2>") |
|
with gr.Row(): |
|
all_components.update(add_pad_tokens()) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>Lora Configuration</h2>") |
|
with gr.Row(): |
|
with centered_column(): |
|
all_components.update(add_lora_components1()) |
|
with centered_column(): |
|
all_components.update(add_lora_components()) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>โ๏ธ Training Arguments โ๏ธ</h2>") |
|
with gr.Row(): |
|
with centered_column(): |
|
all_components.update(add_training_args_1()) |
|
all_components.update(add_training_args_1_bis()) |
|
with centered_column(): |
|
all_components.update(add_training_args_3()) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>Optimizer Arguments</h2>") |
|
with gr.Row(): |
|
with centered_column(): |
|
optimizer1 = add_optimizer1() |
|
all_components.update(optimizer1) |
|
|
|
with centered_column(): |
|
optimizer = add_optimizer() |
|
all_components.update(optimizer) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>Outputs</h2>") |
|
with gr.Row(): |
|
with centered_column(): |
|
output_dir_cmp, push_to_hub_cmp = add_outputs() |
|
all_components.update({output_dir_cmp, push_to_hub_cmp}) |
|
with centered_column(): |
|
all_components.update(add_outputs1()) |
|
|
|
gr.HTML("<h2 style='text-align: center;'>SFTTrainer Arguments</h2>") |
|
with gr.Row(): |
|
sft_args = add_sft_trainer_args() |
|
all_components.update(sft_args) |
|
|
|
with gr.Row(): |
|
iframe = gr.HTML(show_label=False, visible=True) |
|
|
|
with gr.Row(): |
|
greet_btn = gr.Button("Generate ๐ ๏ธ", variant="primary") |
|
|
|
with gr.Row(): |
|
preview_btn = gr.Button(f"๐ Preview {finetuning_notebook}.ipynb", variant="primary", visible=False) |
|
download_btn = gr.HTML(show_label=False, visible=True) |
|
|
|
greet_btn.click(fn=generate_code, inputs=all_components, outputs=[preview_btn, download_btn, iframe]) |
|
|
|
preview_btn.click(fn=preview_notebook, inputs=None, outputs=iframe) |
|
|
|
model_selection.change( |
|
fn=change_model_selection, |
|
inputs=model_selection, |
|
outputs=version_selection |
|
) |
|
|
|
demo.launch(allowed_paths=["/"]) |
|
|
|
|
|
""" |
|
import os |
|
from huggingface_hub import Repository |
|
|
|
# Create a repository object |
|
repo = Repository("Menouar/ft-phi-1") |
|
|
|
# Push the runs directory |
|
os.system(f"git -C {repo.local_dir} add output_dir/runs") |
|
repo.git_commit("Adding TensorBoard logs") |
|
repo.push_to_hub(commit_message="Adding TensorBoard logs") |
|
|
|
""" |
|
|