darabos commited on
Commit
bfa3dae
·
1 Parent(s): 2e080c7

Prototype for Unsloth boxes. Will probably open-source later.

Browse files
examples/Unsloth/Demo.lynxkite.json ADDED
The diff for this file is too large to render. See raw diff
 
examples/Unsloth/boxes.py ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import enum
2
+ from lynxkite_core import ops
3
+ from lynxkite_graph_analytics.core import Bundle
4
+ import unsloth
5
+ import trl
6
+ from datasets import load_dataset
7
+ import unsloth.chat_templates
8
+ from transformers.training_args import OptimizerNames
9
+ from transformers.trainer_utils import SchedulerType
10
+
11
+ op = ops.op_registration("LynxKite Graph Analytics", "Unsloth")
12
+
13
+
14
+ @op("Load base model", slow=True, cache=False)
15
+ def load_base_model(
16
+ *,
17
+ model_name: str,
18
+ max_seq_length=2048,
19
+ load_in_4bit=False,
20
+ load_in_8bit=False,
21
+ full_finetuning=False,
22
+ ):
23
+ model, tokenizer = unsloth.FastModel.from_pretrained(
24
+ model_name=model_name,
25
+ max_seq_length=max_seq_length,
26
+ load_in_4bit=load_in_4bit,
27
+ load_in_8bit=load_in_8bit,
28
+ full_finetuning=full_finetuning,
29
+ )
30
+ return Bundle(other={"model": model, "tokenizer": tokenizer})
31
+
32
+
33
+ @op("Configure LoRA", slow=True, cache=False)
34
+ def configure_lora(bundle: Bundle, *, r=128, lora_dropout=0, random_state=1, rank_stabilized=False):
35
+ bundle = bundle.copy()
36
+ model = bundle.other["model"]
37
+ bundle.other["model"] = unsloth.FastModel.get_peft_model(
38
+ model,
39
+ r=r,
40
+ lora_dropout=lora_dropout,
41
+ random_state=random_state,
42
+ use_rslora=rank_stabilized,
43
+ target_modules=[
44
+ "q_proj",
45
+ "k_proj",
46
+ "v_proj",
47
+ "o_proj",
48
+ "gate_proj",
49
+ "up_proj",
50
+ "down_proj",
51
+ ],
52
+ lora_alpha=128,
53
+ bias="none",
54
+ use_gradient_checkpointing="unsloth",
55
+ loftq_config=None,
56
+ )
57
+ return bundle
58
+
59
+
60
+ @op("Load HF dataset", slow=True, cache=False)
61
+ def load_hf_dataset(*, name: str, split="train[:10000]") -> Bundle:
62
+ return Bundle(other={"dataset": load_dataset(name, split=split)})
63
+
64
+
65
+ @op("Convert to ChatML", slow=True, cache=False)
66
+ def convert_to_chatml(
67
+ bundle: Bundle,
68
+ *,
69
+ system_column_name: str,
70
+ user_column_name: str,
71
+ assistant_column_name: str,
72
+ save_as="conversations",
73
+ ):
74
+ bundle = bundle.copy()
75
+ ds = bundle.other["dataset"]
76
+ bundle.other["dataset"] = ds.map(
77
+ lambda e: {
78
+ save_as: [
79
+ {"role": "system", "content": e[system_column_name]},
80
+ {"role": "user", "content": e[user_column_name]},
81
+ {"role": "assistant", "content": e[assistant_column_name]},
82
+ ]
83
+ }
84
+ )
85
+ return bundle
86
+
87
+
88
+ @op("Apply chat template", slow=True, cache=False)
89
+ def apply_chat_template(bundle: Bundle, *, conversations_field="conversations", save_as="text"):
90
+ bundle = bundle.copy()
91
+ tokenizer = bundle.other["tokenizer"]
92
+ bundle.other["dataset"] = bundle.other["dataset"].map(
93
+ lambda e: {
94
+ save_as: [
95
+ tokenizer.apply_chat_template(
96
+ convo, tokenize=False, add_generation_prompt=False
97
+ ).removeprefix("<bos>")
98
+ for convo in e[conversations_field]
99
+ ]
100
+ },
101
+ batched=True,
102
+ )
103
+ return bundle
104
+
105
+
106
+ @op("Train LLM", slow=True, cache=False)
107
+ def train_llm(
108
+ bundle: Bundle,
109
+ *,
110
+ dataset_text_field="text",
111
+ train_on_responses_only=True,
112
+ per_device_train_batch_size=8,
113
+ gradient_accumulation_steps=1,
114
+ warmup_steps=5,
115
+ num_train_epochs: int | None = 1,
116
+ max_steps: int | None = None,
117
+ learning_rate=5e-5,
118
+ logging_steps=1,
119
+ optim=OptimizerNames.ADAMW_8BIT,
120
+ weight_decay=0.01,
121
+ lr_scheduler_type=SchedulerType.LINEAR,
122
+ seed=1,
123
+ ):
124
+ model = bundle.other["model"]
125
+ tokenizer = bundle.other["tokenizer"]
126
+ dataset = bundle.other["dataset"]
127
+ trainer = trl.SFTTrainer(
128
+ model=model,
129
+ tokenizer=tokenizer,
130
+ train_dataset=dataset,
131
+ eval_dataset=None,
132
+ args=trl.SFTConfig(
133
+ dataset_text_field=dataset_text_field,
134
+ per_device_train_batch_size=per_device_train_batch_size,
135
+ gradient_accumulation_steps=gradient_accumulation_steps,
136
+ warmup_steps=warmup_steps,
137
+ num_train_epochs=num_train_epochs or -1,
138
+ max_steps=max_steps or -1,
139
+ learning_rate=learning_rate,
140
+ logging_steps=logging_steps,
141
+ optim=optim,
142
+ weight_decay=weight_decay,
143
+ lr_scheduler_type=lr_scheduler_type,
144
+ seed=seed,
145
+ output_dir="outputs",
146
+ report_to="none",
147
+ ),
148
+ )
149
+ if train_on_responses_only:
150
+ trainer = unsloth.chat_templates.train_on_responses_only(
151
+ trainer,
152
+ instruction_part="<start_of_turn>user\n",
153
+ response_part="<start_of_turn>model\n",
154
+ )
155
+ trainer_stats = trainer.train()
156
+ bundle = bundle.copy()
157
+ bundle.other["trainer_stats"] = trainer_stats
158
+ return bundle
159
+
160
+
161
+ @op("Save model (LoRA only)", outputs=[], slow=True, cache=False)
162
+ def save_model_lora(bundle: Bundle, *, file_name: str):
163
+ model = bundle.other["model"]
164
+ tokenizer = bundle.other["tokenizer"]
165
+ model.save_pretrained(file_name)
166
+ tokenizer.save_pretrained(file_name)
167
+
168
+
169
+ @op("Save model (float16)", outputs=[], slow=True, cache=False)
170
+ def save_model_float16(bundle: Bundle, *, file_name: str):
171
+ model = bundle.other["model"]
172
+ tokenizer = bundle.other["tokenizer"]
173
+ model.save_pretrained_merged(file_name, tokenizer, save_method="merged_16bit")
174
+
175
+
176
+ @op("Save model (int4)", outputs=[], slow=True, cache=False)
177
+ def save_model_int4(bundle: Bundle, *, file_name: str):
178
+ model = bundle.other["model"]
179
+ tokenizer = bundle.other["tokenizer"]
180
+ model.save_pretrained_merged(file_name, tokenizer, save_method="merged_4bit")
181
+
182
+
183
+ class QuantizationType(enum.StrEnum):
184
+ Q8_0 = "Q8_0"
185
+ BF16 = "BF16"
186
+ F16 = "F16"
187
+
188
+
189
+ @op("Save model (GGUF)", outputs=[], slow=True, cache=False)
190
+ def save_model_gguf(
191
+ bundle: Bundle, *, file_name: str, quantization: QuantizationType = QuantizationType.Q8_0
192
+ ):
193
+ model = bundle.other["model"]
194
+ tokenizer = bundle.other["tokenizer"]
195
+ model.save_pretrained_gguf(
196
+ file_name,
197
+ tokenizer,
198
+ quantization_type=quantization.value,
199
+ )
200
+
201
+
202
+ @op("Chat with model", view="service")
203
+ def chat_with_model(bundle: Bundle):
204
+ # TODO: Implement this.
205
+ pass
examples/Unsloth/requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ datasets
2
+ unsloth