diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ebcd014 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ + +.idea/inspectionProfiles/profiles_settings.xml +.idea/inspectionProfiles/Project_Default.xml +.idea/misc.xml +.idea/modules.xml +.idea/NeuroTrainerWebUI.iml +.idea/vcs.xml diff --git a/AppRU.py b/AppRU.py deleted file mode 100644 index c736e92..0000000 --- a/AppRU.py +++ /dev/null @@ -1,1448 +0,0 @@ -import os -from git import Repo -import requests -import gradio as gr -from transformers import AutoModelForCausalLM, AutoTokenizer, DataCollatorForLanguageModeling, Trainer, TrainingArguments -from llama_cpp import Llama -from peft import LoraConfig, get_peft_model, PeftModel -from diffusers import StableDiffusionPipeline, StableDiffusionXLPipeline, DDPMScheduler -from datasets import load_dataset -import matplotlib.pyplot as plt -import numpy as np -from PIL import Image -import torch -from bert_score import score -import json -from datetime import datetime -from torchmetrics.text.chrf import CHRFScore -from torchmetrics.image.fid import FrechetInceptionDistance -from torchmetrics.image.kid import KernelInceptionDistance -from torchmetrics.image.inception import InceptionScore -from torchmetrics.image.vif import VisualInformationFidelity -from torchvision.transforms import Resize -from torchmetrics.multimodal.clip_score import CLIPScore -from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity -from torchmetrics.image.scc import SpatialCorrelationCoefficient -from torchmetrics.image import SpectralDistortionIndex -from torchmetrics.image import SpectralAngleMapper -from torchmetrics.image.ssim import StructuralSimilarityIndexMeasure -import psutil -import GPUtil -from cpuinfo import get_cpu_info -from pynvml import nvmlInit, nvmlDeviceGetHandleByIndex, nvmlDeviceGetTemperature, NVML_TEMPERATURE_GPU -import sacrebleu -from rouge import Rouge -import subprocess -from tensorboard.backend.event_processing.event_accumulator import EventAccumulator -from mauve import compute_mauve -from sklearn.metrics import accuracy_score, precision_score - - -def authenticate(username, password): - try: - with open("GradioAuth.txt", "r") as file: - stored_credentials = file.read().strip().split(":") - if len(stored_credentials) == 2: - stored_username, stored_password = stored_credentials - return username == stored_username and password == stored_password - except FileNotFoundError: - print("Authentication file not found.") - except Exception as e: - print(f"Error reading authentication file: {e}") - return False - - -def get_system_info(): - gpu = GPUtil.getGPUs()[0] - gpu_total_memory = f"{gpu.memoryTotal} MB" - gpu_used_memory = f"{gpu.memoryUsed} MB" - gpu_free_memory = f"{gpu.memoryFree} MB" - - nvmlInit() - handle = nvmlDeviceGetHandleByIndex(0) - gpu_temp = nvmlDeviceGetTemperature(handle, NVML_TEMPERATURE_GPU) - - cpu_info = get_cpu_info() - cpu_temp = cpu_info.get("cpu_temp", None) - - ram = psutil.virtual_memory() - ram_total = f"{ram.total // (1024 ** 3)} GB" - ram_used = f"{ram.used // (1024 ** 3)} GB" - ram_free = f"{ram.available // (1024 ** 3)} GB" - - return gpu_total_memory, gpu_used_memory, gpu_free_memory, gpu_temp, cpu_temp, ram_total, ram_used, ram_free - - -def get_available_llm_models(): - models_dir = "models/llm" - os.makedirs(models_dir, exist_ok=True) - - llm_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - llm_available_models.append(model_name) - - return llm_available_models - - -def get_available_llm_lora_models(): - models_dir = "finetuned-models/llm/lora" - os.makedirs(models_dir, exist_ok=True) - - llm_lora_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - llm_lora_available_models.append(model_name) - - return llm_lora_available_models - - -def get_available_finetuned_llm_models(): - models_dir = "finetuned-models/llm/full" - os.makedirs(models_dir, exist_ok=True) - - finetuned_available_llm_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - finetuned_available_llm_models.append(model_name) - - return finetuned_available_llm_models - - -def get_available_llm_datasets(): - datasets_dir = "datasets/llm" - os.makedirs(datasets_dir, exist_ok=True) - - llm_available_datasets = [] - for dataset_file in os.listdir(datasets_dir): - if dataset_file.endswith(".json"): - llm_available_datasets.append(dataset_file) - - return llm_available_datasets - - -def get_available_sd_models(): - models_dir = "models/sd" - os.makedirs(models_dir, exist_ok=True) - - sd_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - sd_available_models.append(model_name) - - return sd_available_models - - -def get_available_sd_lora_models(): - models_dir = "finetuned-models/sd/lora" - os.makedirs(models_dir, exist_ok=True) - - sd_lora_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - sd_lora_available_models.append(model_name) - - return sd_lora_available_models - - -def get_available_finetuned_sd_models(): - models_dir = "finetuned-models/sd/full" - os.makedirs(models_dir, exist_ok=True) - - finetuned_sd_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path) or model_name.endswith(".safetensors"): - finetuned_sd_available_models.append(model_name) - - return finetuned_sd_available_models - - -def get_available_sd_datasets(): - datasets_dir = "datasets/sd" - os.makedirs(datasets_dir, exist_ok=True) - - sd_available_datasets = [] - for dataset_dir in os.listdir(datasets_dir): - dataset_path = os.path.join(datasets_dir, dataset_dir) - if os.path.isdir(dataset_path): - sd_available_datasets.append(dataset_dir) - - return sd_available_datasets - - -def load_model_and_tokenizer(model_name, finetuned=False): - if finetuned: - model_path = os.path.join("finetuned-models/llm/full", model_name) - else: - model_path = os.path.join("models/llm", model_name) - try: - device = "cuda" - model = AutoModelForCausalLM.from_pretrained(model_path, device_map=device) - tokenizer = AutoTokenizer.from_pretrained(model_path) - return model, tokenizer - except Exception as e: - print(f"Error loading model and tokenizer: {e}") - return None, None - - -def create_llm_dataset(existing_file, file_name, instruction, input_text, output_text): - if existing_file: - file_path = os.path.join("datasets", "llm", existing_file) - with open(file_path, "r") as f: - data = json.load(f) - data.append({"instruction": instruction, "input": input_text, "output": output_text}) - with open(file_path, "w") as f: - json.dump(data, f, indent=2) - return f"New column added to the existing file: {existing_file}" - else: - file_path = os.path.join("datasets", "llm", f"{file_name}.json") - data = [{"instruction": instruction, "input": input_text, "output": output_text}] - with open(file_path, "w") as f: - json.dump(data, f, indent=2) - return f"New dataset file created: {file_name}.json" - - -def finetune_llm(model_name, dataset_file, finetune_method, model_output_name, epochs, batch_size, learning_rate, - weight_decay, warmup_steps, block_size, grad_accum_steps, adam_beta1, adam_beta2, adam_epsilon, lr_scheduler_type, freeze_layers, lora_r, lora_alpha, lora_dropout, use_xformers=False): - model, tokenizer = load_model_and_tokenizer(model_name) - if model is None or tokenizer is None: - return "Error loading model and tokenizer. Please check the model path.", None - - if not model_name: - return "Please select the model", None - - if not dataset_file: - return "Please select the dataset", None - - if not model_output_name: - return "Please write the model name", None - - dataset_path = os.path.join("datasets/llm", dataset_file) - try: - train_dataset = load_dataset('json', data_files=dataset_path) - train_dataset = train_dataset['train'] - - def process_examples(examples): - input_texts = examples['input'] if 'input' in examples else [''] * len(examples['instruction']) - instruction_texts = examples['instruction'] - output_texts = examples['output'] - - texts = [f"{input_text}{instruction_text}{output_text}" for - input_text, instruction_text, output_text in zip(input_texts, instruction_texts, output_texts)] - return tokenizer(texts, truncation=True, padding='max_length', max_length=block_size) - - train_dataset = train_dataset.map(process_examples, batched=True, - remove_columns=['input', 'instruction', 'output']) - train_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask']) - except Exception as e: - print(f"Error loading dataset: {e}") - return f"Error loading dataset. Please check the dataset path and format. Error: {e}", None - - data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False) - - if finetune_method == "Full" or "Freeze": - save_dir = os.path.join("finetuned-models/llm/full", model_output_name) - elif finetune_method == "LORA": - save_dir = os.path.join("finetuned-models/llm/lora", model_output_name) - - os.makedirs(save_dir, exist_ok=True) - - save_path = save_dir - - training_args = TrainingArguments( - output_dir=save_path, - overwrite_output_dir=True, - num_train_epochs=epochs, - per_device_train_batch_size=batch_size, - learning_rate=learning_rate, - weight_decay=weight_decay, - warmup_steps=warmup_steps, - gradient_accumulation_steps=grad_accum_steps, - save_steps=10_000, - save_total_limit=2, - logging_strategy='epoch', - adam_beta1=adam_beta1, - adam_beta2=adam_beta2, - adam_epsilon=adam_epsilon, - lr_scheduler_type=lr_scheduler_type - ) - - if use_xformers: - try: - import xformers - import xformers.ops - model.enable_xformers_memory_efficient_attention() - except ImportError: - print("xformers not installed. Proceeding without memory-efficient attention.") - - if finetune_method == "LORA": - config = LoraConfig( - r=lora_r, - lora_alpha=lora_alpha, - target_modules=["q_proj", "v_proj"], - lora_dropout=lora_dropout, - bias="none", - task_type="CAUSAL_LM" - ) - - model = get_peft_model(model, config) - - if finetune_method == "Freeze": - num_freeze_layers = len(model.transformer.h) - freeze_layers - for i, layer in enumerate(model.transformer.h): - if i < num_freeze_layers: - for param in layer.parameters(): - param.requires_grad = False - - trainer = Trainer( - model=model, - args=training_args, - data_collator=data_collator, - train_dataset=train_dataset, - ) - - try: - trainer.train() - trainer.save_model() - tokenizer.save_pretrained(save_path) - print("Finetuning completed successfully.") - except Exception as e: - print(f"Error during Finetuning: {e}") - return f"Finetuning failed. Error: {e}", None - - loss_values = [log['loss'] for log in trainer.state.log_history if 'loss' in log] - epochs = [log['epoch'] for log in trainer.state.log_history if 'epoch' in log] - - epochs = epochs[:len(loss_values)] - - fig, ax = plt.subplots(figsize=(8, 6)) - ax.plot(epochs, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) - ax.set_ylabel('Loss') - ax.set_xlabel('Epoch') - ax.set_title('Training Loss') - - if loss_values: - ax.set_ylim(bottom=min(loss_values) - 0.01, top=max(loss_values) + 0.01) - ax.set_xticks(epochs) - ax.set_xticklabels([int(epoch) for epoch in epochs]) - else: - print("No loss values found in trainer.state.log_history") - - ax.grid(True) - - plot_dir = save_dir - os.makedirs(plot_dir, exist_ok=True) - plot_path = os.path.join(save_dir, f"{model_output_name}_loss_plot.png") - plt.tight_layout() - plt.savefig(plot_path) - plt.close() - - return f"Finetuning completed. Model saved at: {save_path}", fig - - -def plot_llm_evaluation_metrics(metrics): - if metrics is None: - return None - - metrics_to_plot = ['bleu', 'bert', 'rouge-1', 'rouge-2', 'rouge-l', 'mauve', 'accuracy', 'precision', 'chrf'] - metric_values = [metrics.get(metric, 0) for metric in metrics_to_plot] - - fig, ax = plt.subplots(figsize=(8, 6)) - bar_width = 0.6 - x = range(len(metrics_to_plot)) - bars = ax.bar(x, metric_values, width=bar_width, align='center', color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#aec7e8']) - - ax.set_xticks(x) - ax.set_xticklabels(metrics_to_plot, rotation=45, ha='right') - ax.set_ylabel('Value') - ax.set_title('Evaluation Metrics') - - for bar in bars: - height = bar.get_height() - ax.annotate(f'{height:.2f}', xy=(bar.get_x() + bar.get_width() / 2, height), - xytext=(0, 3), textcoords='offset points', ha='center', va='bottom') - - fig.tight_layout() - return fig - - -def evaluate_llm(model_name, lora_model_name, dataset_file, user_input, max_length, temperature, top_p, top_k): - model_path = os.path.join("finetuned-models/llm/full", model_name) - model, tokenizer = load_model_and_tokenizer(model_name, finetuned=True) - if model is None or tokenizer is None: - return "Error loading model and tokenizer. Please check the model path.", None - - if not model_name: - return "Please select the model", None - - if not dataset_file: - return "Please select the dataset", None - - if lora_model_name and not model_name: - return "Please select the original model", None - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/llm/lora", lora_model_name) - model = PeftModel.from_pretrained(model, lora_model_path) - - dataset_path = os.path.join("datasets/llm", dataset_file) - try: - eval_dataset = load_dataset('json', data_files=dataset_path) - eval_dataset = eval_dataset['train'] - - def process_examples(examples): - input_texts = examples['input'] if 'input' in examples else [''] * len(examples['instruction']) - instruction_texts = examples['instruction'] - output_texts = examples['output'] - - texts = [f"{input_text}{instruction_text}{output_text}" for - input_text, instruction_text, output_text in zip(input_texts, instruction_texts, output_texts)] - return {'input_ids': tokenizer(texts, truncation=True, padding='max_length', max_length=128)['input_ids'], - 'attention_mask': tokenizer(texts, truncation=True, padding='max_length', max_length=128)[ - 'attention_mask'], - 'labels': output_texts} - - eval_dataset = eval_dataset.map(process_examples, batched=True, - remove_columns=['input', 'instruction', 'output']) - eval_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask', 'labels']) - except Exception as e: - print(f"Error loading dataset: {e}") - return f"Error loading dataset. Please check the dataset path and format. Error: {e}", None - - try: - references = eval_dataset['labels'] - predictions = [generate_text(model_name, lora_model_name, "transformers", - user_input if user_input else tokenizer.decode(example['input_ids'], - skip_special_tokens=True), - max_length, temperature, top_p, top_k, output_format='txt')[0] for example in eval_dataset] - - bert_model_name = "google-bert/bert-base-uncased" - bert_repo_url = f"https://huggingface.co/{bert_model_name}" - bert_repo_dir = os.path.join("trainer-scripts", bert_model_name) - - if not os.path.exists(bert_repo_dir): - Repo.clone_from(bert_repo_url, bert_repo_dir) - - predictions = [pred.strip() for pred in predictions if pred.strip()] - references = [ref.strip() for ref in references if ref.strip()] - - bleu_score = sacrebleu.corpus_bleu(predictions, [references]).score - - P, R, F1 = score(predictions, references, lang='en', model_type=bert_model_name, num_layers=12) - bert_score = F1.mean().item() - - rouge = Rouge() - rouge_scores = rouge.get_scores(predictions, references, avg=True) - - max_length = max(len(tokenizer.encode(ref)) for ref in references) - - tokenized_references = tokenizer(references, return_tensors='pt', padding=True, truncation=True, - max_length=max_length) - tokenized_predictions = tokenizer(predictions, return_tensors='pt', padding=True, truncation=True, - max_length=max_length) - - mauve_result = compute_mauve(tokenized_predictions.input_ids, tokenized_references.input_ids) - mauve_score = mauve_result.mauve - - binary_predictions = [1 if pred else 0 for pred in predictions] - binary_references = [1 if ref else 0 for ref in references] - accuracy = accuracy_score(binary_references, binary_predictions) - precision = precision_score(binary_references, binary_predictions) - - chrf_metric = CHRFScore() - for reference, prediction in zip(references, predictions): - chrf_metric.update(prediction, reference) - chrf_score = chrf_metric.compute().item() - - extracted_metrics = { - 'bleu': bleu_score, - 'bert': bert_score, - 'rouge-1': rouge_scores['rouge-1']['f'], - 'rouge-2': rouge_scores['rouge-2']['f'], - 'rouge-l': rouge_scores['rouge-l']['f'], - 'mauve': mauve_score, - 'accuracy': accuracy, - 'precision': precision, - 'chrf': chrf_score - } - - fig = plot_llm_evaluation_metrics(extracted_metrics) - - plot_path = os.path.join(model_path, f"{model_name}_evaluation_plot.png") - fig.savefig(plot_path) - - return f"Evaluation completed successfully. Results saved to {plot_path}", fig - except Exception as e: - print(f"Error during evaluation: {e}") - return f"Evaluation failed. Error: {e}", None - - -def quantize_llm(model_name, quantization_type): - if not model_name: - return "Please select the model" - - model_path = os.path.join("finetuned-models/llm/full", model_name) - llama_cpp_path = "trainer-scripts/llm/llama.cpp" - - os.makedirs(os.path.dirname(llama_cpp_path), exist_ok=True) - - if not os.path.exists(llama_cpp_path): - llama_cpp_repo_url = "https://github.com/ggerganov/llama.cpp.git" - Repo.clone_from(llama_cpp_repo_url, llama_cpp_path) - - try: - os.chdir(llama_cpp_path) - - subprocess.run(f"cmake -B build", shell=True, check=True) - subprocess.run(f"cmake --build build --config Release", shell=True, check=True) - - subprocess.run(f"python convert.py {model_path}", shell=True, check=True) - - input_model = os.path.join(model_path, "ggml-model-f16.ggml") - output_model = os.path.join(model_path, f"ggml-model-{quantization_type}.ggml") - subprocess.run(f"./quantize {input_model} {output_model} {quantization_type}", shell=True, check=True) - - return f"Quantization completed successfully. Model saved at: {output_model}" - - except subprocess.CalledProcessError as e: - return f"Error during quantization: {e}" - finally: - os.chdir(os.path.dirname(os.path.abspath(__file__))) - - -def generate_text(model_name, lora_model_name, model_type, prompt, max_length, temperature, top_p, top_k, output_format): - if model_type == "transformers": - model, tokenizer = load_model_and_tokenizer(model_name, finetuned=True) - if model is None or tokenizer is None: - return None, "Error loading model and tokenizer. Please check the model path." - - if not model_name: - return None, "Please select the model" - - if lora_model_name and not model_name: - return None, "Please select the original model" - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/llm/lora", lora_model_name) - model = PeftModel.from_pretrained(model, lora_model_path) - - try: - input_ids = tokenizer.encode(prompt, return_tensors='pt') - attention_mask = torch.ones(input_ids.shape, dtype=torch.long) - pad_token_id = tokenizer.eos_token_id - - input_ids = input_ids.to(model.device) - attention_mask = attention_mask.to(model.device) - - output = model.generate( - input_ids, - do_sample=True, - attention_mask=attention_mask, - pad_token_id=pad_token_id, - max_new_tokens=max_length, - num_return_sequences=1, - top_p=top_p, - top_k=top_k, - temperature=temperature, - repetition_penalty=1.1, - num_beams=5, - no_repeat_ngram_size=2, - ) - - generated_text = tokenizer.decode(output[0], skip_special_tokens=True) - - output_dir = "outputs/llm" - os.makedirs(output_dir, exist_ok=True) - - timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - output_file = f"llm_history_{timestamp}.{output_format}" - output_path = os.path.join(output_dir, output_file) - - if output_format == "txt": - with open(output_path, "a", encoding="utf-8") as file: - file.write(f"Human: {prompt}\nAI: {generated_text}\n") - elif output_format == "json": - history = [{"Human": prompt, "AI": generated_text}] - with open(output_path, "w", encoding="utf-8") as file: - json.dump(history, file, indent=2, ensure_ascii=False) - - return generated_text, "Text generation successful" - except Exception as e: - print(f"Error during text generation: {e}") - return None, f"Text generation failed. Error: {e}" - - elif model_type == "llama.cpp": - model_path = os.path.join("finetuned-models/llm/full", model_name) - - try: - - llm = Llama(model_path=model_path, n_ctx=max_length, n_parts=-1, seed=-1, f16_kv=True, logits_all=False, vocab_only=False, use_mlock=False, n_threads=8, n_batch=1, suffix=None) - - output = llm(prompt, max_tokens=max_length, top_k=top_k, top_p=top_p, temperature=temperature, stop=None, echo=False) - - generated_text = output['choices'][0]['text'] - - output_dir = "outputs/llm" - os.makedirs(output_dir, exist_ok=True) - - timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - output_file = f"llm_history_{timestamp}.{output_format}" - output_path = os.path.join(output_dir, output_file) - - if output_format == "txt": - with open(output_path, "a", encoding="utf-8") as file: - file.write(f"Human: {prompt}\nAI: {generated_text}\n") - elif output_format == "json": - history = [{"Human": prompt, "AI": generated_text}] - with open(output_path, "w", encoding="utf-8") as file: - json.dump(history, file, indent=2, ensure_ascii=False) - - return generated_text, "Text generation successful" - except Exception as e: - print(f"Error during text generation: {e}") - return None, f"Text generation failed. Error: {e}" - - -def create_sd_dataset(image_files, existing_dataset, dataset_name, file_prefix, prompt_text): - if existing_dataset: - dataset_dir = os.path.join("datasets", "sd", existing_dataset, "train") - else: - dataset_dir = os.path.join("datasets", "sd", dataset_name, "train") - - os.makedirs(dataset_dir, exist_ok=True) - - metadata_file = os.path.join(dataset_dir, "metadata.jsonl") - - with open(metadata_file, "a") as f: - for i, image_file in enumerate(image_files): - file_name = f"{file_prefix}-{i + 1}.jpg" - image_path = os.path.join(dataset_dir, file_name) - image = Image.open(image_file.name) - image.save(image_path) - - metadata = { - "file_name": file_name, - "text": prompt_text - } - f.write(json.dumps(metadata) + "\n") - - return f"Dataset {'updated' if existing_dataset else 'created'} successfully at {dataset_dir}" - - -def finetune_sd(model_name, dataset_name, model_type, finetune_method, model_output_name, resolution, - train_batch_size, gradient_accumulation_steps, - learning_rate, lr_scheduler, lr_warmup_steps, max_train_steps, adam_beta1, adam_beta2, adam_weight_decay, adam_epsilon, max_grad_norm, noise_offset, rank, enable_xformers): - model_path = os.path.join("models/sd", model_name) - dataset_path = os.path.join("datasets/sd", dataset_name) - - if not model_name: - return "Please select the model", None - - if not dataset_name: - return "Please select the dataset", None - - if not model_output_name: - return "Please write the model name", None - - if finetune_method == "Full": - output_dir = os.path.join("finetuned-models/sd/full", model_output_name) - if model_type == "SD": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - elif model_type == "SDXL": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_sdxl.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - elif finetune_method == "LORA": - output_dir = os.path.join("finetuned-models/sd/lora", model_output_name) - if model_type == "SD": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_lora.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--rank={rank}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - elif model_type == "SDXL": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_lora_sdxl.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--rank={rank}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - else: - raise ValueError(f"Invalid finetune method: {finetune_method}") - - subprocess.run(args) - - if finetune_method == "Full": - logs_dir = os.path.join(output_dir, "logs", "text2image-fine-tune") - events_files = [f for f in os.listdir(logs_dir) if f.startswith("events.out.tfevents")] - latest_event_file = sorted(events_files)[-1] - event_file_path = os.path.join(logs_dir, latest_event_file) - - event_acc = EventAccumulator(event_file_path) - event_acc.Reload() - - loss_values = [s.value for s in event_acc.Scalars("train_loss")] - steps = [s.step for s in event_acc.Scalars("train_loss")] - - fig, ax = plt.subplots(figsize=(8, 6)) - ax.plot(steps, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) - ax.set_ylabel('Loss') - ax.set_xlabel('Step') - ax.set_title('Training Loss') - ax.grid(True) - - plot_path = os.path.join(output_dir, f"{model_name}_loss_plot.png") - plt.tight_layout() - plt.savefig(plot_path) - plt.close() - - return f"Fine-tuning completed. Model saved at: {output_dir}", fig - - elif finetune_method == "LORA": - logs_dir = os.path.join(output_dir, "logs", "text2image-fine-tune") - events_files = [f for f in os.listdir(logs_dir) if f.startswith("events.out.tfevents")] - latest_event_file = sorted(events_files)[-1] - event_file_path = os.path.join(logs_dir, latest_event_file) - - event_acc = EventAccumulator(event_file_path) - event_acc.Reload() - - loss_values = [s.value for s in event_acc.Scalars("train_loss")] - steps = [s.step for s in event_acc.Scalars("train_loss")] - - fig, ax = plt.subplots(figsize=(8, 6)) - ax.plot(steps, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) - ax.set_ylabel('Loss') - ax.set_xlabel('Step') - ax.set_title('Training Loss') - ax.grid(True) - - plot_path = os.path.join(output_dir, f"{model_name}_loss_plot.png") - plt.tight_layout() - plt.savefig(plot_path) - plt.close() - - return f"Finetuning completed. Model saved at: {output_dir}", fig - - -def plot_sd_evaluation_metrics(metrics): - metrics_to_plot = ["FID", "KID", "Inception Score", "VIF", "CLIP Score", "LPIPS", "SCC", "SDI", "SAM", "SSIM"] - metric_values = [metrics[metric] for metric in metrics_to_plot] - - fig, ax = plt.subplots(figsize=(8, 6)) - bar_width = 0.6 - x = range(len(metrics_to_plot)) - bars = ax.bar(x, metric_values, width=bar_width, align="center", color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#bcbd22', '#17becf', '#aaffc3', '#ffe119']) - - ax.set_xticks(x) - ax.set_xticklabels(metrics_to_plot, rotation=45, ha="right") - ax.set_ylabel("Value") - ax.set_title("Evaluation Metrics") - - for bar in bars: - height = bar.get_height() - ax.annotate(f"{height:.2f}", xy=(bar.get_x() + bar.get_width() / 2, height), - xytext=(0, 3), textcoords="offset points", ha="center", va="bottom") - - fig.tight_layout() - return fig - - -def evaluate_sd(model_name, lora_model_name, dataset_name, model_method, model_type, user_prompt, negative_prompt, num_inference_steps, cfg_scale): - if model_method == "Diffusers": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_pretrained(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_method == "Safetensors": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_single_file(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_single_file(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - else: - return "Invalid model type selected", None - - if not model_name: - return "Please select the model", None - - if not dataset_name: - return "Please select the dataset", None - - if lora_model_name and not model_name: - return "Please select the original model", None - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/sd/lora", lora_model_name) - model.unet.load_attn_procs(lora_model_path) - - dataset_path = os.path.join("datasets/sd", dataset_name) - dataset = load_dataset("imagefolder", data_dir=dataset_path) - - num_samples = len(dataset["train"]) - subset_size = min(num_samples, 50) - - fid = FrechetInceptionDistance().to("cuda") - kid = KernelInceptionDistance(subset_size=subset_size).to("cuda") - inception = InceptionScore().to("cuda") - vif = VisualInformationFidelity().to("cuda") - lpips = LearnedPerceptualImagePatchSimilarity().to("cuda") - scc = SpatialCorrelationCoefficient().to("cuda") - sdi = SpectralDistortionIndex().to("cuda") - sam = SpectralAngleMapper().to("cuda") - ssim = StructuralSimilarityIndexMeasure().to("cuda") - - clip_model_name = "openai/clip-vit-base-patch16" - clip_repo_url = f"https://huggingface.co/{clip_model_name}" - clip_repo_dir = os.path.join("trainer-scripts", clip_model_name) - - if not os.path.exists(clip_repo_dir): - Repo.clone_from(clip_repo_url, clip_repo_dir) - - clip_score = CLIPScore(model_name_or_path=clip_model_name).to("cuda") - - resize = Resize((512, 512)) - - clip_scores = [] - - for batch in dataset["train"]: - image = batch["image"].convert("RGB") - image_tensor = torch.from_numpy(np.array(image)).permute(2, 0, 1).unsqueeze(0).to("cuda").to(torch.uint8) - - generated_images = model(prompt=user_prompt, negative_prompt=negative_prompt, num_inference_steps=num_inference_steps, guidance_scale=cfg_scale, - output_type="pil").images - generated_image = generated_images[0].resize((image.width, image.height)) - generated_image_tensor = torch.from_numpy(np.array(generated_image)).permute(2, 0, 1).unsqueeze(0).to( - "cuda").to(torch.uint8) - - fid.update(resize(image_tensor), real=True) - fid.update(resize(generated_image_tensor), real=False) - - kid.update(resize(image_tensor), real=True) - kid.update(resize(generated_image_tensor), real=False) - - inception.update(resize(generated_image_tensor)) - - vif.update(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - - lpips_score = lpips(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - scc_score = scc(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - sdi_score = sdi(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - sam_score = sam(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - ssim_score = ssim(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - - clip_score_value = clip_score(resize(generated_image_tensor).to(torch.float32), "a photo of a generated image") - clip_scores.append(clip_score_value.detach().item()) - - fid_score = fid.compute() - kid_score, _ = kid.compute() - inception_score, _ = inception.compute() - vif_score = vif.compute() - clip_score_avg = np.mean(clip_scores) - - metrics = { - "FID": fid_score.item(), - "KID": kid_score.item(), - "Inception Score": inception_score.item(), - "VIF": vif_score.item(), - "CLIP Score": clip_score_avg, - "LPIPS": lpips_score.item(), - "SCC": scc_score.item(), - "SDI": sdi_score.item(), - "SAM": sam_score.item(), - "SSIM": ssim_score.item() - } - - fig = plot_sd_evaluation_metrics(metrics) - - if model_method == "Diffusers": - plot_path = os.path.join(model_path, f"{model_name}_evaluation_plot.png") - elif model_method == "Safetensors": - plot_path = os.path.join("finetuned-models/sd/full", f"{model_name}_evaluation_plot.png") - fig.savefig(plot_path) - - return f"Evaluation completed successfully. Results saved to {plot_path}", fig - - -def convert_sd_model_to_safetensors(model_name, model_type, use_half, use_safetensors): - model_path = os.path.join("finetuned-models/sd/full", model_name) - output_path = os.path.join("finetuned-models/sd/full") - - if model_type == "SD": - try: - args = [ - "py", - "trainer-scripts/sd/convert_diffusers_to_original_stable_diffusion.py", - "--model_path", model_path, - "--checkpoint_path", output_path, - ] - if use_half: - args.append("--half") - if use_safetensors: - args.append("--use_safetensors") - - subprocess.run(args, check=True) - - return f"Model successfully converted to single file and saved to {output_path}" - except subprocess.CalledProcessError as e: - return f"Error converting model to single file: {e}" - elif model_type == "SDXL": - try: - args = [ - "py", - "trainer-scripts/sd/convert_diffusers_to_original_sdxl.py", - "--model_path", model_path, - "--checkpoint_path", output_path, - ] - if use_half: - args.append("--half") - if use_safetensors: - args.append("--use_safetensors") - - subprocess.run(args, check=True) - - return f"Model successfully converted to single file and saved to {output_path}" - except subprocess.CalledProcessError as e: - return f"Error converting model to single file: {e}" - - -def generate_image(model_name, lora_model_name, model_method, model_type, prompt, negative_prompt, num_inference_steps, cfg_scale, width, height, output_format): - if model_method == "Diffusers": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_pretrained(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_method == "Safetensors": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_single_file(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_single_file(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - else: - return "Invalid model type selected", None - - if not model_name: - return "Please select the model", None - - if lora_model_name and not model_name: - return "Please select the original model", None - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/sd/lora", lora_model_name) - model.unet.load_attn_procs(lora_model_path) - - image = model(prompt, negative_prompt=negative_prompt, num_inference_steps=num_inference_steps, - guidance_scale=cfg_scale, width=width, height=height).images[0] - - output_dir = "outputs/sd" - os.makedirs(output_dir, exist_ok=True) - - timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - output_file = f"sd_image_{timestamp}.{output_format}" - output_path = os.path.join(output_dir, output_file) - - image.save(output_path) - - return image, "Image generation successful" - - -def close_terminal(): - os._exit(1) - - -def open_finetuned_folder(): - outputs_folder = "finetuned-models" - if os.path.exists(outputs_folder): - if os.name == "nt": - os.startfile(outputs_folder) - else: - os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') - - -def open_datasets_folder(): - outputs_folder = "datasets" - if os.path.exists(outputs_folder): - if os.name == "nt": - os.startfile(outputs_folder) - else: - os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') - - -def open_outputs_folder(): - outputs_folder = "outputs" - if os.path.exists(outputs_folder): - if os.name == "nt": - os.startfile(outputs_folder) - else: - os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') - - -def download_model(model_name_llm, model_name_sd): - if not model_name_llm and not model_name_sd: - return "Please select a model to download" - - if model_name_llm and model_name_sd: - return "Please select one model type for downloading" - - if model_name_llm: - model_url = "" - if model_name_llm == "StableLM2-1_6B-Chat": - model_url = "https://huggingface.co/stabilityai/stablelm-2-1_6b-chat" - elif model_name_llm == "Qwen1.5-4B-Chat": - model_url = "https://huggingface.co/Qwen/Qwen1.5-4B-Chat" - model_path = os.path.join("models", "llm", model_name_llm) - - if model_url: - response = requests.get(model_url, allow_redirects=True) - with open(model_path, "wb") as file: - file.write(response.content) - return f"LLM model {model_name_llm} downloaded successfully!" - else: - return "Invalid LLM model name" - - if model_name_sd: - model_url = "" - if model_name_sd == "StableDiffusion1.5": - model_url = "https://huggingface.co/runwayml/stable-diffusion-v1-5" - elif model_name_sd == "StableDiffusionXL": - model_url = "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0" - model_path = os.path.join("models", "sd", model_name_sd) - - if model_url: - response = requests.get(model_url, allow_redirects=True) - with open(model_path, "wb") as file: - file.write(response.content) - return f"StableDiffusion model {model_name_sd} downloaded successfully!" - else: - return "Invalid StableDiffusion model name" - - -def settings_interface(share_value): - global share_mode - share_mode = share_value == "True" - message = f"Settings updated successfully!" - - app.launch(share=share_mode, server_name="localhost") - - return message - - -share_mode = False - -llm_dataset_interface = gr.Interface( - fn=create_llm_dataset, - inputs=[ - gr.Dropdown(choices=get_available_llm_datasets(), label="Existing Dataset (optional)"), - gr.Textbox(label="Dataset Name", type="text"), - gr.Textbox(label="Instruction", type="text"), - gr.Textbox(label="Input", type="text"), - gr.Textbox(label="Output", type="text"), - ], - outputs=[ - gr.Textbox(label="Status", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Dataset", - description="Create a new dataset or add a new column to an existing dataset for LLM", - allow_flagging="never", -) - -llm_finetune_interface = gr.Interface( - fn=finetune_llm, - inputs=[ - gr.Dropdown(choices=get_available_llm_models(), label="Model"), - gr.Dropdown(choices=get_available_llm_datasets(), label="Dataset"), - gr.Radio(choices=["Full", "Freeze", "LORA"], value="Full", label="Finetune Method"), - gr.Textbox(label="Output Model Name", type="text"), - gr.Number(value=10, label="Epochs"), - gr.Number(value=4, label="Batch size"), - gr.Number(value=3e-5, label="Learning rate"), - gr.Number(value=0.01, label="Weight decay"), - gr.Number(value=100, label="Warmup steps"), - gr.Number(value=128, label="Block size"), - gr.Number(value=1, label="Gradient accumulation steps"), - gr.Number(value=0.9, label="Adam beta 1"), - gr.Number(value=0.999, label="Adam beta 2"), - gr.Number(value=1e-8, label="Adam epsilon"), - gr.Dropdown(choices=["linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"], value="linear", label="LR Scheduler"), - gr.Number(value=2, label="Freeze layers"), - gr.Number(value=16, label="LORA r"), - gr.Number(value=32, label="LORA alpha"), - gr.Number(value=0.05, label="LORA dropout"), - gr.Checkbox(label="Use xformers", value=False), - ], - outputs=[ - gr.Textbox(label="Finetuning Status", type="text"), - gr.Plot(label="Finetuning Loss") - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Finetune", - description="Finetune LLM models on a custom dataset", - allow_flagging="never", -) - -llm_evaluate_interface = gr.Interface( - fn=evaluate_llm, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_llm_models(), label="Model"), - gr.Dropdown(choices=get_available_llm_lora_models(), label="LORA Model (optional)"), - gr.Dropdown(choices=get_available_llm_datasets(), label="Dataset"), - gr.Textbox(label="Request", type="text"), - gr.Slider(minimum=1, maximum=2048, value=128, step=1, label="Max Length"), - gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label="Temperature"), - gr.Slider(minimum=0.0, maximum=1.0, value=0.9, step=0.1, label="Top P"), - gr.Slider(minimum=0, maximum=100, value=20, step=1, label="Top K"), - ], - outputs=[ - gr.Textbox(label="Evaluation Status"), - gr.Plot(label="Evaluation Metrics"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Evaluate", - description="Evaluate finetuned LLM models on a custom dataset", - allow_flagging="never", -) - -llm_quantize_interface = gr.Interface( - fn=quantize_llm, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_llm_models(), label="Model"), - gr.Radio(choices=["Q2_K_M", "Q4_K_M", "Q6_K_M", "Q8_K_M"], value="Q4_K_M", label="Quantization Type"), - ], - outputs=[ - gr.Textbox(label="Quantization Status", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Quantize", - description="Quantize finetuned LLM models to .gguf format using llama.cpp", - allow_flagging="never", -) - -llm_generate_interface = gr.Interface( - fn=generate_text, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_llm_models(), label="Model"), - gr.Dropdown(choices=get_available_llm_lora_models(), label="LORA Model (optional)"), - gr.Radio(choices=["transformers", "llama.cpp"], value="transformers", label="Model Type"), - gr.Textbox(label="Request", type="text"), - gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max length"), - gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label="Temperature"), - gr.Slider(minimum=0.0, maximum=1.0, value=0.9, step=0.1, label="Top P"), - gr.Slider(minimum=0, maximum=100, value=20, step=1, label="Top K"), - gr.Radio(choices=["txt", "json"], value="txt", label="Output Format"), - ], - outputs=[ - gr.Textbox(label="Generated text", type="text"), - gr.Textbox(label="Message", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Generate", - description="Generate text using finetuned LLM models", - allow_flagging="never", -) - -sd_dataset_interface = gr.Interface( - fn=create_sd_dataset, - inputs=[ - gr.Files(label="Image Files"), - gr.Dropdown(choices=get_available_sd_datasets(), label="Existing Dataset (optional)"), - gr.Textbox(label="Dataset Name"), - gr.Textbox(label="Files Name"), - gr.Textbox(label="Prompt Text") - ], - outputs=[ - gr.Textbox(label="Status") - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Dataset", - description="Create a new dataset or add a new column to an existing dataset for Stable Diffusion", - allow_flagging="never", -) - -sd_finetune_interface = gr.Interface( - fn=finetune_sd, - inputs=[ - gr.Dropdown(choices=get_available_sd_models(), label="Model"), - gr.Dropdown(choices=get_available_sd_datasets(), label="Dataset"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Radio(choices=["Full", "LORA"], value="Full", label="Finetune Method"), - gr.Textbox(label="Output Model Name", type="text"), - gr.Number(value=512, label="Resolution"), - gr.Number(value=1, label="Train Batch Size"), - gr.Number(value=1, label="Gradient Accumulation Steps"), - gr.Number(value=5e-6, label="Learning Rate"), - gr.Dropdown(choices=["linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"], value="linear", label="LR Scheduler"), - gr.Number(value=0, label="LR Warmup Steps"), - gr.Number(value=100, label="Max Train Steps"), - gr.Number(value=0.9, label="Adam beta 1"), - gr.Number(value=0.999, label="Adam beta 2"), - gr.Number(value=1e-2, label="Adam weight decay"), - gr.Number(value=1e-8, label="Adam epsilon"), - gr.Number(value=1.0, label="Max grad norm"), - gr.Number(value=0, label="Noise offset"), - gr.Number(value=4, label="LORA Rank"), - gr.Checkbox(label="Use xformers", value=False), - ], - outputs=[ - gr.Textbox(label="Finetuning Status", type="text"), - gr.Plot(label="Finetuning Loss") - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Finetune", - description="Finetune Stable Diffusion models on a custom dataset", - allow_flagging="never", -) - -sd_evaluate_interface = gr.Interface( - fn=evaluate_sd, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_sd_models(), label="Model"), - gr.Dropdown(choices=get_available_sd_lora_models(), label="LORA Model (optional)"), - gr.Dropdown(choices=get_available_sd_datasets(), label="Dataset"), - gr.Radio(choices=["Diffusers", "Safetensors"], value="Diffusers", label="Model Method"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Textbox(label="Prompt", type="text"), - gr.Textbox(label="Negative Prompt", type="text"), - gr.Slider(minimum=1, maximum=150, value=30, step=1, label="Steps"), - gr.Slider(minimum=1, maximum=30, value=8, step=0.5, label="CFG"), - ], - outputs=[ - gr.Textbox(label="Evaluation Status"), - gr.Plot(label="Evaluation Metrics"), - ], - title="NeuroTrainerWebUI (ALPHA) - StabledDiffusion-Evaluate", - description="Evaluate finetuned Stable Diffusion models on a custom dataset", - allow_flagging="never", -) - -sd_convert_interface = gr.Interface( - fn=convert_sd_model_to_safetensors, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_sd_models(), label="Model"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Checkbox(label="Use Half Precision", value=False), - gr.Checkbox(label="Use Safetensors", value=False), - ], - outputs=[ - gr.Textbox(label="Conversion Status", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Conversion", - description="Convert finetuned Stable Diffusion models to single file (.ckpt or .safetensors)", - allow_flagging="never", -) - -sd_generate_interface = gr.Interface( - fn=generate_image, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_sd_models(), label="Model"), - gr.Dropdown(choices=get_available_sd_lora_models(), label="LORA Model (optional)"), - gr.Radio(choices=["Diffusers", "Safetensors"], value="Diffusers", label="Model Method"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Textbox(label="Prompt", type="text"), - gr.Textbox(label="Negative Prompt", type="text"), - gr.Slider(minimum=1, maximum=150, value=30, step=1, label="Steps"), - gr.Slider(minimum=1, maximum=30, value=8, step=0.5, label="CFG"), - gr.Slider(minimum=256, maximum=1024, value=512, step=64, label="Width"), - gr.Slider(minimum=256, maximum=1024, value=512, step=64, label="Height"), - gr.Radio(choices=["png", "jpeg"], value="png", label="Output Format"), - ], - outputs=[ - gr.Image(label="Generated Image"), - gr.Textbox(label="Message", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Generate", - description="Generate images using finetuned Stable Diffusion models", - allow_flagging="never", -) - -model_downloader_interface = gr.Interface( - fn=download_model, - inputs=[ - gr.Dropdown(choices=[None, "StableLM2-1_6B-Chat", "Qwen1.5-4B-Chat"], label="Download LLM model", value=None), - gr.Dropdown(choices=[None, "StableDiffusion1.5", "StableDiffusionXL"], label="Download StableDiffusion model", value=None), - ], - outputs=[ - gr.Textbox(label="Message", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - ModelDownloader", - description="This interface allows you to download LLM and StableDiffusion models", - allow_flagging="never", -) - -settings_interface = gr.Interface( - fn=settings_interface, - inputs=[ - gr.Radio(choices=["True", "False"], label="Share Mode", value="False") - ], - outputs=[ - gr.Textbox(label="Message", type="text") - ], - title="NeuroTrainerWebUI (ALPHA) - Settings", - description="This interface allows you to change settings of application", - allow_flagging="never", -) - -system_interface = gr.Interface( - fn=get_system_info, - inputs=[], - outputs=[ - gr.Textbox(label="GPU Total Memory"), - gr.Textbox(label="GPU Used Memory"), - gr.Textbox(label="GPU Free Memory"), - gr.Textbox(label="GPU Temperature"), - gr.Textbox(label="CPU Temperature"), - gr.Textbox(label="RAM Total"), - gr.Textbox(label="RAM Used"), - gr.Textbox(label="RAM Free"), - ], - title="NeuroTrainerWebUI (ALPHA) - System", - description="This interface displays system information", - allow_flagging="never", -) - -with gr.TabbedInterface([gr.TabbedInterface([llm_dataset_interface, llm_finetune_interface, llm_evaluate_interface, llm_quantize_interface, llm_generate_interface], - tab_names=["Dataset", "Finetune", "Evaluate", "Quantize", "Generate"]), - gr.TabbedInterface([sd_dataset_interface, sd_finetune_interface, sd_evaluate_interface, sd_convert_interface, sd_generate_interface], - tab_names=["Dataset", "Finetune", "Evaluate", "Conversion", "Generate"]), - model_downloader_interface, settings_interface, system_interface], - tab_names=["LLM", "StableDiffusion", "Settings", "ModelDownloader", "System"]) as app: - close_button = gr.Button("Close terminal") - close_button.click(close_terminal, [], [], queue=False) - - folder_button = gr.Button("Finetuned-models") - folder_button.click(open_finetuned_folder, [], [], queue=False) - - folder_button = gr.Button("Datasets") - folder_button.click(open_datasets_folder, [], [], queue=False) - - folder_button = gr.Button("Outputs") - folder_button.click(open_outputs_folder, [], [], queue=False) - - github_link = gr.HTML( - '
' - '' - 'GitHub' - '' - '' - 'Hugging Face' - '' - '
' - ) - - app.launch(share=share_mode, server_name="localhost", auth=authenticate) diff --git a/GradioAuth.txt b/GradioAuth.txt deleted file mode 100644 index 3663ae8..0000000 --- a/GradioAuth.txt +++ /dev/null @@ -1 +0,0 @@ -admin:admin \ No newline at end of file diff --git a/Install.bat b/Install.bat index 5121507..cc47441 100644 --- a/Install.bat +++ b/Install.bat @@ -2,23 +2,45 @@ chcp 65001 > NUL set CURRENT_DIR=%~dp0 -echo Creating virtual environment.../Создание виртуальной среды... +echo Creating virtual environment... py -m venv "%CURRENT_DIR%venv" call "%CURRENT_DIR%venv\Scripts\activate.bat" cls -echo Upgrading pip, setuptools and whell.../Обновление pip, setuptools и wheel... -py -m pip install --upgrade pip setuptools -pip install wheel +echo Upgrading pip, setuptools and wheel... +python -m pip install --upgrade pip +pip install wheel setuptools +timeout /t 3 /nobreak >nul cls -echo Installing dependencies.../Установка зависимостей... -pip install --no-deps -r "%CURRENT_DIR%requirements.txt" -pip install --no-deps -r "%CURRENT_DIR%requirements-cuda.txt" -pip install --no-deps -r "%CURRENT_DIR%requirements-llama-cpp.txt" +echo Installing dependencies... +if not exist "%CURRENT_DIR%logs" mkdir "%CURRENT_DIR%logs" +set ERROR_LOG="%CURRENT_DIR%logs\installation_errors.log" +type nul > %ERROR_LOG% + +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements.txt" 2>> %ERROR_LOG% +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements-cuda.txt" 2>> %ERROR_LOG% +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements-llama-cpp.txt" 2>> %ERROR_LOG% +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements-stable-diffusion-cpp.txt" 2>> %ERROR_LOG% +timeout /t 3 /nobreak >nul +cls + +echo Post-installing patches... +python "%CURRENT_DIR%RequirementsFiles\post_install.py" +timeout /t 3 /nobreak >nul +cls + +echo Checking for installation errors... +findstr /C:"error" %ERROR_LOG% >nul +if %ERRORLEVEL% equ 0 ( + echo Some packages failed to install. Please check %ERROR_LOG% for details. +) else ( + echo Installation completed successfully. +) +timeout /t 5 /nobreak >nul cls -echo Application has been installed successfully. Run start.bat/Приложение успешно установлено. Запустите start.bat +echo Application installation process completed. Run start.bat to launch the application. call "%CURRENT_DIR%venv\Scripts\deactivate.bat" diff --git a/Install.sh b/Install.sh index dda953b..3e8262b 100644 --- a/Install.sh +++ b/Install.sh @@ -2,24 +2,45 @@ CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" -echo "Creating virtual environment.../Создание виртуальной среды..." +echo "Creating virtual environment..." python3 -m venv "$CURRENT_DIR/venv" source "$CURRENT_DIR/venv/bin/activate" clear -echo "Upgrading pip, setuptools and whell.../Обновление pip, setuptools и wheel..." -python3 -m pip install --upgrade pip setuptools -pip install wheel +echo "Upgrading pip, setuptools and wheel..." +python3 -m pip install --upgrade pip +pip install wheel setuptools +sleep 3 clear -echo "Installing dependencies.../Установка зависимостей..." -pip install --no-deps -r "$CURRENT_DIR/requirements.txt" -pip install --no-deps -r "$CURRENT_DIR/requirements-cuda.txt" -pip install --no-deps -r "$CURRENT_DIR/requirements-llama-cpp.txt" +echo "Installing dependencies..." +mkdir -p "$CURRENT_DIR/logs" +ERROR_LOG="$CURRENT_DIR/logs/installation_errors.log" +touch "$ERROR_LOG" + +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements.txt" 2>> "$ERROR_LOG" +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements-cuda.txt" 2>> "$ERROR_LOG" +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements-llama-cpp.txt" 2>> "$ERROR_LOG" +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements-stable-diffusion-cpp.txt" 2>> "$ERROR_LOG" +sleep 3 +clear + +echo "Post-installing patches..." +python3 "$CURRENT_DIR/RequirementsFiles/post_install.py" +sleep 3 +clear + +echo "Checking for installation errors..." +if grep -iq "error" "$ERROR_LOG"; then + echo "Some packages failed to install. Please check $ERROR_LOG for details." +else + echo "All packages installed successfully." +fi +sleep 5 clear -echo "Application has been installed successfully. Run start.sh/Приложение успешно установлено. Запустите start.sh" +echo "Application installation process completed. Run start.sh to launch the application." deactivate -read -p "Press enter to continue/Нажмите enter для продолжения" +read -p "Press enter to continue" \ No newline at end of file diff --git a/AppEN.py b/LaunchFile/app.py similarity index 67% rename from AppEN.py rename to LaunchFile/app.py index c736e92..935c0ac 100644 --- a/AppEN.py +++ b/LaunchFile/app.py @@ -1,1448 +1,1751 @@ -import os -from git import Repo -import requests -import gradio as gr -from transformers import AutoModelForCausalLM, AutoTokenizer, DataCollatorForLanguageModeling, Trainer, TrainingArguments -from llama_cpp import Llama -from peft import LoraConfig, get_peft_model, PeftModel -from diffusers import StableDiffusionPipeline, StableDiffusionXLPipeline, DDPMScheduler -from datasets import load_dataset -import matplotlib.pyplot as plt -import numpy as np -from PIL import Image -import torch -from bert_score import score -import json -from datetime import datetime -from torchmetrics.text.chrf import CHRFScore -from torchmetrics.image.fid import FrechetInceptionDistance -from torchmetrics.image.kid import KernelInceptionDistance -from torchmetrics.image.inception import InceptionScore -from torchmetrics.image.vif import VisualInformationFidelity -from torchvision.transforms import Resize -from torchmetrics.multimodal.clip_score import CLIPScore -from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity -from torchmetrics.image.scc import SpatialCorrelationCoefficient -from torchmetrics.image import SpectralDistortionIndex -from torchmetrics.image import SpectralAngleMapper -from torchmetrics.image.ssim import StructuralSimilarityIndexMeasure -import psutil -import GPUtil -from cpuinfo import get_cpu_info -from pynvml import nvmlInit, nvmlDeviceGetHandleByIndex, nvmlDeviceGetTemperature, NVML_TEMPERATURE_GPU -import sacrebleu -from rouge import Rouge -import subprocess -from tensorboard.backend.event_processing.event_accumulator import EventAccumulator -from mauve import compute_mauve -from sklearn.metrics import accuracy_score, precision_score - - -def authenticate(username, password): - try: - with open("GradioAuth.txt", "r") as file: - stored_credentials = file.read().strip().split(":") - if len(stored_credentials) == 2: - stored_username, stored_password = stored_credentials - return username == stored_username and password == stored_password - except FileNotFoundError: - print("Authentication file not found.") - except Exception as e: - print(f"Error reading authentication file: {e}") - return False - - -def get_system_info(): - gpu = GPUtil.getGPUs()[0] - gpu_total_memory = f"{gpu.memoryTotal} MB" - gpu_used_memory = f"{gpu.memoryUsed} MB" - gpu_free_memory = f"{gpu.memoryFree} MB" - - nvmlInit() - handle = nvmlDeviceGetHandleByIndex(0) - gpu_temp = nvmlDeviceGetTemperature(handle, NVML_TEMPERATURE_GPU) - - cpu_info = get_cpu_info() - cpu_temp = cpu_info.get("cpu_temp", None) - - ram = psutil.virtual_memory() - ram_total = f"{ram.total // (1024 ** 3)} GB" - ram_used = f"{ram.used // (1024 ** 3)} GB" - ram_free = f"{ram.available // (1024 ** 3)} GB" - - return gpu_total_memory, gpu_used_memory, gpu_free_memory, gpu_temp, cpu_temp, ram_total, ram_used, ram_free - - -def get_available_llm_models(): - models_dir = "models/llm" - os.makedirs(models_dir, exist_ok=True) - - llm_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - llm_available_models.append(model_name) - - return llm_available_models - - -def get_available_llm_lora_models(): - models_dir = "finetuned-models/llm/lora" - os.makedirs(models_dir, exist_ok=True) - - llm_lora_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - llm_lora_available_models.append(model_name) - - return llm_lora_available_models - - -def get_available_finetuned_llm_models(): - models_dir = "finetuned-models/llm/full" - os.makedirs(models_dir, exist_ok=True) - - finetuned_available_llm_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - finetuned_available_llm_models.append(model_name) - - return finetuned_available_llm_models - - -def get_available_llm_datasets(): - datasets_dir = "datasets/llm" - os.makedirs(datasets_dir, exist_ok=True) - - llm_available_datasets = [] - for dataset_file in os.listdir(datasets_dir): - if dataset_file.endswith(".json"): - llm_available_datasets.append(dataset_file) - - return llm_available_datasets - - -def get_available_sd_models(): - models_dir = "models/sd" - os.makedirs(models_dir, exist_ok=True) - - sd_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - sd_available_models.append(model_name) - - return sd_available_models - - -def get_available_sd_lora_models(): - models_dir = "finetuned-models/sd/lora" - os.makedirs(models_dir, exist_ok=True) - - sd_lora_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path): - sd_lora_available_models.append(model_name) - - return sd_lora_available_models - - -def get_available_finetuned_sd_models(): - models_dir = "finetuned-models/sd/full" - os.makedirs(models_dir, exist_ok=True) - - finetuned_sd_available_models = [] - for model_name in os.listdir(models_dir): - model_path = os.path.join(models_dir, model_name) - if os.path.isdir(model_path) or model_name.endswith(".safetensors"): - finetuned_sd_available_models.append(model_name) - - return finetuned_sd_available_models - - -def get_available_sd_datasets(): - datasets_dir = "datasets/sd" - os.makedirs(datasets_dir, exist_ok=True) - - sd_available_datasets = [] - for dataset_dir in os.listdir(datasets_dir): - dataset_path = os.path.join(datasets_dir, dataset_dir) - if os.path.isdir(dataset_path): - sd_available_datasets.append(dataset_dir) - - return sd_available_datasets - - -def load_model_and_tokenizer(model_name, finetuned=False): - if finetuned: - model_path = os.path.join("finetuned-models/llm/full", model_name) - else: - model_path = os.path.join("models/llm", model_name) - try: - device = "cuda" - model = AutoModelForCausalLM.from_pretrained(model_path, device_map=device) - tokenizer = AutoTokenizer.from_pretrained(model_path) - return model, tokenizer - except Exception as e: - print(f"Error loading model and tokenizer: {e}") - return None, None - - -def create_llm_dataset(existing_file, file_name, instruction, input_text, output_text): - if existing_file: - file_path = os.path.join("datasets", "llm", existing_file) - with open(file_path, "r") as f: - data = json.load(f) - data.append({"instruction": instruction, "input": input_text, "output": output_text}) - with open(file_path, "w") as f: - json.dump(data, f, indent=2) - return f"New column added to the existing file: {existing_file}" - else: - file_path = os.path.join("datasets", "llm", f"{file_name}.json") - data = [{"instruction": instruction, "input": input_text, "output": output_text}] - with open(file_path, "w") as f: - json.dump(data, f, indent=2) - return f"New dataset file created: {file_name}.json" - - -def finetune_llm(model_name, dataset_file, finetune_method, model_output_name, epochs, batch_size, learning_rate, - weight_decay, warmup_steps, block_size, grad_accum_steps, adam_beta1, adam_beta2, adam_epsilon, lr_scheduler_type, freeze_layers, lora_r, lora_alpha, lora_dropout, use_xformers=False): - model, tokenizer = load_model_and_tokenizer(model_name) - if model is None or tokenizer is None: - return "Error loading model and tokenizer. Please check the model path.", None - - if not model_name: - return "Please select the model", None - - if not dataset_file: - return "Please select the dataset", None - - if not model_output_name: - return "Please write the model name", None - - dataset_path = os.path.join("datasets/llm", dataset_file) - try: - train_dataset = load_dataset('json', data_files=dataset_path) - train_dataset = train_dataset['train'] - - def process_examples(examples): - input_texts = examples['input'] if 'input' in examples else [''] * len(examples['instruction']) - instruction_texts = examples['instruction'] - output_texts = examples['output'] - - texts = [f"{input_text}{instruction_text}{output_text}" for - input_text, instruction_text, output_text in zip(input_texts, instruction_texts, output_texts)] - return tokenizer(texts, truncation=True, padding='max_length', max_length=block_size) - - train_dataset = train_dataset.map(process_examples, batched=True, - remove_columns=['input', 'instruction', 'output']) - train_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask']) - except Exception as e: - print(f"Error loading dataset: {e}") - return f"Error loading dataset. Please check the dataset path and format. Error: {e}", None - - data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False) - - if finetune_method == "Full" or "Freeze": - save_dir = os.path.join("finetuned-models/llm/full", model_output_name) - elif finetune_method == "LORA": - save_dir = os.path.join("finetuned-models/llm/lora", model_output_name) - - os.makedirs(save_dir, exist_ok=True) - - save_path = save_dir - - training_args = TrainingArguments( - output_dir=save_path, - overwrite_output_dir=True, - num_train_epochs=epochs, - per_device_train_batch_size=batch_size, - learning_rate=learning_rate, - weight_decay=weight_decay, - warmup_steps=warmup_steps, - gradient_accumulation_steps=grad_accum_steps, - save_steps=10_000, - save_total_limit=2, - logging_strategy='epoch', - adam_beta1=adam_beta1, - adam_beta2=adam_beta2, - adam_epsilon=adam_epsilon, - lr_scheduler_type=lr_scheduler_type - ) - - if use_xformers: - try: - import xformers - import xformers.ops - model.enable_xformers_memory_efficient_attention() - except ImportError: - print("xformers not installed. Proceeding without memory-efficient attention.") - - if finetune_method == "LORA": - config = LoraConfig( - r=lora_r, - lora_alpha=lora_alpha, - target_modules=["q_proj", "v_proj"], - lora_dropout=lora_dropout, - bias="none", - task_type="CAUSAL_LM" - ) - - model = get_peft_model(model, config) - - if finetune_method == "Freeze": - num_freeze_layers = len(model.transformer.h) - freeze_layers - for i, layer in enumerate(model.transformer.h): - if i < num_freeze_layers: - for param in layer.parameters(): - param.requires_grad = False - - trainer = Trainer( - model=model, - args=training_args, - data_collator=data_collator, - train_dataset=train_dataset, - ) - - try: - trainer.train() - trainer.save_model() - tokenizer.save_pretrained(save_path) - print("Finetuning completed successfully.") - except Exception as e: - print(f"Error during Finetuning: {e}") - return f"Finetuning failed. Error: {e}", None - - loss_values = [log['loss'] for log in trainer.state.log_history if 'loss' in log] - epochs = [log['epoch'] for log in trainer.state.log_history if 'epoch' in log] - - epochs = epochs[:len(loss_values)] - - fig, ax = plt.subplots(figsize=(8, 6)) - ax.plot(epochs, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) - ax.set_ylabel('Loss') - ax.set_xlabel('Epoch') - ax.set_title('Training Loss') - - if loss_values: - ax.set_ylim(bottom=min(loss_values) - 0.01, top=max(loss_values) + 0.01) - ax.set_xticks(epochs) - ax.set_xticklabels([int(epoch) for epoch in epochs]) - else: - print("No loss values found in trainer.state.log_history") - - ax.grid(True) - - plot_dir = save_dir - os.makedirs(plot_dir, exist_ok=True) - plot_path = os.path.join(save_dir, f"{model_output_name}_loss_plot.png") - plt.tight_layout() - plt.savefig(plot_path) - plt.close() - - return f"Finetuning completed. Model saved at: {save_path}", fig - - -def plot_llm_evaluation_metrics(metrics): - if metrics is None: - return None - - metrics_to_plot = ['bleu', 'bert', 'rouge-1', 'rouge-2', 'rouge-l', 'mauve', 'accuracy', 'precision', 'chrf'] - metric_values = [metrics.get(metric, 0) for metric in metrics_to_plot] - - fig, ax = plt.subplots(figsize=(8, 6)) - bar_width = 0.6 - x = range(len(metrics_to_plot)) - bars = ax.bar(x, metric_values, width=bar_width, align='center', color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#aec7e8']) - - ax.set_xticks(x) - ax.set_xticklabels(metrics_to_plot, rotation=45, ha='right') - ax.set_ylabel('Value') - ax.set_title('Evaluation Metrics') - - for bar in bars: - height = bar.get_height() - ax.annotate(f'{height:.2f}', xy=(bar.get_x() + bar.get_width() / 2, height), - xytext=(0, 3), textcoords='offset points', ha='center', va='bottom') - - fig.tight_layout() - return fig - - -def evaluate_llm(model_name, lora_model_name, dataset_file, user_input, max_length, temperature, top_p, top_k): - model_path = os.path.join("finetuned-models/llm/full", model_name) - model, tokenizer = load_model_and_tokenizer(model_name, finetuned=True) - if model is None or tokenizer is None: - return "Error loading model and tokenizer. Please check the model path.", None - - if not model_name: - return "Please select the model", None - - if not dataset_file: - return "Please select the dataset", None - - if lora_model_name and not model_name: - return "Please select the original model", None - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/llm/lora", lora_model_name) - model = PeftModel.from_pretrained(model, lora_model_path) - - dataset_path = os.path.join("datasets/llm", dataset_file) - try: - eval_dataset = load_dataset('json', data_files=dataset_path) - eval_dataset = eval_dataset['train'] - - def process_examples(examples): - input_texts = examples['input'] if 'input' in examples else [''] * len(examples['instruction']) - instruction_texts = examples['instruction'] - output_texts = examples['output'] - - texts = [f"{input_text}{instruction_text}{output_text}" for - input_text, instruction_text, output_text in zip(input_texts, instruction_texts, output_texts)] - return {'input_ids': tokenizer(texts, truncation=True, padding='max_length', max_length=128)['input_ids'], - 'attention_mask': tokenizer(texts, truncation=True, padding='max_length', max_length=128)[ - 'attention_mask'], - 'labels': output_texts} - - eval_dataset = eval_dataset.map(process_examples, batched=True, - remove_columns=['input', 'instruction', 'output']) - eval_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask', 'labels']) - except Exception as e: - print(f"Error loading dataset: {e}") - return f"Error loading dataset. Please check the dataset path and format. Error: {e}", None - - try: - references = eval_dataset['labels'] - predictions = [generate_text(model_name, lora_model_name, "transformers", - user_input if user_input else tokenizer.decode(example['input_ids'], - skip_special_tokens=True), - max_length, temperature, top_p, top_k, output_format='txt')[0] for example in eval_dataset] - - bert_model_name = "google-bert/bert-base-uncased" - bert_repo_url = f"https://huggingface.co/{bert_model_name}" - bert_repo_dir = os.path.join("trainer-scripts", bert_model_name) - - if not os.path.exists(bert_repo_dir): - Repo.clone_from(bert_repo_url, bert_repo_dir) - - predictions = [pred.strip() for pred in predictions if pred.strip()] - references = [ref.strip() for ref in references if ref.strip()] - - bleu_score = sacrebleu.corpus_bleu(predictions, [references]).score - - P, R, F1 = score(predictions, references, lang='en', model_type=bert_model_name, num_layers=12) - bert_score = F1.mean().item() - - rouge = Rouge() - rouge_scores = rouge.get_scores(predictions, references, avg=True) - - max_length = max(len(tokenizer.encode(ref)) for ref in references) - - tokenized_references = tokenizer(references, return_tensors='pt', padding=True, truncation=True, - max_length=max_length) - tokenized_predictions = tokenizer(predictions, return_tensors='pt', padding=True, truncation=True, - max_length=max_length) - - mauve_result = compute_mauve(tokenized_predictions.input_ids, tokenized_references.input_ids) - mauve_score = mauve_result.mauve - - binary_predictions = [1 if pred else 0 for pred in predictions] - binary_references = [1 if ref else 0 for ref in references] - accuracy = accuracy_score(binary_references, binary_predictions) - precision = precision_score(binary_references, binary_predictions) - - chrf_metric = CHRFScore() - for reference, prediction in zip(references, predictions): - chrf_metric.update(prediction, reference) - chrf_score = chrf_metric.compute().item() - - extracted_metrics = { - 'bleu': bleu_score, - 'bert': bert_score, - 'rouge-1': rouge_scores['rouge-1']['f'], - 'rouge-2': rouge_scores['rouge-2']['f'], - 'rouge-l': rouge_scores['rouge-l']['f'], - 'mauve': mauve_score, - 'accuracy': accuracy, - 'precision': precision, - 'chrf': chrf_score - } - - fig = plot_llm_evaluation_metrics(extracted_metrics) - - plot_path = os.path.join(model_path, f"{model_name}_evaluation_plot.png") - fig.savefig(plot_path) - - return f"Evaluation completed successfully. Results saved to {plot_path}", fig - except Exception as e: - print(f"Error during evaluation: {e}") - return f"Evaluation failed. Error: {e}", None - - -def quantize_llm(model_name, quantization_type): - if not model_name: - return "Please select the model" - - model_path = os.path.join("finetuned-models/llm/full", model_name) - llama_cpp_path = "trainer-scripts/llm/llama.cpp" - - os.makedirs(os.path.dirname(llama_cpp_path), exist_ok=True) - - if not os.path.exists(llama_cpp_path): - llama_cpp_repo_url = "https://github.com/ggerganov/llama.cpp.git" - Repo.clone_from(llama_cpp_repo_url, llama_cpp_path) - - try: - os.chdir(llama_cpp_path) - - subprocess.run(f"cmake -B build", shell=True, check=True) - subprocess.run(f"cmake --build build --config Release", shell=True, check=True) - - subprocess.run(f"python convert.py {model_path}", shell=True, check=True) - - input_model = os.path.join(model_path, "ggml-model-f16.ggml") - output_model = os.path.join(model_path, f"ggml-model-{quantization_type}.ggml") - subprocess.run(f"./quantize {input_model} {output_model} {quantization_type}", shell=True, check=True) - - return f"Quantization completed successfully. Model saved at: {output_model}" - - except subprocess.CalledProcessError as e: - return f"Error during quantization: {e}" - finally: - os.chdir(os.path.dirname(os.path.abspath(__file__))) - - -def generate_text(model_name, lora_model_name, model_type, prompt, max_length, temperature, top_p, top_k, output_format): - if model_type == "transformers": - model, tokenizer = load_model_and_tokenizer(model_name, finetuned=True) - if model is None or tokenizer is None: - return None, "Error loading model and tokenizer. Please check the model path." - - if not model_name: - return None, "Please select the model" - - if lora_model_name and not model_name: - return None, "Please select the original model" - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/llm/lora", lora_model_name) - model = PeftModel.from_pretrained(model, lora_model_path) - - try: - input_ids = tokenizer.encode(prompt, return_tensors='pt') - attention_mask = torch.ones(input_ids.shape, dtype=torch.long) - pad_token_id = tokenizer.eos_token_id - - input_ids = input_ids.to(model.device) - attention_mask = attention_mask.to(model.device) - - output = model.generate( - input_ids, - do_sample=True, - attention_mask=attention_mask, - pad_token_id=pad_token_id, - max_new_tokens=max_length, - num_return_sequences=1, - top_p=top_p, - top_k=top_k, - temperature=temperature, - repetition_penalty=1.1, - num_beams=5, - no_repeat_ngram_size=2, - ) - - generated_text = tokenizer.decode(output[0], skip_special_tokens=True) - - output_dir = "outputs/llm" - os.makedirs(output_dir, exist_ok=True) - - timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - output_file = f"llm_history_{timestamp}.{output_format}" - output_path = os.path.join(output_dir, output_file) - - if output_format == "txt": - with open(output_path, "a", encoding="utf-8") as file: - file.write(f"Human: {prompt}\nAI: {generated_text}\n") - elif output_format == "json": - history = [{"Human": prompt, "AI": generated_text}] - with open(output_path, "w", encoding="utf-8") as file: - json.dump(history, file, indent=2, ensure_ascii=False) - - return generated_text, "Text generation successful" - except Exception as e: - print(f"Error during text generation: {e}") - return None, f"Text generation failed. Error: {e}" - - elif model_type == "llama.cpp": - model_path = os.path.join("finetuned-models/llm/full", model_name) - - try: - - llm = Llama(model_path=model_path, n_ctx=max_length, n_parts=-1, seed=-1, f16_kv=True, logits_all=False, vocab_only=False, use_mlock=False, n_threads=8, n_batch=1, suffix=None) - - output = llm(prompt, max_tokens=max_length, top_k=top_k, top_p=top_p, temperature=temperature, stop=None, echo=False) - - generated_text = output['choices'][0]['text'] - - output_dir = "outputs/llm" - os.makedirs(output_dir, exist_ok=True) - - timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - output_file = f"llm_history_{timestamp}.{output_format}" - output_path = os.path.join(output_dir, output_file) - - if output_format == "txt": - with open(output_path, "a", encoding="utf-8") as file: - file.write(f"Human: {prompt}\nAI: {generated_text}\n") - elif output_format == "json": - history = [{"Human": prompt, "AI": generated_text}] - with open(output_path, "w", encoding="utf-8") as file: - json.dump(history, file, indent=2, ensure_ascii=False) - - return generated_text, "Text generation successful" - except Exception as e: - print(f"Error during text generation: {e}") - return None, f"Text generation failed. Error: {e}" - - -def create_sd_dataset(image_files, existing_dataset, dataset_name, file_prefix, prompt_text): - if existing_dataset: - dataset_dir = os.path.join("datasets", "sd", existing_dataset, "train") - else: - dataset_dir = os.path.join("datasets", "sd", dataset_name, "train") - - os.makedirs(dataset_dir, exist_ok=True) - - metadata_file = os.path.join(dataset_dir, "metadata.jsonl") - - with open(metadata_file, "a") as f: - for i, image_file in enumerate(image_files): - file_name = f"{file_prefix}-{i + 1}.jpg" - image_path = os.path.join(dataset_dir, file_name) - image = Image.open(image_file.name) - image.save(image_path) - - metadata = { - "file_name": file_name, - "text": prompt_text - } - f.write(json.dumps(metadata) + "\n") - - return f"Dataset {'updated' if existing_dataset else 'created'} successfully at {dataset_dir}" - - -def finetune_sd(model_name, dataset_name, model_type, finetune_method, model_output_name, resolution, - train_batch_size, gradient_accumulation_steps, - learning_rate, lr_scheduler, lr_warmup_steps, max_train_steps, adam_beta1, adam_beta2, adam_weight_decay, adam_epsilon, max_grad_norm, noise_offset, rank, enable_xformers): - model_path = os.path.join("models/sd", model_name) - dataset_path = os.path.join("datasets/sd", dataset_name) - - if not model_name: - return "Please select the model", None - - if not dataset_name: - return "Please select the dataset", None - - if not model_output_name: - return "Please write the model name", None - - if finetune_method == "Full": - output_dir = os.path.join("finetuned-models/sd/full", model_output_name) - if model_type == "SD": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - elif model_type == "SDXL": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_sdxl.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - elif finetune_method == "LORA": - output_dir = os.path.join("finetuned-models/sd/lora", model_output_name) - if model_type == "SD": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_lora.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--rank={rank}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - elif model_type == "SDXL": - dataset = load_dataset("imagefolder", data_dir=dataset_path) - args = [ - "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_lora_sdxl.py", - f"--pretrained_model_name_or_path={model_path}", - f"--train_data_dir={dataset_path}", - f"--output_dir={output_dir}", - f"--resolution={resolution}", - f"--train_batch_size={train_batch_size}", - f"--gradient_accumulation_steps={gradient_accumulation_steps}", - f"--learning_rate={learning_rate}", - f"--lr_scheduler={lr_scheduler}", - f"--lr_warmup_steps={lr_warmup_steps}", - f"--max_train_steps={max_train_steps}", - f"--adam_beta1={adam_beta1}", - f"--adam_beta2={adam_beta2}", - f"--adam_weight_decay={adam_weight_decay}", - f"--adam_epsilon={adam_epsilon}", - f"--max_grad_norm={max_grad_norm}", - f"--noise_offset={noise_offset}", - f"--rank={rank}", - f"--caption_column=text", - f"--mixed_precision=no", - f"--seed=0" - ] - if enable_xformers: - args.append("--enable_xformers_memory_efficient_attention") - else: - raise ValueError(f"Invalid finetune method: {finetune_method}") - - subprocess.run(args) - - if finetune_method == "Full": - logs_dir = os.path.join(output_dir, "logs", "text2image-fine-tune") - events_files = [f for f in os.listdir(logs_dir) if f.startswith("events.out.tfevents")] - latest_event_file = sorted(events_files)[-1] - event_file_path = os.path.join(logs_dir, latest_event_file) - - event_acc = EventAccumulator(event_file_path) - event_acc.Reload() - - loss_values = [s.value for s in event_acc.Scalars("train_loss")] - steps = [s.step for s in event_acc.Scalars("train_loss")] - - fig, ax = plt.subplots(figsize=(8, 6)) - ax.plot(steps, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) - ax.set_ylabel('Loss') - ax.set_xlabel('Step') - ax.set_title('Training Loss') - ax.grid(True) - - plot_path = os.path.join(output_dir, f"{model_name}_loss_plot.png") - plt.tight_layout() - plt.savefig(plot_path) - plt.close() - - return f"Fine-tuning completed. Model saved at: {output_dir}", fig - - elif finetune_method == "LORA": - logs_dir = os.path.join(output_dir, "logs", "text2image-fine-tune") - events_files = [f for f in os.listdir(logs_dir) if f.startswith("events.out.tfevents")] - latest_event_file = sorted(events_files)[-1] - event_file_path = os.path.join(logs_dir, latest_event_file) - - event_acc = EventAccumulator(event_file_path) - event_acc.Reload() - - loss_values = [s.value for s in event_acc.Scalars("train_loss")] - steps = [s.step for s in event_acc.Scalars("train_loss")] - - fig, ax = plt.subplots(figsize=(8, 6)) - ax.plot(steps, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) - ax.set_ylabel('Loss') - ax.set_xlabel('Step') - ax.set_title('Training Loss') - ax.grid(True) - - plot_path = os.path.join(output_dir, f"{model_name}_loss_plot.png") - plt.tight_layout() - plt.savefig(plot_path) - plt.close() - - return f"Finetuning completed. Model saved at: {output_dir}", fig - - -def plot_sd_evaluation_metrics(metrics): - metrics_to_plot = ["FID", "KID", "Inception Score", "VIF", "CLIP Score", "LPIPS", "SCC", "SDI", "SAM", "SSIM"] - metric_values = [metrics[metric] for metric in metrics_to_plot] - - fig, ax = plt.subplots(figsize=(8, 6)) - bar_width = 0.6 - x = range(len(metrics_to_plot)) - bars = ax.bar(x, metric_values, width=bar_width, align="center", color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#bcbd22', '#17becf', '#aaffc3', '#ffe119']) - - ax.set_xticks(x) - ax.set_xticklabels(metrics_to_plot, rotation=45, ha="right") - ax.set_ylabel("Value") - ax.set_title("Evaluation Metrics") - - for bar in bars: - height = bar.get_height() - ax.annotate(f"{height:.2f}", xy=(bar.get_x() + bar.get_width() / 2, height), - xytext=(0, 3), textcoords="offset points", ha="center", va="bottom") - - fig.tight_layout() - return fig - - -def evaluate_sd(model_name, lora_model_name, dataset_name, model_method, model_type, user_prompt, negative_prompt, num_inference_steps, cfg_scale): - if model_method == "Diffusers": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_pretrained(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_method == "Safetensors": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_single_file(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_single_file(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - else: - return "Invalid model type selected", None - - if not model_name: - return "Please select the model", None - - if not dataset_name: - return "Please select the dataset", None - - if lora_model_name and not model_name: - return "Please select the original model", None - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/sd/lora", lora_model_name) - model.unet.load_attn_procs(lora_model_path) - - dataset_path = os.path.join("datasets/sd", dataset_name) - dataset = load_dataset("imagefolder", data_dir=dataset_path) - - num_samples = len(dataset["train"]) - subset_size = min(num_samples, 50) - - fid = FrechetInceptionDistance().to("cuda") - kid = KernelInceptionDistance(subset_size=subset_size).to("cuda") - inception = InceptionScore().to("cuda") - vif = VisualInformationFidelity().to("cuda") - lpips = LearnedPerceptualImagePatchSimilarity().to("cuda") - scc = SpatialCorrelationCoefficient().to("cuda") - sdi = SpectralDistortionIndex().to("cuda") - sam = SpectralAngleMapper().to("cuda") - ssim = StructuralSimilarityIndexMeasure().to("cuda") - - clip_model_name = "openai/clip-vit-base-patch16" - clip_repo_url = f"https://huggingface.co/{clip_model_name}" - clip_repo_dir = os.path.join("trainer-scripts", clip_model_name) - - if not os.path.exists(clip_repo_dir): - Repo.clone_from(clip_repo_url, clip_repo_dir) - - clip_score = CLIPScore(model_name_or_path=clip_model_name).to("cuda") - - resize = Resize((512, 512)) - - clip_scores = [] - - for batch in dataset["train"]: - image = batch["image"].convert("RGB") - image_tensor = torch.from_numpy(np.array(image)).permute(2, 0, 1).unsqueeze(0).to("cuda").to(torch.uint8) - - generated_images = model(prompt=user_prompt, negative_prompt=negative_prompt, num_inference_steps=num_inference_steps, guidance_scale=cfg_scale, - output_type="pil").images - generated_image = generated_images[0].resize((image.width, image.height)) - generated_image_tensor = torch.from_numpy(np.array(generated_image)).permute(2, 0, 1).unsqueeze(0).to( - "cuda").to(torch.uint8) - - fid.update(resize(image_tensor), real=True) - fid.update(resize(generated_image_tensor), real=False) - - kid.update(resize(image_tensor), real=True) - kid.update(resize(generated_image_tensor), real=False) - - inception.update(resize(generated_image_tensor)) - - vif.update(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - - lpips_score = lpips(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - scc_score = scc(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - sdi_score = sdi(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - sam_score = sam(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - ssim_score = ssim(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) - - clip_score_value = clip_score(resize(generated_image_tensor).to(torch.float32), "a photo of a generated image") - clip_scores.append(clip_score_value.detach().item()) - - fid_score = fid.compute() - kid_score, _ = kid.compute() - inception_score, _ = inception.compute() - vif_score = vif.compute() - clip_score_avg = np.mean(clip_scores) - - metrics = { - "FID": fid_score.item(), - "KID": kid_score.item(), - "Inception Score": inception_score.item(), - "VIF": vif_score.item(), - "CLIP Score": clip_score_avg, - "LPIPS": lpips_score.item(), - "SCC": scc_score.item(), - "SDI": sdi_score.item(), - "SAM": sam_score.item(), - "SSIM": ssim_score.item() - } - - fig = plot_sd_evaluation_metrics(metrics) - - if model_method == "Diffusers": - plot_path = os.path.join(model_path, f"{model_name}_evaluation_plot.png") - elif model_method == "Safetensors": - plot_path = os.path.join("finetuned-models/sd/full", f"{model_name}_evaluation_plot.png") - fig.savefig(plot_path) - - return f"Evaluation completed successfully. Results saved to {plot_path}", fig - - -def convert_sd_model_to_safetensors(model_name, model_type, use_half, use_safetensors): - model_path = os.path.join("finetuned-models/sd/full", model_name) - output_path = os.path.join("finetuned-models/sd/full") - - if model_type == "SD": - try: - args = [ - "py", - "trainer-scripts/sd/convert_diffusers_to_original_stable_diffusion.py", - "--model_path", model_path, - "--checkpoint_path", output_path, - ] - if use_half: - args.append("--half") - if use_safetensors: - args.append("--use_safetensors") - - subprocess.run(args, check=True) - - return f"Model successfully converted to single file and saved to {output_path}" - except subprocess.CalledProcessError as e: - return f"Error converting model to single file: {e}" - elif model_type == "SDXL": - try: - args = [ - "py", - "trainer-scripts/sd/convert_diffusers_to_original_sdxl.py", - "--model_path", model_path, - "--checkpoint_path", output_path, - ] - if use_half: - args.append("--half") - if use_safetensors: - args.append("--use_safetensors") - - subprocess.run(args, check=True) - - return f"Model successfully converted to single file and saved to {output_path}" - except subprocess.CalledProcessError as e: - return f"Error converting model to single file: {e}" - - -def generate_image(model_name, lora_model_name, model_method, model_type, prompt, negative_prompt, num_inference_steps, cfg_scale, width, height, output_format): - if model_method == "Diffusers": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_pretrained(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_method == "Safetensors": - if model_type == "SD": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionPipeline.from_single_file(model_path, torch_dtype=torch.float16, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - elif model_type == "SDXL": - model_path = os.path.join("finetuned-models/sd/full", model_name) - model = StableDiffusionXLPipeline.from_single_file(model_path, torch_dtype=torch.float16, attention_slice=1, - safety_checker=None).to( - "cuda") - model.scheduler = DDPMScheduler.from_config(model.scheduler.config) - else: - return "Invalid model type selected", None - - if not model_name: - return "Please select the model", None - - if lora_model_name and not model_name: - return "Please select the original model", None - - if lora_model_name: - lora_model_path = os.path.join("finetuned-models/sd/lora", lora_model_name) - model.unet.load_attn_procs(lora_model_path) - - image = model(prompt, negative_prompt=negative_prompt, num_inference_steps=num_inference_steps, - guidance_scale=cfg_scale, width=width, height=height).images[0] - - output_dir = "outputs/sd" - os.makedirs(output_dir, exist_ok=True) - - timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") - output_file = f"sd_image_{timestamp}.{output_format}" - output_path = os.path.join(output_dir, output_file) - - image.save(output_path) - - return image, "Image generation successful" - - -def close_terminal(): - os._exit(1) - - -def open_finetuned_folder(): - outputs_folder = "finetuned-models" - if os.path.exists(outputs_folder): - if os.name == "nt": - os.startfile(outputs_folder) - else: - os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') - - -def open_datasets_folder(): - outputs_folder = "datasets" - if os.path.exists(outputs_folder): - if os.name == "nt": - os.startfile(outputs_folder) - else: - os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') - - -def open_outputs_folder(): - outputs_folder = "outputs" - if os.path.exists(outputs_folder): - if os.name == "nt": - os.startfile(outputs_folder) - else: - os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') - - -def download_model(model_name_llm, model_name_sd): - if not model_name_llm and not model_name_sd: - return "Please select a model to download" - - if model_name_llm and model_name_sd: - return "Please select one model type for downloading" - - if model_name_llm: - model_url = "" - if model_name_llm == "StableLM2-1_6B-Chat": - model_url = "https://huggingface.co/stabilityai/stablelm-2-1_6b-chat" - elif model_name_llm == "Qwen1.5-4B-Chat": - model_url = "https://huggingface.co/Qwen/Qwen1.5-4B-Chat" - model_path = os.path.join("models", "llm", model_name_llm) - - if model_url: - response = requests.get(model_url, allow_redirects=True) - with open(model_path, "wb") as file: - file.write(response.content) - return f"LLM model {model_name_llm} downloaded successfully!" - else: - return "Invalid LLM model name" - - if model_name_sd: - model_url = "" - if model_name_sd == "StableDiffusion1.5": - model_url = "https://huggingface.co/runwayml/stable-diffusion-v1-5" - elif model_name_sd == "StableDiffusionXL": - model_url = "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0" - model_path = os.path.join("models", "sd", model_name_sd) - - if model_url: - response = requests.get(model_url, allow_redirects=True) - with open(model_path, "wb") as file: - file.write(response.content) - return f"StableDiffusion model {model_name_sd} downloaded successfully!" - else: - return "Invalid StableDiffusion model name" - - -def settings_interface(share_value): - global share_mode - share_mode = share_value == "True" - message = f"Settings updated successfully!" - - app.launch(share=share_mode, server_name="localhost") - - return message - - -share_mode = False - -llm_dataset_interface = gr.Interface( - fn=create_llm_dataset, - inputs=[ - gr.Dropdown(choices=get_available_llm_datasets(), label="Existing Dataset (optional)"), - gr.Textbox(label="Dataset Name", type="text"), - gr.Textbox(label="Instruction", type="text"), - gr.Textbox(label="Input", type="text"), - gr.Textbox(label="Output", type="text"), - ], - outputs=[ - gr.Textbox(label="Status", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Dataset", - description="Create a new dataset or add a new column to an existing dataset for LLM", - allow_flagging="never", -) - -llm_finetune_interface = gr.Interface( - fn=finetune_llm, - inputs=[ - gr.Dropdown(choices=get_available_llm_models(), label="Model"), - gr.Dropdown(choices=get_available_llm_datasets(), label="Dataset"), - gr.Radio(choices=["Full", "Freeze", "LORA"], value="Full", label="Finetune Method"), - gr.Textbox(label="Output Model Name", type="text"), - gr.Number(value=10, label="Epochs"), - gr.Number(value=4, label="Batch size"), - gr.Number(value=3e-5, label="Learning rate"), - gr.Number(value=0.01, label="Weight decay"), - gr.Number(value=100, label="Warmup steps"), - gr.Number(value=128, label="Block size"), - gr.Number(value=1, label="Gradient accumulation steps"), - gr.Number(value=0.9, label="Adam beta 1"), - gr.Number(value=0.999, label="Adam beta 2"), - gr.Number(value=1e-8, label="Adam epsilon"), - gr.Dropdown(choices=["linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"], value="linear", label="LR Scheduler"), - gr.Number(value=2, label="Freeze layers"), - gr.Number(value=16, label="LORA r"), - gr.Number(value=32, label="LORA alpha"), - gr.Number(value=0.05, label="LORA dropout"), - gr.Checkbox(label="Use xformers", value=False), - ], - outputs=[ - gr.Textbox(label="Finetuning Status", type="text"), - gr.Plot(label="Finetuning Loss") - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Finetune", - description="Finetune LLM models on a custom dataset", - allow_flagging="never", -) - -llm_evaluate_interface = gr.Interface( - fn=evaluate_llm, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_llm_models(), label="Model"), - gr.Dropdown(choices=get_available_llm_lora_models(), label="LORA Model (optional)"), - gr.Dropdown(choices=get_available_llm_datasets(), label="Dataset"), - gr.Textbox(label="Request", type="text"), - gr.Slider(minimum=1, maximum=2048, value=128, step=1, label="Max Length"), - gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label="Temperature"), - gr.Slider(minimum=0.0, maximum=1.0, value=0.9, step=0.1, label="Top P"), - gr.Slider(minimum=0, maximum=100, value=20, step=1, label="Top K"), - ], - outputs=[ - gr.Textbox(label="Evaluation Status"), - gr.Plot(label="Evaluation Metrics"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Evaluate", - description="Evaluate finetuned LLM models on a custom dataset", - allow_flagging="never", -) - -llm_quantize_interface = gr.Interface( - fn=quantize_llm, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_llm_models(), label="Model"), - gr.Radio(choices=["Q2_K_M", "Q4_K_M", "Q6_K_M", "Q8_K_M"], value="Q4_K_M", label="Quantization Type"), - ], - outputs=[ - gr.Textbox(label="Quantization Status", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Quantize", - description="Quantize finetuned LLM models to .gguf format using llama.cpp", - allow_flagging="never", -) - -llm_generate_interface = gr.Interface( - fn=generate_text, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_llm_models(), label="Model"), - gr.Dropdown(choices=get_available_llm_lora_models(), label="LORA Model (optional)"), - gr.Radio(choices=["transformers", "llama.cpp"], value="transformers", label="Model Type"), - gr.Textbox(label="Request", type="text"), - gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max length"), - gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label="Temperature"), - gr.Slider(minimum=0.0, maximum=1.0, value=0.9, step=0.1, label="Top P"), - gr.Slider(minimum=0, maximum=100, value=20, step=1, label="Top K"), - gr.Radio(choices=["txt", "json"], value="txt", label="Output Format"), - ], - outputs=[ - gr.Textbox(label="Generated text", type="text"), - gr.Textbox(label="Message", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - LLM-Generate", - description="Generate text using finetuned LLM models", - allow_flagging="never", -) - -sd_dataset_interface = gr.Interface( - fn=create_sd_dataset, - inputs=[ - gr.Files(label="Image Files"), - gr.Dropdown(choices=get_available_sd_datasets(), label="Existing Dataset (optional)"), - gr.Textbox(label="Dataset Name"), - gr.Textbox(label="Files Name"), - gr.Textbox(label="Prompt Text") - ], - outputs=[ - gr.Textbox(label="Status") - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Dataset", - description="Create a new dataset or add a new column to an existing dataset for Stable Diffusion", - allow_flagging="never", -) - -sd_finetune_interface = gr.Interface( - fn=finetune_sd, - inputs=[ - gr.Dropdown(choices=get_available_sd_models(), label="Model"), - gr.Dropdown(choices=get_available_sd_datasets(), label="Dataset"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Radio(choices=["Full", "LORA"], value="Full", label="Finetune Method"), - gr.Textbox(label="Output Model Name", type="text"), - gr.Number(value=512, label="Resolution"), - gr.Number(value=1, label="Train Batch Size"), - gr.Number(value=1, label="Gradient Accumulation Steps"), - gr.Number(value=5e-6, label="Learning Rate"), - gr.Dropdown(choices=["linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"], value="linear", label="LR Scheduler"), - gr.Number(value=0, label="LR Warmup Steps"), - gr.Number(value=100, label="Max Train Steps"), - gr.Number(value=0.9, label="Adam beta 1"), - gr.Number(value=0.999, label="Adam beta 2"), - gr.Number(value=1e-2, label="Adam weight decay"), - gr.Number(value=1e-8, label="Adam epsilon"), - gr.Number(value=1.0, label="Max grad norm"), - gr.Number(value=0, label="Noise offset"), - gr.Number(value=4, label="LORA Rank"), - gr.Checkbox(label="Use xformers", value=False), - ], - outputs=[ - gr.Textbox(label="Finetuning Status", type="text"), - gr.Plot(label="Finetuning Loss") - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Finetune", - description="Finetune Stable Diffusion models on a custom dataset", - allow_flagging="never", -) - -sd_evaluate_interface = gr.Interface( - fn=evaluate_sd, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_sd_models(), label="Model"), - gr.Dropdown(choices=get_available_sd_lora_models(), label="LORA Model (optional)"), - gr.Dropdown(choices=get_available_sd_datasets(), label="Dataset"), - gr.Radio(choices=["Diffusers", "Safetensors"], value="Diffusers", label="Model Method"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Textbox(label="Prompt", type="text"), - gr.Textbox(label="Negative Prompt", type="text"), - gr.Slider(minimum=1, maximum=150, value=30, step=1, label="Steps"), - gr.Slider(minimum=1, maximum=30, value=8, step=0.5, label="CFG"), - ], - outputs=[ - gr.Textbox(label="Evaluation Status"), - gr.Plot(label="Evaluation Metrics"), - ], - title="NeuroTrainerWebUI (ALPHA) - StabledDiffusion-Evaluate", - description="Evaluate finetuned Stable Diffusion models on a custom dataset", - allow_flagging="never", -) - -sd_convert_interface = gr.Interface( - fn=convert_sd_model_to_safetensors, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_sd_models(), label="Model"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Checkbox(label="Use Half Precision", value=False), - gr.Checkbox(label="Use Safetensors", value=False), - ], - outputs=[ - gr.Textbox(label="Conversion Status", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Conversion", - description="Convert finetuned Stable Diffusion models to single file (.ckpt or .safetensors)", - allow_flagging="never", -) - -sd_generate_interface = gr.Interface( - fn=generate_image, - inputs=[ - gr.Dropdown(choices=get_available_finetuned_sd_models(), label="Model"), - gr.Dropdown(choices=get_available_sd_lora_models(), label="LORA Model (optional)"), - gr.Radio(choices=["Diffusers", "Safetensors"], value="Diffusers", label="Model Method"), - gr.Radio(choices=["SD", "SDXL"], value="SD", label="Model Type"), - gr.Textbox(label="Prompt", type="text"), - gr.Textbox(label="Negative Prompt", type="text"), - gr.Slider(minimum=1, maximum=150, value=30, step=1, label="Steps"), - gr.Slider(minimum=1, maximum=30, value=8, step=0.5, label="CFG"), - gr.Slider(minimum=256, maximum=1024, value=512, step=64, label="Width"), - gr.Slider(minimum=256, maximum=1024, value=512, step=64, label="Height"), - gr.Radio(choices=["png", "jpeg"], value="png", label="Output Format"), - ], - outputs=[ - gr.Image(label="Generated Image"), - gr.Textbox(label="Message", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - StableDiffusion-Generate", - description="Generate images using finetuned Stable Diffusion models", - allow_flagging="never", -) - -model_downloader_interface = gr.Interface( - fn=download_model, - inputs=[ - gr.Dropdown(choices=[None, "StableLM2-1_6B-Chat", "Qwen1.5-4B-Chat"], label="Download LLM model", value=None), - gr.Dropdown(choices=[None, "StableDiffusion1.5", "StableDiffusionXL"], label="Download StableDiffusion model", value=None), - ], - outputs=[ - gr.Textbox(label="Message", type="text"), - ], - title="NeuroTrainerWebUI (ALPHA) - ModelDownloader", - description="This interface allows you to download LLM and StableDiffusion models", - allow_flagging="never", -) - -settings_interface = gr.Interface( - fn=settings_interface, - inputs=[ - gr.Radio(choices=["True", "False"], label="Share Mode", value="False") - ], - outputs=[ - gr.Textbox(label="Message", type="text") - ], - title="NeuroTrainerWebUI (ALPHA) - Settings", - description="This interface allows you to change settings of application", - allow_flagging="never", -) - -system_interface = gr.Interface( - fn=get_system_info, - inputs=[], - outputs=[ - gr.Textbox(label="GPU Total Memory"), - gr.Textbox(label="GPU Used Memory"), - gr.Textbox(label="GPU Free Memory"), - gr.Textbox(label="GPU Temperature"), - gr.Textbox(label="CPU Temperature"), - gr.Textbox(label="RAM Total"), - gr.Textbox(label="RAM Used"), - gr.Textbox(label="RAM Free"), - ], - title="NeuroTrainerWebUI (ALPHA) - System", - description="This interface displays system information", - allow_flagging="never", -) - -with gr.TabbedInterface([gr.TabbedInterface([llm_dataset_interface, llm_finetune_interface, llm_evaluate_interface, llm_quantize_interface, llm_generate_interface], - tab_names=["Dataset", "Finetune", "Evaluate", "Quantize", "Generate"]), - gr.TabbedInterface([sd_dataset_interface, sd_finetune_interface, sd_evaluate_interface, sd_convert_interface, sd_generate_interface], - tab_names=["Dataset", "Finetune", "Evaluate", "Conversion", "Generate"]), - model_downloader_interface, settings_interface, system_interface], - tab_names=["LLM", "StableDiffusion", "Settings", "ModelDownloader", "System"]) as app: - close_button = gr.Button("Close terminal") - close_button.click(close_terminal, [], [], queue=False) - - folder_button = gr.Button("Finetuned-models") - folder_button.click(open_finetuned_folder, [], [], queue=False) - - folder_button = gr.Button("Datasets") - folder_button.click(open_datasets_folder, [], [], queue=False) - - folder_button = gr.Button("Outputs") - folder_button.click(open_outputs_folder, [], [], queue=False) - - github_link = gr.HTML( - '' - ) - - app.launch(share=share_mode, server_name="localhost", auth=authenticate) +import logging +import os +import warnings +os.chdir(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True" +warnings.filterwarnings("ignore") +logging.getLogger("httpx").setLevel(logging.WARNING) +cache_dir = os.path.join("cache") +os.makedirs(cache_dir, exist_ok=True) +os.environ["XDG_CACHE_HOME"] = cache_dir +temp_dir = os.path.join("temp") +os.makedirs(temp_dir, exist_ok=True) +os.environ["TMPDIR"] = temp_dir +import markdown +import gc +import platform +import sys +import xformers +from git import Repo +import requests +import gradio as gr +from transformers import AutoModelForCausalLM, AutoTokenizer, DataCollatorForLanguageModeling, Trainer, TrainingArguments +from llama_cpp import Llama +from peft import LoraConfig, get_peft_model, PeftModel +from diffusers import StableDiffusionPipeline, StableDiffusionXLPipeline, DDPMScheduler +from datasets import load_dataset +import matplotlib.pyplot as plt +import numpy as np +from PIL import Image +import torch +from bert_score import score +import json +from datetime import datetime +from torchmetrics.text.chrf import CHRFScore +from torchmetrics.image.fid import FrechetInceptionDistance +from torchmetrics.image.kid import KernelInceptionDistance +from torchmetrics.image.inception import InceptionScore +from torchmetrics.image.vif import VisualInformationFidelity +from torchvision.transforms import Resize +from torchmetrics.multimodal.clip_score import CLIPScore +from torchmetrics.image.lpip import LearnedPerceptualImagePatchSimilarity +from torchmetrics.image.scc import SpatialCorrelationCoefficient +from torchmetrics.image import SpectralDistortionIndex +from torchmetrics.image import SpectralAngleMapper +from torchmetrics.image.ssim import StructuralSimilarityIndexMeasure +import psutil +import GPUtil +from cpuinfo import get_cpu_info +from pynvml import nvmlInit, nvmlDeviceGetHandleByIndex, nvmlDeviceGetTemperature, NVML_TEMPERATURE_GPU +import sacrebleu +from rouge import Rouge +import subprocess +from tensorboard.backend.event_processing.event_accumulator import EventAccumulator +from mauve import compute_mauve +from sklearn.metrics import accuracy_score, precision_score + + +def print_system_info(): + print(f"NeuroSandboxWebUI") + print(f"Python version: {sys.version}") + print(f"Python executable: {sys.executable}") + print(f"Platform: {sys.platform}") + print(f"OS: {platform.system()} {platform.release()}") + print(f"Machine: {platform.machine()}") + print(f"Processor: {platform.processor()}") + print(f"CPU cores: {os.cpu_count()}") + print(f"RAM: {psutil.virtual_memory().total / (1024 ** 3):.2f} GB") + print(f"Disk space: {psutil.disk_usage('/').total / (1024 ** 3):.2f} GB") + + if torch.cuda.is_available(): + print(f"CUDA available: Yes") + print(f"CUDA version: {torch.version.cuda}") + print(f"GPU: {torch.cuda.get_device_name(0)}") + print(f"VRAM: {torch.cuda.get_device_properties(0).total_memory / (1024 ** 3):.2f} GB") + else: + print("CUDA available: No") + + print(f"PyTorch version: {torch.__version__}") + print(f"Xformers version: {xformers.__version__}") + + +try: + print_system_info() +except Exception as e: + print(f"Unable to access system information: {e}") + pass + + +def flush(): + gc.collect() + torch.cuda.empty_cache() + + +def load_translation(lang): + try: + with open(f"translations/{lang}.json", "r", encoding="utf-8") as f: + return json.load(f) + except FileNotFoundError: + return {} + + +translations = { + "EN": {}, + "RU": load_translation("ru"), + "ZH": load_translation("zh") +} + + +def _(text, lang="EN"): + return translations[lang].get(text, text) + + +def load_settings(): + if not os.path.exists('Settings.json'): + default_settings = { + "language": "EN", + "share_mode": False, + "debug_mode": False, + "monitoring_mode": False, + "auto_launch": False, + "show_api": False, + "api_open": False, + "queue_max_size": 10, + "status_update_rate": "auto", + "auth": {"username": "admin", "password": "admin"}, + "server_name": "localhost", + "server_port": 7860, + "hf_token": "", + "theme": "Default", + "custom_theme": { + "enabled": False, + "primary_hue": "red", + "secondary_hue": "pink", + "neutral_hue": "stone", + "spacing_size": "spacing_md", + "radius_size": "radius_md", + "text_size": "text_md", + "font": "Arial", + "font_mono": "Courier New" + } + } + with open('Settings.json', 'w') as f: + json.dump(default_settings, f, indent=4) + + with open('Settings.json', 'r') as f: + return json.load(f) + + +def save_settings(settings): + with open('Settings.json', 'w') as f: + json.dump(settings, f, indent=4) + + +def authenticate(username, password): + settings = load_settings() + auth = settings.get('auth', {}) + return username == auth.get('username') and password == auth.get('password') + + +def get_available_llm_models(): + models_dir = "models/llm" + os.makedirs(models_dir, exist_ok=True) + + llm_available_models = [] + for model_name in os.listdir(models_dir): + model_path = os.path.join(models_dir, model_name) + if os.path.isdir(model_path): + llm_available_models.append(model_name) + + return llm_available_models + + +def get_available_llm_lora_models(): + models_dir = "finetuned-models/llm/lora" + os.makedirs(models_dir, exist_ok=True) + + llm_lora_available_models = [] + for model_name in os.listdir(models_dir): + model_path = os.path.join(models_dir, model_name) + if os.path.isdir(model_path): + llm_lora_available_models.append(model_name) + + return llm_lora_available_models + + +def get_available_finetuned_llm_models(): + models_dir = "finetuned-models/llm/full" + os.makedirs(models_dir, exist_ok=True) + + finetuned_available_llm_models = [] + for model_name in os.listdir(models_dir): + model_path = os.path.join(models_dir, model_name) + if os.path.isdir(model_path): + finetuned_available_llm_models.append(model_name) + + return finetuned_available_llm_models + + +def get_available_llm_datasets(): + datasets_dir = "datasets/llm" + os.makedirs(datasets_dir, exist_ok=True) + + llm_available_datasets = [] + for dataset_file in os.listdir(datasets_dir): + if dataset_file.endswith(".json"): + llm_available_datasets.append(dataset_file) + + return llm_available_datasets + + +def get_available_sd_models(): + models_dir = "models/sd" + os.makedirs(models_dir, exist_ok=True) + + sd_available_models = [] + for model_name in os.listdir(models_dir): + model_path = os.path.join(models_dir, model_name) + if os.path.isdir(model_path): + sd_available_models.append(model_name) + + return sd_available_models + + +def get_available_sd_lora_models(): + models_dir = "finetuned-models/sd/lora" + os.makedirs(models_dir, exist_ok=True) + + sd_lora_available_models = [] + for model_name in os.listdir(models_dir): + model_path = os.path.join(models_dir, model_name) + if os.path.isdir(model_path): + sd_lora_available_models.append(model_name) + + return sd_lora_available_models + + +def get_available_finetuned_sd_models(): + models_dir = "finetuned-models/sd/full" + os.makedirs(models_dir, exist_ok=True) + + finetuned_sd_available_models = [] + for model_name in os.listdir(models_dir): + model_path = os.path.join(models_dir, model_name) + if os.path.isdir(model_path) or model_name.endswith(".safetensors"): + finetuned_sd_available_models.append(model_name) + + return finetuned_sd_available_models + + +def get_available_sd_datasets(): + datasets_dir = "datasets/sd" + os.makedirs(datasets_dir, exist_ok=True) + + sd_available_datasets = [] + for dataset_dir in os.listdir(datasets_dir): + dataset_path = os.path.join(datasets_dir, dataset_dir) + if os.path.isdir(dataset_path): + sd_available_datasets.append(dataset_dir) + + return sd_available_datasets + + +def reload_model_lists(): + llm_models = get_available_llm_models() + llm_lora_models = get_available_llm_lora_models() + finetuned_llm_models = get_available_finetuned_llm_models() + llm_datasets = get_available_llm_datasets() + sd_models = get_available_sd_models() + sd_lora_models = get_available_sd_lora_models() + finetuned_sd_models = get_available_finetuned_sd_models() + sd_datasets = get_available_sd_datasets() + + return [ + llm_models, llm_lora_models, finetuned_llm_models, llm_datasets, + sd_models, sd_lora_models, finetuned_sd_models, sd_datasets + ] + + +def reload_interface(): + updated_lists = reload_model_lists()[:8] + return [gr.Dropdown(choices=list) for list in updated_lists] + + +def load_model_and_tokenizer(model_name, finetuned=False): + if finetuned: + model_path = os.path.join("finetuned-models/llm/full", model_name) + else: + model_path = os.path.join("models/llm", model_name) + try: + device = "cuda" + model = AutoModelForCausalLM.from_pretrained(model_path, device_map=device) + tokenizer = AutoTokenizer.from_pretrained(model_path) + return model, tokenizer + except Exception as e: + print(f"Error loading model and tokenizer: {e}") + return None, None + + +def create_llm_dataset(existing_file, file_name, instruction, input_text, output_text): + if existing_file: + file_path = os.path.join("datasets", "llm", existing_file) + with open(file_path, "r") as f: + data = json.load(f) + data.append({"instruction": instruction, "input": input_text, "output": output_text}) + with open(file_path, "w") as f: + json.dump(data, f, indent=2) + return f"New column added to the existing file: {existing_file}" + else: + file_path = os.path.join("datasets", "llm", f"{file_name}.json") + data = [{"instruction": instruction, "input": input_text, "output": output_text}] + with open(file_path, "w") as f: + json.dump(data, f, indent=2) + return f"New dataset file created: {file_name}.json" + + +def finetune_llm(model_name, dataset_file, finetune_method, model_output_name, epochs, batch_size, learning_rate, + weight_decay, warmup_steps, block_size, grad_accum_steps, adam_beta1, adam_beta2, adam_epsilon, lr_scheduler_type, freeze_layers, lora_r, lora_alpha, lora_dropout, use_xformers=False): + model, tokenizer = load_model_and_tokenizer(model_name) + if model is None or tokenizer is None: + return "Error loading model and tokenizer. Please check the model path.", None + + if not model_name: + return "Please select the model", None + + if not dataset_file: + return "Please select the dataset", None + + if not model_output_name: + return "Please write the model name", None + + dataset_path = os.path.join("datasets/llm", dataset_file) + try: + train_dataset = load_dataset('json', data_files=dataset_path) + train_dataset = train_dataset['train'] + + def process_examples(examples): + input_texts = examples['input'] if 'input' in examples else [''] * len(examples['instruction']) + instruction_texts = examples['instruction'] + output_texts = examples['output'] + + texts = [f"{input_text}{instruction_text}{output_text}" for + input_text, instruction_text, output_text in zip(input_texts, instruction_texts, output_texts)] + return tokenizer(texts, truncation=True, padding='max_length', max_length=block_size) + + train_dataset = train_dataset.map(process_examples, batched=True, + remove_columns=['input', 'instruction', 'output']) + train_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask']) + except Exception as e: + print(f"Error loading dataset: {e}") + return f"Error loading dataset. Please check the dataset path and format. Error: {e}", None + + data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False) + + if finetune_method == "Full" or "Freeze": + save_dir = os.path.join("finetuned-models/llm/full", model_output_name) + elif finetune_method == "LORA": + save_dir = os.path.join("finetuned-models/llm/lora", model_output_name) + + os.makedirs(save_dir, exist_ok=True) + + save_path = save_dir + + training_args = TrainingArguments( + output_dir=save_path, + overwrite_output_dir=True, + num_train_epochs=epochs, + per_device_train_batch_size=batch_size, + learning_rate=learning_rate, + weight_decay=weight_decay, + warmup_steps=warmup_steps, + gradient_accumulation_steps=grad_accum_steps, + save_steps=10_000, + save_total_limit=2, + logging_strategy='epoch', + adam_beta1=adam_beta1, + adam_beta2=adam_beta2, + adam_epsilon=adam_epsilon, + lr_scheduler_type=lr_scheduler_type + ) + + if use_xformers: + try: + import xformers.ops + model.enable_xformers_memory_efficient_attention() + except ImportError: + print("xformers not installed. Proceeding without memory-efficient attention.") + + if finetune_method == "LORA": + config = LoraConfig( + r=lora_r, + lora_alpha=lora_alpha, + target_modules=["q_proj", "v_proj"], + lora_dropout=lora_dropout, + bias="none", + task_type="CAUSAL_LM" + ) + + model = get_peft_model(model, config) + + if finetune_method == "Freeze": + num_freeze_layers = len(model.transformer.h) - freeze_layers + for i, layer in enumerate(model.transformer.h): + if i < num_freeze_layers: + for param in layer.parameters(): + param.requires_grad = False + + trainer = Trainer( + model=model, + args=training_args, + data_collator=data_collator, + train_dataset=train_dataset, + ) + + try: + trainer.train() + trainer.save_model() + tokenizer.save_pretrained(save_path) + print("Finetuning completed successfully.") + except Exception as e: + print(f"Error during Finetuning: {e}") + return f"Finetuning failed. Error: {e}", None + + loss_values = [log['loss'] for log in trainer.state.log_history if 'loss' in log] + epochs = [log['epoch'] for log in trainer.state.log_history if 'epoch' in log] + + epochs = epochs[:len(loss_values)] + + fig, ax = plt.subplots(figsize=(8, 6)) + ax.plot(epochs, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) + ax.set_ylabel('Loss') + ax.set_xlabel('Epoch') + ax.set_title('Training Loss') + + if loss_values: + ax.set_ylim(bottom=min(loss_values) - 0.01, top=max(loss_values) + 0.01) + ax.set_xticks(epochs) + ax.set_xticklabels([int(epoch) for epoch in epochs]) + else: + print("No loss values found in trainer.state.log_history") + + ax.grid(True) + + plot_dir = save_dir + os.makedirs(plot_dir, exist_ok=True) + plot_path = os.path.join(save_dir, f"{model_output_name}_loss_plot.png") + plt.tight_layout() + plt.savefig(plot_path) + plt.close() + + return f"Finetuning completed. Model saved at: {save_path}", fig + + +def plot_llm_evaluation_metrics(metrics): + if metrics is None: + return None + + metrics_to_plot = ['bleu', 'bert', 'rouge-1', 'rouge-2', 'rouge-l', 'mauve', 'accuracy', 'precision', 'chrf'] + metric_values = [metrics.get(metric, 0) for metric in metrics_to_plot] + + fig, ax = plt.subplots(figsize=(8, 6)) + bar_width = 0.6 + x = range(len(metrics_to_plot)) + bars = ax.bar(x, metric_values, width=bar_width, align='center', color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#e377c2', '#7f7f7f', '#aec7e8']) + + ax.set_xticks(x) + ax.set_xticklabels(metrics_to_plot, rotation=45, ha='right') + ax.set_ylabel('Value') + ax.set_title('Evaluation Metrics') + + for bar in bars: + height = bar.get_height() + ax.annotate(f'{height:.2f}', xy=(bar.get_x() + bar.get_width() / 2, height), + xytext=(0, 3), textcoords='offset points', ha='center', va='bottom') + + fig.tight_layout() + return fig + + +def evaluate_llm(model_name, lora_model_name, dataset_file, user_input, max_length, temperature, top_p, top_k): + model_path = os.path.join("finetuned-models/llm/full", model_name) + model, tokenizer = load_model_and_tokenizer(model_name, finetuned=True) + if model is None or tokenizer is None: + return "Error loading model and tokenizer. Please check the model path.", None + + if not model_name: + return "Please select the model", None + + if not dataset_file: + return "Please select the dataset", None + + if lora_model_name and not model_name: + return "Please select the original model", None + + if lora_model_name: + lora_model_path = os.path.join("finetuned-models/llm/lora", lora_model_name) + model = PeftModel.from_pretrained(model, lora_model_path) + + dataset_path = os.path.join("datasets/llm", dataset_file) + try: + eval_dataset = load_dataset('json', data_files=dataset_path) + eval_dataset = eval_dataset['train'] + + def process_examples(examples): + input_texts = examples['input'] if 'input' in examples else [''] * len(examples['instruction']) + instruction_texts = examples['instruction'] + output_texts = examples['output'] + + texts = [f"{input_text}{instruction_text}{output_text}" for + input_text, instruction_text, output_text in zip(input_texts, instruction_texts, output_texts)] + return {'input_ids': tokenizer(texts, truncation=True, padding='max_length', max_length=128)['input_ids'], + 'attention_mask': tokenizer(texts, truncation=True, padding='max_length', max_length=128)[ + 'attention_mask'], + 'labels': output_texts} + + eval_dataset = eval_dataset.map(process_examples, batched=True, + remove_columns=['input', 'instruction', 'output']) + eval_dataset.set_format(type='torch', columns=['input_ids', 'attention_mask', 'labels']) + except Exception as e: + print(f"Error loading dataset: {e}") + return f"Error loading dataset. Please check the dataset path and format. Error: {e}", None + + try: + references = eval_dataset['labels'] + predictions = [generate_text(model_name, lora_model_name, "transformers", + user_input if user_input else tokenizer.decode(example['input_ids'], + skip_special_tokens=True), + max_length, temperature, top_p, top_k, output_format='txt')[0] for example in eval_dataset] + + bert_model_name = "google-bert/bert-base-uncased" + bert_repo_url = f"https://huggingface.co/{bert_model_name}" + bert_repo_dir = os.path.join("trainer-scripts", bert_model_name) + + if not os.path.exists(bert_repo_dir): + Repo.clone_from(bert_repo_url, bert_repo_dir) + + predictions = [pred.strip() for pred in predictions if pred.strip()] + references = [ref.strip() for ref in references if ref.strip()] + + bleu_score = sacrebleu.corpus_bleu(predictions, [references]).score + + P, R, F1 = score(predictions, references, lang='en', model_type=bert_model_name, num_layers=12) + bert_score = F1.mean().item() + + rouge = Rouge() + rouge_scores = rouge.get_scores(predictions, references, avg=True) + + max_length = max(len(tokenizer.encode(ref)) for ref in references) + + tokenized_references = tokenizer(references, return_tensors='pt', padding=True, truncation=True, + max_length=max_length) + tokenized_predictions = tokenizer(predictions, return_tensors='pt', padding=True, truncation=True, + max_length=max_length) + + mauve_result = compute_mauve(tokenized_predictions.input_ids, tokenized_references.input_ids) + mauve_score = mauve_result.mauve + + binary_predictions = [1 if pred else 0 for pred in predictions] + binary_references = [1 if ref else 0 for ref in references] + accuracy = accuracy_score(binary_references, binary_predictions) + precision = precision_score(binary_references, binary_predictions) + + chrf_metric = CHRFScore() + for reference, prediction in zip(references, predictions): + chrf_metric.update(prediction, reference) + chrf_score = chrf_metric.compute().item() + + extracted_metrics = { + 'bleu': bleu_score, + 'bert': bert_score, + 'rouge-1': rouge_scores['rouge-1']['f'], + 'rouge-2': rouge_scores['rouge-2']['f'], + 'rouge-l': rouge_scores['rouge-l']['f'], + 'mauve': mauve_score, + 'accuracy': accuracy, + 'precision': precision, + 'chrf': chrf_score + } + + fig = plot_llm_evaluation_metrics(extracted_metrics) + + plot_path = os.path.join(model_path, f"{model_name}_evaluation_plot.png") + fig.savefig(plot_path) + + return f"Evaluation completed successfully. Results saved to {plot_path}", fig + except Exception as e: + print(f"Error during evaluation: {e}") + return f"Evaluation failed. Error: {e}", None + + +def quantize_llm(model_name, quantization_type): + if not model_name: + return "Please select the model" + + model_path = os.path.join("finetuned-models/llm/full", model_name) + llama_cpp_path = "trainer-scripts/llm/llama.cpp" + + os.makedirs(os.path.dirname(llama_cpp_path), exist_ok=True) + + if not os.path.exists(llama_cpp_path): + llama_cpp_repo_url = "https://github.com/ggerganov/llama.cpp.git" + Repo.clone_from(llama_cpp_repo_url, llama_cpp_path) + + try: + os.chdir(llama_cpp_path) + + subprocess.run(f"cmake -B build", shell=True, check=True) + subprocess.run(f"cmake --build build --config Release", shell=True, check=True) + + subprocess.run(f"python convert.py {model_path}", shell=True, check=True) + + input_model = os.path.join(model_path, "ggml-model-f16.ggml") + output_model = os.path.join(model_path, f"ggml-model-{quantization_type}.ggml") + subprocess.run(f"./quantize {input_model} {output_model} {quantization_type}", shell=True, check=True) + + return f"Quantization completed successfully. Model saved at: {output_model}" + + except subprocess.CalledProcessError as e: + return f"Error during quantization: {e}" + finally: + os.chdir(os.path.dirname(os.path.abspath(__file__))) + + +def generate_text(model_name, lora_model_name, model_type, prompt, max_length, temperature, top_p, top_k, output_format): + if model_type == "transformers": + model, tokenizer = load_model_and_tokenizer(model_name, finetuned=True) + if model is None or tokenizer is None: + return None, "Error loading model and tokenizer. Please check the model path." + + if not model_name: + return None, "Please select the model" + + if lora_model_name and not model_name: + return None, "Please select the original model" + + if lora_model_name: + lora_model_path = os.path.join("finetuned-models/llm/lora", lora_model_name) + model = PeftModel.from_pretrained(model, lora_model_path) + + try: + input_ids = tokenizer.encode(prompt, return_tensors='pt') + attention_mask = torch.ones(input_ids.shape, dtype=torch.long) + pad_token_id = tokenizer.eos_token_id + + input_ids = input_ids.to(model.device) + attention_mask = attention_mask.to(model.device) + + output = model.generate( + input_ids, + do_sample=True, + attention_mask=attention_mask, + pad_token_id=pad_token_id, + max_new_tokens=max_length, + num_return_sequences=1, + top_p=top_p, + top_k=top_k, + temperature=temperature, + repetition_penalty=1.1, + num_beams=5, + no_repeat_ngram_size=2, + ) + + generated_text = tokenizer.decode(output[0], skip_special_tokens=True) + + output_dir = "outputs/llm" + os.makedirs(output_dir, exist_ok=True) + + timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + output_file = f"llm_history_{timestamp}.{output_format}" + output_path = os.path.join(output_dir, output_file) + + if output_format == "txt": + with open(output_path, "a", encoding="utf-8") as file: + file.write(f"Human: {prompt}\nAI: {generated_text}\n") + elif output_format == "json": + history = [{"Human": prompt, "AI": generated_text}] + with open(output_path, "w", encoding="utf-8") as file: + json.dump(history, file, indent=2, ensure_ascii=False) + + return generated_text, "Text generation successful" + except Exception as e: + print(f"Error during text generation: {e}") + return None, f"Text generation failed. Error: {e}" + + elif model_type == "llama.cpp": + model_path = os.path.join("finetuned-models/llm/full", model_name) + + try: + + llm = Llama(model_path=model_path, n_ctx=max_length, n_parts=-1, seed=-1, f16_kv=True, logits_all=False, vocab_only=False, use_mlock=False, n_threads=8, n_batch=1, suffix=None) + + output = llm(prompt, max_tokens=max_length, top_k=top_k, top_p=top_p, temperature=temperature, stop=None, echo=False) + + generated_text = output['choices'][0]['text'] + + output_dir = "outputs/llm" + os.makedirs(output_dir, exist_ok=True) + + timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + output_file = f"llm_history_{timestamp}.{output_format}" + output_path = os.path.join(output_dir, output_file) + + if output_format == "txt": + with open(output_path, "a", encoding="utf-8") as file: + file.write(f"Human: {prompt}\nAI: {generated_text}\n") + elif output_format == "json": + history = [{"Human": prompt, "AI": generated_text}] + with open(output_path, "w", encoding="utf-8") as file: + json.dump(history, file, indent=2, ensure_ascii=False) + + return generated_text, "Text generation successful" + except Exception as e: + print(f"Error during text generation: {e}") + return None, f"Text generation failed. Error: {e}" + + +def create_sd_dataset(image_files, existing_dataset, dataset_name, file_prefix, prompt_text): + if existing_dataset: + dataset_dir = os.path.join("datasets", "sd", existing_dataset, "train") + else: + dataset_dir = os.path.join("datasets", "sd", dataset_name, "train") + + os.makedirs(dataset_dir, exist_ok=True) + + metadata_file = os.path.join(dataset_dir, "metadata.jsonl") + + with open(metadata_file, "a") as f: + for i, image_file in enumerate(image_files): + file_name = f"{file_prefix}-{i + 1}.jpg" + image_path = os.path.join(dataset_dir, file_name) + image = Image.open(image_file.name) + image.save(image_path) + + metadata = { + "file_name": file_name, + "text": prompt_text + } + f.write(json.dumps(metadata) + "\n") + + return f"Dataset {'updated' if existing_dataset else 'created'} successfully at {dataset_dir}" + + +def finetune_sd(model_name, dataset_name, model_type, finetune_method, model_output_name, resolution, + train_batch_size, gradient_accumulation_steps, + learning_rate, lr_scheduler, lr_warmup_steps, max_train_steps, adam_beta1, adam_beta2, adam_weight_decay, adam_epsilon, max_grad_norm, noise_offset, rank, enable_xformers): + model_path = os.path.join("models/sd", model_name) + dataset_path = os.path.join("datasets/sd", dataset_name) + + if not model_name: + return "Please select the model", None + + if not dataset_name: + return "Please select the dataset", None + + if not model_output_name: + return "Please write the model name", None + + if finetune_method == "Full": + output_dir = os.path.join("finetuned-models/sd/full", model_output_name) + if model_type == "SD": + dataset = load_dataset("imagefolder", data_dir=dataset_path) + args = [ + "accelerate", "launch", "trainer-scripts/sd/train_text_to_image.py", + f"--pretrained_model_name_or_path={model_path}", + f"--train_data_dir={dataset_path}", + f"--output_dir={output_dir}", + f"--resolution={resolution}", + f"--train_batch_size={train_batch_size}", + f"--gradient_accumulation_steps={gradient_accumulation_steps}", + f"--learning_rate={learning_rate}", + f"--lr_scheduler={lr_scheduler}", + f"--lr_warmup_steps={lr_warmup_steps}", + f"--max_train_steps={max_train_steps}", + f"--adam_beta1={adam_beta1}", + f"--adam_beta2={adam_beta2}", + f"--adam_weight_decay={adam_weight_decay}", + f"--adam_epsilon={adam_epsilon}", + f"--max_grad_norm={max_grad_norm}", + f"--noise_offset={noise_offset}", + f"--caption_column=text", + f"--mixed_precision=no", + f"--seed=0" + ] + if enable_xformers: + args.append("--enable_xformers_memory_efficient_attention") + elif model_type == "SDXL": + dataset = load_dataset("imagefolder", data_dir=dataset_path) + args = [ + "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_sdxl.py", + f"--pretrained_model_name_or_path={model_path}", + f"--train_data_dir={dataset_path}", + f"--output_dir={output_dir}", + f"--resolution={resolution}", + f"--train_batch_size={train_batch_size}", + f"--gradient_accumulation_steps={gradient_accumulation_steps}", + f"--learning_rate={learning_rate}", + f"--lr_scheduler={lr_scheduler}", + f"--lr_warmup_steps={lr_warmup_steps}", + f"--max_train_steps={max_train_steps}", + f"--adam_beta1={adam_beta1}", + f"--adam_beta2={adam_beta2}", + f"--adam_weight_decay={adam_weight_decay}", + f"--adam_epsilon={adam_epsilon}", + f"--max_grad_norm={max_grad_norm}", + f"--noise_offset={noise_offset}", + f"--caption_column=text", + f"--mixed_precision=no", + f"--seed=0" + ] + if enable_xformers: + args.append("--enable_xformers_memory_efficient_attention") + elif finetune_method == "LORA": + output_dir = os.path.join("finetuned-models/sd/lora", model_output_name) + if model_type == "SD": + dataset = load_dataset("imagefolder", data_dir=dataset_path) + args = [ + "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_lora.py", + f"--pretrained_model_name_or_path={model_path}", + f"--train_data_dir={dataset_path}", + f"--output_dir={output_dir}", + f"--resolution={resolution}", + f"--train_batch_size={train_batch_size}", + f"--gradient_accumulation_steps={gradient_accumulation_steps}", + f"--learning_rate={learning_rate}", + f"--lr_scheduler={lr_scheduler}", + f"--lr_warmup_steps={lr_warmup_steps}", + f"--max_train_steps={max_train_steps}", + f"--adam_beta1={adam_beta1}", + f"--adam_beta2={adam_beta2}", + f"--adam_weight_decay={adam_weight_decay}", + f"--adam_epsilon={adam_epsilon}", + f"--max_grad_norm={max_grad_norm}", + f"--noise_offset={noise_offset}", + f"--rank={rank}", + f"--caption_column=text", + f"--mixed_precision=no", + f"--seed=0" + ] + if enable_xformers: + args.append("--enable_xformers_memory_efficient_attention") + elif model_type == "SDXL": + dataset = load_dataset("imagefolder", data_dir=dataset_path) + args = [ + "accelerate", "launch", "trainer-scripts/sd/train_text_to_image_lora_sdxl.py", + f"--pretrained_model_name_or_path={model_path}", + f"--train_data_dir={dataset_path}", + f"--output_dir={output_dir}", + f"--resolution={resolution}", + f"--train_batch_size={train_batch_size}", + f"--gradient_accumulation_steps={gradient_accumulation_steps}", + f"--learning_rate={learning_rate}", + f"--lr_scheduler={lr_scheduler}", + f"--lr_warmup_steps={lr_warmup_steps}", + f"--max_train_steps={max_train_steps}", + f"--adam_beta1={adam_beta1}", + f"--adam_beta2={adam_beta2}", + f"--adam_weight_decay={adam_weight_decay}", + f"--adam_epsilon={adam_epsilon}", + f"--max_grad_norm={max_grad_norm}", + f"--noise_offset={noise_offset}", + f"--rank={rank}", + f"--caption_column=text", + f"--mixed_precision=no", + f"--seed=0" + ] + if enable_xformers: + args.append("--enable_xformers_memory_efficient_attention") + else: + raise ValueError(f"Invalid finetune method: {finetune_method}") + + subprocess.run(args) + + if finetune_method == "Full": + logs_dir = os.path.join(output_dir, "logs", "text2image-fine-tune") + events_files = [f for f in os.listdir(logs_dir) if f.startswith("events.out.tfevents")] + latest_event_file = sorted(events_files)[-1] + event_file_path = os.path.join(logs_dir, latest_event_file) + + event_acc = EventAccumulator(event_file_path) + event_acc.Reload() + + loss_values = [s.value for s in event_acc.Scalars("train_loss")] + steps = [s.step for s in event_acc.Scalars("train_loss")] + + fig, ax = plt.subplots(figsize=(8, 6)) + ax.plot(steps, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) + ax.set_ylabel('Loss') + ax.set_xlabel('Step') + ax.set_title('Training Loss') + ax.grid(True) + + plot_path = os.path.join(output_dir, f"{model_name}_loss_plot.png") + plt.tight_layout() + plt.savefig(plot_path) + plt.close() + + return f"Fine-tuning completed. Model saved at: {output_dir}", fig + + elif finetune_method == "LORA": + logs_dir = os.path.join(output_dir, "logs", "text2image-fine-tune") + events_files = [f for f in os.listdir(logs_dir) if f.startswith("events.out.tfevents")] + latest_event_file = sorted(events_files)[-1] + event_file_path = os.path.join(logs_dir, latest_event_file) + + event_acc = EventAccumulator(event_file_path) + event_acc.Reload() + + loss_values = [s.value for s in event_acc.Scalars("train_loss")] + steps = [s.step for s in event_acc.Scalars("train_loss")] + + fig, ax = plt.subplots(figsize=(8, 6)) + ax.plot(steps, loss_values, marker='o', markersize=4, linestyle='-', linewidth=1) + ax.set_ylabel('Loss') + ax.set_xlabel('Step') + ax.set_title('Training Loss') + ax.grid(True) + + plot_path = os.path.join(output_dir, f"{model_name}_loss_plot.png") + plt.tight_layout() + plt.savefig(plot_path) + plt.close() + + return f"Finetuning completed. Model saved at: {output_dir}", fig + + +def plot_sd_evaluation_metrics(metrics): + metrics_to_plot = ["FID", "KID", "Inception Score", "VIF", "CLIP Score", "LPIPS", "SCC", "SDI", "SAM", "SSIM"] + metric_values = [metrics[metric] for metric in metrics_to_plot] + + fig, ax = plt.subplots(figsize=(8, 6)) + bar_width = 0.6 + x = range(len(metrics_to_plot)) + bars = ax.bar(x, metric_values, width=bar_width, align="center", color=['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', '#8c564b', '#bcbd22', '#17becf', '#aaffc3', '#ffe119']) + + ax.set_xticks(x) + ax.set_xticklabels(metrics_to_plot, rotation=45, ha="right") + ax.set_ylabel("Value") + ax.set_title("Evaluation Metrics") + + for bar in bars: + height = bar.get_height() + ax.annotate(f"{height:.2f}", xy=(bar.get_x() + bar.get_width() / 2, height), + xytext=(0, 3), textcoords="offset points", ha="center", va="bottom") + + fig.tight_layout() + return fig + + +def evaluate_sd(model_name, lora_model_name, dataset_name, model_method, model_type, user_prompt, negative_prompt, num_inference_steps, cfg_scale): + if model_method == "Diffusers": + if model_type == "SD": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + elif model_type == "SDXL": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionXLPipeline.from_pretrained(model_path, torch_dtype=torch.float16, attention_slice=1, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + elif model_method == "Safetensors": + if model_type == "SD": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionPipeline.from_single_file(model_path, torch_dtype=torch.float16, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + elif model_type == "SDXL": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionXLPipeline.from_single_file(model_path, torch_dtype=torch.float16, attention_slice=1, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + else: + return "Invalid model type selected", None + + if not model_name: + return "Please select the model", None + + if not dataset_name: + return "Please select the dataset", None + + if lora_model_name and not model_name: + return "Please select the original model", None + + if lora_model_name: + lora_model_path = os.path.join("finetuned-models/sd/lora", lora_model_name) + model.unet.load_attn_procs(lora_model_path) + + dataset_path = os.path.join("datasets/sd", dataset_name) + dataset = load_dataset("imagefolder", data_dir=dataset_path) + + num_samples = len(dataset["train"]) + subset_size = min(num_samples, 50) + + fid = FrechetInceptionDistance().to("cuda") + kid = KernelInceptionDistance(subset_size=subset_size).to("cuda") + inception = InceptionScore().to("cuda") + vif = VisualInformationFidelity().to("cuda") + lpips = LearnedPerceptualImagePatchSimilarity().to("cuda") + scc = SpatialCorrelationCoefficient().to("cuda") + sdi = SpectralDistortionIndex().to("cuda") + sam = SpectralAngleMapper().to("cuda") + ssim = StructuralSimilarityIndexMeasure().to("cuda") + + clip_model_name = "openai/clip-vit-base-patch16" + clip_repo_url = f"https://huggingface.co/{clip_model_name}" + clip_repo_dir = os.path.join("trainer-scripts", clip_model_name) + + if not os.path.exists(clip_repo_dir): + Repo.clone_from(clip_repo_url, clip_repo_dir) + + clip_score = CLIPScore(model_name_or_path=clip_model_name).to("cuda") + + resize = Resize((512, 512)) + + clip_scores = [] + + for batch in dataset["train"]: + image = batch["image"].convert("RGB") + image_tensor = torch.from_numpy(np.array(image)).permute(2, 0, 1).unsqueeze(0).to("cuda").to(torch.uint8) + + generated_images = model(prompt=user_prompt, negative_prompt=negative_prompt, num_inference_steps=num_inference_steps, guidance_scale=cfg_scale, + output_type="pil").images + generated_image = generated_images[0].resize((image.width, image.height)) + generated_image_tensor = torch.from_numpy(np.array(generated_image)).permute(2, 0, 1).unsqueeze(0).to( + "cuda").to(torch.uint8) + + fid.update(resize(image_tensor), real=True) + fid.update(resize(generated_image_tensor), real=False) + + kid.update(resize(image_tensor), real=True) + kid.update(resize(generated_image_tensor), real=False) + + inception.update(resize(generated_image_tensor)) + + vif.update(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) + + lpips_score = lpips(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) + scc_score = scc(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) + sdi_score = sdi(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) + sam_score = sam(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) + ssim_score = ssim(resize(image_tensor).to(torch.float32), resize(generated_image_tensor).to(torch.float32)) + + clip_score_value = clip_score(resize(generated_image_tensor).to(torch.float32), "a photo of a generated image") + clip_scores.append(clip_score_value.detach().item()) + + fid_score = fid.compute() + kid_score, _ = kid.compute() + inception_score, _ = inception.compute() + vif_score = vif.compute() + clip_score_avg = np.mean(clip_scores) + + metrics = { + "FID": fid_score.item(), + "KID": kid_score.item(), + "Inception Score": inception_score.item(), + "VIF": vif_score.item(), + "CLIP Score": clip_score_avg, + "LPIPS": lpips_score.item(), + "SCC": scc_score.item(), + "SDI": sdi_score.item(), + "SAM": sam_score.item(), + "SSIM": ssim_score.item() + } + + fig = plot_sd_evaluation_metrics(metrics) + + if model_method == "Diffusers": + plot_path = os.path.join(model_path, f"{model_name}_evaluation_plot.png") + elif model_method == "Safetensors": + plot_path = os.path.join("finetuned-models/sd/full", f"{model_name}_evaluation_plot.png") + fig.savefig(plot_path) + + return f"Evaluation completed successfully. Results saved to {plot_path}", fig + + +def convert_sd_model_to_safetensors(model_name, model_type, use_half, use_safetensors): + model_path = os.path.join("finetuned-models/sd/full", model_name) + output_path = os.path.join("finetuned-models/sd/full") + + if model_type == "SD": + try: + args = [ + "py", + "trainer-scripts/sd/convert_diffusers_to_original_stable_diffusion.py", + "--model_path", model_path, + "--checkpoint_path", output_path, + ] + if use_half: + args.append("--half") + if use_safetensors: + args.append("--use_safetensors") + + subprocess.run(args, check=True) + + return f"Model successfully converted to single file and saved to {output_path}" + except subprocess.CalledProcessError as e: + return f"Error converting model to single file: {e}" + elif model_type == "SDXL": + try: + args = [ + "py", + "trainer-scripts/sd/convert_diffusers_to_original_sdxl.py", + "--model_path", model_path, + "--checkpoint_path", output_path, + ] + if use_half: + args.append("--half") + if use_safetensors: + args.append("--use_safetensors") + + subprocess.run(args, check=True) + + return f"Model successfully converted to single file and saved to {output_path}" + except subprocess.CalledProcessError as e: + return f"Error converting model to single file: {e}" + + +def generate_image(model_name, lora_model_name, model_method, model_type, prompt, negative_prompt, num_inference_steps, cfg_scale, width, height, output_format): + if model_method == "Diffusers": + if model_type == "SD": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + elif model_type == "SDXL": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionXLPipeline.from_pretrained(model_path, torch_dtype=torch.float16, attention_slice=1, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + elif model_method == "Safetensors": + if model_type == "SD": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionPipeline.from_single_file(model_path, torch_dtype=torch.float16, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + elif model_type == "SDXL": + model_path = os.path.join("finetuned-models/sd/full", model_name) + model = StableDiffusionXLPipeline.from_single_file(model_path, torch_dtype=torch.float16, attention_slice=1, + safety_checker=None).to( + "cuda") + model.scheduler = DDPMScheduler.from_config(model.scheduler.config) + else: + return "Invalid model type selected", None + + if not model_name: + return "Please select the model", None + + if lora_model_name and not model_name: + return "Please select the original model", None + + if lora_model_name: + lora_model_path = os.path.join("finetuned-models/sd/lora", lora_model_name) + model.unet.load_attn_procs(lora_model_path) + + image = model(prompt, negative_prompt=negative_prompt, num_inference_steps=num_inference_steps, + guidance_scale=cfg_scale, width=width, height=height).images[0] + + output_dir = "outputs/sd" + os.makedirs(output_dir, exist_ok=True) + + timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + output_file = f"sd_image_{timestamp}.{output_format}" + output_path = os.path.join(output_dir, output_file) + + image.save(output_path) + + return image, "Image generation successful" + + +def close_terminal(): + os._exit(1) + + +def open_finetuned_folder(): + outputs_folder = "finetuned-models" + if os.path.exists(outputs_folder): + if os.name == "nt": + os.startfile(outputs_folder) + else: + os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') + + +def open_datasets_folder(): + outputs_folder = "datasets" + if os.path.exists(outputs_folder): + if os.name == "nt": + os.startfile(outputs_folder) + else: + os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') + + +def open_outputs_folder(): + outputs_folder = "outputs" + if os.path.exists(outputs_folder): + if os.name == "nt": + os.startfile(outputs_folder) + else: + os.system(f'open "{outputs_folder}"' if os.name == "darwin" else f'xdg-open "{outputs_folder}"') + + +def get_system_info(): + gpu = GPUtil.getGPUs()[0] + gpu_total_memory = f"{gpu.memoryTotal} MB" + gpu_used_memory = f"{gpu.memoryUsed} MB" + gpu_free_memory = f"{gpu.memoryFree} MB" + + nvmlInit() + handle = nvmlDeviceGetHandleByIndex(0) + gpu_temp = nvmlDeviceGetTemperature(handle, NVML_TEMPERATURE_GPU) + + cpu_info = get_cpu_info() + cpu_temp = cpu_info.get("cpu_temp", None) + + ram = psutil.virtual_memory() + ram_total = f"{ram.total // (1024 ** 3)} GB" + ram_used = f"{ram.used // (1024 ** 3)} GB" + ram_free = f"{ram.available // (1024 ** 3)} GB" + + disk = psutil.disk_usage('/') + disk_total = f"{disk.total // (1024 ** 3)} GB" + disk_free = f"{disk.free // (1024 ** 3)} GB" + + app_folder = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) + app_size = sum(os.path.getsize(os.path.join(dirpath, filename)) + for dirpath, dirnames, filenames in os.walk(app_folder) + for filename in filenames) + app_size = f"{app_size // (1024 ** 3):.2f} GB" + + return (gpu_total_memory, gpu_used_memory, gpu_free_memory, gpu_temp, cpu_temp, + ram_total, ram_used, ram_free, disk_total, disk_free, app_size) + + +def settings_interface(language, share_value, debug_value, monitoring_value, auto_launch, api_status, open_api, queue_max_size, status_update_rate, gradio_auth, server_name, server_port, hf_token, theme, + enable_custom_theme, primary_hue, secondary_hue, neutral_hue, + spacing_size, radius_size, text_size, font, font_mono): + settings = load_settings() + + settings['language'] = language + settings['share_mode'] = share_value == "True" + settings['debug_mode'] = debug_value == "True" + settings['monitoring_mode'] = monitoring_value == "True" + settings['auto_launch'] = auto_launch == "True" + settings['show_api'] = api_status == "True" + settings['api_open'] = open_api == "True" + settings['queue_max_size'] = int(queue_max_size) if queue_max_size else 10 + settings['status_update_rate'] = status_update_rate + if gradio_auth: + username, password = gradio_auth.split(':') + settings['auth'] = {"username": username, "password": password} + settings['server_name'] = server_name + settings['server_port'] = int(server_port) if server_port else 7860 + settings['hf_token'] = hf_token + settings['theme'] = theme + settings['custom_theme']['enabled'] = enable_custom_theme + settings['custom_theme']['primary_hue'] = primary_hue + settings['custom_theme']['secondary_hue'] = secondary_hue + settings['custom_theme']['neutral_hue'] = neutral_hue + settings['custom_theme']['spacing_size'] = spacing_size + settings['custom_theme']['radius_size'] = radius_size + settings['custom_theme']['text_size'] = text_size + settings['custom_theme']['font'] = font + settings['custom_theme']['font_mono'] = font_mono + + save_settings(settings) + + message = "Settings updated successfully!" + message += f"\nLanguage set to {settings['language']}" + message += f"\nShare mode is {settings['share_mode']}" + message += f"\nDebug mode is {settings['debug_mode']}" + message += f"\nMonitoring mode is {settings['monitoring_mode']}" + message += f"\nAutoLaunch mode is {settings['auto_launch']}" + message += f"\nShow API mode is {settings['show_api']}" + message += f"\nOpen API mode is {settings['api_open']}" + message += f"\nQueue max size is {settings['queue_max_size']}" + message += f"\nStatus update rate is {settings['status_update_rate']}" + message += f"\nNew Gradio Auth is {settings['auth']}" + message += f" Server will run on {settings['server_name']}:{settings['server_port']}" + message += f"\nNew HF-Token is {settings['hf_token']}" + message += f"\nTheme set to {theme and settings['custom_theme'] if enable_custom_theme else theme}" + message += f"\nPlease restart the application for changes to take effect!" + + return message + + +def download_model(model_name_llm, model_name_sd): + if not model_name_llm and not model_name_sd: + return "Please select a model to download" + + if model_name_llm and model_name_sd: + return "Please select one model type for downloading" + + if model_name_llm: + model_url = "" + if model_name_llm == "StarlingLM(Transformers7B)": + model_url = "https://huggingface.co/Nexusflow/Starling-LM-7B-beta" + elif model_name_llm == "OpenChat3.6(Llama8B.Q4)": + model_url = "https://huggingface.co/bartowski/openchat-3.6-8b-20240522-GGUF/resolve/main/openchat-3.6-8b-20240522-Q4_K_M.gguf" + model_path = os.path.join("inputs", "text", "llm_models", model_name_llm) + + if model_url: + if model_name_llm == "StarlingLM(Transformers7B)": + Repo.clone_from(model_url, model_path) + else: + response = requests.get(model_url, allow_redirects=True) + with open(model_path, "wb") as file: + file.write(response.content) + return f"LLM model {model_name_llm} downloaded successfully!" + else: + return "Invalid LLM model name" + + if model_name_sd: + model_url = "" + if model_name_sd == "Dreamshaper8(SD1.5)": + model_url = "https://huggingface.co/Lykon/DreamShaper/resolve/main/DreamShaper_8_pruned.safetensors" + elif model_name_sd == "RealisticVisionV4.0(SDXL)": + model_url = "https://huggingface.co/SG161222/RealVisXL_V4.0/resolve/main/RealVisXL_V4.0.safetensors" + model_path = os.path.join("inputs", "image", "sd_models", f"{model_name_sd}.safetensors") + + if model_url: + response = requests.get(model_url, allow_redirects=True) + with open(model_path, "wb") as file: + file.write(response.content) + return f"StableDiffusion model {model_name_sd} downloaded successfully!" + else: + return "Invalid StableDiffusion model name" + + +def get_wiki_content(url, local_file="Wikies/WikiEN.md"): + try: + response = requests.get(url) + if response.status_code == 200: + return response.text + except: + pass + + try: + with open(local_file, 'r', encoding='utf-8') as file: + content = file.read() + return markdown.markdown(content) + except: + return "

Wiki content is not available.

" + + +settings = load_settings() +lang = settings['language'] + + +llm_dataset_interface = gr.Interface( + fn=create_llm_dataset, + inputs=[ + gr.Dropdown(choices=get_available_llm_datasets(), label=_("Existing Dataset (optional)", lang)), + gr.Textbox(label=_("Dataset Name", lang), type="text"), + gr.Textbox(label=_("Instruction", lang), type="text"), + gr.Textbox(label=_("Input", lang), type="text"), + gr.Textbox(label=_("Output", lang), type="text"), + ], + outputs=[ + gr.Textbox(label=_("Status", lang), type="text"), + ], + title=_("NeuroTrainerWebUI (ALPHA) - LLM-Dataset", lang), + description=_("Create a new dataset or add a new column to an existing dataset for LLM", lang), + allow_flagging="never", +) + +llm_finetune_interface = gr.Interface( + fn=finetune_llm, + inputs=[ + gr.Dropdown(choices=get_available_llm_models(), label=_("Model", lang)), + gr.Dropdown(choices=get_available_llm_datasets(), label=_("Dataset", lang)), + gr.Radio(choices=["Full", "Freeze", "LORA"], value="Full", label=_("Finetune Method", lang)), + gr.Textbox(label=_("Output Model Name", lang), type="text"), + gr.Number(value=10, label=_("Epochs", lang)), + gr.Number(value=4, label=_("Batch size", lang)), + gr.Number(value=3e-5, label=_("Learning rate", lang)), + gr.Number(value=0.01, label=_("Weight decay", lang)), + gr.Number(value=100, label=_("Warmup steps", lang)), + gr.Number(value=128, label=_("Block size", lang)), + gr.Number(value=1, label=_("Gradient accumulation steps", lang)), + gr.Number(value=0.9, label=_("Adam beta 1", lang)), + gr.Number(value=0.999, label=_("Adam beta 2", lang)), + gr.Number(value=1e-8, label=_("Adam epsilon", lang)), + gr.Dropdown(choices=["linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"], value="linear", label=_("LR Scheduler", lang)), + gr.Number(value=2, label=_("Freeze layers", lang)), + gr.Number(value=16, label=_("LORA r", lang)), + gr.Number(value=32, label=_("LORA alpha", lang)), + gr.Number(value=0.05, label=_("LORA dropout", lang)), + gr.Checkbox(label=_("Use xformers", lang), value=False), + ], + outputs=[ + gr.Textbox(label=_("Finetuning Status", lang), type="text"), + gr.Plot(label=_("Finetuning Loss", lang)) + ], + title=_("NeuroTrainerWebUI (ALPHA) - LLM-Finetune", lang), + description=_("Finetune LLM models on a custom dataset", lang), + allow_flagging="never", +) + +llm_evaluate_interface = gr.Interface( + fn=evaluate_llm, + inputs=[ + gr.Dropdown(choices=get_available_finetuned_llm_models(), label=_("Model", lang)), + gr.Dropdown(choices=get_available_llm_lora_models(), label=_("LORA Model (optional)", lang)), + gr.Dropdown(choices=get_available_llm_datasets(), label=_("Dataset", lang)), + gr.Textbox(label=_("Request", lang), type="text"), + gr.Slider(minimum=1, maximum=2048, value=128, step=1, label=_("Max Length", lang)), + gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label=_("Temperature", lang)), + gr.Slider(minimum=0.0, maximum=1.0, value=0.9, step=0.1, label=_("Top P", lang)), + gr.Slider(minimum=0, maximum=100, value=20, step=1, label=_("Top K", lang)), + ], + outputs=[ + gr.Textbox(label=_("Evaluation Status", lang)), + gr.Plot(label=_("Evaluation Metrics", lang)), + ], + title=_("NeuroTrainerWebUI (ALPHA) - LLM-Evaluate", lang), + description=_("Evaluate finetuned LLM models on a custom dataset", lang), + allow_flagging="never", +) + +llm_quantize_interface = gr.Interface( + fn=quantize_llm, + inputs=[ + gr.Dropdown(choices=get_available_finetuned_llm_models(), label=_("Model", lang)), + gr.Radio(choices=["Q2_K_M", "Q4_K_M", "Q6_K_M", "Q8_K_M"], value="Q4_K_M", label=_("Quantization Type", lang)), + ], + outputs=[ + gr.Textbox(label=_("Quantization Status", lang), type="text"), + ], + title=_("NeuroTrainerWebUI (ALPHA) - LLM-Quantize", lang), + description=_("Quantize finetuned LLM models to .gguf format using llama.cpp", lang), + allow_flagging="never", +) + +llm_generate_interface = gr.Interface( + fn=generate_text, + inputs=[ + gr.Dropdown(choices=get_available_finetuned_llm_models(), label=_("Model", lang)), + gr.Dropdown(choices=get_available_llm_lora_models(), label=_("LORA Model (optional)", lang)), + gr.Radio(choices=["transformers", "llama.cpp"], value="transformers", label=_("Model Type", lang)), + gr.Textbox(label=_("Request", lang), type="text"), + gr.Slider(minimum=1, maximum=2048, value=512, step=1, label=_("Max length", lang)), + gr.Slider(minimum=0.0, maximum=2.0, value=0.7, step=0.1, label=_("Temperature", lang)), + gr.Slider(minimum=0.0, maximum=1.0, value=0.9, step=0.1, label=_("Top P", lang)), + gr.Slider(minimum=0, maximum=100, value=20, step=1, label=_("Top K", lang)), + gr.Radio(choices=["txt", "json"], value="txt", label=_("Output Format", lang)), + ], + outputs=[ + gr.Textbox(label=_("Generated text", lang), type="text"), + gr.Textbox(label=_("Message", lang), type="text"), + ], + title=_("NeuroTrainerWebUI (ALPHA) - LLM-Generate", lang), + description=_("Generate text using finetuned LLM models", lang), + allow_flagging="never", +) + +sd_dataset_interface = gr.Interface( + fn=create_sd_dataset, + inputs=[ + gr.Files(label=_("Image Files", lang)), + gr.Dropdown(choices=get_available_sd_datasets(), label=_("Existing Dataset (optional)", lang)), + gr.Textbox(label=_("Dataset Name", lang)), + gr.Textbox(label=_("Files Name", lang)), + gr.Textbox(label=_("Prompt Text", lang)) + ], + outputs=[ + gr.Textbox(label=_("Status", lang)) + ], + title=_("NeuroTrainerWebUI (ALPHA) - StableDiffusion-Dataset", lang), + description=_("Create a new dataset or add a new column to an existing dataset for Stable Diffusion", lang), + allow_flagging="never", +) + +sd_finetune_interface = gr.Interface( + fn=finetune_sd, + inputs=[ + gr.Dropdown(choices=get_available_sd_models(), label=_("Model", lang)), + gr.Dropdown(choices=get_available_sd_datasets(), label=_("Dataset", lang)), + gr.Radio(choices=["SD", "SDXL"], value="SD", label=_("Model Type", lang)), + gr.Radio(choices=["Full", "LORA"], value="Full", label=_("Finetune Method", lang)), + gr.Textbox(label=_("Output Model Name", lang), type="text"), + gr.Number(value=512, label=_("Resolution", lang)), + gr.Number(value=1, label=_("Train Batch Size", lang)), + gr.Number(value=1, label=_("Gradient Accumulation Steps", lang)), + gr.Number(value=5e-6, label=_("Learning Rate", lang)), + gr.Dropdown(choices=["linear", "cosine", "cosine_with_restarts", "polynomial", "constant", "constant_with_warmup"], value="linear", label=_("LR Scheduler", lang)), + gr.Number(value=0, label=_("LR Warmup Steps", lang)), + gr.Number(value=100, label=_("Max Train Steps", lang)), + gr.Number(value=0.9, label=_("Adam beta 1", lang)), + gr.Number(value=0.999, label=_("Adam beta 2", lang)), + gr.Number(value=1e-2, label=_("Adam weight decay", lang)), + gr.Number(value=1e-8, label=_("Adam epsilon", lang)), + gr.Number(value=1.0, label=_("Max grad norm", lang)), + gr.Number(value=0, label=_("Noise offset", lang)), + gr.Number(value=4, label=_("LORA Rank", lang)), + gr.Checkbox(label=_("Use xformers", lang), value=False), + ], + outputs=[ + gr.Textbox(label=_("Finetuning Status", lang), type="text"), + gr.Plot(label=_("Finetuning Loss", lang)) + ], + title=_("NeuroTrainerWebUI (ALPHA) - StableDiffusion-Finetune", lang), + description=_("Finetune Stable Diffusion models on a custom dataset", lang), + allow_flagging="never", +) + +sd_evaluate_interface = gr.Interface( + fn=evaluate_sd, + inputs=[ + gr.Dropdown(choices=get_available_finetuned_sd_models(), label=_("Model", lang)), + gr.Dropdown(choices=get_available_sd_lora_models(), label=_("LORA Model (optional)", lang)), + gr.Dropdown(choices=get_available_sd_datasets(), label=_("Dataset", lang)), + gr.Radio(choices=["Diffusers", "Safetensors"], value="Diffusers", label=_("Model Method", lang)), + gr.Radio(choices=["SD", "SDXL"], value="SD", label=_("Model Type", lang)), + gr.Textbox(label=_("Prompt", lang), type="text"), + gr.Textbox(label=_("Negative Prompt", lang), type="text"), + gr.Slider(minimum=1, maximum=150, value=30, step=1, label=_("Steps", lang)), + gr.Slider(minimum=1, maximum=30, value=8, step=0.5, label=_("CFG", lang)), + ], + outputs=[ + gr.Textbox(label=_("Evaluation Status", lang)), + gr.Plot(label=_("Evaluation Metrics", lang)), + ], + title=_("NeuroTrainerWebUI (ALPHA) - StabledDiffusion-Evaluate", lang), + description=_("Evaluate finetuned Stable Diffusion models on a custom dataset", lang), + allow_flagging="never", +) + +sd_convert_interface = gr.Interface( + fn=convert_sd_model_to_safetensors, + inputs=[ + gr.Dropdown(choices=get_available_finetuned_sd_models(), label=_("Model", lang)), + gr.Radio(choices=["SD", "SDXL"], value="SD", label=_("Model Type", lang)), + gr.Checkbox(label=_("Use Half Precision", lang), value=False), + gr.Checkbox(label=_("Use Safetensors", lang), value=False), + ], + outputs=[ + gr.Textbox(label=_("Conversion Status", lang), type="text"), + ], + title=_("NeuroTrainerWebUI (ALPHA) - StableDiffusion-Conversion", lang), + description=_("Convert finetuned Stable Diffusion models to single file (.ckpt or .safetensors)", lang), + allow_flagging="never", +) + +sd_generate_interface = gr.Interface( + fn=generate_image, + inputs=[ + gr.Dropdown(choices=get_available_finetuned_sd_models(), label=_("Model", lang)), + gr.Dropdown(choices=get_available_sd_lora_models(), label=_("LORA Model (optional)", lang)), + gr.Radio(choices=["Diffusers", "Safetensors"], value="Diffusers", label=_("Model Method", lang)), + gr.Radio(choices=["SD", "SDXL"], value="SD", label=_("Model Type", lang)), + gr.Textbox(label=_("Prompt", lang), type="text"), + gr.Textbox(label=_("Negative Prompt", lang), type="text"), + gr.Slider(minimum=1, maximum=150, value=30, step=1, label=_("Steps", lang)), + gr.Slider(minimum=1, maximum=30, value=8, step=0.5, label=_("CFG", lang)), + gr.Slider(minimum=256, maximum=1024, value=512, step=64, label=_("Width", lang)), + gr.Slider(minimum=256, maximum=1024, value=512, step=64, label=_("Height", lang)), + gr.Radio(choices=["png", "jpeg"], value="png", label=_("Output Format", lang)), + ], + outputs=[ + gr.Image(label=_("Generated Image", lang)), + gr.Textbox(label=_("Message", lang), type="text"), + ], + title=_("NeuroTrainerWebUI (ALPHA) - StableDiffusion-Generate", lang), + description=_("Generate images using finetuned Stable Diffusion models", lang), + allow_flagging="never", +) + +wiki_interface = gr.Interface( + fn=get_wiki_content, + inputs=[ + gr.Textbox(label=_("Online Wiki", lang), value=( + "https://github.com/Dartvauder/NeuroTrainerWebUI/wiki/EN‐Wiki" if lang == "EN" else + "https://github.com/Dartvauder/NeuroTrainerWebUI/wiki/ZH‐Wiki" if lang == "ZH" else + "https://github.com/Dartvauder/NeuroTrainerWebUI/wiki/RU‐Wiki" + ), interactive=False), + gr.Textbox(label=_("Local Wiki", lang), value=( + "Wikies/WikiEN.md" if lang == "EN" else + "Wikies/WikiZH.md" if lang == "ZH" else + "Wikies/WikiRU.md" + ), interactive=False) + ], + outputs=gr.HTML(label=_("Wiki Content", lang)), + title=_("NeuroTrainerWebUI (ALPHA) - Wiki", lang), + description=_("This interface displays the Wiki content from the specified URL or local file.", lang), + allow_flagging="never", + clear_btn=None, +) + +model_downloader_interface = gr.Interface( + fn=download_model, + inputs=[ + gr.Dropdown(choices=[None, "StarlingLM(Transformers7B)", "OpenChat3.6(Llama8B.Q4)"], label=_("Download LLM model", lang), value=None), + gr.Dropdown(choices=[None, "Dreamshaper8(SD1.5)", "RealisticVisionV4.0(SDXL)"], label=_("Download StableDiffusion model", lang), value=None), + ], + outputs=[ + gr.Textbox(label=_("Message", lang), type="text"), + ], + title=_("NeuroTrainerWebUI (ALPHA) - ModelDownloader", lang), + description=_("This user interface allows you to download LLM and StableDiffusion models", lang), + allow_flagging="never", +) + +settings_interface = gr.Interface( + fn=settings_interface, + inputs=[ + gr.Radio(choices=["EN", "RU", "ZH"], label=_("Language", lang), value=settings['language']), + gr.Radio(choices=["True", "False"], label=_("Share Mode", lang), value="False"), + gr.Radio(choices=["True", "False"], label=_("Debug Mode", lang), value="False"), + gr.Radio(choices=["True", "False"], label=_("Monitoring Mode", lang), value="False"), + gr.Radio(choices=["True", "False"], label=_("Enable AutoLaunch", lang), value="False"), + gr.Radio(choices=["True", "False"], label=_("Show API", lang), value="False"), + gr.Radio(choices=["True", "False"], label=_("Open API", lang), value="False"), + gr.Number(label=_("Queue max size", lang), value=settings['queue_max_size']), + gr.Textbox(label=_("Queue status update rate", lang), value=settings['status_update_rate']), + gr.Textbox(label=_("Gradio Auth", lang), value=settings['auth']), + gr.Textbox(label=_("Server Name", lang), value=settings['server_name']), + gr.Number(label=_("Server Port", lang), value=settings['server_port']), + gr.Textbox(label=_("Hugging Face Token", lang), value=settings['hf_token']) + ], + additional_inputs=[ + gr.Radio(choices=["Base", "Default", "Glass", "Monochrome", "Soft"], label=_("Theme", lang), value=settings['theme']), + gr.Checkbox(label=_("Enable Custom Theme", lang), value=settings['custom_theme']['enabled']), + gr.Textbox(label=_("Primary Hue", lang), value=settings['custom_theme']['primary_hue']), + gr.Textbox(label=_("Secondary Hue", lang), value=settings['custom_theme']['secondary_hue']), + gr.Textbox(label=_("Neutral Hue", lang), value=settings['custom_theme']['neutral_hue']), + gr.Radio(choices=["spacing_sm", "spacing_md", "spacing_lg"], label=_("Spacing Size", lang), value=settings['custom_theme'].get('spacing_size', 'spacing_md')), + gr.Radio(choices=["radius_none", "radius_sm", "radius_md", "radius_lg"], label=_("Radius Size", lang), value=settings['custom_theme'].get('radius_size', 'radius_md')), + gr.Radio(choices=["text_sm", "text_md", "text_lg"], label=_("Text Size", lang), value=settings['custom_theme'].get('text_size', 'text_md')), + gr.Textbox(label=_("Font", lang), value=settings['custom_theme'].get('font', 'Arial')), + gr.Textbox(label=_("Monospaced Font", lang), value=settings['custom_theme'].get('font_mono', 'Courier New')) + ], + additional_inputs_accordion=gr.Accordion(label=_("Theme builder", lang), open=False), + outputs=[ + gr.Textbox(label=_("Message", lang), type="text") + ], + title=_("NeuroTrainerWebUI (ALPHA) - Settings", lang), + description=_("This user interface allows you to change settings of the application", lang), + allow_flagging="never", +) + +system_interface = gr.Interface( + fn=get_system_info, + inputs=[], + outputs=[ + gr.Textbox(label=_("GPU Total Memory", lang)), + gr.Textbox(label=_("GPU Used Memory", lang)), + gr.Textbox(label=_("GPU Free Memory", lang)), + gr.Textbox(label=_("GPU Temperature", lang)), + gr.Textbox(label=_("CPU Temperature", lang)), + gr.Textbox(label=_("RAM Total", lang)), + gr.Textbox(label=_("RAM Used", lang)), + gr.Textbox(label=_("RAM Free", lang)), + gr.Textbox(label=_("Disk Total Space", lang)), + gr.Textbox(label=_("Disk Free Space", lang)), + gr.Textbox(label=_("Application Folder Size", lang)), + ], + title=_("NeuroTrainerWebUI (ALPHA) - System", lang), + description=_("This interface displays system information", lang), + allow_flagging="never", +) + +if settings['custom_theme']['enabled']: + theme = getattr(gr.themes, settings['theme'])( + primary_hue=settings['custom_theme']['primary_hue'], + secondary_hue=settings['custom_theme']['secondary_hue'], + neutral_hue=settings['custom_theme']['neutral_hue'], + spacing_size=getattr(gr.themes.sizes, settings['custom_theme']['spacing_size']), + radius_size=getattr(gr.themes.sizes, settings['custom_theme']['radius_size']), + text_size=getattr(gr.themes.sizes, settings['custom_theme']['text_size']), + font=settings['custom_theme']['font'], + font_mono=settings['custom_theme']['font_mono'] + ) +else: + theme = getattr(gr.themes, settings['theme'])() + +with gr.TabbedInterface([ + gr.TabbedInterface([llm_dataset_interface, llm_finetune_interface, llm_evaluate_interface, llm_quantize_interface, llm_generate_interface], + tab_names=[_("Dataset", lang), _("Finetune", lang), _("Evaluate", lang), _("Quantize", lang), _("Generate", lang)]), + gr.TabbedInterface([sd_dataset_interface, sd_finetune_interface, sd_evaluate_interface, sd_convert_interface, sd_generate_interface], + tab_names=[_("Dataset", lang), _("Finetune", lang), _("Evaluate", lang), _("Conversion", lang), _("Generate", lang)]), + gr.TabbedInterface([wiki_interface, model_downloader_interface, settings_interface, system_interface], + tab_names=[_("Wiki", lang), _("ModelDownloader", lang), _("Settings", lang), _("System", lang)]) +], + tab_names=[_("LLM", lang), _("StableDiffusion", lang), _("Interface", lang)], theme=theme) as app: + reload_button = gr.Button(_("Reload interface", lang)) + + close_button = gr.Button(_("Close terminal", lang)) + close_button.click(close_terminal, [], [], queue=False) + + folder_button = gr.Button(_("Finetuned-models", lang)) + folder_button.click(open_finetuned_folder, [], [], queue=False) + + folder_button = gr.Button(_("Datasets", lang)) + folder_button.click(open_datasets_folder, [], [], queue=False) + + folder_button = gr.Button(_("Outputs", lang)) + folder_button.click(open_outputs_folder, [], [], queue=False) + + dropdowns_to_update = [ + llm_dataset_interface.input_components[0], + llm_finetune_interface.input_components[0], + llm_finetune_interface.input_components[1], + llm_evaluate_interface.input_components[0], + llm_evaluate_interface.input_components[1], + llm_evaluate_interface.input_components[2], + llm_quantize_interface.input_components[0], + llm_generate_interface.input_components[0], + llm_generate_interface.input_components[1], + sd_dataset_interface.input_components[1], + sd_finetune_interface.input_components[0], + sd_finetune_interface.input_components[1], + sd_evaluate_interface.input_components[0], + sd_evaluate_interface.input_components[1], + sd_evaluate_interface.input_components[2], + sd_convert_interface.input_components[0], + sd_generate_interface.input_components[0], + sd_generate_interface.input_components[1], + ] + + reload_button.click(reload_interface, outputs=dropdowns_to_update[:8]) + + github_link = gr.HTML( + '' + ) + + app.queue(api_open=settings['api_open'], max_size=settings['queue_max_size'], + status_update_rate=settings['status_update_rate']) + app.launch( + share=settings['share_mode'], + debug=settings['debug_mode'], + enable_monitoring=settings['monitoring_mode'], + inbrowser=settings['auto_launch'], + show_api=settings['show_api'], + auth=authenticate if settings['auth'] else None, + server_name=settings['server_name'], + server_port=settings['server_port'], + favicon_path="project-image.jpg", + auth_message=_("Welcome to NeuroTrainerWebUI! (ALPHA)", lang) + ) diff --git a/README.md b/README.md index 7a04cf2..ab52ed1 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,23 @@ -## [Features](/#Features) | [Dependencies](/#Required-Dependencies) | [SystemRequirements](/#Minimum-System-Requirements) | [Install](/#How-to-install) | [Usage](/#How-to-use) | [Models](/#Where-can-I-get-models) | [Wiki](/#Wiki) | [Acknowledgment](/#Acknowledgment-to-developers) | [Licenses](/#Third-Party-Licenses) +## [Features](/#Features) | [Dependencies](/#Required-Dependencies) | [SystemRequirements](/#Minimum-System-Requirements) | [Install](/#How-to-install) | [Models](/#Where-can-I-get-models) | [Wiki](/#Wiki) | [Acknowledgment](/#Acknowledgment-to-developers) | [Licenses](/#Third-Party-Licenses) + +![project-image](https://github.com/user-attachments/assets/2a47ff0d-9131-4c3b-897b-46f7cb9e4ae2) # ![1](https://github.com/Dartvauder/NeuroTrainerWebUI/assets/140557322/05329b36-ab08-4317-8d2e-43b326daa034) * Work in progress! (ALPHA) -* English | [Русский](/README_RU.md) +* English | [Русский](/Readmes/README_RU.md) | [漢語](/Readmes/README_ZH.md) + ## Description: -A simple and convenient interface for using of various neural network models. You can create datasets, finetune, evaluate and generate with LLM and StableDiffusion, using various hyperparameters. You can also view files from the outputs directory in gallery, download the LLM and StableDiffusion models, change the application settings inside the interface and check system sensors +A simple and convenient interface for using of various neural network models. You can create datasets, finetune, evaluate and generate with LLM and StableDiffusion, using various hyperparameters. You can also check the wiki, download the LLM and StableDiffusion models, change the application settings inside the interface and check system sensors The goal of the project - to create the easiest possible application to finetune, evaluate and generate of neural network models -### LLM: ![1](https://github.com/Dartvauder/NeuroTrainerWebUI/assets/140557322/a1de823d-1818-4212-a821-e9b92367ffeb) - -### StableDiffusion: ![2](https://github.com/Dartvauder/NeuroTrainerWebUI/assets/140557322/ed61b74c-4a2e-4f0c-ba0b-a41d600ca737) +### LLM: 1 -### Gallery: ![3](https://github.com/Dartvauder/NeuroTrainerWebUI/assets/140557322/2bf3c8ec-ed37-4053-9cbe-4fef98a91a34) +### StableDiffusion: 2 -### ModelDownloader: ![4](https://github.com/Dartvauder/NeuroTrainerWebUI/assets/140557322/ae2f94e0-eeb4-45b5-9450-376434a52513) - -### Settings: ![5](https://github.com/Dartvauder/NeuroTrainerWebUI/assets/140557322/4c453be7-9839-41a6-9154-10447036c435) - -### System: ![6](https://github.com/Dartvauder/NeuroTrainerWebUI/assets/140557322/55e01cba-dab6-4654-8d3f-2cccef4dd040) +### Interface: 3 ## Features: @@ -31,20 +28,19 @@ The goal of the project - to create the easiest possible application to finetune * Support for Diffusers and Safetensors: finetune, evaluate, conversion and generate (StableDiffusion) * Full and LORA types of finetune, evaluate and generate (For LLM and StableDiffusion) * Ability to create a dataset (For LLM and StableDiffusion) -* Gallery +* Wiki * ModelDownloader (For LLM and StableDiffusion) * Application settings * Ability to see system sensors ## Required Dependencies: -* [Python](https://www.python.org/downloads/) (3.10+) +* [Python](https://www.python.org/downloads/) (3.10.11) * [Git](https://git-scm.com/downloads) -* [CUDA](https://developer.nvidia.com/cuda-downloads) (12.X) and [cuDNN](https://developer.nvidia.com/cudnn-downloads) (9.X) -* [Cmake](https://cmake.org/download/) +* [CUDA](https://developer.nvidia.com/cuda-downloads) (12.4) and [cuDNN](https://developer.nvidia.com/cudnn-downloads) (9.1) - C+ compiler - - Windows: [VisualStudio](https://visualstudio.microsoft.com/ru/) - - Linux: [GCC](https://gcc.gnu.org/) + - Windows: [VisualStudio](https://visualstudio.microsoft.com/ru/), [VisualStudioCode](https://code.visualstudio.com) and [Cmake](https://cmake.org) + - Linux: [GCC](https://gcc.gnu.org/), [VisualStudioCode](https://code.visualstudio.com) and [Cmake](https://cmake.org) ## Minimum System Requirements: @@ -58,141 +54,28 @@ The goal of the project - to create the easiest possible application to finetune ### Windows -1) `git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` to any location -2) Run the `Install.bat` and wait for installation -3) After installation, run `Start.bat` -4) Select the file version and wait for the application to launch -5) Now you can start experiment with your models! +1) First install all [RequiredDependencies](/#Required-Dependencies) +2) `Git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` to any location +3) Run the `Install.bat` and wait for installation +4) After installation, run `Start.bat` +5) Wait for the application to launch +6) Now you can start generating! To get update, run `Update.bat` To work with the virtual environment through the terminal, run `Venv.bat` ### Linux -1) `git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` to any location -2) In the terminal, run the `./Install.sh` and wait for installation of all dependencies -3) After installation, run `./Start.sh` -4) Wait for the application to launch -5) Now you can start experiment with your models! +1) First install all [RequiredDependencies](/#Required-Dependencies) +2) `Git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` to any location +3) In the terminal, run the `./Install.sh` and wait for installation of all dependencies +4) After installation, run `./Start.sh` +5) Wait for the application to launch +6) Now you can start generating! To get update, run `./Update.sh` To work with the virtual environment through the terminal, run `./Venv.sh` -## How to use: - -#### Interface has six tabs: LLM, StableDiffusion, Gallery, ModelDownloader, Settings and System. Select the one you need and follow the instructions below - -### LLM - has five sub-tabs: - -#### Dataset: - -* Here you can create a new or expand an existing dataset -* Datasets are saved in a folder *datasets/llm* - -#### Finetune: - -1) First upload your models to the folder: *models/llm* -2) Upload your dataset to the folder: *datasets/llm* -3) Select your model and dataset from the drop-down lists -4) Select a finetune method -5) Write a name for the model -6) Set up the model hyper-parameters for finetuning -7) Click the `Submit` button to receive the finetuned model - -#### Evaluate: - -1) First upload your models to the folder: *finetuned-models/llm* -2) Upload your dataset to the folder: *datasets/llm* -3) Select your models and dataset from the drop-down lists -4) Set up the models parameters for evaluate -5) Click the `Submit` button to receive the evaluate of model - -#### Quantize: - -1) First upload your models to the folder: *finetuned-models/llm* -2) Select a Model and Quantization Type -3) Click the `Submit` button to receive the conversion of model - -#### Generate: - -1) Select your models from the drop-down list -2) Set up the models according to the parameters you need -3) Set up the models parameters to generate -4) Click the `Submit` button to receive the generated text - -### StableDiffusion - has five sub-tabs: - -#### Dataset: - -* Here you can create a new or expand an existing dataset -* Datasets are saved in a folder *datasets/sd* - -#### Finetune: - -1) First upload your models to the folder: *models/sd* -2) Upload your dataset to the folder: *datasets/sd* -3) Select your model and dataset from the drop-down lists -4) Select a model type and finetune method -5) Write a name for the model -6) Set up the model hyper-parameters for finetuning -7) Click the `Submit` button to receive the finetuned model - -#### Evaluate: - -1) First upload your models to the folder: *finetuned-models/sd* -2) Upload your dataset to the folder: *datasets/sd* -3) Select your models and dataset from the drop-down lists -4) Select a model method and model type -5) Enter your prompt -6) Set up the models parameters for evaluate -7) Click the `Submit` button to receive the evaluate of model - -#### Conversion: - -1) First upload your models to the folder: *finetuned-models/sd* -2) Select a model type -3) Set up the models parameters for convert -4) Click the `Submit` button to receive the conversion of model - -#### Generate: - -1) First upload your models to the folder: *finetuned-models/sd* -2) Select your models from the drop-down list -3) Select a model method and model type -5) Enter your prompt -6) Set up the models parameters to generate -7) Click the `Submit` button to receive the generated image - -### Gallery: - -* Here you can view files from the outputs directory - -### ModelDownloader: - -* Here you can download `LLM` and `StableDiffusion` models. Just choose the model from the drop-down list and click the `Submit` button -#### `LLM` models are downloaded here: *models/llm* -#### `StableDiffusion` models are downloaded here: *models/sd* - -### Settings: - -* Here you can change the application settings. For now you can only change `Share` mode to `True` or `False` - -### System: - -* Here you can see the indicators of your computer's sensors by clicking on the `Submit` button - -### Additional Information: - -1) All finetunes are saved in the *finetuned-models* folder -2) You can press the `Clear` button to reset your selection -3) You can turn off the application using the `Close terminal` button -4) You can open the *finetuned-models*, *datasets*, and *outputs* folders by clicking on the folder name button - -## Where can i get models and datasets? - -* LLM and StableDiffusion models can be taken from [HuggingFace](https://huggingface.co/models) or from ModelDownloader inside interface -* LLM and StableDiffusion datasets can be taken from [HuggingFace](https://huggingface.co/datasets) or you can create own datasets inside interface - ## Wiki * https://github.com/Dartvauder/NeuroTrainerWebUI/wiki @@ -216,15 +99,20 @@ First of all, I want to thank the developers of [PyCharm](https://www.jetbrains. * [StableDiffusion1.5](https://huggingface.co/spaces/CompVis/stable-diffusion-license) * [StableDiffusion2](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/LICENSE.md) * [StableDiffusionXL](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/LICENSE.md) -* [TrainerScripts](http://www.apache.org/licenses/LICENSE-2.0) * [CLIP](https://huggingface.co/openai/clip-vit-base-patch16) * [BERT](https://huggingface.co/google-bert/bert-base-uncased) * [LLAMA.CPP](https://github.com/ggerganov/llama.cpp/blob/master/LICENSE) +#### These third-party repository codes are also used in my project: + +* [Diffusers scripts for training SD](https://github.com/huggingface/diffusers/tree/main/examples/text_to_image) + ## Donation ### *If you liked my project and want to donate, here is options to donate. Thank you very much in advance!* -* CryptoWallet(BEP-20) - 0x3d86bdb5f50b92d0d7Eb44F1a833acC5e91aAEcA - * [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/Dartvauder) + +## Star History + +[![Star History Chart](https://api.star-history.com/svg?repos=Dartvauder/NeuroTrainerWebUI&type=Date)](https://star-history.com/#Dartvauder/NeuroTrainerWebUI&Date) diff --git a/README_RU.md b/README_RU.md deleted file mode 100644 index 666dab9..0000000 --- a/README_RU.md +++ /dev/null @@ -1 +0,0 @@ -# NeuroTrainerWebUI diff --git a/Readmes/README_RU.md b/Readmes/README_RU.md new file mode 100644 index 0000000..af9bcbf --- /dev/null +++ b/Readmes/README_RU.md @@ -0,0 +1,118 @@ +# Веб-интерфейс для обучения нейронных сетей + +## [Функции](/#Функции) | [Зависимости](/#Необходимые-зависимости) | [Системные требования](/#Минимальные-системные-требования) | [Установка](/#Как-установить) | [Модели](/#Где-можно-получить-модели) | [Wiki](/#Wiki) | [Благодарность](/#Благодарность-разработчикам) | [Лицензии](/#Сторонние-лицензии) + +![project-image](https://github.com/user-attachments/assets/2a47ff0d-9131-4c3b-897b-46f7cb9e4ae2) + +* В процессе разработки! (АЛЬФА-версия) +* [English](/README.md) | Русский | [漢語](/Readmes/README_ZH.md) + +## Описание: + +Простой и удобный интерфейс для использования различных моделей нейронных сетей. Вы можете создавать датасеты, дообучать, оценивать и генерировать с помощью LLM и StableDiffusion, используя различные гиперпараметры. Вы также можете проверить wiki, загрузить модели LLM и StableDiffusion, изменить настройки приложения внутри интерфейса и проверить системные датчики. + +Цель проекта - создать максимально простое приложение для дообучения, оценки и генерации моделей нейронных сетей. + +### LLM: 1ru + +### StableDiffusion: 2ru + +### Интерфейс: 3ru + +## Функции: + +* Простая установка через install.bat (Windows) или install.sh (Linux) +* Гибкий и оптимизированный интерфейс (на основе Gradio) +* Аутентификация через admin:admin (Вы можете ввести свои данные для входа в файл GradioAuth.txt) +* Поддержка Transformers: дообучение, оценка, квантизация и генерация (LLM) +* Поддержка Diffusers и Safetensors: дообучение, оценка, конвертация и генерация (StableDiffusion) +* Полный и LORA типы дообучения, оценки и генерации (для LLM и StableDiffusion) +* Возможность создания датасета (для LLM и StableDiffusion) +* Wiki +* ModelDownloader (для LLM и StableDiffusion) +* Настройки приложения +* Возможность просмотра системных датчиков + +## Необходимые зависимости: + +* [Python](https://www.python.org/downloads/) (3.10.11) +* [Git](https://git-scm.com/downloads) +* [CUDA](https://developer.nvidia.com/cuda-downloads) (12.4) и [cuDNN](https://developer.nvidia.com/cudnn-downloads) (9.1) +- C++ компилятор + - Windows: [VisualStudio](https://visualstudio.microsoft.com/ru/), [VisualStudioCode](https://code.visualstudio.com) и [Cmake](https://cmake.org) + - Linux: [GCC](https://gcc.gnu.org/), [VisualStudioCode](https://code.visualstudio.com) и [Cmake](https://cmake.org) + +## Минимальные системные требования: + +* Система: Windows или Linux +* GPU: 8GB+ или CPU: 16 ядер 3.6Ghz +* RAM: 24GB+ +* Дисковое пространство: 10GB+ +* Интернет для установки + +## Как установить: + +### Windows + +1) Сначала установите все [Необходимые зависимости](/#Необходимые-зависимости) +2) Выполните `Git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` в любое место +3) Запустите `Install.bat` и дождитесь завершения установки +4) После установки запустите `Start.bat` +5) Дождитесь запуска приложения +6) Теперь вы можете начать генерацию! + +Для получения обновлений запустите `Update.bat` +Для работы с виртуальным окружением через терминал запустите `Venv.bat` + +### Linux + +1) Сначала установите все [Необходимые зависимости](/#Необходимые-зависимости) +2) Выполните `Git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` в любое место +3) В терминале запустите `./Install.sh` и дождитесь установки всех зависимостей +4) После установки запустите `./Start.sh` +5) Дождитесь запуска приложения +6) Теперь вы можете начать генерацию! + +Для получения обновлений запустите `./Update.sh` +Для работы с виртуальным окружением через терминал запустите `./Venv.sh` + +## Wiki + +* https://github.com/Dartvauder/NeuroTrainerWebUI/wiki + +## Благодарность разработчикам + +#### Большое спасибо этим проектам, потому что благодаря их приложениям/библиотекам я смог создать свое приложение: + +Прежде всего, я хочу поблагодарить разработчиков [PyCharm](https://www.jetbrains.com/pycharm/) и [GitHub](https://desktop.github.com). С помощью их приложений я смог создать и поделиться своим кодом. + +* `gradio` - https://github.com/gradio-app/gradio +* `transformers` - https://github.com/huggingface/transformers +* `diffusers` - https://github.com/huggingface/diffusers + +## Сторонние лицензии: + +#### Многие модели имеют свои собственные лицензии на использование. Перед использованием я советую вам ознакомиться с ними: + +* [Transformers](https://github.com/huggingface/transformers/blob/main/LICENSE) +* [Diffusers](https://github.com/huggingface/diffusers/blob/main/LICENSE) +* [StableDiffusion1.5](https://huggingface.co/spaces/CompVis/stable-diffusion-license) +* [StableDiffusion2](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/LICENSE.md) +* [StableDiffusionXL](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/LICENSE.md) +* [CLIP](https://huggingface.co/openai/clip-vit-base-patch16) +* [BERT](https://huggingface.co/google-bert/bert-base-uncased) +* [LLAMA.CPP](https://github.com/ggerganov/llama.cpp/blob/master/LICENSE) + +#### Эти коды сторонних репозиториев также используются в моем проекте: + +* [Скрипты Diffusers для обучения SD](https://github.com/huggingface/diffusers/tree/main/examples/text_to_image) + +## Пожертвование + +### *Если вам понравился мой проект и вы хотите сделать пожертвование, вот варианты для этого. Заранее большое спасибо!* + +* [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/Dartvauder) + +## История звезд + +[![Star History Chart](https://api.star-history.com/svg?repos=Dartvauder/NeuroTrainerWebUI&type=Date)](https://star-history.com/#Dartvauder/NeuroTrainerWebUI&Date) diff --git a/Readmes/README_ZH.md b/Readmes/README_ZH.md new file mode 100644 index 0000000..c2d770b --- /dev/null +++ b/Readmes/README_ZH.md @@ -0,0 +1,118 @@ +# 神经网络训练Web界面 + +## [功能](/#功能) | [依赖](/#必需的依赖项) | [系统要求](/#最低系统要求) | [安装](/#如何安装) | [模型](/#我在哪里可以获得模型) | [Wiki](/#Wiki) | [致谢](/#对开发者的致谢) | [许可证](/#第三方许可证) + +![project-image](https://github.com/user-attachments/assets/2a47ff0d-9131-4c3b-897b-46f7cb9e4ae2) + +* 正在进行中!(Alpha版本) +* [English](/README.md) | [Русский](/Readmes/README_RU.md) | 漢語 + +## 描述: + +一个简单且方便的界面,用于使用各种神经网络模型。您可以创建数据集,对LLM和StableDiffusion进行微调、评估和生成,使用各种超参数。您还可以查看wiki,下载LLM和StableDiffusion模型,在界面内更改应用程序设置并检查系统传感器。 + +项目目标 - 创建一个尽可能简单的应用程序来微调、评估和生成神经网络模型。 + +### LLM:1zh + +### StableDiffusion:2zh + +### 界面:3zh + +## 功能: + +* 通过install.bat(Windows)或install.sh(Linux)轻松安装 +* 灵活且优化的界面(由Gradio提供) +* 通过admin:admin进行身份验证(您可以在GradioAuth.txt文件中输入您的登录详细信息) +* 支持Transformers:微调、评估、量化和生成(LLM) +* 支持Diffusers和Safetensors:微调、评估、转换和生成(StableDiffusion) +* 完整和LORA类型的微调、评估和生成(适用于LLM和StableDiffusion) +* 能够创建数据集(适用于LLM和StableDiffusion) +* Wiki +* 模型下载器(适用于LLM和StableDiffusion) +* 应用程序设置 +* 能够查看系统传感器 + +## 必需的依赖项: + +* [Python](https://www.python.org/downloads/)(3.10.11) +* [Git](https://git-scm.com/downloads) +* [CUDA](https://developer.nvidia.com/cuda-downloads)(12.4)和[cuDNN](https://developer.nvidia.com/cudnn-downloads)(9.1) +- C++编译器 + - Windows:[VisualStudio](https://visualstudio.microsoft.com/ru/)、[VisualStudioCode](https://code.visualstudio.com)和[Cmake](https://cmake.org) + - Linux:[GCC](https://gcc.gnu.org/)、[VisualStudioCode](https://code.visualstudio.com)和[Cmake](https://cmake.org) + +## 最低系统要求: + +* 系统:Windows或Linux +* GPU:8GB+或CPU:16核3.6Ghz +* RAM:24GB+ +* 磁盘空间:10GB+ +* 安装需要互联网连接 + +## 如何安装: + +### Windows + +1) 首先安装所有[必需的依赖项](/#必需的依赖项) +2) 在任意位置执行`Git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` +3) 运行`Install.bat`并等待安装完成 +4) 安装完成后,运行`Start.bat` +5) 等待应用程序启动 +6) 现在您可以开始生成了! + +要获取更新,请运行`Update.bat` +要通过终端使用虚拟环境,请运行`Venv.bat` + +### Linux + +1) 首先安装所有[必需的依赖项](/#必需的依赖项) +2) 在任意位置执行`Git clone https://github.com/Dartvauder/NeuroTrainerWebUI.git` +3) 在终端中运行`./Install.sh`并等待所有依赖项安装完成 +4) 安装完成后,运行`./Start.sh` +5) 等待应用程序启动 +6) 现在您可以开始生成了! + +要获取更新,请运行`./Update.sh` +要通过终端使用虚拟环境,请运行`./Venv.sh` + +## Wiki + +* https://github.com/Dartvauder/NeuroTrainerWebUI/wiki + +## 对开发者的致谢 + +#### 非常感谢这些项目,因为正是由于他们的应用程序/库,我才能够创建我的应用程序: + +首先,我要感谢[PyCharm](https://www.jetbrains.com/pycharm/)和[GitHub](https://desktop.github.com)的开发者。在他们的应用程序的帮助下,我能够创建并分享我的代码。 + +* `gradio` - https://github.com/gradio-app/gradio +* `transformers` - https://github.com/huggingface/transformers +* `diffusers` - https://github.com/huggingface/diffusers + +## 第三方许可证: + +#### 许多模型都有自己的使用许可证。在使用之前,我建议您熟悉它们: + +* [Transformers](https://github.com/huggingface/transformers/blob/main/LICENSE) +* [Diffusers](https://github.com/huggingface/diffusers/blob/main/LICENSE) +* [StableDiffusion1.5](https://huggingface.co/spaces/CompVis/stable-diffusion-license) +* [StableDiffusion2](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/LICENSE.md) +* [StableDiffusionXL](https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/blob/main/LICENSE.md) +* [CLIP](https://huggingface.co/openai/clip-vit-base-patch16) +* [BERT](https://huggingface.co/google-bert/bert-base-uncased) +* [LLAMA.CPP](https://github.com/ggerganov/llama.cpp/blob/master/LICENSE) + +#### 这些第三方仓库的代码也在我的项目中使用: + +* [用于训练SD的Diffusers脚本](https://github.com/huggingface/diffusers/tree/main/examples/text_to_image) + +## 捐赠 + +### *如果您喜欢我的项目并想要捐赠,这里有捐赠的选项。非常感谢您的支持!* + +* [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/Dartvauder) + +## 星星的历史 + +[![Star History Chart](https://api.star-history.com/svg?repos=Dartvauder/NeuroTrainerWebUI&type=Date)](https://star-history.com/#Dartvauder/NeuroTrainerWebUI&Date) diff --git a/RequirementsFiles/requirements-cuda.txt b/RequirementsFiles/requirements-cuda.txt new file mode 100644 index 0000000..1b2ae13 --- /dev/null +++ b/RequirementsFiles/requirements-cuda.txt @@ -0,0 +1,6 @@ +--extra-index-url https://download.pytorch.org/whl/cu124 +torch==2.4.1+cu124 +torchtext==0.18.0 +torchaudio==2.4.1+cu124 +torchvision==0.19.1+cu124 +xformers==0.0.28.post1 diff --git a/requirements-llama-cpp.txt b/RequirementsFiles/requirements-llama-cpp.txt similarity index 65% rename from requirements-llama-cpp.txt rename to RequirementsFiles/requirements-llama-cpp.txt index fe9caa5..a1ab600 100644 --- a/requirements-llama-cpp.txt +++ b/RequirementsFiles/requirements-llama-cpp.txt @@ -1,2 +1,2 @@ ---extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu121 -llama-cpp-python==0.2.78 +--extra-index-url https://abetlen.github.io/llama-cpp-python/whl/cu124 +llama-cpp-python==0.2.90 diff --git a/RequirementsFiles/requirements-stable-diffusion-cpp.txt b/RequirementsFiles/requirements-stable-diffusion-cpp.txt new file mode 100644 index 0000000..f799bc1 --- /dev/null +++ b/RequirementsFiles/requirements-stable-diffusion-cpp.txt @@ -0,0 +1 @@ +stable-diffusion-cpp-python==0.1.8 -C cmake.args="-DSD_CUBLAS=on" \ No newline at end of file diff --git a/RequirementsFiles/requirements.txt b/RequirementsFiles/requirements.txt new file mode 100644 index 0000000..1ce1c48 Binary files /dev/null and b/RequirementsFiles/requirements.txt differ diff --git a/Settings.json b/Settings.json new file mode 100644 index 0000000..86c61ab --- /dev/null +++ b/Settings.json @@ -0,0 +1,30 @@ +{ + "language": "EN", + "share_mode": false, + "debug_mode": false, + "monitoring_mode": false, + "auto_launch": false, + "show_api": false, + "api_open": false, + "queue_max_size": 10, + "status_update_rate": "auto", + "auth": { + "username": "admin", + "password": "admin" + }, + "server_name": "localhost", + "server_port": 7860, + "hf_token": "hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + "theme": "Default", + "custom_theme": { + "enabled": false, + "primary_hue": "red", + "secondary_hue": "pink", + "neutral_hue": "stone", + "spacing_size": "spacing_md", + "radius_size": "radius_md", + "text_size": "text_md", + "font": "Arial", + "font_mono": "Courier New" + } +} \ No newline at end of file diff --git a/Start.bat b/Start.bat index d02cb20..46c726b 100644 --- a/Start.bat +++ b/Start.bat @@ -5,32 +5,27 @@ set CURRENT_DIR=%~dp0 call "%CURRENT_DIR%venv\Scripts\activate.bat" -:menu -echo Select a file for launch/Выберите файл для запуска: -echo [English version: 1] appEN.py -echo [Русская версия: 2] appRU.py -echo. - -:input -set /p choice=Enter number/Введите число: -if "%choice%"=="1" ( - cls - start /b py "%CURRENT_DIR%appEN.py" - timeout /t 30 > NUL - start http://localhost:7860 - goto end +echo Attempting to read Settings.json... +if not exist Settings.json ( + echo Settings.json file not found! + pause + exit /b ) -if "%choice%"=="2" ( - cls - start /b py "%CURRENT_DIR%appRU.py" - timeout /t 30 > NUL - start http://localhost:7860 - goto end +for /f "tokens=2 delims=:, " %%a in ('type Settings.json ^| findstr "hf_token"') do set HF_TOKEN=%%~a +echo HF_TOKEN value: "%HF_TOKEN%" +if "%HF_TOKEN%"=="" ( + echo HF token is empty or not found in Settings.json. Please add your Hugging Face token to this file. + type Settings.json + pause + exit /b ) -echo Invalid choice, please try again/Неверный выбор, попробуйте еще раз -goto input +echo Logging in to Hugging Face... +huggingface-cli login --token %HF_TOKEN% --add-to-git-credential + +cls +echo Launching NeuroTrainerWebUI... +start /b py -c "import os, sys; sys.path.insert(0, os.path.join(os.path.dirname(__name__), 'LaunchFile')); import app" -:end -call "%CURRENT_DIR%venv\Scripts\deactivate.bat" +call "%CURRENT_DIR%venv\Scripts\deactivate.bat" \ No newline at end of file diff --git a/Start.sh b/Start.sh index f57f495..40e69de 100644 --- a/Start.sh +++ b/Start.sh @@ -4,34 +4,29 @@ CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" source "$CURRENT_DIR/venv/bin/activate" -while true; do - clear - echo "Select a file for launch/Выберите файл для запуска:" - echo "[English version: 1] appEN.py" - echo "[Русская версия: 2] appRU.py" - echo - - read -p "Enter number/Введите число: " choice - - case $choice in - 1) - clear - python "$CURRENT_DIR/appEN.py" & - sleep 30 - xdg-open "http://localhost:7860" - break - ;; - 2) - clear - python "$CURRENT_DIR/appRU.py" & - sleep 30 - xdg-open "http://localhost:7860" - break - ;; - *) - echo "Invalid choice, please try again/Неверный выбор, попробуйте еще раз" - ;; - esac -done +echo "Attempting to read Settings.json..." +if [ ! -f Settings.json ]; then + echo "Settings.json file not found!" + exit 1 +fi + +echo "Contents of Settings.json:" +cat Settings.json + +HF_TOKEN=$(grep -oP '"hf_token"\s*:\s*"\K[^"]+' Settings.json) + +echo "HF_TOKEN value: '$HF_TOKEN'" + +if [ -z "$HF_TOKEN" ]; then + echo "HF token is empty or not found in Settings.json. Please add your Hugging Face token to this file." + exit 1 +fi + +echo "Logging in to Hugging Face..." +huggingface-cli login --token "$HF_TOKEN" --add-to-git-credential + +clear +echo "Launching NeuroTrainerWebUI..." +python -c "import os, sys; sys.path.insert(0, os.path.join('$(dirname "${BASH_SOURCE[0]}")', 'LaunchFile')); import app" & deactivate diff --git a/Update.bat b/Update.bat index deecfe8..bd60387 100644 --- a/Update.bat +++ b/Update.bat @@ -1,20 +1,45 @@ -@chcp 65001 > NUL +@@chcp 65001 > NUL @echo off git pull +timeout /t 3 /nobreak >nul +cls set CURRENT_DIR=%~dp0 call "%CURRENT_DIR%venv\Scripts\activate.bat" -echo Updating dependencies.../Обновление зависимостей... -pip install --no-deps -r "%CURRENT_DIR%requirements.txt" -pip install --no-deps -r "%CURRENT_DIR%requirements-cuda.txt" -pip install --no-deps -r "%CURRENT_DIR%requirements-llama-cpp.txt" +echo Updating dependencies... +if not exist "%CURRENT_DIR%logs" mkdir "%CURRENT_DIR%logs" +set ERROR_LOG="%CURRENT_DIR%logs\update_errors.log" +type nul > %ERROR_LOG% + +python -m pip install --upgrade pip +pip install wheel setuptools +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements.txt" 2>> %ERROR_LOG% +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements-cuda.txt" 2>> %ERROR_LOG% +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements-llama-cpp.txt" 2>> %ERROR_LOG% +pip install --no-deps -r "%CURRENT_DIR%RequirementsFiles\requirements-stable-diffusion-cpp.txt" 2>> %ERROR_LOG% +timeout /t 3 /nobreak >nul +cls + +echo Post-installing patches... +python "%CURRENT_DIR%RequirementsFiles\post_install.py" +timeout /t 3 /nobreak >nul +cls + +echo Checking for update errors... +findstr /C:"error" %ERROR_LOG% >nul +if %ERRORLEVEL% equ 0 ( + echo Some packages failed to install. Please check %ERROR_LOG% for details. +) else ( + echo Installation completed successfully. +) +timeout /t 5 /nobreak >nul cls -echo Application has been updated successfully. Run start.bat/Приложение успешно обновлено. Запустите start.bat +echo Application update process completed. Run start.bat to launch the application. call "%CURRENT_DIR%venv\Scripts\deactivate.bat" -pause +pause \ No newline at end of file diff --git a/Update.sh b/Update.sh index a253194..f339edf 100644 --- a/Update.sh +++ b/Update.sh @@ -1,19 +1,43 @@ #!/bin/bash git pull +sleep 3 +clear CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" source "$CURRENT_DIR/venv/bin/activate" -echo "Updating dependencies.../Обновление зависимостей..." -pip install --no-deps -r "$CURRENT_DIR/requirements.txt" -pip install --no-deps -r "$CURRENT_DIR/requirements-cuda.txt" -pip install --no-deps -r "$CURRENT_DIR/requirements-llama-cpp.txt" +echo "Updating dependencies..." +mkdir -p "$CURRENT_DIR/logs" +ERROR_LOG="$CURRENT_DIR/logs/update_errors.log" +touch "$ERROR_LOG" + +python3 -m pip install --upgrade pip +pip install wheel setuptools +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements.txt" 2>> "$ERROR_LOG" +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements-cuda.txt" 2>> "$ERROR_LOG" +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements-llama-cpp.txt" 2>> "$ERROR_LOG" +pip install --no-deps -r "$CURRENT_DIR/RequirementsFiles/requirements-stable-diffusion-cpp.txt" 2>> "$ERROR_LOG" +sleep 3 +clear + +echo "Post-installing patches..." +python3 "$CURRENT_DIR/RequirementsFiles/post_install.py" +sleep 3 +clear + +echo "Checking for update errors..." +if grep -iq "error" "$ERROR_LOG"; then + echo "Some packages failed to install. Please check $ERROR_LOG for details." +else + echo "All packages installed successfully." +fi +sleep 5 clear -echo "Application has been updated successfully. Run start.sh/Приложение успешно обновлено. Запустите start.sh" +echo "Application update process completed. Run start.sh to launch the application." deactivate -read -p "Press enter to continue/Нажмите enter для продолжения" +read -p "Press enter to continue" \ No newline at end of file diff --git a/Venv.bat b/Venv.bat index 7345906..671c5df 100644 --- a/Venv.bat +++ b/Venv.bat @@ -5,7 +5,7 @@ set CURRENT_DIR=%~dp0 call "%CURRENT_DIR%venv\Scripts\activate.bat" -echo Virtual environment activated/Виртуальное окружение активировано -echo To deactivate the virtual environment, type 'deactivate'/Чтобы деактивировать виртуальное окружение, наберите 'deactivate' +echo Virtual environment activated +echo To deactivate the virtual environment, type 'deactivate' -cmd /k \ No newline at end of file +cmd /k diff --git a/Venv.sh b/Venv.sh index 27e8c4d..b9d8e92 100644 --- a/Venv.sh +++ b/Venv.sh @@ -4,7 +4,7 @@ CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${CURRENT_DIR}/venv/bin/activate" -echo "Virtual environment activated/Виртуальное окружение активировано" -echo "To deactivate the virtual environment, type 'deactivate'/Чтобы деактивировать виртуальное окружение, наберите 'deactivate'." +echo "Virtual environment activated" +echo "To deactivate the virtual environment, type 'deactivate'" bash \ No newline at end of file diff --git a/Wikies/WikiEN.md b/Wikies/WikiEN.md new file mode 100644 index 0000000..78a566a --- /dev/null +++ b/Wikies/WikiEN.md @@ -0,0 +1,115 @@ +## How to use: + +#### Interface has six tabs: LLM, StableDiffusion, Wiki, ModelDownloader, Settings and System. Select the one you need and follow the instructions below + +### LLM - has five sub-tabs: + +#### Dataset: + +* Here you can create a new or expand an existing dataset +* Datasets are saved in a folder *datasets/llm* + +#### Finetune: + +1) First upload your models to the folder: *models/llm* +2) Upload your dataset to the folder: *datasets/llm* +3) Select your model and dataset from the drop-down lists +4) Select a finetune method +5) Write a name for the model +6) Set up the model hyper-parameters for finetuning +7) Click the `Submit` button to receive the finetuned model + +#### Evaluate: + +1) First upload your models to the folder: *finetuned-models/llm* +2) Upload your dataset to the folder: *datasets/llm* +3) Select your models and dataset from the drop-down lists +4) Set up the models parameters for evaluate +5) Click the `Submit` button to receive the evaluate of model + +#### Quantize: + +1) First upload your models to the folder: *finetuned-models/llm* +2) Select a Model and Quantization Type +3) Click the `Submit` button to receive the conversion of model + +#### Generate: + +1) Select your models from the drop-down list +2) Set up the models according to the parameters you need +3) Set up the models parameters to generate +4) Click the `Submit` button to receive the generated text + +### StableDiffusion - has five sub-tabs: + +#### Dataset: + +* Here you can create a new or expand an existing dataset +* Datasets are saved in a folder *datasets/sd* + +#### Finetune: + +1) First upload your models to the folder: *models/sd* +2) Upload your dataset to the folder: *datasets/sd* +3) Select your model and dataset from the drop-down lists +4) Select a model type and finetune method +5) Write a name for the model +6) Set up the model hyper-parameters for finetuning +7) Click the `Submit` button to receive the finetuned model + +#### Evaluate: + +1) First upload your models to the folder: *finetuned-models/sd* +2) Upload your dataset to the folder: *datasets/sd* +3) Select your models and dataset from the drop-down lists +4) Select a model method and model type +5) Enter your prompt +6) Set up the models parameters for evaluate +7) Click the `Submit` button to receive the evaluate of model + +#### Conversion: + +1) First upload your models to the folder: *finetuned-models/sd* +2) Select a model type +3) Set up the models parameters for convert +4) Click the `Submit` button to receive the conversion of model + +#### Generate: + +1) First upload your models to the folder: *finetuned-models/sd* +2) Select your models from the drop-down list +3) Select a model method and model type +5) Enter your prompt +6) Set up the models parameters to generate +7) Click the `Submit` button to receive the generated image + +### Wiki: + +* Here you can view online or offline wiki of project + +### ModelDownloader: + +* Here you can download `LLM` and `StableDiffusion` models. Just choose the model from the drop-down list and click the `Submit` button +#### `LLM` models are downloaded here: *models/llm* +#### `StableDiffusion` models are downloaded here: *models/sd* + +### Settings: + +* Here you can change the application settings + +### System: + +* Here you can see the indicators of your computer's sensors by clicking on the `Submit` button + +### Additional Information: + +1) All finetunes are saved in the *finetuned-models* folder +2) You can press the `Clear` button to reset your selection +3) You can turn off the application using the `Close terminal` button +4) You can open the *finetuned-models*, *datasets*, and *outputs* folders by clicking on the folder name button +5) You can reload interface dropdown lists by clicking on the `Reload interface` + +## Where can i get models and datasets? + +* LLM and StableDiffusion models can be taken from [HuggingFace](https://huggingface.co/models) or from ModelDownloader inside interface +* LLM and StableDiffusion datasets can be taken from [HuggingFace](https://huggingface.co/datasets) or you can create own datasets inside interface diff --git a/Wikies/WikiRU.md b/Wikies/WikiRU.md new file mode 100644 index 0000000..f803ffe --- /dev/null +++ b/Wikies/WikiRU.md @@ -0,0 +1,117 @@ +# Инструкция по использованию + +## Как использовать: + +#### Интерфейс имеет шесть вкладок: LLM, StableDiffusion, Wiki, ModelDownloader, Settings и System. Выберите нужную и следуйте инструкциям ниже + +### LLM - имеет пять подвкладок: + +#### Датасет: + +* Здесь вы можете создать новый или расширить существующий датасет +* Датасеты сохраняются в папке *datasets/llm* + +#### Дообучение: + +1) Сначала загрузите ваши модели в папку: *models/llm* +2) Загрузите ваш датасет в папку: *datasets/llm* +3) Выберите вашу модель и датасет из выпадающих списков +4) Выберите метод дообучения +5) Напишите название для модели +6) Настройте гиперпараметры модели для дообучения +7) Нажмите кнопку `Submit`, чтобы получить дообученную модель + +#### Оценка: + +1) Сначала загрузите ваши модели в папку: *finetuned-models/llm* +2) Загрузите ваш датасет в папку: *datasets/llm* +3) Выберите ваши модели и датасет из выпадающих списков +4) Настройте параметры моделей для оценки +5) Нажмите кнопку `Submit`, чтобы получить оценку модели + +#### Квантизация: + +1) Сначала загрузите ваши модели в папку: *finetuned-models/llm* +2) Выберите модель и тип квантизации +3) Нажмите кнопку `Submit`, чтобы получить преобразованную модель + +#### Генерация: + +1) Выберите ваши модели из выпадающего списка +2) Настройте модели в соответствии с нужными параметрами +3) Настройте параметры моделей для генерации +4) Нажмите кнопку `Submit`, чтобы получить сгенерированный текст + +### StableDiffusion - имеет пять подвкладок: + +#### Датасет: + +* Здесь вы можете создать новый или расширить существующий датасет +* Датасеты сохраняются в папке *datasets/sd* + +#### Дообучение: + +1) Сначала загрузите ваши модели в папку: *models/sd* +2) Загрузите ваш датасет в папку: *datasets/sd* +3) Выберите вашу модель и датасет из выпадающих списков +4) Выберите тип модели и метод дообучения +5) Напишите название для модели +6) Настройте гиперпараметры модели для дообучения +7) Нажмите кнопку `Submit`, чтобы получить дообученную модель + +#### Оценка: + +1) Сначала загрузите ваши модели в папку: *finetuned-models/sd* +2) Загрузите ваш датасет в папку: *datasets/sd* +3) Выберите ваши модели и датасет из выпадающих списков +4) Выберите метод модели и тип модели +5) Введите ваш запрос +6) Настройте параметры моделей для оценки +7) Нажмите кнопку `Submit`, чтобы получить оценку модели + +#### Конвертация: + +1) Сначала загрузите ваши модели в папку: *finetuned-models/sd* +2) Выберите тип модели +3) Настройте параметры моделей для конвертации +4) Нажмите кнопку `Submit`, чтобы получить преобразованную модель + +#### Генерация: + +1) Сначала загрузите ваши модели в папку: *finetuned-models/sd* +2) Выберите ваши модели из выпадающего списка +3) Выберите метод модели и тип модели +4) Введите ваш запрос +5) Настройте параметры моделей для генерации +6) Нажмите кнопку `Submit`, чтобы получить сгенерированное изображение + +### Wiki: + +* Здесь вы можете просмотреть онлайн или оффлайн вики проекта + +### ModelDownloader: + +* Здесь вы можете скачать модели `LLM` и `StableDiffusion`. Просто выберите модель из выпадающего списка и нажмите кнопку `Submit` +#### Модели `LLM` скачиваются сюда: *models/llm* +#### Модели `StableDiffusion` скачиваются сюда: *models/sd* + +### Settings: + +* Здесь вы можете изменить настройки приложения + +### System: + +* Здесь вы можете увидеть показатели датчиков вашего компьютера, нажав кнопку `Submit` + +### Дополнительная информация: + +1) Все дообученные модели сохраняются в папке *finetuned-models* +2) Вы можете нажать кнопку `Clear`, чтобы сбросить ваш выбор +3) Вы можете выключить приложение, используя кнопку `Close terminal` +4) Вы можете открыть папки *finetuned-models*, *datasets* и *outputs*, нажав на кнопку с названием папки +5) Вы можете перезагрузить выпадающие списки интерфейса, нажав на `Reload interface` + +## Где я могу получить модели и датасеты? + +* Модели LLM и StableDiffusion можно взять с [HuggingFace](https://huggingface.co/models) или из ModelDownloader внутри интерфейса +* Датасеты LLM и StableDiffusion можно взять с [HuggingFace](https://huggingface.co/datasets) или вы можете создать собственные датасеты внутри интерфейса diff --git a/Wikies/WikiZH.md b/Wikies/WikiZH.md new file mode 100644 index 0000000..838a834 --- /dev/null +++ b/Wikies/WikiZH.md @@ -0,0 +1,117 @@ +# 使用说明 + +## 如何使用: + +#### 界面有六个标签:LLM、StableDiffusion、Wiki、ModelDownloader、Settings和System。选择您需要的标签并按照以下说明操作 + +### LLM - 有五个子标签: + +#### 数据集: + +* 在这里,您可以创建新的或扩展现有的数据集 +* 数据集保存在 *datasets/llm* 文件夹中 + +#### 微调: + +1) 首先将您的模型上传到文件夹:*models/llm* +2) 将您的数据集上传到文件夹:*datasets/llm* +3) 从下拉列表中选择您的模型和数据集 +4) 选择微调方法 +5) 为模型写一个名称 +6) 设置模型微调的超参数 +7) 点击`Submit`按钮以获取微调后的模型 + +#### 评估: + +1) 首先将您的模型上传到文件夹:*finetuned-models/llm* +2) 将您的数据集上传到文件夹:*datasets/llm* +3) 从下拉列表中选择您的模型和数据集 +4) 设置模型评估参数 +5) 点击`Submit`按钮以获取模型评估结果 + +#### 量化: + +1) 首先将您的模型上传到文件夹:*finetuned-models/llm* +2) 选择模型和量化类型 +3) 点击`Submit`按钮以获取模型转换结果 + +#### 生成: + +1) 从下拉列表中选择您的模型 +2) 根据您需要的参数设置模型 +3) 设置生成的模型参数 +4) 点击`Submit`按钮以获取生成的文本 + +### StableDiffusion - 有五个子标签: + +#### 数据集: + +* 在这里,您可以创建新的或扩展现有的数据集 +* 数据集保存在 *datasets/sd* 文件夹中 + +#### 微调: + +1) 首先将您的模型上传到文件夹:*models/sd* +2) 将您的数据集上传到文件夹:*datasets/sd* +3) 从下拉列表中选择您的模型和数据集 +4) 选择模型类型和微调方法 +5) 为模型写一个名称 +6) 设置模型微调的超参数 +7) 点击`Submit`按钮以获取微调后的模型 + +#### 评估: + +1) 首先将您的模型上传到文件夹:*finetuned-models/sd* +2) 将您的数据集上传到文件夹:*datasets/sd* +3) 从下拉列表中选择您的模型和数据集 +4) 选择模型方法和模型类型 +5) 输入您的提示 +6) 设置模型评估参数 +7) 点击`Submit`按钮以获取模型评估结果 + +#### 转换: + +1) 首先将您的模型上传到文件夹:*finetuned-models/sd* +2) 选择模型类型 +3) 设置模型转换参数 +4) 点击`Submit`按钮以获取模型转换结果 + +#### 生成: + +1) 首先将您的模型上传到文件夹:*finetuned-models/sd* +2) 从下拉列表中选择您的模型 +3) 选择模型方法和模型类型 +4) 输入您的提示 +5) 设置生成的模型参数 +6) 点击`Submit`按钮以获取生成的图像 + +### Wiki: + +* 在这里,您可以查看项目的在线或离线维基 + +### ModelDownloader: + +* 在这里,您可以下载`LLM`和`StableDiffusion`模型。只需从下拉列表中选择模型并点击`Submit`按钮 +#### `LLM`模型下载到这里:*models/llm* +#### `StableDiffusion`模型下载到这里:*models/sd* + +### Settings: + +* 在这里,您可以更改应用程序设置 + +### System: + +* 在这里,您可以通过点击`Submit`按钮查看计算机传感器的指标 + +### 附加信息: + +1) 所有微调都保存在 *finetuned-models* 文件夹中 +2) 您可以按`Clear`按钮重置您的选择 +3) 您可以使用`Close terminal`按钮关闭应用程序 +4) 您可以通过点击文件夹名称按钮打开 *finetuned-models*、*datasets* 和 *outputs* 文件夹 +5) 您可以通过点击`Reload interface`重新加载界面下拉列表 + +## 我在哪里可以获得模型和数据集? + +* LLM和StableDiffusion模型可以从[HuggingFace](https://huggingface.co/models)获取,或者从界面内的ModelDownloader获取 +* LLM和StableDiffusion数据集可以从[HuggingFace](https://huggingface.co/datasets)获取,或者您可以在界面内创建自己的数据集 diff --git a/project-image.jpg b/project-image.jpg new file mode 100644 index 0000000..06a670b Binary files /dev/null and b/project-image.jpg differ diff --git a/requirements-cuda.txt b/requirements-cuda.txt deleted file mode 100644 index ee78e65..0000000 --- a/requirements-cuda.txt +++ /dev/null @@ -1,6 +0,0 @@ ---extra-index-url https://download.pytorch.org/whl/cu121 -torch==2.3.0+cu121 -torchtext==0.18.0 -torchaudio==2.3.0+cu121 -torchvision==0.18.0+cu121 -xformers==0.0.26.post1 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index b82687c..0000000 --- a/requirements.txt +++ /dev/null @@ -1,135 +0,0 @@ -absl-py==2.1.0 -accelerate==0.31.0 -aiofiles==23.2.1 -aiohttp==3.9.5 -aiosignal==1.3.1 -altair==5.3.0 -annotated-types==0.6.0 -anyio==4.3.0 -attrs==23.2.0 -bert-score==0.3.13 -certifi==2024.2.2 -charset-normalizer==3.3.2 -click==8.1.7 -cmake==3.29.5.1 -colorama==0.4.6 -contourpy==1.2.1 -cycler==0.12.1 -datasets==2.20.0 -diffusers==0.29.0 -dill==0.3.8 -dnspython==2.6.1 -email_validator==2.1.1 -evaluate==0.4.2 -faiss-cpu==1.8.0 -fastapi==0.111.0 -fastapi-cli==0.0.3 -ffmpy==0.3.2 -filelock==3.14.0 -fonttools==4.51.0 -frozenlist==1.4.1 -fsspec==2024.3.1 -ftfy==6.2.0 -gguf==0.6.0 -git-python==1.0.3 -gitdb==4.0.11 -GitPython==3.1.43 -GPUtil==1.4.0 -gradio==4.36.1 -gradio_client==1.0.1 -grpcio==1.63.0 -h11==0.14.0 -httpcore==1.0.5 -httptools==0.6.1 -httpx==0.27.0 -huggingface-hub==0.23.4 -idna==3.7 -importlib_metadata==7.1.0 -importlib_resources==6.4.0 -intel-openmp==2021.4.0 -Jinja2==3.1.4 -joblib==1.4.2 -jsonschema==4.22.0 -jsonschema-specifications==2023.12.1 -kiwisolver==1.4.5 -lightning-utilities==0.11.2 -lxml==5.2.2 -Markdown==3.6 -markdown-it-py==3.0.0 -MarkupSafe==2.1.5 -matplotlib==3.9.0 -mauve-text==0.3.0 -mdurl==0.1.2 -mkl==2021.4.0 -mpmath==1.3.0 -multidict==6.0.5 -multiprocess==0.70.16 -networkx==3.2.1 -numpy==1.26.4 -orjson==3.10.3 -packaging==24.1 -pandas==2.2.2 -peft==0.11.1 -pillow==10.3.0 -portalocker==2.8.2 -protobuf==5.26.1 -psutil==5.9.8 -py-cpuinfo==9.0.0 -pyarrow==16.1.0 -pyarrow-hotfix==0.6 -pydantic==2.7.1 -pydantic_core==2.18.2 -pydub==0.25.1 -Pygments==2.18.0 -pynvml==11.5.0 -pyparsing==3.1.2 -python-dateutil==2.9.0.post0 -python-dotenv==1.0.1 -python-multipart==0.0.9 -pytz==2024.1 -pywin32==306 -PyYAML==6.0.1 -referencing==0.35.1 -regex==2024.5.15 -requests==2.32.3 -rich==13.7.1 -rouge==1.0.1 -rpds-py==0.18.1 -ruff==0.4.4 -sacrebleu==2.4.2 -safetensors==0.4.3 -scikit-learn==1.4.2 -scipy==1.13.0 -semantic-version==2.10.0 -sentencepiece==0.2.0 -shellingham==1.5.4 -six==1.16.0 -smmap==5.0.1 -sniffio==1.3.1 -starlette==0.37.2 -sympy==1.12 -tabulate==0.9.0 -tbb==2021.11.0 -tensorboard==2.16.2 -tensorboard-data-server==0.7.2 -threadpoolctl==3.5.0 -tokenizers==0.19.1 -tomlkit==0.12.0 -toolz==0.12.1 -torch-fidelity==0.3.0 -torchmetrics==1.4.0.post0 -tqdm==4.66.4 -transformers==4.41.2 -typer==0.12.3 -typing_extensions==4.11.0 -tzdata==2024.1 -ujson==5.10.0 -urllib3==2.2.1 -uvicorn==0.29.0 -watchfiles==0.21.0 -wcwidth==0.2.13 -websockets==11.0.3 -Werkzeug==3.0.3 -xxhash==3.4.1 -yarl==1.9.4 -zipp==3.18.2 diff --git a/trainer-scripts/sd/train_text_to_image.py b/trainer-scripts/sd/train_text_to_image.py index ccbf94c..051d887 100644 --- a/trainer-scripts/sd/train_text_to_image.py +++ b/trainer-scripts/sd/train_text_to_image.py @@ -55,6 +55,10 @@ if is_wandb_available(): import wandb + +# Will error if the minimal version of diffusers is not installed. Remove at your own risks. +check_min_version("0.30.0") + logger = get_logger(__name__, log_level="INFO") DATASET_NAME_MAPPING = { @@ -383,6 +387,8 @@ def parse_args(): ), ) parser.add_argument("--use_ema", action="store_true", help="Whether to use EMA model.") + parser.add_argument("--offload_ema", action="store_true", help="Offload EMA model to CPU during training step.") + parser.add_argument("--foreach_ema", action="store_true", help="Use faster foreach implementation of EMAModel.") parser.add_argument( "--non_ema_revision", type=str, @@ -620,7 +626,12 @@ def deepspeed_zero_init_disabled_context_manager(): ema_unet = UNet2DConditionModel.from_pretrained( args.pretrained_model_name_or_path, subfolder="unet", revision=args.revision, variant=args.variant ) - ema_unet = EMAModel(ema_unet.parameters(), model_cls=UNet2DConditionModel, model_config=ema_unet.config) + ema_unet = EMAModel( + ema_unet.parameters(), + model_cls=UNet2DConditionModel, + model_config=ema_unet.config, + foreach=args.foreach_ema, + ) if args.enable_xformers_memory_efficient_attention: if is_xformers_available(): @@ -651,9 +662,14 @@ def save_model_hook(models, weights, output_dir): def load_model_hook(models, input_dir): if args.use_ema: - load_model = EMAModel.from_pretrained(os.path.join(input_dir, "unet_ema"), UNet2DConditionModel) + load_model = EMAModel.from_pretrained( + os.path.join(input_dir, "unet_ema"), UNet2DConditionModel, foreach=args.foreach_ema + ) ema_unet.load_state_dict(load_model.state_dict()) - ema_unet.to(accelerator.device) + if args.offload_ema: + ema_unet.pin_memory() + else: + ema_unet.to(accelerator.device) del load_model for _ in range(len(models)): @@ -829,7 +845,10 @@ def collate_fn(examples): ) if args.use_ema: - ema_unet.to(accelerator.device) + if args.offload_ema: + ema_unet.pin_memory() + else: + ema_unet.to(accelerator.device) # For mixed precision training we cast all non-trainable weights (vae, non-lora text_encoder and non-lora unet) to half-precision # as these weights are only used for inference, keeping weights in full precision is not required. @@ -1007,7 +1026,11 @@ def unwrap_model(model): # Checks if the accelerator has performed an optimization step behind the scenes if accelerator.sync_gradients: if args.use_ema: + if args.offload_ema: + ema_unet.to(device="cuda", non_blocking=True) ema_unet.step(unet.parameters()) + if args.offload_ema: + ema_unet.to(device="cpu", non_blocking=True) progress_bar.update(1) global_step += 1 accelerator.log({"train_loss": train_loss}, step=global_step) diff --git a/trainer-scripts/sd/train_text_to_image_lora.py b/trainer-scripts/sd/train_text_to_image_lora.py index 534e7a1..1c77792 100644 --- a/trainer-scripts/sd/train_text_to_image_lora.py +++ b/trainer-scripts/sd/train_text_to_image_lora.py @@ -55,6 +55,9 @@ if is_wandb_available(): import wandb +# Will error if the minimal version of diffusers is not installed. Remove at your own risks. +check_min_version("0.30.0") + logger = get_logger(__name__, log_level="INFO") diff --git a/trainer-scripts/sd/train_text_to_image_lora_sdxl.py b/trainer-scripts/sd/train_text_to_image_lora_sdxl.py index ce1e0e7..82125f7 100644 --- a/trainer-scripts/sd/train_text_to_image_lora_sdxl.py +++ b/trainer-scripts/sd/train_text_to_image_lora_sdxl.py @@ -50,7 +50,7 @@ StableDiffusionXLPipeline, UNet2DConditionModel, ) -from diffusers.loaders import LoraLoaderMixin +from diffusers.loaders import StableDiffusionLoraLoaderMixin from diffusers.optimization import get_scheduler from diffusers.training_utils import _set_state_dict_into_text_encoder, cast_training_params, compute_snr from diffusers.utils import ( @@ -67,6 +67,9 @@ if is_wandb_available(): import wandb +# Will error if the minimal version of diffusers is not installed. Remove at your own risks. +check_min_version("0.30.0") + logger = get_logger(__name__) if is_torch_npu_available(): torch.npu.config.allow_internal_format = False @@ -763,7 +766,7 @@ def load_model_hook(models, input_dir): else: raise ValueError(f"unexpected save model: {model.__class__}") - lora_state_dict, _ = LoraLoaderMixin.lora_state_dict(input_dir) + lora_state_dict, _ = StableDiffusionLoraLoaderMixin.lora_state_dict(input_dir) unet_state_dict = {f'{k.replace("unet.", "")}': v for k, v in lora_state_dict.items() if k.startswith("unet.")} unet_state_dict = convert_unet_state_dict_to_peft(unet_state_dict) incompatible_keys = set_peft_model_state_dict(unet_, unet_state_dict, adapter_name="default") diff --git a/trainer-scripts/sd/train_text_to_image_sdxl.py b/trainer-scripts/sd/train_text_to_image_sdxl.py index b7b9726..30ed49f 100644 --- a/trainer-scripts/sd/train_text_to_image_sdxl.py +++ b/trainer-scripts/sd/train_text_to_image_sdxl.py @@ -53,6 +53,10 @@ from diffusers.utils.import_utils import is_torch_npu_available, is_xformers_available from diffusers.utils.torch_utils import is_compiled_module + +# Will error if the minimal version of diffusers is not installed. Remove at your own risks. +check_min_version("0.30.0") + logger = get_logger(__name__) if is_torch_npu_available(): torch.npu.config.allow_internal_format = False diff --git a/translations/ru.json b/translations/ru.json new file mode 100644 index 0000000..9e4bc00 --- /dev/null +++ b/translations/ru.json @@ -0,0 +1,152 @@ +{ + "Existing Dataset (optional)": "Существующий набор данных (необязательно)", + "Dataset Name": "Название набора данных", + "Instruction": "Инструкция", + "Input": "Ввод", + "Output": "Вывод", + "Status": "Статус", + "NeuroTrainerWebUI (ALPHA) - LLM-Dataset": "NeuroTrainerWebUI (АЛЬФА) - LLM-Набор данных", + "Create a new dataset or add a new column to an existing dataset for LLM": "Создайте новый набор данных или добавьте новый столбец в существующий набор данных для LLM", + "Model": "Модель", + "Dataset": "Набор данных", + "Finetune Method": "Метод тонкой настройки", + "Output Model Name": "Название выходной модели", + "Epochs": "Эпохи", + "Batch size": "Размер пакета", + "Learning rate": "Скорость обучения", + "Weight decay": "Затухание весов", + "Warmup steps": "Шаги разогрева", + "Block size": "Размер блока", + "Gradient accumulation steps": "Шаги накопления градиента", + "Adam beta 1": "Адам бета 1", + "Adam beta 2": "Адам бета 2", + "Adam epsilon": "Адам эпсилон", + "LR Scheduler": "Планировщик LR", + "Freeze layers": "Замороженные слои", + "LORA r": "LORA r", + "LORA alpha": "LORA альфа", + "LORA dropout": "LORA отсев", + "Use xformers": "Использовать xformers", + "Finetuning Status": "Статус тонкой настройки", + "Finetuning Loss": "Потери при тонкой настройке", + "NeuroTrainerWebUI (ALPHA) - LLM-Finetune": "NeuroTrainerWebUI (АЛЬФА) - LLM-Тонкая настройка", + "Finetune LLM models on a custom dataset": "Тонкая настройка моделей LLM на пользовательском наборе данных", + "LORA Model (optional)": "Модель LORA (необязательно)", + "Request": "Запрос", + "Max Length": "Максимальная длина", + "Temperature": "Температура", + "Top P": "Верхнее P", + "Top K": "Верхнее K", + "Evaluation Status": "Статус оценки", + "Evaluation Metrics": "Метрики оценки", + "NeuroTrainerWebUI (ALPHA) - LLM-Evaluate": "NeuroTrainerWebUI (АЛЬФА) - LLM-Оценка", + "Evaluate finetuned LLM models on a custom dataset": "Оценка тонко настроенных моделей LLM на пользовательском наборе данных", + "Quantization Type": "Тип квантования", + "Quantization Status": "Статус квантования", + "NeuroTrainerWebUI (ALPHA) - LLM-Quantize": "NeuroTrainerWebUI (АЛЬФА) - LLM-Квантование", + "Quantize finetuned LLM models to .gguf format using llama.cpp": "Квантование тонко настроенных моделей LLM в формат .gguf с использованием llama.cpp", + "Model Type": "Тип модели", + "Max length": "Максимальная длина", + "Output Format": "Формат вывода", + "Generated text": "Сгенерированный текст", + "Message": "Сообщение", + "NeuroTrainerWebUI (ALPHA) - LLM-Generate": "NeuroTrainerWebUI (АЛЬФА) - LLM-Генерация", + "Generate text using finetuned LLM models": "Генерация текста с использованием тонко настроенных моделей LLM", + "Image Files": "Файлы изображений", + "Files Name": "Имена файлов", + "Prompt Text": "Текст подсказки", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Dataset": "NeuroTrainerWebUI (АЛЬФА) - StableDiffusion-Набор данных", + "Create a new dataset or add a new column to an existing dataset for Stable Diffusion": "Создайте новый набор данных или добавьте новый столбец в существующий набор данных для Stable Diffusion", + "Resolution": "Разрешение", + "Train Batch Size": "Размер обучающего пакета", + "LR Warmup Steps": "Шаги разогрева LR", + "Max Train Steps": "Максимальное количество шагов обучения", + "Max grad norm": "Максимальная норма градиента", + "Noise offset": "Смещение шума", + "LORA Rank": "Ранг LORA", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Finetune": "NeuroTrainerWebUI (АЛЬФА) - StableDiffusion-Тонкая настройка", + "Finetune Stable Diffusion models on a custom dataset": "Тонкая настройка моделей Stable Diffusion на пользовательском наборе данных", + "Model Method": "Метод модели", + "Prompt": "Подсказка", + "Negative Prompt": "Отрицательная подсказка", + "Steps": "Шаги", + "CFG": "CFG", + "NeuroTrainerWebUI (ALPHA) - StabledDiffusion-Evaluate": "NeuroTrainerWebUI (АЛЬФА) - StableDiffusion-Оценка", + "Evaluate finetuned Stable Diffusion models on a custom dataset": "Оценка тонко настроенных моделей Stable Diffusion на пользовательском наборе данных", + "Use Half Precision": "Использовать половинную точность", + "Use Safetensors": "Использовать Safetensors", + "Conversion Status": "Статус конвертации", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Conversion": "NeuroTrainerWebUI (АЛЬФА) - StableDiffusion-Конвертация", + "Convert finetuned Stable Diffusion models to single file (.ckpt or .safetensors)": "Конвертация тонко настроенных моделей Stable Diffusion в единый файл (.ckpt или .safetensors)", + "Width": "Ширина", + "Height": "Высота", + "Generated Image": "Сгенерированное изображение", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Generate": "NeuroTrainerWebUI (АЛЬФА) - StableDiffusion-Генерация", + "Generate images using finetuned Stable Diffusion models": "Генерация изображений с использованием тонко настроенных моделей Stable Diffusion", + "Download LLM model": "Скачать модель LLM", + "Download StableDiffusion model": "Скачать модель StableDiffusion", + "NeuroTrainerWebUI (ALPHA) - ModelDownloader": "NeuroTrainerWebUI (АЛЬФА) - Загрузчик моделей", + "This user interface allows you to download LLM and StableDiffusion models": "Этот пользовательский интерфейс позволяет вам скачивать модели LLM и StableDiffusion", + "Language": "Язык", + "Share Mode": "Режим общего доступа", + "Debug Mode": "Режим отладки", + "Monitoring Mode": "Режим мониторинга", + "Enable AutoLaunch": "Включить автозапуск", + "Show API": "Показать API", + "Open API": "Открыть API", + "Queue max size": "Максимальный размер очереди", + "Queue status update rate": "Частота обновления статуса очереди", + "Gradio Auth": "Аутентификация Gradio", + "Server Name": "Имя сервера", + "Server Port": "Порт сервера", + "Hugging Face Token": "Токен Hugging Face", + "Theme": "Тема", + "Enable Custom Theme": "Включить пользовательскую тему", + "Primary Hue": "Основной оттенок", + "Secondary Hue": "Вторичный оттенок", + "Neutral Hue": "Нейтральный оттенок", + "Spacing Size": "Размер отступов", + "Radius Size": "Размер радиуса", + "Text Size": "Размер текста", + "Font": "Шрифт", + "Monospaced Font": "Моноширинный шрифт", + "Theme builder": "Конструктор темы", + "NeuroTrainerWebUI (ALPHA) - Settings": "NeuroTrainerWebUI (АЛЬФА) - Настройки", + "This user interface allows you to change settings of the application": "Этот пользовательский интерфейс позволяет вам изменять настройки приложения", + "GPU Total Memory": "Общая память GPU", + "GPU Used Memory": "Использованная память GPU", + "GPU Free Memory": "Свободная память GPU", + "GPU Temperature": "Температура GPU", + "CPU Temperature": "Температура CPU", + "RAM Total": "Общая RAM", + "RAM Used": "Использованная RAM", + "RAM Free": "Свободная RAM", + "Disk Total Space": "Общее пространство диска", + "Disk Free Space": "Свободное пространство диска", + "Application Folder Size": "Размер папки приложения", + "NeuroTrainerWebUI (ALPHA) - System": "NeuroTrainerWebUI (АЛЬФА) - Система", + "This interface displays system information": "Этот интерфейс отображает системную информацию", + "Finetune": "Тонкая настройка", + "Evaluate": "Оценка", + "Quantize": "Квантование", + "Generate": "Генерация", + "Conversion": "Конвертация", + "Wiki": "Вики", + "ModelDownloader": "Загрузчик моделей", + "Settings": "Настройки", + "System": "Система", + "LLM": "LLM", + "StableDiffusion": "StableDiffusion", + "Interface": "Интерфейс", + "Close terminal": "Закрыть терминал", + "Reload interface": "Перезагрузить интерфейс", + "Finetuned-models": "Тонко настроенные модели", + "Datasets": "Наборы данных", + "Outputs": "Выходные данные", + "Welcome to NeuroTrainerWebUI! (ALPHA)": "Добро пожаловать в NeuroTrainerWebUI! (АЛЬФА)", + "Online Wiki": "Онлайн вики", + "Local Wiki": "Локальная вики", + "Wiki Content": "Содержание вики", + "NeuroTrainerWebUI (ALPHA) - Wiki": "NeuroTrainerWebUI (АЛЬФА) - Вики", + "This interface displays the Wiki content from the specified URL or local file.": "Этот интерфейс отображает содержание вики из указанного URL или локального файла." +} \ No newline at end of file diff --git a/translations/zh.json b/translations/zh.json new file mode 100644 index 0000000..9c8f6c3 --- /dev/null +++ b/translations/zh.json @@ -0,0 +1,152 @@ +{ + "Existing Dataset (optional)": "现有数据集(可选)", + "Dataset Name": "数据集名称", + "Instruction": "指令", + "Input": "输入", + "Output": "输出", + "Status": "状态", + "NeuroTrainerWebUI (ALPHA) - LLM-Dataset": "NeuroTrainerWebUI(测试版)- LLM-数据集", + "Create a new dataset or add a new column to an existing dataset for LLM": "为LLM创建新数据集或向现有数据集添加新列", + "Model": "模型", + "Dataset": "数据集", + "Finetune Method": "微调方法", + "Output Model Name": "输出模型名称", + "Epochs": "训练轮数", + "Batch size": "批次大小", + "Learning rate": "学习率", + "Weight decay": "权重衰减", + "Warmup steps": "预热步数", + "Block size": "块大小", + "Gradient accumulation steps": "梯度累积步数", + "Adam beta 1": "Adam beta 1", + "Adam beta 2": "Adam beta 2", + "Adam epsilon": "Adam epsilon", + "LR Scheduler": "学习率调度器", + "Freeze layers": "冻结层", + "LORA r": "LORA r", + "LORA alpha": "LORA alpha", + "LORA dropout": "LORA dropout", + "Use xformers": "使用xformers", + "Finetuning Status": "微调状态", + "Finetuning Loss": "微调损失", + "NeuroTrainerWebUI (ALPHA) - LLM-Finetune": "NeuroTrainerWebUI(测试版)- LLM-微调", + "Finetune LLM models on a custom dataset": "在自定义数据集上微调LLM模型", + "LORA Model (optional)": "LORA模型(可选)", + "Request": "请求", + "Max Length": "最大长度", + "Temperature": "温度", + "Top P": "Top P", + "Top K": "Top K", + "Evaluation Status": "评估状态", + "Evaluation Metrics": "评估指标", + "NeuroTrainerWebUI (ALPHA) - LLM-Evaluate": "NeuroTrainerWebUI(测试版)- LLM-评估", + "Evaluate finetuned LLM models on a custom dataset": "在自定义数据集上评估微调后的LLM模型", + "Quantization Type": "量化类型", + "Quantization Status": "量化状态", + "NeuroTrainerWebUI (ALPHA) - LLM-Quantize": "NeuroTrainerWebUI(测试版)- LLM-量化", + "Quantize finetuned LLM models to .gguf format using llama.cpp": "使用llama.cpp将微调后的LLM模型量化为.gguf格式", + "Model Type": "模型类型", + "Max length": "最大长度", + "Output Format": "输出格式", + "Generated text": "生成的文本", + "Message": "消息", + "NeuroTrainerWebUI (ALPHA) - LLM-Generate": "NeuroTrainerWebUI(测试版)- LLM-生成", + "Generate text using finetuned LLM models": "使用微调后的LLM模型生成文本", + "Image Files": "图像文件", + "Files Name": "文件名", + "Prompt Text": "提示文本", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Dataset": "NeuroTrainerWebUI(测试版)- StableDiffusion-数据集", + "Create a new dataset or add a new column to an existing dataset for Stable Diffusion": "为Stable Diffusion创建新数据集或向现有数据集添加新列", + "Resolution": "分辨率", + "Train Batch Size": "训练批次大小", + "LR Warmup Steps": "学习率预热步数", + "Max Train Steps": "最大训练步数", + "Max grad norm": "最大梯度范数", + "Noise offset": "噪声偏移", + "LORA Rank": "LORA秩", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Finetune": "NeuroTrainerWebUI(测试版)- StableDiffusion-微调", + "Finetune Stable Diffusion models on a custom dataset": "在自定义数据集上微调Stable Diffusion模型", + "Model Method": "模型方法", + "Prompt": "提示", + "Negative Prompt": "负面提示", + "Steps": "步数", + "CFG": "CFG", + "NeuroTrainerWebUI (ALPHA) - StabledDiffusion-Evaluate": "NeuroTrainerWebUI(测试版)- StableDiffusion-评估", + "Evaluate finetuned Stable Diffusion models on a custom dataset": "在自定义数据集上评估微调后的Stable Diffusion模型", + "Use Half Precision": "使用半精度", + "Use Safetensors": "使用Safetensors", + "Conversion Status": "转换状态", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Conversion": "NeuroTrainerWebUI(测试版)- StableDiffusion-转换", + "Convert finetuned Stable Diffusion models to single file (.ckpt or .safetensors)": "将微调后的Stable Diffusion模型转换为单个文件(.ckpt或.safetensors)", + "Width": "宽度", + "Height": "高度", + "Generated Image": "生成的图像", + "NeuroTrainerWebUI (ALPHA) - StableDiffusion-Generate": "NeuroTrainerWebUI(测试版)- StableDiffusion-生成", + "Generate images using finetuned Stable Diffusion models": "使用微调后的Stable Diffusion模型生成图像", + "Download LLM model": "下载LLM模型", + "Download StableDiffusion model": "下载StableDiffusion模型", + "NeuroTrainerWebUI (ALPHA) - ModelDownloader": "NeuroTrainerWebUI(测试版)- 模型下载器", + "This user interface allows you to download LLM and StableDiffusion models": "此用户界面允许您下载LLM和StableDiffusion模型", + "Language": "语言", + "Share Mode": "共享模式", + "Debug Mode": "调试模式", + "Monitoring Mode": "监控模式", + "Enable AutoLaunch": "启用自动启动", + "Show API": "显示API", + "Open API": "开放API", + "Queue max size": "队列最大大小", + "Queue status update rate": "队列状态更新频率", + "Gradio Auth": "Gradio认证", + "Server Name": "服务器名称", + "Server Port": "服务器端口", + "Hugging Face Token": "Hugging Face令牌", + "Theme": "主题", + "Enable Custom Theme": "启用自定义主题", + "Primary Hue": "主要色调", + "Secondary Hue": "次要色调", + "Neutral Hue": "中性色调", + "Spacing Size": "间距大小", + "Radius Size": "圆角大小", + "Text Size": "文本大小", + "Font": "字体", + "Monospaced Font": "等宽字体", + "Theme builder": "主题构建器", + "NeuroTrainerWebUI (ALPHA) - Settings": "NeuroTrainerWebUI(测试版)- 设置", + "This user interface allows you to change settings of the application": "此用户界面允许您更改应用程序的设置", + "GPU Total Memory": "GPU总内存", + "GPU Used Memory": "GPU已用内存", + "GPU Free Memory": "GPU可用内存", + "GPU Temperature": "GPU温度", + "CPU Temperature": "CPU温度", + "RAM Total": "总RAM", + "RAM Used": "已用RAM", + "RAM Free": "可用RAM", + "Disk Total Space": "磁盘总空间", + "Disk Free Space": "磁盘可用空间", + "Application Folder Size": "应用程序文件夹大小", + "NeuroTrainerWebUI (ALPHA) - System": "NeuroTrainerWebUI(测试版)- 系统", + "This interface displays system information": "此界面显示系统信息", + "Finetune": "微调", + "Evaluate": "评估", + "Quantize": "量化", + "Generate": "生成", + "Conversion": "转换", + "Wiki": "维基", + "ModelDownloader": "模型下载器", + "Settings": "设置", + "System": "系统", + "LLM": "LLM", + "StableDiffusion": "StableDiffusion", + "Interface": "界面", + "Close terminal": "关闭终端", + "Reload interface": "重新加载界面", + "Finetuned-models": "微调模型", + "Datasets": "数据集", + "Outputs": "输出", + "Welcome to NeuroTrainerWebUI! (ALPHA)": "欢迎使用NeuroTrainerWebUI!(测试版)", + "Online Wiki": "在线维基", + "Local Wiki": "本地维基", + "Wiki Content": "维基内容", + "NeuroTrainerWebUI (ALPHA) - Wiki": "NeuroTrainerWebUI(测试版) - 维基", + "This interface displays the Wiki content from the specified URL or local file.": "此界面显示来自指定URL或本地文件的维基内容。" +} \ No newline at end of file