Text Generation
Transformers
finance
domain-specialization
amd-rocm
mi300x
fine-tuned
ml-intern
shah-shazid-askary commited on
Commit
6d3e36d
·
verified ·
1 Parent(s): d013f73

Upload train_job.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. train_job.py +113 -0
train_job.py ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os, sys, argparse, logging
3
+ import torch
4
+ from datasets import load_dataset
5
+ from transformers import AutoModelForCausalLM, AutoTokenizer
6
+ from trl import SFTTrainer, SFTConfig
7
+ from peft import LoraConfig, TaskType
8
+
9
+ if torch.cuda.is_available():
10
+ print(f"GPU: {torch.cuda.is_available()}, devices={torch.cuda.device_count()}")
11
+ for i in range(torch.cuda.device_count()):
12
+ print(f" Device {i}: {torch.cuda.get_device_name(i)}")
13
+
14
+ def to_messages(example):
15
+ messages = []
16
+ system = example.get("system", "")
17
+ if system and str(system).strip():
18
+ messages.append({"role": "system", "content": str(system).strip()})
19
+ messages.append({"role": "user", "content": str(example["user"]).strip()})
20
+ messages.append({"role": "assistant", "content": str(example["assistant"]).strip()})
21
+ return {"messages": messages}
22
+
23
+ def main():
24
+ parser = argparse.ArgumentParser()
25
+ parser.add_argument("--model_name", default="Qwen/Qwen2.5-7B-Instruct")
26
+ parser.add_argument("--dataset_name", default="Josephgflowers/Finance-Instruct-500k")
27
+ parser.add_argument("--output_dir", default="/tmp/output/finance-sft")
28
+ parser.add_argument("--hub_model_id", default="shah-shazid-askary/amd-finance-llm")
29
+ parser.add_argument("--learning_rate", type=float, default=1e-5)
30
+ parser.add_argument("--num_train_epochs", type=int, default=3)
31
+ parser.add_argument("--warmup_ratio", type=float, default=0.1)
32
+ parser.add_argument("--max_seq_length", type=int, default=8192)
33
+ parser.add_argument("--per_device_train_batch_size", type=int, default=1)
34
+ parser.add_argument("--gradient_accumulation_steps", type=int, default=16)
35
+ parser.add_argument("--bf16", action="store_true", default=True)
36
+ parser.add_argument("--use_lora", action="store_true", default=False)
37
+ parser.add_argument("--max_samples", type=int, default=None)
38
+ parser.add_argument("--logging_steps", type=int, default=10)
39
+ parser.add_argument("--save_steps", type=int, default=500)
40
+ parser.add_argument("--eval_steps", type=int, default=500)
41
+ parser.add_argument("--seed", type=int, default=42)
42
+ parser.add_argument("--push_to_hub", action="store_true", default=True)
43
+ args = parser.parse_args()
44
+
45
+ logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
46
+ logger = logging.getLogger(__name__)
47
+
48
+ logger.info("Loading tokenizer...")
49
+ tokenizer = AutoTokenizer.from_pretrained(args.model_name, trust_remote_code=True)
50
+ if tokenizer.pad_token is None:
51
+ tokenizer.pad_token = tokenizer.eos_token
52
+
53
+ logger.info("Loading dataset...")
54
+ ds = load_dataset(args.dataset_name, split="train")
55
+ if args.max_samples:
56
+ ds = ds.select(range(min(args.max_samples, len(ds))))
57
+ ds = ds.map(to_messages, remove_columns=ds.column_names, batched=False)
58
+ ds = ds.train_test_split(test_size=0.05, seed=args.seed)
59
+ logger.info(f"Train: {len(ds["train"])} | Eval: {len(ds["test"])}")
60
+
61
+ logger.info("Loading model...")
62
+ attn_impl = "flash_attention_2" if torch.cuda.is_available() else "eager"
63
+ model_kwargs = {
64
+ "torch_dtype": torch.bfloat16 if args.bf16 else torch.float32,
65
+ "attn_implementation": attn_impl,
66
+ "trust_remote_code": True,
67
+ }
68
+ if torch.cuda.device_count() >= 1:
69
+ model_kwargs["device_map"] = "auto"
70
+ model = AutoModelForCausalLM.from_pretrained(args.model_name, **model_kwargs)
71
+
72
+ peft_config = None
73
+ if args.use_lora:
74
+ peft_config = LoraConfig(
75
+ task_type=TaskType.CAUSAL_LM, inference_mode=False,
76
+ r=32, lora_alpha=16, lora_dropout=0.05,
77
+ target_modules=["q_proj","k_proj","v_proj","o_proj","gate_proj","up_proj","down_proj"],
78
+ )
79
+ model.print_trainable_parameters()
80
+
81
+ sft_args = SFTConfig(
82
+ output_dir=args.output_dir, num_train_epochs=args.num_train_epochs,
83
+ per_device_train_batch_size=args.per_device_train_batch_size,
84
+ gradient_accumulation_steps=args.gradient_accumulation_steps,
85
+ learning_rate=args.learning_rate, warmup_ratio=args.warmup_ratio,
86
+ lr_scheduler_type="cosine", max_seq_length=args.max_seq_length,
87
+ bf16=args.bf16,
88
+ logging_steps=args.logging_steps, logging_strategy="steps",
89
+ logging_first_step=True, save_steps=args.save_steps,
90
+ eval_strategy="steps", eval_steps=args.eval_steps,
91
+ load_best_model_at_end=True, metric_for_best_model="eval_loss",
92
+ greater_is_better=False, seed=args.seed,
93
+ push_to_hub=args.push_to_hub, hub_model_id=args.hub_model_id,
94
+ disable_tqdm=True, gradient_checkpointing=True,
95
+ run_name=f"finance-sft",
96
+ )
97
+
98
+ trainer = SFTTrainer(
99
+ model=model, tokenizer=tokenizer,
100
+ train_dataset=ds["train"], eval_dataset=ds["test"],
101
+ args=sft_args, peft_config=peft_config,
102
+ )
103
+ logger.info("Starting training...")
104
+ trainer.train()
105
+ logger.info("Saving model...")
106
+ trainer.save_model(args.output_dir)
107
+ tokenizer.save_pretrained(args.output_dir)
108
+ if args.push_to_hub:
109
+ trainer.push_to_hub()
110
+ logger.info("Done.")
111
+
112
+ if __name__ == "__main__":
113
+ main()