Views
No views yet
1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer, pipeline
3from peft import PeftModel
4
5# Define the paths
6base_model_path = "./SmolLM3-3B-Base/"
7adapter_path = "./SmolLM3-3B-Instruct-Anime/"
8
9# Load the base model and the tokenizer in bf16
10print("Loading base model and tokenizer...")
11base_model = AutoModelForCausalLM.from_pretrained(
12 base_model_path,
13 torch_dtype=torch.bfloat16,
14 device_map="auto",
15)
16tokenizer = AutoTokenizer.from_pretrained(base_model_path)
17
18# Load the LoRA adapter and merge it into the base model
19print("Loading LoRA adapter and merging...")
20model = PeftModel.from_pretrained(base_model, adapter_path)
21model = model.merge_and_unload() # Merge the weights
22
23# Create the text generation pipeline
24print("Creating pipeline...")
25generator = pipeline("text-generation", model=model, tokenizer=tokenizer)
26
27# Your question
28question = "If you had a time machine, but could only go to the past or the future once and never return, which would you choose and why? "
29
30# Format the prompt using the chat template
31# We need to load the template file just like in the training script
32with open("chat_template.jinja", "r") as f:
33 chat_template = f.read()
34tokenizer.chat_template = chat_template
35
36prompt = tokenizer.apply_chat_template([{"role": "user", "content": question}], tokenize=False, add_generation_prompt=True)
37
38# Generate the output
39print("Generating response...")
40output = generator(prompt, max_new_tokens=2048, return_full_text=False)
41print("--- Model Response ---")
42print(output[0]["generated_text"])1import torch
2from transformers import AutoModelForCausalLM, AutoTokenizer
3from datasets import load_dataset
4from peft import LoraConfig
5from trl import SFTTrainer, SFTConfig
6import trackio
7
8# --- Configuration ---
9model_name = "./SmolLM3-3B-Base/"
10dataset_path = "./Instruct-Anime/instruct_dataset.jsonl"
11output_dir = "./SmolLM3-3B-Instruct-Anime"
12project_name = "smollm3-sft-anime"
13
14# --- 1. Initialize Trackio ---
15trackio.init(project=project_name)
16
17# --- 2. Load the model and the tokenizer ---
18print("Loading the model and the tokenizer...")
19model = AutoModelForCausalLM.from_pretrained(
20 model_name,
21 device_map="auto",
22 dtype=torch.bfloat16,
23 low_cpu_mem_usage=True,
24 trust_remote_code=True,
25 attn_implementation="flash_attention_2",
26)
27tokenizer = AutoTokenizer.from_pretrained(model_name)
28# Add a pad token if it's missing
29if tokenizer.pad_token is None:
30 tokenizer.pad_token = tokenizer.eos_token
31 model.config.pad_token_id = model.config.eos_token_id
32
33# Load and set the chat template from the jinja file
34with open("chat_template.jinja", "r") as f:
35 chat_template = f.read()
36tokenizer.chat_template = chat_template
37print("The chat template has been loaded from chat_template.jinja and set on the tokenizer.")
38
39
40# --- Enable gradient checkpointing ---
41print("Enabling Gradient Checkpointing...")
42model.gradient_checkpointing_enable()
43
44
45# --- 3. Load and process the dataset ---
46print("Loading and processing the dataset...")
47dataset = load_dataset("json", data_files=dataset_path, split="train")
48
49def formatting_prompts_func(example):
50 # This function formats the chat messages into a single string
51 # by applying the model's chat template.
52 text = tokenizer.apply_chat_template(example['messages'], tokenize=False)
53 example['text'] = text
54 return example
55
56dataset = dataset.map(formatting_prompts_func, remove_columns=["messages", "source"])
57print(f"Dataset loaded and formatted with {len(dataset)} examples.")
58
59
60# --- 4. Configure the LoRA ---
61print("Configuring the LoRA...")
62peft_config = LoraConfig(
63 r=8,
64 lora_alpha=16,
65 lora_dropout=0.1,
66 target_modules=['q_proj', 'v_proj'], # From the test script
67 bias="none",
68 task_type="CAUSAL_LM",
69)
70
71# --- 5. Configure training ---
72# Balanced learning rate and batch size for a GPU with ~24GB VRAM
73print("Configuring training arguments...")
74training_args = SFTConfig(
75 output_dir=output_dir,
76 num_train_epochs=5, # Train for a total of 5 epochs
77 per_device_train_batch_size=2,
78 gradient_accumulation_steps=8,
79 optim="paged_adamw_8bit",
80 learning_rate=1e-4,
81 lr_scheduler: rex,
82 warmup_steps=50,
83 logging_steps=8,
84 save_total_limit=5, # Keep best + last few checkpoints
85 load_best_model_at_end=true,
86 save_strategy="steps",
87 report_to="trackio",
88 packing=True,
89 max_length=5120,
90 metric_for_best_model=eval_loss,
91 greater_is_better=false
92)
93
94# --- 6. Create and run the trainer ---
95print("Creating SFTTrainer...")
96trainer = SFTTrainer(
97 model=model,
98 args=training_args,
99 train_dataset=dataset,
100 peft_config=peft_config,
101 # The trainer will automatically use the 'text' column
102)
103
104print("Starting training...")
105trainer.train() #resume_from_checkpoint=True
106
107# --- 7. Save the final adapter ---
108print("Training has finished. Saving the adapter.")
109trainer.save_model(output_dir)
110
111print(f"The LoRA adapter saved to {output_dir}")
112trackio.finish()1@misc{vonwerra2022trl,
2 title = {{TRL: Transformer Reinforcement Learning}},
3 author = {Leandro von Werra and Younes Belkada and Lewis Tunstall and Edward Beeching and Tristan Thrush and Nathan Lambert and Shengyi Huang and Kashif Rasul and Quentin Gallou{\'e}dec},
4 year = 2020,
5 journal = {GitHub repository},
6 publisher = {GitHub},
7 howpublished = {\url{https://github.com/huggingface/trl}}
8}