menouar
Improve comments
6c5232f
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;
cursor: pointer;
}
.a_custom:hover {
border-color: var(--button-primary-border-color-hover);
background: var(--button-primary-background-fill-hover);
color: var(--button-primary-text-color-hover);
}
.a_custom a {
text-decoration: none;
color: white;
display: block;
}
.dashed_row {
border: 2px dashed #60a5fa;
}
"""
def centered_column():
return gr.Column(elem_classes=["container"])
def dashed_row():
return gr.Row(elem_classes=["dashed_row"])
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'], output_dir=output_dir)
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 Fine-Tuning Jupyter Notebook Generator 🛠️🧠", show_label=False)
gr.Markdown('''
This space generates a **Jupyter Notebook file (.ipynb)** 📔⚙️ that guides you through the
entire process of **supervised fine-tuning** of a raw Large Language Model (**LLM**) 🧠 on a chosen dataset in
the **Conversational format**. The process is facilitated by an intuitive **User Interface (UI)** 👆💻 **:**
''', elem_classes=["center_text"])
with dashed_row():
with centered_column():
with gr.Accordion("1. No Coding Required", open=False):
gr.Markdown("The UI guides you through the entire process, eliminating the need for manual coding.")
with gr.Accordion("2. Customizable Parameters", open=False):
gr.Markdown(
"You can customize the most commonly used parameters for supervised fine-tuning to suit your needs.")
with centered_column():
with gr.Accordion("3. Comprehensive Notebook", open=False):
gr.Markdown("The generated .ipynb contains all steps, from installing libraries and writing a "
"README.md, "
"to pushing the final model to the Hugging Face Hub.")
with gr.Accordion("4. Preview Before Download", open=False):
gr.Markdown("You can preview the generated .ipynb before downloading it to ensure it "
"meets "
"your requirements.")
with centered_column():
with gr.Accordion("5. User-Friendly", open=False):
gr.Markdown("The UI is designed to be easy to use and understand, making the fine-tuning process "
"accessible "
"to everyone.")
with gr.Accordion("6. Open-Source", open=False):
gr.Markdown(
"This space is open source, so you can collaborate to improve it and make it more powerful.")
all_components: Set[Component] = set()
gr.HTML("<h2 style='text-align: center;'>Model 🧠</h2>")
with gr.Row():
model_selection = gr.Dropdown(
[model.name for model in models],
elem_id=MODEL_SELECTION_ID,
label="Select a raw LLM",
info="Select a raw Large Language Model (LLM) to fine-tune."
)
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=["/"])
# Upload metrics to the hub....
"""
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")
"""