Distillflow 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. distillflow/common/__init__.py +10 -0
  2. distillflow/common/common.py +98 -0
  3. distillflow/common/logger.py +101 -0
  4. distillflow/config/__init__.py +6 -0
  5. distillflow/config/config.py +26 -0
  6. distillflow/config/validator.py +38 -0
  7. distillflow/datasets/__init__.py +6 -0
  8. distillflow/datasets/args.py +99 -0
  9. distillflow/datasets/loader.py +191 -0
  10. distillflow/datasets/template/__init__.py +12 -0
  11. distillflow/datasets/template/alpaca.py +85 -0
  12. distillflow/datasets/template/args.py +56 -0
  13. distillflow/datasets/template/role.py +10 -0
  14. distillflow/datasets/template/sharegpt.py +84 -0
  15. distillflow/datasets/template/template.py +6 -0
  16. distillflow/evaluation/__init__.py +0 -0
  17. distillflow/evaluation/rouge.py +30 -0
  18. distillflow/model/__init__.py +0 -0
  19. distillflow/model/adapter.py +257 -0
  20. distillflow/model/args.py +173 -0
  21. distillflow/model/checkpoint.py +146 -0
  22. distillflow/model/finetuning_args.py +132 -0
  23. distillflow/model/generating_args.py +72 -0
  24. distillflow/model/liger_kernel.py +46 -0
  25. distillflow/model/loader.py +286 -0
  26. distillflow/model/quantization.py +193 -0
  27. distillflow/model/tokenizer.py +55 -0
  28. distillflow/model/unsloth.py +92 -0
  29. distillflow/trainer/AdaptationLayer.py +82 -0
  30. distillflow/trainer/__init__.py +0 -0
  31. distillflow/trainer/args.py +56 -0
  32. distillflow/trainer/attention_distillation.py +113 -0
  33. distillflow/trainer/fine_tuning.py +51 -0
  34. distillflow/trainer/layers_distillation.py +106 -0
  35. distillflow/trainer/logits_distillation.py +96 -0
  36. distillflow-0.2.0.dist-info/LICENSE +201 -0
  37. distillflow-0.2.0.dist-info/METADATA +162 -0
  38. distillflow-0.2.0.dist-info/RECORD +39 -0
  39. distillflow-0.2.0.dist-info/WHEEL +4 -0
@@ -0,0 +1,56 @@
1
+ from typing import Literal, Optional, Union
2
+
3
+ from pydantic import BaseModel, Field, model_validator
4
+
5
+ from . import ShareGptArgs, AlpacaArgs
6
+
7
+
8
+ class TemplateArgs(BaseModel):
9
+ name: Literal["sharegpt", "alpaca"] = Field(
10
+ default="sharegpt",
11
+ description="Template used by the dataset. Based on the template, the data will be converted to a standard format before training"
12
+ )
13
+ args: Optional[Union[ShareGptArgs, AlpacaArgs]] = Field(
14
+ default=None,
15
+ description="Template args to map the corresponding dataset columns to the ones expected by sharegpt/alpaca"
16
+ )
17
+
18
+ # Validate and transform args based on template name
19
+ @model_validator(mode='after')
20
+ def validate_args(self) -> 'TemplateArgs':
21
+ if self.args is None:
22
+ # Set default args based on template
23
+ self.args = {
24
+ "sharegpt": ShareGptArgs(),
25
+ "alpaca": AlpacaArgs()
26
+ }[self.name]
27
+ return self
28
+
29
+ # If args is a dict, convert to appropriate type
30
+ if isinstance(self.args, dict):
31
+ template_classes = {
32
+ "sharegpt": ShareGptArgs,
33
+ "alpaca": AlpacaArgs
34
+ }
35
+
36
+ template_class = template_classes.get(self.name)
37
+ if template_class is None:
38
+ raise ValueError(f"Unknown template: {self.name}")
39
+
40
+ try:
41
+ self.args = template_class(**self.args)
42
+ except Exception as e:
43
+ raise ValueError(f"Invalid args for template '{self.name}': {str(e)}")
44
+
45
+ # Validate that args matches template
46
+ expected_type = ShareGptArgs if self.name == "sharegpt" else AlpacaArgs
47
+ if not isinstance(self.args, expected_type):
48
+ raise ValueError(
49
+ f"Template '{self.name}' expects {expected_type.__name__} "
50
+ f"but got {type(self.args).__name__}"
51
+ )
52
+ return self
53
+
54
+ model_config = {
55
+ "extra": "forbid"
56
+ }
@@ -0,0 +1,10 @@
1
+ from enum import Enum, unique
2
+
3
+
4
+ @unique
5
+ class Role(str, Enum):
6
+ USER = "user"
7
+ ASSISTANT = "assistant"
8
+ SYSTEM = "system"
9
+ FUNCTION = "function"
10
+ OBSERVATION = "observation"
@@ -0,0 +1,84 @@
1
+ import json
2
+ from dataclasses import dataclass
3
+ from typing import Dict, Any, Optional
4
+
5
+ from .template import Template
6
+ from .role import Role
7
+ from ...common import get_logger
8
+
9
+ logger = get_logger(__name__)
10
+
11
+ @dataclass
12
+ class ShareGptArgs:
13
+ messages: Optional[str] = "conversations"
14
+ # sharegpt tags
15
+ role_tag: Optional[str] = "from"
16
+ content_tag: Optional[str] = "value"
17
+ user_tag: Optional[str] = "human"
18
+ assistant_tag: Optional[str] = "gpt"
19
+ observation_tag: Optional[str] = "observation"
20
+ function_tag: Optional[str] = "function_call"
21
+ system_tag: Optional[str] = "system"
22
+
23
+ class ShareGpt(Template):
24
+
25
+ def __init__(self, args: Optional[ShareGptArgs] = ShareGptArgs()):
26
+ self.args = args
27
+
28
+ def convert(self, example: Dict[str, Any]) -> Dict[str, Any]:
29
+ r"""
30
+ Converts sharegpt format dataset to the standard format.
31
+ """
32
+ tag_mapping = {
33
+ self.args.user_tag: Role.USER.value,
34
+ self.args.assistant_tag: Role.ASSISTANT.value,
35
+ self.args.observation_tag: Role.OBSERVATION.value,
36
+ self.args.function_tag: Role.FUNCTION.value,
37
+ self.args.system_tag: Role.SYSTEM.value,
38
+ }
39
+ odd_tags = (self.args.user_tag, self.args.observation_tag)
40
+ even_tags = (self.args.assistant_tag, self.args.function_tag)
41
+ accept_tags = (odd_tags, even_tags)
42
+ messages = example[self.args.messages]
43
+ system = []
44
+ if (
45
+ self.args.system_tag
46
+ and len(messages) != 0
47
+ and messages[0][self.args.role_tag] == self.args.system_tag
48
+ ):
49
+ system.append({"role": Role.SYSTEM.value, "content": messages[0][self.args.content_tag]})
50
+ messages = messages[1:]
51
+ else:
52
+ system.append({"role": Role.SYSTEM.value, "content": example[self.args.system_tag]} if self.args.system_tag in example else {"role": Role.SYSTEM.value,
53
+ "content": "You are a helpful assistant."})
54
+
55
+ aligned_messages = []
56
+ broken_data = False
57
+ for turn_idx, message in enumerate(messages):
58
+ if message[self.args.role_tag] not in accept_tags[turn_idx % 2]:
59
+ logger.warning("Invalid role tag in {}.".format(messages))
60
+ broken_data = True
61
+
62
+ aligned_messages.append(
63
+ {"role": tag_mapping[message.get(self.args.role_tag, '')], "content": message.get(self.args.content_tag, '')}
64
+ )
65
+
66
+ prompt = aligned_messages[:-1]
67
+ response = aligned_messages[-1:]
68
+
69
+ if isinstance(response, str):
70
+ try:
71
+ response = json.loads(response)
72
+ except json.JSONDecodeError as e:
73
+ raise ValueError(f"Invalid JSON in response: {response}") from e
74
+ if broken_data:
75
+ logger.warning("Skipping this abnormal example.")
76
+ prompt, response = [], []
77
+
78
+ output = {
79
+ "_prompt": prompt,
80
+ "_response": response,
81
+ "_system": system,
82
+ }
83
+
84
+ return output
@@ -0,0 +1,6 @@
1
+ from typing import Dict, Any
2
+
3
+ class Template:
4
+ def convert(self, example: Dict[str, Any]) -> Dict[str, Any]:
5
+ raise NotImplementedError("Template must implement the convert method.")
6
+
File without changes
@@ -0,0 +1,30 @@
1
+ import evaluate
2
+
3
+ def read_file(file_path):
4
+ """Reads text from a file and returns it as a list of lines."""
5
+ with open(file_path, 'r', encoding='utf-8') as file:
6
+ return [line.strip() for line in file.readlines()]
7
+
8
+
9
+ def compute_rouge_scores(reference_file, generated_file):
10
+ # Load the ROUGE metric from the evaluate library
11
+ rouge = evaluate.load('rouge')
12
+
13
+ reference_texts = read_file(reference_file)
14
+ generated_texts = read_file(generated_file)
15
+
16
+ # Compute ROUGE scores for the provided texts
17
+ scores = rouge.compute(predictions=generated_texts, references=reference_texts)
18
+
19
+ # Return the scores
20
+ return scores
21
+
22
+
23
+ # Example usage
24
+ # reference_texts = ["The cat sat on the mat."]
25
+ # generated_texts = ["The cat is sitting on the mat."]
26
+ #
27
+ # # Compute and print ROUGE scores
28
+ # rouge_scores = compute_rouge_scores(reference_texts, generated_texts)
29
+ # for metric, score in rouge_scores.items():
30
+ # print(f"{metric}: {score:.4f}")
File without changes
@@ -0,0 +1,257 @@
1
+ import re
2
+
3
+ import torch
4
+ from peft import LoraConfig, LoraModel, PeftModel, TaskType, get_peft_model
5
+ from transformers.integrations import is_deepspeed_zero3_enabled
6
+ from transformers.modeling_utils import is_fsdp_enabled
7
+
8
+ from .args import ModelArgs
9
+ from .finetuning_args import FinetuningArgs
10
+ from ..common.logger import get_logger
11
+ from .unsloth import get_unsloth_peft_model, load_unsloth_peft_model
12
+
13
+ from transformers import PretrainedConfig, PreTrainedModel
14
+
15
+ from ..common import find_all_linear_modules
16
+
17
+ logger = get_logger(__name__)
18
+
19
+
20
+ def _setup_full_tuning(model: PreTrainedModel, is_trainable: bool, cast_trainable_params_to_fp32: bool) -> None:
21
+ if not is_trainable:
22
+ return
23
+
24
+ logger.info("Fine-tuning method: Full")
25
+ for name, param in model.named_parameters():
26
+ if cast_trainable_params_to_fp32:
27
+ param.data = param.data.to(torch.float32)
28
+
29
+
30
+ def _setup_freeze_tuning(
31
+ model: PreTrainedModel,
32
+ finetuning_args: FinetuningArgs,
33
+ is_trainable: bool,
34
+ cast_trainable_params_to_fp32: bool,
35
+ ) -> None:
36
+ if not is_trainable:
37
+ return
38
+
39
+ logger.info("Fine-tuning method: Freeze")
40
+ if hasattr(model.config, "text_config"): # composite models
41
+ config = getattr(model.config, "text_config")
42
+ else:
43
+ config = model.config
44
+
45
+ num_layers = (
46
+ getattr(config, "num_hidden_layers", None)
47
+ or getattr(config, "num_layers", None)
48
+ or getattr(config, "n_layer", None)
49
+ )
50
+ if not num_layers:
51
+ raise ValueError("Current model does not support freeze tuning.")
52
+
53
+ if finetuning_args.use_llama_pro:
54
+ if num_layers % finetuning_args.freeze_trainable_layers != 0:
55
+ raise ValueError(
56
+ "`num_layers` {} should be divisible by `num_layer_trainable` {}.".format(
57
+ num_layers, finetuning_args.freeze_trainable_layers
58
+ )
59
+ )
60
+
61
+ stride = num_layers // finetuning_args.freeze_trainable_layers
62
+ trainable_layer_ids = range(stride - 1, num_layers + stride - 1, stride)
63
+ elif finetuning_args.freeze_trainable_layers > 0: # fine-tuning the last n layers if num_layer_trainable > 0
64
+ trainable_layer_ids = range(max(0, num_layers - finetuning_args.freeze_trainable_layers), num_layers)
65
+ else: # fine-tuning the first n layers if num_layer_trainable < 0
66
+ trainable_layer_ids = range(min(-finetuning_args.freeze_trainable_layers, num_layers))
67
+
68
+ hidden_modules = set()
69
+ non_hidden_modules = set()
70
+ for name, _ in model.named_parameters():
71
+ if ".0." in name:
72
+ hidden_modules.add(name.split(".0.")[-1].split(".")[0])
73
+ elif ".1." in name: # MoD starts from layer 1
74
+ hidden_modules.add(name.split(".1.")[-1].split(".")[0])
75
+
76
+ if re.search(r"\.\d+\.", name) is None:
77
+ non_hidden_modules.add(name.split(".")[-2])
78
+
79
+ trainable_layers = []
80
+ for module_name in finetuning_args.freeze_trainable_modules:
81
+ if module_name != "all" and module_name not in hidden_modules:
82
+ raise ValueError(
83
+ "Module {} is not found, please choose from {}".format(module_name, ", ".join(hidden_modules))
84
+ )
85
+
86
+ for idx in trainable_layer_ids:
87
+ trainable_layers.append(".{:d}.{}".format(idx, module_name if module_name != "all" else ""))
88
+
89
+ if finetuning_args.freeze_extra_modules:
90
+ for module_name in finetuning_args.freeze_extra_modules:
91
+ if module_name not in non_hidden_modules:
92
+ raise ValueError(
93
+ "Module {} is not found, please choose from {}".format(module_name, ", ".join(non_hidden_modules))
94
+ )
95
+
96
+ trainable_layers.append(module_name)
97
+
98
+ for name, param in model.named_parameters():
99
+ if any(trainable_layer in name for trainable_layer in trainable_layers):
100
+ if cast_trainable_params_to_fp32:
101
+ param.data = param.data.to(torch.float32)
102
+ else:
103
+ param.requires_grad_(False)
104
+
105
+ logger.info("Set trainable layers: {}".format(",".join(trainable_layers)))
106
+
107
+
108
+ def _setup_lora_tuning(
109
+ config: PretrainedConfig,
110
+ model: PreTrainedModel,
111
+ model_args: ModelArgs,
112
+ is_trainable: bool,
113
+ cast_trainable_params_to_fp32: bool,
114
+ ) -> PeftModel:
115
+ finetuning_args = model_args.finetuning_args
116
+ if is_trainable:
117
+ logger.info("Fine-tuning method: {}".format("DoRA" if finetuning_args.use_dora else "LoRA"))
118
+
119
+ adapter_to_resume = None
120
+
121
+ if model_args.adapter_name_or_path is not None:
122
+ is_mergeable = True
123
+ if getattr(model, "quantization_method", None): # merge lora in quantized model is unstable
124
+ assert len(model_args.adapter_name_or_path) == 1, "Quantized model only accepts a single adapter."
125
+ is_mergeable = False
126
+
127
+ if is_deepspeed_zero3_enabled():
128
+ assert len(model_args.adapter_name_or_path) == 1, "Cannot use multiple adapters in DeepSpeed ZeRO-3."
129
+ is_mergeable = False
130
+
131
+ if model_args.use_unsloth:
132
+ assert len(model_args.adapter_name_or_path) == 1, "Unsloth model only accepts a single adapter."
133
+ is_mergeable = False
134
+
135
+ if (is_trainable and not finetuning_args.create_new_adapter) or (not is_mergeable):
136
+ adapter_to_merge = model_args.adapter_name_or_path[:-1]
137
+ adapter_to_resume = model_args.adapter_name_or_path[-1]
138
+ else:
139
+ adapter_to_merge = model_args.adapter_name_or_path
140
+
141
+ init_kwargs = {
142
+ "subfolder": model_args.adapter_folder,
143
+ "offload_folder": model_args.offload_folder,
144
+ "cache_dir": model_args.cache_dir,
145
+ "revision": model_args.model_revision,
146
+ "token": model_args.hf_hub_token,
147
+ }
148
+
149
+ for adapter in adapter_to_merge:
150
+ model: LoraModel = PeftModel.from_pretrained(model, adapter, **init_kwargs)
151
+ model = model.merge_and_unload()
152
+
153
+ if len(adapter_to_merge) > 0:
154
+ logger.info("Merged {} adapter(s).".format(len(adapter_to_merge)))
155
+
156
+ if adapter_to_resume is not None: # resume lora training
157
+ if model_args.use_unsloth:
158
+ model = load_unsloth_peft_model(config, model_args, is_trainable=is_trainable)
159
+ else:
160
+ model = PeftModel.from_pretrained(model, adapter_to_resume, is_trainable=is_trainable, **init_kwargs)
161
+
162
+ logger.info("Loaded adapter(s): {}".format(",".join(model_args.adapter_name_or_path)))
163
+
164
+ if is_trainable and adapter_to_resume is None: # create new lora weights while training
165
+ if len(finetuning_args.lora_target) == 1 and finetuning_args.lora_target[0] == "all":
166
+ target_modules = find_all_linear_modules(model)
167
+ else:
168
+ target_modules = finetuning_args.lora_target
169
+
170
+ if model_args.resize_vocab and finetuning_args.additional_target is None:
171
+ input_embeddings = model.get_input_embeddings()
172
+ output_embeddings = model.get_output_embeddings()
173
+ module_names = set()
174
+ for name, module in model.named_modules():
175
+ if module in [input_embeddings, output_embeddings]:
176
+ module_names.add(name.split(".")[-1])
177
+
178
+ finetuning_args.additional_target = module_names
179
+ logger.warning("Vocab has been resized, add {} to trainable params.".format(",".join(module_names)))
180
+
181
+ peft_kwargs = {
182
+ "r": finetuning_args.lora_rank,
183
+ "target_modules": target_modules,
184
+ "lora_alpha": finetuning_args.lora_alpha,
185
+ "lora_dropout": finetuning_args.lora_dropout,
186
+ "use_rslora": finetuning_args.use_rslora,
187
+ "use_dora": finetuning_args.use_dora,
188
+ "modules_to_save": finetuning_args.additional_target,
189
+ }
190
+
191
+ if model_args.use_unsloth:
192
+ model = get_unsloth_peft_model(model, model_args, peft_kwargs)
193
+ else:
194
+ if finetuning_args.pissa_init:
195
+ if finetuning_args.pissa_iter == -1:
196
+ logger.info("Using PiSSA initialization.")
197
+ peft_kwargs["init_lora_weights"] = "pissa"
198
+ else:
199
+ logger.info("Using PiSSA initialization with FSVD steps {}.".format(finetuning_args.pissa_iter))
200
+ peft_kwargs["init_lora_weights"] = "pissa_niter_{}".format(finetuning_args.pissa_iter)
201
+
202
+ lora_config = LoraConfig(
203
+ task_type=TaskType.CAUSAL_LM,
204
+ inference_mode=False,
205
+ **peft_kwargs,
206
+ )
207
+ model = get_peft_model(model, lora_config)
208
+
209
+ if is_trainable and cast_trainable_params_to_fp32:
210
+ for param in filter(lambda p: p.requires_grad, model.parameters()):
211
+ param.data = param.data.to(torch.float32)
212
+
213
+ return model
214
+
215
+
216
+ def init_adapter(
217
+ config: PretrainedConfig, model: PreTrainedModel, model_args: ModelArgs, is_trainable: bool) -> PreTrainedModel:
218
+ r"""
219
+ Initializes the adapters.
220
+
221
+ Support full-parameter, freeze and LoRA training.
222
+
223
+ Note that the trainable parameters must be cast to float32.
224
+ """
225
+ finetuning_args = model_args.finetuning_args
226
+ if is_trainable and getattr(model, "quantization_method", None) is not None:
227
+ if finetuning_args.finetuning_type != "lora":
228
+ raise ValueError("Quantized models can only be used for the LoRA tuning.")
229
+
230
+ if finetuning_args.pissa_init:
231
+ raise ValueError("Cannot initialize PiSSA adapter on quantized models.")
232
+
233
+ # cast trainable parameters to float32 if:
234
+ # 1. is_trainable and not pure_bf16 and not badam and quantization_bit is not None (qlora)
235
+ # 2. is_trainable and not pure_bf16 and not badam and not zero3 and not fsdp (zero3 or fsdp already in fp32)
236
+ cast_trainable_params_to_fp32 = False
237
+ quantization_args = model_args.quantization_args
238
+ if not is_trainable:
239
+ pass
240
+ elif quantization_args.quantization_bit is None and (is_deepspeed_zero3_enabled() or is_fsdp_enabled()):
241
+ logger.info("ZeRO3 / FSDP detected, remaining trainable params in float32.")
242
+ else:
243
+ logger.info("Upcasting trainable params to float32.")
244
+ cast_trainable_params_to_fp32 = True
245
+
246
+ if finetuning_args.finetuning_type == "full":
247
+ _setup_full_tuning(model, is_trainable, cast_trainable_params_to_fp32)
248
+ elif finetuning_args.finetuning_type == "freeze":
249
+ _setup_freeze_tuning(model, finetuning_args, is_trainable, cast_trainable_params_to_fp32)
250
+ elif finetuning_args.finetuning_type == "lora":
251
+ model = _setup_lora_tuning(
252
+ config, model, model_args, is_trainable, cast_trainable_params_to_fp32
253
+ )
254
+ else:
255
+ raise NotImplementedError("Unknown finetuning type: {}.".format(finetuning_args.finetuning_type))
256
+
257
+ return model
@@ -0,0 +1,173 @@
1
+ from typing import Optional, Literal
2
+
3
+ from pydantic import Field, BaseModel
4
+
5
+ from distillflow.model.finetuning_args import FinetuningArgs
6
+
7
+ class ExportArguments(BaseModel):
8
+ r"""
9
+ Arguments pertaining to the model export.
10
+ """
11
+ export_quantization_bit: Optional[int] = Field(
12
+ default=None,
13
+ description="The number of bits to quantize the exported model."
14
+ )
15
+ export_quantization_dataset: Optional[str] = Field(
16
+ default=None,
17
+ description="Path to the dataset or dataset name to use in quantizing the exported model."
18
+ )
19
+ export_quantization_nsamples: int = Field(
20
+ default=128,
21
+ description="The number of samples used for quantization."
22
+ )
23
+ export_quantization_maxlen: int = Field(
24
+ default=1024,
25
+ description="The maximum length of the model inputs used for quantization."
26
+ )
27
+
28
+
29
+ class QuantizationArgs(ExportArguments, BaseModel):
30
+ r"""
31
+ Arguments pertaining to the quantization method.
32
+ """
33
+
34
+ quantization_method: Literal["bitsandbytes", "hqq", "eetq", "gptq"] = Field(
35
+ default="bitsandbytes",
36
+ description="Quantization method to use for on-the-fly quantization."
37
+ )
38
+ quantization_bit: Optional[int] = Field(
39
+ default=None,
40
+ description="The number of bits to quantize the model using on-the-fly quantization."
41
+ )
42
+ quantization_type: Literal["fp4", "nf4"] = Field(
43
+ default="nf4",
44
+ description="Quantization data type to use in bitsandbytes int4 training."
45
+ )
46
+ double_quantization: bool = Field(
47
+ default=True,
48
+ description="Whether or not to use double quantization in bitsandbytes int4 training."
49
+ )
50
+ quantization_device_map: Optional[Literal["auto"]] = Field(
51
+ default=None,
52
+ description="Device map used to infer the 4-bit quantized model, needs bitsandbytes>=0.43.0."
53
+ )
54
+
55
+ model_config = {
56
+ "extra": "forbid"
57
+ }
58
+
59
+
60
+ class ModelArgs(BaseModel):
61
+ r"""
62
+ Arguments pertaining to which model/config/tokenizer we are going to fine-tune or infer.
63
+ """
64
+
65
+ model_name_or_path: str = Field(
66
+ description="Path to the model weight or identifier from huggingface.co/models or modelscope.cn/models.",
67
+ examples=["Qwen/Qwen2-0.5B"]
68
+ )
69
+ adapter_name_or_path: Optional[str] = Field(
70
+ default=None,
71
+ description="Path to the adapter weight or identifier from huggingface.co/models. "
72
+ "Use commas to separate multiple adapters."
73
+ )
74
+ adapter_folder: Optional[str] = Field(
75
+ default=None,
76
+ description="The folder containing the adapter weights to load."
77
+ )
78
+ cache_dir: Optional[str] = Field(
79
+ default=None,
80
+ description="Where to store the pre-trained models downloaded from huggingface.co or modelscope.cn."
81
+ )
82
+ resize_vocab: bool = Field(
83
+ default=False,
84
+ description="Whether or not to resize the tokenizer vocab and the embedding layers."
85
+ )
86
+ split_special_tokens: bool = Field(
87
+ default=False,
88
+ description="Whether or not the special tokens should be split during the tokenization process."
89
+ )
90
+ new_special_tokens: Optional[str] = Field(
91
+ default=None,
92
+ description="Special tokens to be added into the tokenizer. Use commas to separate multiple tokens."
93
+ )
94
+ model_revision: str = Field(
95
+ default="main",
96
+ description="The specific model version to use (can be a branch name, tag name or commit id)."
97
+ )
98
+ low_cpu_mem_usage: bool = Field(
99
+ default=True,
100
+ description="Whether or not to use memory-efficient model loading."
101
+ )
102
+ flash_attn: Literal["auto", "disabled", "sdpa", "fa2"] = Field(
103
+ default="auto",
104
+ description="Enable FlashAttention for faster training and inference."
105
+ )
106
+ use_unsloth: bool = Field(
107
+ default=False,
108
+ description="Whether or not to use unsloth's optimization for the LoRA training."
109
+ )
110
+ use_unsloth_gc: bool = Field(
111
+ default=False,
112
+ description="Whether or not to use unsloth's gradient checkpointing."
113
+ )
114
+ enable_liger_kernel: bool = Field(
115
+ default=False,
116
+ description="Whether or not to enable liger kernel for faster training."
117
+ )
118
+ disable_gradient_checkpointing: bool = Field(
119
+ default=False,
120
+ description="Whether or not to disable gradient checkpointing."
121
+ )
122
+ upcast_layernorm: bool = Field(
123
+ default=False,
124
+ description="Whether or not to upcast the layernorm weights in fp32."
125
+ )
126
+ upcast_lmhead_output: bool = Field(
127
+ default=False,
128
+ description="Whether or not to upcast the output of lm_head in fp32."
129
+ )
130
+ offload_folder: str = Field(
131
+ default="offload",
132
+ description="Path to offload model weights."
133
+ )
134
+ use_cache: bool = Field(
135
+ default=True,
136
+ description="Whether or not to use KV cache in generation."
137
+ )
138
+ infer_dtype: Literal["auto", "float16", "bfloat16", "float32"] = Field(
139
+ default="auto",
140
+ description="Data type for model weights and activations at inference."
141
+ )
142
+ hf_hub_token: Optional[str] = Field(
143
+ default=None,
144
+ description="Auth token to log in with Hugging Face Hub."
145
+ )
146
+ print_param_status: bool = Field(
147
+ default=False,
148
+ description="For debugging purposes, print the status of the parameters in the model."
149
+ )
150
+ output_attentions: bool = Field(
151
+ default=False,
152
+ description="Whether to output the attention mask for the model during forward pass"
153
+ )
154
+ quantization_args: Optional[QuantizationArgs] = Field(
155
+ default=QuantizationArgs(),
156
+ description="Arguments related to quantization"
157
+ )
158
+ finetuning_args: Optional[FinetuningArgs] = Field(
159
+ default=FinetuningArgs(),
160
+ description="Arguments related to finetuning (LoRA, Freeze etc.)"
161
+ )
162
+ deepspeed_config: str = Field(
163
+ default='./deepspeed/zero0.json',
164
+ description="Path to deepspeed config file. Defaults to stage-0 no optimization (Training/Inference)."
165
+ )
166
+ chat_template: Optional[str] = Field(
167
+ default=None,
168
+ description="Chat template to use when loading the model's tokenizer"
169
+ )
170
+
171
+ model_config = {
172
+ "extra": "forbid"
173
+ }