* Update llama.py * offload * Update llama.py * Update llama.py * Update llama.py * Update llama.py * Update llama.py * Update llama.py * Update llama.py * continued pretraining trainer * Update trainer.py * Update trainer.py * Update trainer.py * Update trainer.py * is_bfloat16_supported * Update __init__.py * Update README.md * Update llama.py * is_bfloat16_supported * Update __init__.py * Mistral v3 * Phi 3 medium * Update chat_templates.py * Update chat_templates.py * Phi-3 * Update save.py * Update README.md Mistral v3 to Mistral v0.3 * Untrained tokens * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update llama.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update save.py * Update save.py * Update save.py * checkpoint * Update _utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update tokenizer_utils.py * Update llama.py * accelerate * Update _utils.py * Update _utils.py * Update _utils.py * Update _utils.py * Update _utils.py * Update _utils.py * Update _utils.py * Update tokenizer_utils.py * train_dataloader * Update llama.py * Update llama.py * Update llama.py * use_fast_convert * Update save.py * Update save.py * Update save.py * Update save.py * remove_special_tokens * Ollama * Update chat_templates.py * Update chat_templates.py * Update chat_templates.py * Update llama.py * Update chat_templates.py * Support bfloat16 GGUF * Update save.py * Update llama.py * fast_forward_inference * Update mapper.py * Update loader.py * Update llama.py * Update tokenizer_utils.py * info * edits * Create chat template * Fix tokenizer * Update tokenizer_utils.py * fix case where gguf saving fails due to first_conversion dtype (#630) * Support revision parameter in FastLanguageModel.from_pretrained (#629) * support `revision` parameter * match unsloth formatting of named parameters * clears any selected_adapters before calling internal_model.save_pretrained (#609) * Update __init__.py (#602) Check for incompatible modules before importing unsloth * Fixed unsloth/tokenizer_utils.py for chat training (#604) * Add GGML saving option to Unsloth for easier Ollama model creation and testing. (#345) * Add save to llama.cpp GGML to save.py. * Fix conversion command and path of convert to GGML function. * Add autosaving lora to the GGML function * Create lora save function for conversion to GGML * Test fix #2 for saving lora * Test fix #3 to save the lora adapters to convert to GGML * Remove unwated tokenizer saving for conversion to ggml and added a few print statements. * Needed tokenizer for saving, added it back, also made it more unslothy style by having positional arguments, and added a few messages. * Positional arguments didn't work out, so reverted to older version of the code, and added a few comments. * Test fix 1 for arch * Test fix 2 new Mistral error. * Test fix 3 * Revert to old version for testing. * Upload issue test fix 1 * Fix 2 uploading ggml * Positional ags added. * Temporray remove positional args * Fix upload again!!! * Add print statements and fix link * Make the calling name better * Create local saving for GGML * Add choosing directory to save local GGML. * Fix lil variable error in the save_to_custom_dir func * docs: Add LoraConfig parameters documentation (#619) * llama.cpp failing (#371) llama.cpp is failing to generate quantize versions for the trained models. Error: ```bash You might have to compile llama.cpp yourself, then run this again. You do not need to close this Python program. Run the following commands in a new terminal: You must run this in the same folder as you're saving your model. git clone https://github.com/ggerganov/llama.cpp cd llama.cpp && make clean && LLAMA_CUDA=1 make all -j Once that's done, redo the quantization. ``` But when i do clone this with recursive it works. Co-authored-by: Daniel Han <danielhanchen@gmail.com> * fix libcuda_dirs import for triton 3.0 (#227) * fix libcuda_dirs import for triton 3.0 * Update __init__.py * Update __init__.py --------- Co-authored-by: Daniel Han <danielhanchen@gmail.com> * Update save.py * Update __init__.py * Update fast_lora.py * Update save.py * Update save.py * Update save.py * Update loader.py * Update save.py * Update save.py * quantize now llama-quantize * Update chat_templates.py * Update loader.py * Update mapper.py * Update __init__.py * embedding size * Update qwen2.py * docs * Update README.md * Update qwen2.py * README: Fix minor typo. (#559) * README: Fix minor typo. One-character typo fix while reading. * Update README.md --------- Co-authored-by: Daniel Han <danielhanchen@gmail.com> * Update mistral.py * Update qwen2.py * Update qwen2.py * Update qwen2.py * Update llama.py * Update llama.py * Update llama.py * Update README.md * FastMistralModel * Update mistral.py * Update mistral.py * Update mistral.py * Update mistral.py * Update mistral.py * Auto check rope scaling * Update llama.py * Update llama.py * Update llama.py * GPU support * Typo * Update gemma.py * gpu * Multiple GGUF saving * Update save.py * Update save.py * check PEFT and base * Update llama.py * Update llama.py * Update llama.py * Update llama.py * Update llama.py * Update chat_templates.py --------- Co-authored-by: Michael Han <107991372+shimmyshimmer@users.noreply.github.com> Co-authored-by: Eliot Hall <60240707+chrehall68@users.noreply.github.com> Co-authored-by: Rickard Edén <rickardeden@gmail.com> Co-authored-by: XiaoYang <xyangk@gmail.com> Co-authored-by: Oseltamivir <58582368+Oseltamivir@users.noreply.github.com> Co-authored-by: mahiatlinux <110882203+mahiatlinux@users.noreply.github.com> Co-authored-by: Sébastien De Greef <sebdg@binarycompany.com> Co-authored-by: Alberto Ferrer <albertof@barrahome.org> Co-authored-by: Thomas Viehmann <tv.github-private@beamnet.de> Co-authored-by: Walter Korman <lemurware@gmail.com>
222 lines
9 KiB
Python
222 lines
9 KiB
Python
# Copyright 2023-present Daniel Han-Chen & the Unsloth team. All rights reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from .llama import FastLlamaModel, logger
|
|
from .mistral import FastMistralModel
|
|
from .qwen2 import FastQwen2Model
|
|
from transformers import AutoConfig
|
|
from transformers import __version__ as transformers_version
|
|
from peft import PeftConfig, PeftModel
|
|
from .mapper import INT_TO_FLOAT_MAPPER, FLOAT_TO_INT_MAPPER
|
|
import os
|
|
|
|
# https://github.com/huggingface/transformers/pull/26037 allows 4 bit loading!
|
|
major, minor = transformers_version.split(".")[:2]
|
|
major, minor = int(major), int(minor)
|
|
SUPPORTS_FOURBIT = (major > 4) or (major == 4 and minor >= 37)
|
|
SUPPORTS_GEMMA = (major > 4) or (major == 4 and minor >= 38)
|
|
if SUPPORTS_GEMMA:
|
|
from .gemma import FastGemmaModel
|
|
del major, minor
|
|
|
|
|
|
def _get_model_name(model_name, load_in_4bit = True):
|
|
|
|
if not SUPPORTS_FOURBIT and model_name in INT_TO_FLOAT_MAPPER:
|
|
model_name = INT_TO_FLOAT_MAPPER[model_name.lower()]
|
|
logger.warning_once(
|
|
f"Unsloth: Your transformers version of {transformers_version} does not support native "\
|
|
f"4bit loading.\nThe minimum required version is 4.37.\n"\
|
|
f'Try `pip install --upgrade "transformers>=4.37"`\n'\
|
|
f"to obtain the latest transformers build, then restart this session.\n"\
|
|
f"For now, we shall load `{model_name}` instead (still 4bit, just slower downloading)."
|
|
)
|
|
|
|
elif not load_in_4bit and model_name in INT_TO_FLOAT_MAPPER:
|
|
new_model_name = INT_TO_FLOAT_MAPPER[model_name.lower()]
|
|
# logger.warning_once(
|
|
# f"Unsloth: You passed in `{model_name}` which is a 4bit model, yet you set\n"\
|
|
# f"`load_in_4bit = False`. We shall load `{new_model_name}` instead."
|
|
# )
|
|
model_name = new_model_name
|
|
|
|
elif load_in_4bit and SUPPORTS_FOURBIT and model_name in FLOAT_TO_INT_MAPPER:
|
|
new_model_name = FLOAT_TO_INT_MAPPER[model_name.lower()]
|
|
# logger.warning_once(
|
|
# f"Unsloth: You passed in `{model_name}` and `load_in_4bit = True`.\n"\
|
|
# f"We shall load `{new_model_name}` for 4x faster loading."
|
|
# )
|
|
model_name = new_model_name
|
|
pass
|
|
|
|
return model_name
|
|
pass
|
|
|
|
|
|
class FastLanguageModel(FastLlamaModel):
|
|
@staticmethod
|
|
def from_pretrained(
|
|
model_name = "unsloth/llama-3-8b-bnb-4bit",
|
|
max_seq_length = None,
|
|
dtype = None,
|
|
load_in_4bit = True,
|
|
token = None,
|
|
device_map = "sequential",
|
|
rope_scaling = None,
|
|
fix_tokenizer = True,
|
|
trust_remote_code = False,
|
|
use_gradient_checkpointing = "unsloth",
|
|
resize_model_vocab = None,
|
|
revision = None,
|
|
*args, **kwargs,
|
|
):
|
|
if token is None and "HF_TOKEN" in os.environ:
|
|
token = os.environ["HF_TOKEN"]
|
|
|
|
if token is None and "HUGGINGFACE_TOKEN" in os.environ:
|
|
token = os.environ["HUGGINGFACE_TOKEN"]
|
|
|
|
old_model_name = model_name
|
|
model_name = _get_model_name(model_name, load_in_4bit)
|
|
|
|
# First check if it's a normal model via AutoConfig
|
|
try:
|
|
model_config = AutoConfig.from_pretrained(model_name, token = token, revision = revision)
|
|
is_model = True
|
|
except:
|
|
is_model = False
|
|
try:
|
|
peft_config = PeftConfig .from_pretrained(model_name, token = token, revision = revision)
|
|
is_peft = True
|
|
except:
|
|
is_peft = False
|
|
|
|
# Cannot be both!
|
|
if is_model and is_peft:
|
|
raise RuntimeError(
|
|
"Unsloth: You repo has a LoRA adapter and a base model.\n"\
|
|
"You have 2 files `config.json` and `adapter_config.json`.\n"\
|
|
"We must only allow one config file.\n"\
|
|
"Please separate the LoRA and base models to 2 repos."
|
|
)
|
|
elif not is_model and not is_peft:
|
|
raise RuntimeError(
|
|
f"Unsloth: `{model_name}` is not a base model or a PEFT model.\n"\
|
|
"We could not locate a `config.json` or `adapter_config.json` file"
|
|
)
|
|
pass
|
|
|
|
# Get base model for PEFT:
|
|
if is_peft:
|
|
# Check base model again for PEFT
|
|
model_name = _get_model_name(peft_config.base_model_name_or_path, load_in_4bit)
|
|
model_config = AutoConfig.from_pretrained(model_name, token = token, revision = revision)
|
|
pass
|
|
|
|
model_type = model_config.model_type
|
|
|
|
if model_type == "llama": dispatch_model = FastLlamaModel
|
|
elif model_type == "mistral": dispatch_model = FastMistralModel
|
|
elif model_type == "gemma":
|
|
if not SUPPORTS_GEMMA:
|
|
raise RuntimeError(
|
|
f"Unsloth: Your transformers version of {transformers_version} does not support Gemma.\n"\
|
|
f"The minimum required version is 4.38.\n"\
|
|
f'Try `pip install --upgrade "transformers>=4.38"`\n'\
|
|
f"to obtain the latest transformers build, then restart this session."\
|
|
)
|
|
dispatch_model = FastGemmaModel
|
|
elif model_type == "qwen2":
|
|
dispatch_model = FastQwen2Model
|
|
else:
|
|
raise NotImplementedError(
|
|
f"Unsloth: {model_name} not supported yet!\n"\
|
|
"Make an issue to https://github.com/unslothai/unsloth!",
|
|
)
|
|
pass
|
|
|
|
# Check if this is local model since the tokenizer gets overwritten
|
|
if os.path.exists(os.path.join(old_model_name, "tokenizer_config.json")) and \
|
|
os.path.exists(os.path.join(old_model_name, "tokenizer.json")) and \
|
|
os.path.exists(os.path.join(old_model_name, "special_tokens_map.json")):
|
|
|
|
tokenizer_name = old_model_name
|
|
else:
|
|
tokenizer_name = None
|
|
pass
|
|
|
|
model, tokenizer = dispatch_model.from_pretrained(
|
|
model_name = model_name,
|
|
max_seq_length = max_seq_length,
|
|
dtype = dtype,
|
|
load_in_4bit = load_in_4bit,
|
|
token = token,
|
|
device_map = device_map,
|
|
rope_scaling = rope_scaling,
|
|
fix_tokenizer = fix_tokenizer,
|
|
model_patcher = dispatch_model,
|
|
tokenizer_name = tokenizer_name,
|
|
trust_remote_code = trust_remote_code,
|
|
revision = revision if not is_peft else None,
|
|
*args, **kwargs,
|
|
)
|
|
|
|
if resize_model_vocab is not None:
|
|
model.resize_token_embeddings(resize_model_vocab)
|
|
pass
|
|
|
|
# In case the model supports tagging, add the unsloth tag.
|
|
if hasattr(model, "add_model_tags"):
|
|
model.add_model_tags(["unsloth",])
|
|
pass
|
|
if hasattr(tokenizer, "add_model_tags"):
|
|
tokenizer.add_model_tags(["unsloth",])
|
|
pass
|
|
|
|
if load_in_4bit:
|
|
# Fix up bitsandbytes config
|
|
quantization_config = \
|
|
{
|
|
# Sometimes torch_dtype is not a string!!
|
|
"bnb_4bit_compute_dtype" : model.config.to_dict()["torch_dtype"],
|
|
"bnb_4bit_quant_type" : "nf4",
|
|
"bnb_4bit_use_double_quant" : True,
|
|
"llm_int8_enable_fp32_cpu_offload" : False,
|
|
"llm_int8_has_fp16_weight" : False,
|
|
"llm_int8_skip_modules" : None,
|
|
"llm_int8_threshold" : 6.0,
|
|
"load_in_4bit" : True,
|
|
"load_in_8bit" : False,
|
|
"quant_method" : "bitsandbytes",
|
|
}
|
|
model.config.update({"quantization_config" : quantization_config})
|
|
pass
|
|
|
|
if is_peft:
|
|
# From https://github.com/huggingface/peft/issues/184
|
|
# Now add PEFT adapters
|
|
model.enable_input_require_grads()
|
|
model = PeftModel.from_pretrained(
|
|
model,
|
|
old_model_name,
|
|
token = token,
|
|
revision = revision,
|
|
is_trainable = True,
|
|
)
|
|
# Patch it as well!
|
|
model = dispatch_model.patch_peft_model(model, use_gradient_checkpointing)
|
|
pass
|
|
return model, tokenizer
|
|
pass
|
|
pass
|