Spaces:
Paused
Paused
Download model_training/train_colab.py from rishik1111/vector-backend: direct link, hf CLI and curl.
- Browser
- Download file 4.3 kB
-
https://huggingface.co/spaces/rishik1111/vector-backend/resolve/main/model_training/train_colab.py
- Command line
-
hf download hf://spaces/rishik1111/vector-backend/model_training/train_colab.py
-
curl -L -o train_colab.py https://huggingface.co/spaces/rishik1111/vector-backend/resolve/main/model_training/train_colab.py
4.3 kB
| """ | |
| Fine-Tuning Qwen2.5-0.5B-Instruct on Multilingual RAG Dataset (Google Colab / CUDA). | |
| Requirements: | |
| pip install torch transformers peft trl datasets accelerate bitsandbytes | |
| Usage in Google Colab: | |
| 1. Upload `rag_sft_dataset.jsonl` | |
| 2. Run: python train_colab.py | |
| """ | |
| import os | |
| import json | |
| import torch | |
| from knowledge_base import load_dataset | |
| from transformers import ( | |
| AutoModelForCausalLM, | |
| AutoTokenizer, | |
| TrainingArguments, | |
| BitsAndBytesConfig | |
| ) | |
| from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training | |
| from trl import SFTTrainer | |
| # 1. Configuration | |
| MODEL_ID = "Qwen/Qwen2.5-0.5B-Instruct" | |
| DATASET_PATH = "rag_sft_dataset.jsonl" | |
| OUTPUT_DIR = "qwen2.5_0.5b_indic_rag_lora" | |
| MERGED_DIR = "qwen2.5_0.5b_indic_rag_merged" | |
| # 2. Load Dataset | |
| print(f"Loading dataset from {DATASET_PATH}...") | |
| dataset = load_dataset("json", data_files=DATASET_PATH, split="train") | |
| print(f"Loaded {len(dataset)} examples. Shuffling and splitting...") | |
| dataset = dataset.shuffle(seed=42).train_test_split(test_size=0.05) | |
| # 3. Load Tokenizer | |
| tokenizer = AutoTokenizer.from_pretrained(MODEL_ID, trust_remote_code=True) | |
| if tokenizer.pad_token is None: | |
| tokenizer.pad_token = tokenizer.eos_token | |
| # 4. Format Conversations for SFTTrainer | |
| def format_chat_template(example): | |
| text = tokenizer.apply_chat_template( | |
| example["messages"], | |
| tokenize=False, | |
| add_generation_prompt=False | |
| ) | |
| return {"text": text} | |
| formatted_train = dataset["train"].map(format_chat_template) | |
| formatted_eval = dataset["test"].map(format_chat_template) | |
| # 5. Load Model with QLoRA (4-bit) if CUDA is available | |
| is_cuda = torch.cuda.is_available() | |
| print(f"CUDA Available: {is_cuda}") | |
| if is_cuda: | |
| bnb_config = BitsAndBytesConfig( | |
| load_in_4bit=True, | |
| bnb_4bit_quant_type="nf4", | |
| bnb_4bit_compute_dtype=torch.float16, | |
| bnb_4bit_use_double_quant=True, | |
| ) | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_ID, | |
| quantization_config=bnb_config, | |
| device_map="auto", | |
| trust_remote_code=True | |
| ) | |
| model = prepare_model_for_kbit_training(model) | |
| else: | |
| model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_ID, | |
| torch_dtype=torch.float32, | |
| device_map="cpu", | |
| trust_remote_code=True | |
| ) | |
| # 6. Apply LoRA Config | |
| lora_config = LoraConfig( | |
| r=16, | |
| lora_alpha=32, | |
| target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], | |
| lora_dropout=0.05, | |
| bias="none", | |
| task_type="CAUSAL_LM" | |
| ) | |
| model = get_peft_model(model, lora_config) | |
| model.print_trainable_parameters() | |
| # 7. Training Arguments optimized for full 126k dataset | |
| training_args = TrainingArguments( | |
| output_dir=OUTPUT_DIR, | |
| per_device_train_batch_size=16 if is_cuda else 2, | |
| gradient_accumulation_steps=2, | |
| learning_rate=2e-4, | |
| lr_scheduler_type="cosine", | |
| num_train_epochs=1, | |
| logging_steps=100, | |
| eval_strategy="steps", | |
| eval_steps=1000, | |
| save_strategy="steps", | |
| save_steps=1000, | |
| fp16=is_cuda, | |
| optim="paged_adamw_8bit" if is_cuda else "adamw_torch", | |
| report_to="none", | |
| save_total_limit=1, | |
| ) | |
| # 8. Train with SFTTrainer | |
| trainer = SFTTrainer( | |
| model=model, | |
| train_dataset=formatted_train, | |
| eval_dataset=formatted_eval, | |
| dataset_text_field="text", | |
| max_seq_length=384, | |
| tokenizer=tokenizer, | |
| args=training_args, | |
| ) | |
| print("Starting LoRA Fine-Tuning...") | |
| trainer.train() | |
| # 9. Save LoRA Adapter | |
| print(f"Saving LoRA Adapter to {OUTPUT_DIR}...") | |
| trainer.model.save_pretrained(OUTPUT_DIR) | |
| tokenizer.save_pretrained(OUTPUT_DIR) | |
| # 10. Merge LoRA with Base Model for fast CPU inference | |
| print("Merging LoRA weights with Base Model for CPU inference...") | |
| base_model = AutoModelForCausalLM.from_pretrained( | |
| MODEL_ID, | |
| torch_dtype=torch.float16 if is_cuda else torch.float32, | |
| device_map="auto" if is_cuda else "cpu", | |
| trust_remote_code=True | |
| ) | |
| from peft import PeftModel | |
| merged_model = PeftModel.from_pretrained(base_model, OUTPUT_DIR) | |
| merged_model = merged_model.merge_and_unload() | |
| print(f"Saving Merged Model to {MERGED_DIR}...") | |
| merged_model.save_pretrained(MERGED_DIR) | |
| tokenizer.save_pretrained(MERGED_DIR) | |
| print("\n Training & Merging Completed Successfully!") | |
| print(f"Model ready at: {MERGED_DIR}") | |