Text Generation
PEFT
Safetensors
PyTorch
English
causal-lm
lora
qwen
sft
dpo
seal
self-adaptation
hitl
Instructions to use aaronr43210/MiniSEAL with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use aaronr43210/MiniSEAL with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
Download src/train/sft.py from aaronr43210/MiniSEAL: direct link, hf CLI and curl.
- Browser
- Download file 3.58 kB
-
https://huggingface.co/aaronr43210/MiniSEAL/resolve/main/src/train/sft.py
- Command line
-
hf download hf://aaronr43210/MiniSEAL/src/train/sft.py
-
curl -L -o sft.py https://huggingface.co/aaronr43210/MiniSEAL/resolve/main/src/train/sft.py
3.58 kB
| import argparse | |
| import os | |
| import yaml | |
| import torch | |
| from datasets import load_dataset | |
| from transformers import AutoModelForCausalLM, AutoTokenizer, TrainingArguments, Trainer, DataCollatorForLanguageModeling | |
| from peft import LoraConfig, get_peft_model | |
| import sys | |
| # Add project root to python path | |
| sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) | |
| from src.common.utils import ensure_dir, set_seed | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("--config", type=str, required=True) | |
| args = parser.parse_args() | |
| with open(args.config, "r", encoding="utf-8") as f: | |
| cfg = yaml.safe_load(f) | |
| set_seed(cfg.get("seed", 42)) | |
| out_dir = cfg["out_dir"] | |
| ensure_dir(out_dir) | |
| base_model_path = cfg.get("pretrained_model_path", "Qwen/Qwen2.5-1.5B-Instruct") | |
| print(f"[SFT] Loading base model: {base_model_path}") | |
| tokenizer = AutoTokenizer.from_pretrained(base_model_path) | |
| if tokenizer.pad_token is None: | |
| tokenizer.pad_token = tokenizer.eos_token | |
| # No device_map="auto": the HF Trainer handles device placement itself, and | |
| # device_map conflicts with the Trainer on some single-/multi-GPU setups. | |
| model = AutoModelForCausalLM.from_pretrained( | |
| base_model_path, | |
| torch_dtype=torch.bfloat16 if torch.cuda.is_available() else torch.float32, | |
| ) | |
| lora_config = LoraConfig( | |
| r=16, | |
| lora_alpha=32, | |
| target_modules=["q_proj", "v_proj"], | |
| lora_dropout=0.05, | |
| bias="none", | |
| task_type="CAUSAL_LM" | |
| ) | |
| # Apply PEFT directly | |
| model = get_peft_model(model, lora_config) | |
| model.print_trainable_parameters() | |
| dataset_path = cfg["sft_data_path"] | |
| print(f"[SFT] Loading dataset from {dataset_path}") | |
| dataset = load_dataset('json', data_files=dataset_path, split='train') | |
| # We will format AND tokenize manually to avoid all third-party TRL bugs | |
| def tokenize_function(example): | |
| p = example['prompt'] | |
| r = example['response'] | |
| messages = [{"role": "user", "content": p}, {"role": "assistant", "content": r}] | |
| try: | |
| text = tokenizer.apply_chat_template(messages, tokenize=False) | |
| except Exception: | |
| text = f"User: {p}\nAssistant: {r}{tokenizer.eos_token}" | |
| return tokenizer(text, truncation=True, max_length=cfg.get("block_size", 1024)) | |
| dataset = dataset.map(tokenize_function, batched=False) | |
| sft_config = TrainingArguments( | |
| output_dir=out_dir, | |
| per_device_train_batch_size=cfg.get("micro_batch_size", 2), | |
| gradient_accumulation_steps=cfg.get("grad_accum_steps", 4), | |
| learning_rate=float(cfg.get("learning_rate", 2e-4)), | |
| logging_steps=cfg.get("log_interval", 10), | |
| max_steps=cfg.get("max_steps", 1000), | |
| save_steps=cfg.get("save_interval", 200), | |
| bf16=True if torch.cuda.is_available() else False, | |
| fp16=False, | |
| ) | |
| # Standard HuggingFace Trainer (Bulletproof) | |
| trainer = Trainer( | |
| model=model, | |
| train_dataset=dataset, | |
| args=sft_config, | |
| data_collator=DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False) | |
| ) | |
| print("\n[SFT] Starting HuggingFace LoRA Training...\n") | |
| trainer.train() | |
| final_path = os.path.join(out_dir, "final_adapter") | |
| trainer.model.save_pretrained(final_path) | |
| tokenizer.save_pretrained(final_path) | |
| print(f"\n[SFT] Saved final LoRA adapter to {final_path}") | |
| if __name__ == "__main__": | |
| main() | |