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'' 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'''
''', "" 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("