Download run_lora_mistral.py from 1earner1/llm_for_Code: direct link, hf CLI and curl.
- Browser
- Download file 20.2 kB
-
https://huggingface.co/1earner1/llm_for_Code/resolve/main/run_lora_mistral.py
- Command line
-
hf download hf://1earner1/llm_for_Code/run_lora_mistral.py
-
curl -L -o run_lora_mistral.py https://huggingface.co/1earner1/llm_for_Code/resolve/main/run_lora_mistral.py
20.2 kB
| model_name = "mistralai/Mistral-7B-Instruct-v0.3" | |
| #model_name = "bigcode/starcoder2-7b" | |
| #model_name = "dorkai/codeX-1.0" #"Alibaba-NLP/gte-Qwen1.5-7B-instruct" #"google/flan-t5-small" #"microsoft/Phi-3-medium-128k-instruct" #"google/gemma-2-9b-it" # "meta-llama/CodeLlama-7b-hf" #"deepseek-ai/DeepSeek-Coder-V2-Instruct" #"deepseek-ai/DeepSeek-Coder-V2-Lite-Instruct" | |
| out_name = "HPC_2_mistral_iffp_20k_5_lora" #"meta-llama/Meta-Llama-3-8B" #"tiiuae/falcon-40b" #"Phind/Phind-CodeLlama-34B-v2" # "deepseek-ai/DeepSeek-Coder-V2-Instruct" # | |
| from datasets import load_dataset, Dataset | |
| import pandas as pd | |
| import json | |
| import traceback | |
| import peft | |
| import os | |
| from tqdm import tqdm | |
| import sys | |
| import math | |
| from transformers import AutoModelForCausalLM, AutoTokenizer, BitsAndBytesConfig, AdamW, default_data_collator, get_linear_schedule_with_warmup, get_cosine_schedule_with_warmup,set_seed | |
| from torch.utils.data import DataLoader | |
| import numpy as np | |
| # import json | |
| # filepath = "/kaggle/input/code-sim-try1/mutated_graph_all_lang_eq.json" | |
| # examples = [] | |
| # with open(filepath, 'r') as file: | |
| # for l in file: | |
| # examples.append(json.loads(l)) | |
| # len(examples) | |
| # examples[0] | |
| # instruct_tune_dataset = load_dataset("mosaicml/instruct-v3",cache_dir = "/scratch/scai/mtech/aib222688/HF") | |
| # instruct_tune_dataset = instruct_tune_dataset.filter(lambda x: x["source"] == "dolly_hhrlhf") | |
| traindataset_file = "./dataset_lfs/allpairs_data_large.json" | |
| valdataset_file = "./dataset_lfs/allpairs_data_val.json" | |
| testdataset_file = "./llm_for_code/datasets/codecontests/verified_iffp_1200.json" | |
| traindata = [] | |
| initial_lr = 5e-6 | |
| checkpoint_store_dir_path = "./HPC_2_codellama_iffp_20k_4_lora_1200" | |
| os.makedirs(checkpoint_store_dir_path, exist_ok=True) | |
| num_epochs = 5 | |
| batch_size_train = 1 | |
| max_length = 2000 | |
| ckpnt_NUM = 2000 | |
| #ckpnt_NUM2 = 5000 | |
| SAVEALL = False #True | |
| import os | |
| import torch | |
| from datasets import load_dataset | |
| from transformers import ( | |
| AutoModelForCausalLM, | |
| AutoTokenizer, | |
| BitsAndBytesConfig, | |
| HfArgumentParser, | |
| TrainingArguments, | |
| pipeline, | |
| logging, | |
| ) | |
| from peft import LoraConfig, PeftModel | |
| from trl import SFTTrainer | |
| nf4_config = BitsAndBytesConfig( | |
| load_in_4bit=True, | |
| bnb_4bit_quant_type="nf4", | |
| bnb_4bit_use_double_quant=True, | |
| bnb_4bit_compute_dtype=torch.bfloat16 | |
| ) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| model_name, | |
| #device_map='auto', | |
| #quantization_config=nf4_config, | |
| use_cache=True, | |
| cache_dir = "/scratch/scai/mtech/aib222688/HF", | |
| attn_implementation="flash_attention_2", | |
| torch_dtype=torch.float16, | |
| trust_remote_code=True, | |
| ) | |
| print(model) | |
| # model = AutoModelForCausalLM.from_pretrained( | |
| # "./HPC_2_codellama_iffp_20k_3_lora_900/checkpoint_0_99/", | |
| # use_cache=True, | |
| # cache_dir = "/scratch/scai/mtech/aib222688/HF", | |
| # ) | |
| tokenizer = AutoTokenizer.from_pretrained(model_name) | |
| tokenizer.pad_token = tokenizer.eos_token | |
| tokenizer.padding_side = "right" | |
| with open(traindataset_file, 'r') as file: | |
| for l in file: | |
| traindata.append(json.loads(l)) | |
| valdata = [] | |
| with open(valdataset_file, 'r') as file: | |
| for l in file: | |
| valdata.append(json.loads(l)) | |
| testdata = [] | |
| with open(testdataset_file, 'r') as file: | |
| for l in file: | |
| testdata.append(json.loads(l)) | |
| print(len(traindata), len(valdata), len(testdata)) | |
| file_path = './prompt_file.txt' | |
| file_content = "" | |
| with open(file_path, 'r') as file: | |
| file_content = file.read() | |
| def create_prompt(pair): | |
| bos_token = "<s>" | |
| eos_token = "</s>" | |
| if pair['prog1']['probid'] == pair['prog2']['probid']: | |
| response = "Yes" | |
| else: | |
| response = "No" | |
| full_prompt = "" | |
| full_prompt += bos_token | |
| full_prompt += file_content + pair['prog1']['scode'] + "\nProgram 2:" | |
| full_prompt += pair['prog2']['scode']+ "\n### Response:" | |
| full_prompt += "\n" #+ response | |
| full_prompt += eos_token | |
| return full_prompt, response | |
| #print(create_prompt(instruct_tune_dataset["train"][1])) | |
| traindata1 = list(traindata) #[0:] | |
| valdata1 = list( valdata) | |
| testdata1 = list(testdata) #[0:] | |
| traindata = [] | |
| for tdata in traindata1: | |
| inp, trg = create_prompt(tdata) | |
| traindata.append({ | |
| 'inputs' : inp, | |
| 'targets' : trg | |
| }) | |
| valdata = [] | |
| for tdata in valdata1: | |
| inp, trg = create_prompt(tdata) | |
| valdata.append({ | |
| 'inputs' : inp, | |
| 'targets' : trg | |
| }) | |
| testdata = [] | |
| for tdata in testdata1: | |
| inp, trg = create_prompt(tdata) | |
| testdata.append({ | |
| 'inputs' : inp, | |
| 'targets' : trg | |
| }) | |
| traindataset = Dataset.from_pandas(pd.DataFrame(traindata)) | |
| valdataset = Dataset.from_pandas(pd.DataFrame(valdata)) | |
| testdataset = Dataset.from_pandas(pd.DataFrame(testdata)) | |
| instruct_tune_dataset = {"train": traindataset, | |
| "val" : valdataset, | |
| "test" : testdataset} | |
| def preprocess_function(examples): | |
| batch_size = len(examples['inputs']) | |
| #inputs = [f"<s>[INST] Question : {x} [/INST] \\n Answer : " for x in examples[past_context_code]] | |
| #inputs = [f"\n<|user|>\n You are given a set of APIs and previously generated Code as context. The task is given a new requirement from Bob modify or expand the given code using the provided APIs.\n\nAPIs:\n{apis}\n\nContext:\n{past_context}\n\nInput:\n{new_input} \n<|assistant|>\n " for apis, past_context, new_input in zip(examples['apis'], examples['past_context_code'], examples['new_input'])] | |
| #targets = [str(x) for x in examples[label_column]] | |
| #inputs, targets = get_examples_all_context(examples) | |
| #inputs, targets = get_examples_all_context(examples) | |
| #inputs, targets = get_examples_all_context_granite(examples, only_code=False) | |
| inputs = [] | |
| targets = [] | |
| # for eg in examples: | |
| # print(eg) | |
| # #inp, trg = create_prompt(eg) | |
| # #inputs.append(inp) | |
| # #targets.append(trg) | |
| inputs = examples['inputs'] | |
| targets = examples['targets'] | |
| model_inputs = tokenizer(inputs) | |
| #print("Input example:\n{}".format(inputs[0])) | |
| #print("Output example:\n{}".format(targets[0])) | |
| input_sizes = [len(tokens) for tokens in model_inputs['input_ids']] | |
| #print("Input sizes {}".format(input_sizes)) | |
| labels = tokenizer(targets, add_special_tokens=False) # don't add bos token because we concatenate with inputs | |
| label_sizes = [len(tokens) for tokens in labels['input_ids']] | |
| #print("Label sizes {}".format(label_sizes)) | |
| for i in range(batch_size): | |
| sample_input_ids = model_inputs["input_ids"][i] | |
| label_input_ids = labels["input_ids"][i] + [tokenizer.eos_token_id] | |
| # print(i, sample_input_ids, label_input_ids) | |
| model_inputs["input_ids"][i] = sample_input_ids + label_input_ids | |
| labels["input_ids"][i] = [-100] * len(sample_input_ids) + label_input_ids | |
| model_inputs["attention_mask"][i] = [1] * len(model_inputs["input_ids"][i]) | |
| # print(model_inputs) | |
| for i in range(batch_size): | |
| sample_input_ids = model_inputs["input_ids"][i] | |
| label_input_ids = labels["input_ids"][i] | |
| model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * ( | |
| max_length - len(sample_input_ids) | |
| ) + sample_input_ids | |
| model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs["attention_mask"][i] | |
| labels["input_ids"][i] = [-100] * (max_length - len(sample_input_ids)) + label_input_ids | |
| model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) | |
| model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) | |
| labels["input_ids"][i] = torch.tensor(labels["input_ids"][i][:max_length]) | |
| model_inputs["labels"] = labels["input_ids"] | |
| input_sizes = [len(tokens) for tokens in model_inputs['input_ids']] | |
| #print("Input sizes {}".format(input_sizes)) | |
| return model_inputs | |
| processed_datasets = traindataset.map( | |
| preprocess_function, | |
| batched=True, | |
| num_proc=1, | |
| remove_columns=traindataset.column_names, | |
| load_from_cache_file=False, | |
| desc="Running tokenizer on dataset", | |
| ) | |
| train_dataset = processed_datasets | |
| train_dataloader = DataLoader( | |
| train_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size_train, pin_memory=True | |
| ) | |
| processed_datasets = valdataset.map( | |
| preprocess_function, | |
| batched=True, | |
| num_proc=1, | |
| remove_columns=valdataset.column_names, | |
| load_from_cache_file=False, | |
| desc="Running tokenizer on dataset", | |
| ) | |
| val_dataset = processed_datasets | |
| val_dataloader = DataLoader( | |
| val_dataset, shuffle=True, collate_fn=default_data_collator, batch_size=batch_size_train, pin_memory=True | |
| ) | |
| def test_preprocess_function(examples): | |
| batch_size = len(examples['inputs']) | |
| #inputs, targets = get_examples_all_context(examples) | |
| #inputs, targets = get_examples_all_context_granite(examples) | |
| #inputs = [f"\n<|user|>\n You are given a set of APIs and previously generated Code as context. The task is given a new requirement from Bob modify or expand the given code using the provided APIs.\n\nAPIs:\n{apis}\n\nContext:\n{past_context}\n\nInput:\n{new_input} \n<|assistant|>\n " for apis, past_context, new_input in zip(examples['apis'], examples['past_context_code'], examples['new_input'])] | |
| model_inputs = tokenizer(examples['inputs']) | |
| # print(model_inputs) | |
| for i in range(batch_size): | |
| sample_input_ids = model_inputs["input_ids"][i] | |
| model_inputs["input_ids"][i] = [tokenizer.pad_token_id] * ( | |
| max_length - len(sample_input_ids) | |
| ) + sample_input_ids | |
| model_inputs["attention_mask"][i] = [0] * (max_length - len(sample_input_ids)) + model_inputs["attention_mask"][i] | |
| model_inputs["input_ids"][i] = torch.tensor(model_inputs["input_ids"][i][:max_length]) | |
| model_inputs["attention_mask"][i] = torch.tensor(model_inputs["attention_mask"][i][:max_length]) | |
| return model_inputs | |
| processed_datasets = testdataset.map( | |
| preprocess_function, | |
| batched=True, | |
| num_proc=1, | |
| remove_columns=testdataset.column_names, | |
| load_from_cache_file=False, | |
| desc="Running tokenizer on dataset", | |
| ) | |
| test_dataset = processed_datasets | |
| test_dataloader = DataLoader( | |
| test_dataset, shuffle=False, collate_fn=default_data_collator, batch_size=batch_size_train, pin_memory=True | |
| ) | |
| peft_config = LoraConfig( | |
| lora_alpha=16, | |
| lora_dropout=0.1, | |
| #target_modules = ['c_attn'], | |
| target_modules = ['q_proj', 'kv_a_proj_with_mqa', 'o_proj'], #['q_proj', 'kv_a_proj_with_mqa', 'kv_b_proj', 'o_proj'], | |
| r=64, | |
| bias="none", | |
| task_type="CAUSAL_LM" | |
| ) | |
| # peft_config = LoraConfig( | |
| # r=lora_r, | |
| # lora_alpha=lora_alpha, | |
| # lora_dropout=lora_dropout, | |
| # target_modules= target_modules, | |
| # bias="none", | |
| # task_type="CAUSAL_LM" | |
| # ) | |
| model = peft.get_peft_model(model, peft_config) | |
| print("Model loaded successfully!") | |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| #optimizer = AdamW(model.parameters(), lr=3e-4) | |
| optimizer = AdamW(model.parameters(), lr=initial_lr) | |
| # Instantiate scheduler | |
| lr_scheduler = get_cosine_schedule_with_warmup( | |
| optimizer=optimizer, | |
| num_warmup_steps=0.06 * (len(train_dataloader) * num_epochs), | |
| num_training_steps=(len(train_dataloader) * num_epochs), | |
| ) | |
| model.to(device) | |
| #model = torch.nn.DataParallel(model) | |
| #model = model.cuda() | |
| for epoch in range(num_epochs): | |
| try: | |
| model.train() | |
| total_loss = 0 | |
| best_eval_loss = 10000 #np.inf | |
| for step, batch in enumerate(tqdm(train_dataloader)): | |
| batch = {k: v.to(device) for k, v in batch.items()} | |
| #batch = {k: v.cuda() for k, v in batch.items()} | |
| # print(batch) | |
| #print(batch["input_ids"].shape) | |
| # if step > 5: | |
| # break | |
| #batch.to(device) | |
| outputs = model(**batch) | |
| loss = outputs.loss | |
| total_loss += loss.detach().float() | |
| if step % 100 == 0: | |
| print(loss) | |
| loss.backward() | |
| #print("Loss {}".format(loss.item())) | |
| optimizer.step() | |
| lr_scheduler.step() | |
| optimizer.zero_grad() | |
| # if step % ckpnt_NUM2 == 0: | |
| # checkpoint_dir = os.path.join(checkpoint_store_dir_path, f"checkpoint_{epoch}_{step}/") | |
| # os.makedirs(checkpoint_dir, exist_ok=True) | |
| # model.save_pretrained(checkpoint_dir) | |
| if step % ckpnt_NUM == 0: | |
| model.eval() | |
| eval_loss = 0 | |
| eval_preds = [] | |
| eval_cnt = 1 | |
| for step1, batch_eval in enumerate(tqdm(val_dataloader)): | |
| batch_eval = {k: v.to(device) for k, v in batch_eval.items()} | |
| #batch_eval = {k: v.cuda() for k, v in batch_eval.items()} | |
| #outputs = model.generate(**batch_eval, max_new_tokens=48) | |
| #out = tokenizer.batch_decode(outputs, skip_special_tokens=True) | |
| # for x in out: | |
| # print(x) | |
| # print("#" * 50) | |
| with torch.no_grad(): | |
| outputs = model(**batch_eval) | |
| loss = outputs.loss | |
| if not math.isnan(loss.detach().float()) : | |
| eval_loss += loss.detach().float() | |
| eval_cnt += 1 | |
| # eval_preds.extend( | |
| # tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), | |
| # skip_special_tokens=True) | |
| # ) | |
| print(eval_loss) | |
| eval_epoch_loss = eval_loss / len(val_dataloader) | |
| if ((eval_loss/eval_cnt) < best_eval_loss) or SAVEALL: | |
| best_eval_loss = eval_loss/eval_cnt | |
| print(f"saving...{best_eval_loss} to checkpoint_{epoch}_{step}\n") | |
| checkpoint_dir = os.path.join(checkpoint_store_dir_path, f"checkpoint_{epoch}_{step}/") | |
| os.makedirs(checkpoint_dir, exist_ok=True) | |
| model.save_pretrained(checkpoint_dir) | |
| eval_ppl = torch.exp(eval_epoch_loss) | |
| train_epoch_loss = total_loss #/ len(train_dataloader) | |
| train_ppl = torch.exp(train_epoch_loss) | |
| print(f"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=} {eval_loss/eval_cnt=} {eval_cnt=}") | |
| #print(f"{epoch=}: {train_ppl=} {train_epoch_loss=}") | |
| except KeyboardInterrupt: | |
| checkpoint_dir = os.path.join(checkpoint_store_dir_path, f"checkpoint_{epoch}_interrupt/") | |
| os.makedirs(checkpoint_dir, exist_ok=True) | |
| model.save_pretrained(checkpoint_dir) | |
| print("Total Loss {}".format(total_loss.item())) | |
| if ((epoch+1) % 1) == 0: | |
| checkpoint_dir = os.path.join(checkpoint_store_dir_path, f"checkpoint_{epoch}/") | |
| os.makedirs(checkpoint_dir, exist_ok=True) | |
| model.save_pretrained(checkpoint_dir) | |
| model.eval() | |
| eval_loss = 0 | |
| eval_preds = [] | |
| for step1, batch_eval in enumerate(tqdm(test_dataloader)): | |
| if step1 > 5: | |
| break | |
| batch_eval = {k: v.to(device) for k, v in batch_eval.items()} | |
| #batch_eval = {k: v.cuda() for k, v in batch_eval.items()} | |
| outputs = model.generate(**batch_eval, max_new_tokens=48) | |
| out = tokenizer.batch_decode(outputs, skip_special_tokens=True) | |
| for x in out: | |
| print(x) | |
| print("#" * 50) | |
| # with torch.no_grad(): | |
| # outputs = model(**batch) | |
| # loss = outputs.loss | |
| # eval_loss += loss.detach().float() | |
| # eval_preds.extend( | |
| # tokenizer.batch_decode(torch.argmax(outputs.logits, -1).detach().cpu().numpy(), | |
| # skip_special_tokens=True) | |
| # ) | |
| # eval_epoch_loss = eval_loss / len(test_dataloader) | |
| # eval_ppl = torch.exp(eval_epoch_loss) | |
| train_epoch_loss = total_loss / len(train_dataloader) | |
| train_ppl = torch.exp(train_epoch_loss) | |
| #print(f"{epoch=}: {train_ppl=} {train_epoch_loss=} {eval_ppl=} {eval_epoch_loss=}") | |
| print(f"{epoch=}: {train_ppl=} {train_epoch_loss=}") | |
| sys.exit(0) | |
| #model = peft.prepare_model_for_kbit_training(model) | |
| #model = peft.get_peft_model(model, peft_config) | |
| args = TrainingArguments( | |
| output_dir = out_name, | |
| num_train_epochs=5, | |
| #max_steps = 100, | |
| per_device_train_batch_size = 4, | |
| warmup_steps = 0.03, | |
| logging_steps=10, | |
| save_strategy="epoch", | |
| #evaluation_strategy="epoch", | |
| evaluation_strategy="steps", | |
| eval_steps=100, | |
| learning_rate=2e-4, | |
| bf16=True, | |
| lr_scheduler_type='constant', | |
| ) | |
| max_seq_length = 2048 | |
| trainer = SFTTrainer( | |
| model=model, | |
| peft_config=peft_config, | |
| max_seq_length=max_seq_length, | |
| tokenizer=tokenizer, | |
| packing=True, | |
| formatting_func=create_prompt, | |
| args=args, | |
| train_dataset=instruct_tune_dataset["train"], | |
| eval_dataset=instruct_tune_dataset["val"] | |
| ) | |
| # predictions, labels, _ = trainer.predict(instruct_tune_dataset["train"][1]) | |
| # # Convert predictions and labels to text | |
| # predicted_texts = tokenizer.batch_decode(predictions.argmax(axis=-1), skip_special_tokens=True) | |
| # true_texts = tokenizer.batch_decode(labels, skip_special_tokens=True) | |
| # print(f" Pred {predicted_texts}, True {true_texts}") | |
| import time | |
| start = time.time() | |
| try: | |
| trainer.train() | |
| except Exception as e: | |
| print(f"ERRORR\n {e}") | |
| traceback.print_exc() | |
| print(time.time()- start) | |
| def generate_response(prompt, model): | |
| encoded_input = tokenizer(prompt, return_tensors="pt", add_special_tokens=True) | |
| model_inputs = encoded_input.to('cuda') | |
| generated_ids = model.generate(**model_inputs, max_new_tokens=1000, do_sample=True, pad_token_id=tokenizer.eos_token_id) | |
| decoded_output = tokenizer.batch_decode(generated_ids) | |
| return decoded_output[0].replace(prompt, "") | |
| try: | |
| print(generate_response("### Instruction:\nUse the provided input to create an instruction that could have been used to generate the response with an LLM.### Input:\nThere are more than 12,000 species of grass. The most common is Kentucky Bluegrass, because it grows quickly, easily, and is soft to the touch. Rygrass is shiny and bright green colored. Fescues are dark green and shiny. Bermuda grass is harder but can grow in drier soil.\n\n### Response:", trainer.model)) | |
| except Exception as e: | |
| print(f"ERRORR\n {e}") | |
| traceback.print_exc() | |
| try: | |
| trainer.save_model(out_name) | |
| except Exception as e: | |
| print(f"ERRORR\n {e}") | |
| traceback.print_exc() | |
| try: | |
| tester = SFTTrainer( | |
| model=trainer.model, | |
| peft_config=peft_config, | |
| max_seq_length=max_seq_length, | |
| tokenizer=tokenizer, | |
| packing=True, | |
| formatting_func=create_prompt, | |
| args=args, | |
| train_dataset=instruct_tune_dataset["train"], | |
| eval_dataset=instruct_tune_dataset["test"] | |
| ) | |
| print(tester.evaluate()) | |
| except Exception as e: | |
| print(f"ERRORR\n {e}") | |
| traceback.print_exc() | |
| trainer.push_to_hub("FT/mistral-instruct-generation") |