示例1:Qlora训练Qwen2.5
参考脚本:https://github.com/QwenLM/Qwen/blob/main/recipes/finetune/deepspeed/finetune_qlora_multi_gpu.ipynb
训练命令如下:
!torchrun --nproc_per_node 2 --nnodes 1 --node_rank 0 --master_addr localhost --master_port 6601 ../../finetune.py \
--model_name_or_path "Qwen/Qwen-1_8B-Chat-Int4/" \
--data_path "Belle_sampled_qwen.json" \
--bf16 True \
--output_dir "output_qwen" \
--num_train_epochs 5 \
--per_device_train_batch_size 1 \
--per_device_eval_batch_size 1 \
--gradient_accumulation_steps 16 \
--evaluation_strategy "no" \
--save_strategy "steps" \
--save_steps 1000 \
--save_total_limit 10 \
--learning_rate 1e-5 \
--weight_decay 0.1 \
--adam_beta2 0.95 \
--warmup_ratio 0.01 \
--lr_scheduler_type "cosine" \
--logging_steps 1 \
--report_to "none" \
--model_max_length 512 \
--gradient_checkpointing True \
--lazy_preprocess True \
--deepspeed "../../finetune/ds_config_zero2.json" \
--use_lora \
--q_lora
选择底座模型
上面命令选用的Qwen/Qwen-1_8B-Chat-Int4/
加载模型
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
# Load model and tokenizer
model = transformers.AutoModelForCausalLM.from_pretrained(
model_args.model_name_or_path,
config=config,
cache_dir=training_args.cache_dir,
device_map=device_map,
trust_remote_code=True,
quantization_config=GPTQConfig(
bits=4, disable_exllama=True
)
if training_args.use_lora and lora_args.q_lora
else None,
**model_load_kwargs,
)
tokenizer = transformers.AutoTokenizer.from_pretrained(
model_args.model_name_or_path,
cache_dir=training_args.cache_dir,
model_max_length=training_args.model_max_length,
padding_side="right",
use_fast=False,
trust_remote_code=True,
)
tokenizer.pad_token_id = tokenizer.eod_id
if training_args.use_lora:
if lora_args.q_lora or is_chat_model:
modules_to_save = None
else:
modules_to_save = ["wte", "lm_head"]
lora_config = LoraConfig(
r=lora_args.lora_r,
lora_alpha=lora_args.lora_alpha,
target_modules=lora_args.lora_target_modules,
lora_dropout=lora_args.lora_dropout,
bias=lora_args.lora_bias,
task_type="CAUSAL_LM",
modules_to_save=modules_to_save # This argument serves for adding new tokens.
)
if lora_args.q_lora:
model = prepare_model_for_kbit_training(
model, use_gradient_checkpointing=training_args.gradient_checkpointing
)
model = get_peft_model(model, lora_config)
# Print peft trainable params
model.print_trainable_parameters()
if training_args.gradient_checkpointing:
model.enable_input_require_grads()
我给大家准备了一份全套的《AI大模型零基础入门+进阶学习资源包》,包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。😝有需要的小伙伴,可以VX扫描下方二维码免费领取🆓
prepare_model_for_kbit_training函数说明
调用 prepare_model_for_kbit_training() 函数来预处理用于训练的量化模型。我们在peft库中可以看到源码:
def prepare_model_for_kbit_training(model, use_gradient_checkpointing=True, gradient_checkpointing_kwargs=None):
r"""
Note this method only works for `transformers` models.
This method wraps the entire protocol for preparing a model before running a training. This includes:
1- Cast the layernorm in fp32 2- making output embedding layer require grads 3- Add the upcasting of the lm
head to fp32
Args:
model (`transformers.PreTrainedModel`):
The loaded model from `transformers`
use_gradient_checkpointing (`bool`, *optional*, defaults to `True`):
If True, use gradient checkpointing to save memory at the expense of slower backward pass.
gradient_checkpointing_kwargs (`dict`, *optional*, defaults to `None`):
Keyword arguments to pass to the gradient checkpointing function, please refer to the documentation of
`torch.utils.checkpoint.checkpoint` for more details about the arguments that you can pass to that method.
Note this is only available in the latest transformers versions (> 4.34.1).
"""
loaded_in_kbit = getattr(model, "is_loaded_in_8bit", False) or getattr(model, "is_loaded_in_4bit", False)
is_gptq_quantized = getattr(model, "quantization_method", None) == "gptq"
is_aqlm_quantized = getattr(model, "quantization_method", None) == "aqlm"
is_eetq_quantized = getattr(model, "quantization_method", None) == "eetq"
is_hqq_quantized = getattr(model, "quantization_method", None) == "hqq" or getattr(model, "hqq_quantized", False)
if gradient_checkpointing_kwargs is None:
gradient_checkpointing_kwargs = {}
for name, param in model.named_parameters():
# freeze base model's layers
param.requires_grad = False
if not is_gptq_quantized and not is_aqlm_quantized and not is_eetq_quantized and not is_hqq_quantized:
# cast all non INT8 parameters to fp32
for param in model.parameters():
if (
(param.dtype == torch.float16) or (param.dtype == torch.bfloat16)
) and param.__class__.__name__ != "Params4bit":
param.data = param.data.to(torch.float32)
if (
loaded_in_kbit or is_gptq_quantized or is_aqlm_quantized or is_eetq_quantized or is_hqq_quantized
) and use_gradient_checkpointing:
# When having `use_reentrant=False` + gradient_checkpointing, there is no need for this hack
if "use_reentrant" not in gradient_checkpointing_kwargs or gradient_checkpointing_kwargs["use_reentrant"]:
# For backward compatibility
if hasattr(model, "enable_input_require_grads"):
model.enable_input_require_grads()
else:
def make_inputs_require_grad(module, input, output):
output.requires_grad_(True)
model.get_input_embeddings().register_forward_hook(make_inputs_require_grad)
# To support older transformers versions, check if the model supports gradient_checkpointing_kwargs
_supports_gc_kwargs = "gradient_checkpointing_kwargs" in list(
inspect.signature(model.gradient_checkpointing_enable).parameters
)
if not _supports_gc_kwargs and len(gradient_checkpointing_kwargs) > 0:
warnings.warn(
"gradient_checkpointing_kwargs is not supported in this version of transformers. The passed kwargs will be ignored."
" if you want to use that feature, please upgrade to the latest version of transformers.",
FutureWarning,
)
gc_enable_kwargs = (
{} if not _supports_gc_kwargs else {"gradient_checkpointing_kwargs": gradient_checkpointing_kwargs}
)
# enable gradient checkpointing for memory efficiency
model.gradient_checkpointing_enable(**gc_enable_kwargs)
return model
这个函数prepare_model_for_kbit_training
主要用于准备一个transformers
库的预训练模型(PreTrainedModel
),以便进行低比特(k-bit)量化训练或其他特定情况下的训练。函数提供了一些设置和优化步骤,使模型更适合量化训练环境。
核心功能:
-
将 LayerNorm 层参数转换为 FP32(32 位浮点数)。
-
设置模型的输出嵌入层参数为需要计算梯度(即使冻结了其他参数,嵌入层可以被微调)。
-
将语言模型头(lm head)的计算强制提升为 FP32,以提高训练的数值稳定性。
参数说明:
-
model
: -
一个从
transformers
加载的预训练模型对象(如 GPT、BERT)。 -
use_gradient_checkpointing
: -
是否启用梯度检查点功能,用于在内存和计算速度之间进行权衡(减少内存占用,牺牲反向传播速度)。
-
gradient_checkpointing_kwargs
: -
一个可选字典,传递给梯度检查点的配置参数。需要
transformers
版本大于4.34.1
才支持。
函数分步骤解析:
- 识别模型的量化情况:
- 检查模型是否被加载为低比特格式(8 位或 4 位),以及是否采用了特定的量化方法(如 GPTQ、AQLM、EETQ 或 HQQ 等)。
- 冻结所有参数:
- 遍历模型的所有参数,设置
requires_grad = False
,即冻结所有层,不计算梯度。这是低比特量化训练常见的步骤,用于只训练部分特定参数。
- 非量化模型处理:
- 如果模型未被量化,所有的非 INT8 参数(比如 FP16 或 BF16)都会被强制转换为 FP32。这是为了确保数值稳定性,特别是在低精度下训练时。
- 启用梯度检查点(可选):
-
检查是否需要启用输入张量的梯度。对于某些老版本的
transformers
,可能需要通过forward_hook
的方式显式设置输入张量的requires_grad
。 -
检查模型是否支持
gradient_checkpointing_kwargs
,并发出警告(如果版本过旧)。 -
如果模型是低比特量化模型且启用了
use_gradient_checkpointing
:
- 启用梯度检查点功能:
- 调用模型的
gradient_checkpointing_enable
方法,根据是否支持额外参数传递对应配置,最终节省内存。
输出:
经过此函数处理后的模型:
-
更适合在量化或低精度(FP16/BF16)环境下训练。
-
非量化模型的关键参数被转换为 FP32,以提升稳定性。
-
冻结大部分参数,只保留需要训练的部分。
-
在内存有限的情况下启用梯度检查点功能,优化 GPU 显存占用。
使用场景:
这个函数特别适用于以下情境:
-
使用低比特(如 8-bit 或 4-bit)的模型进行训练。
-
微调大模型时希望通过梯度检查点功能减少显存消耗。
-
对特定参数(如语言模型头或嵌入层)进行微调,而冻结其他层的参数。
合并模型
这里注意:合并模型需要使用Base模型合并,不是量化模型
from modelscope.hub.snapshot_download import snapshot_download
snapshot_download('Qwen/Qwen-1_8B-Chat', cache_dir='.', revision='master')
from transformers import AutoModelForCausalLM
from peft import PeftModel
import torch
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-1_8B-Chat/", torch_dtype=torch.float16, device_map="auto", trust_remote_code=True)
model = PeftModel.from_pretrained(model, "output_qwen/")
merged_model = model.merge_and_unload()
merged_model.save_pretrained("output_qwen_merged", max_shard_size="2048MB", safe_serialization=True)
在 LoRA 和 Q-LoRA 的训练过程中,仅保存了适配器参数(adapter parameters),而不是完整的模型权重。需要注意的是,权重不能直接合并到量化模型(quantized models)中。相反,我们可以基于原始的非量化模型来合并权重。
这意味着,合并权重的过程需要加载原始的基础模型,并将微调的适配器参数与之结合,生成一个新的模型权重文件。以下是实现权重合并的示例代码:
示例2:Qlora微调Llama
fine-tuning-llama-2-using-lora-and-qlora-a-comprehensive-guide
选择模型
model_name = "NousResearch/Llama-2-7b-chat-hf"
dataset_name = "mlabonne/guanaco-llama2-1k"
new_model = "Llama-2-7b-chat-finetune-qlora"
参数设置
lora_r = 64 #lora attention dimension/ rank
lora_alpha = 16 #lora scaling parameter
lora_dropout = 0.1 #lora dropout probability
量化设置
use_4bit = True
bnb_4bit_compute_dtype = "float16"
bnb_4bit_quant_type = "nf4"
use_nested_quant = False
我给大家准备了一份全套的《AI大模型零基础入门+进阶学习资源包》,包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。😝有需要的小伙伴,可以VX扫描下方二维码免费领取🆓
BitsAndBytes 配置项中文解释
**use_4bit = True**
-
功能: 启用 4 位量化(4-bit quantization)以减少模型的内存占用。
-
作用: 将模型参数从通常的高精度(如 FP32 或 FP16)压缩为 4 位表示,显著降低显存使用。
**bnb_4bit_compute_dtype = "float16"**
-
功能: 指定训练过程中用于计算的精度类型,这里选择
float16
(16 位浮点数)。 -
作用: 即使模型参数被量化为 4 位,计算时仍使用更高的精度(FP16),以确保训练过程中的数值稳定性和性能。
**bnb_4bit_quant_type = "nf4"**
-
功能: 设置 4 位量化的类型,
nf4
(Normalized Float 4)是一种常见的选择。 -
作用:
nf4
是一种专门设计的量化格式,相比传统的量化类型,能够更好地保留模型权重的数值分布特性,提升量化模型的性能。
**use_nested_quant = False**
-
功能: 是否启用嵌套量化(Nested Quantization),即“双重量化”。
-
作用: 嵌套量化是一种更进一步的量化技术,可以进一步减少内存占用,但可能会对模型性能有一定影响。这里选择禁用该功能。
这组配置是为了使用BitsAndBytes库实现4 位量化,目的是在显存资源有限的情况下训练大型模型,同时尽量保持模型性能。具体设置包括:
-
启用 4 位量化来压缩模型权重。
-
使用 FP16 进行计算,平衡计算速度与精度。
-
采用**
**nf4**
量化类型**来优化量化模型的效果。 -
禁用嵌套量化以避免额外的复杂性或性能损失。
此配置非常适合需要在低资源环境下进行高效训练的场景。
加载模型
#load dataset
dataset = load_dataset(dataset_name,split = "train")
#load tokenizer and model with QLoRA config
compute_dtype = getattr(torch, bnb_4bit_compute_dtype)
bnb_config = BitsAndBytesConfig(
load_in_4bit = use_4bit,
bnb_4bit_quant_type = bnb_4bit_quant_type,
bnb_4bit_compute_dtype = compute_dtype,
bnb_4bit_use_double_quant = use_nested_quant,)
#cheking GPU compatibility with bfloat16
if compute_dtype == torch.float16 and use_4bit:
major, _ = torch.cuda.get_device_capability()
if major >= 8:
print("="*80)
print("Your GPU supports bfloat16, you are getting accelerate training with bf16= True")
print("="*80)
#load base model
model = AutoModelForCausalLM.from_pretrained(
model_name,
quantization_config = bnb_config,
device_map = device_map,
)
model.config.use_cache = False
model.config.pretraining_tp = 1
合并模型
同样使用底座合并模型
# Reload model in FP16 and merge it with LoRA weights
base_model = AutoModelForCausalLM.from_pretrained(
model_name,
low_cpu_mem_usage=True,
return_dict=True,
torch_dtype=torch.float16,
device_map=device_map,
)
model = PeftModel.from_pretrained(base_model, new_model)
model = model.merge_and_unload()
# Reload tokenizer to save it
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
tokenizer.pad_token = tokenizer.eos_token
tokenizer.padding_side = "right"
总结
模型为量化模型
-
训练:需要prepare_model_for_kbit_training(model)
-
合并:加载基础模型进行合并qlora
-
推理:加载base模型然后加载qlora权重也可以加载合并之后的
模型为基础模型
-
训练:加载需要使用bnb对基础模型量化
-
合并:加载基础模型进行合并qlora
-
推理:加载base模型然后加载qlora权重也可以加载合并之后的
如何学习AI大模型 ?
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,故此将并将重要的AI大模型资料。包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。【保证100%免费】🆓
对于0基础小白入门:
如果你是零基础小白,想快速入门大模型是可以考虑的。
一方面是学习时间相对较短,学习内容更全面更集中。
二方面是可以根据这些资料规划好学习计划和方向。
😝有需要的小伙伴,可以VX扫描下方二维码免费领取🆓
👉1.大模型入门学习思维导图👈
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
对于从来没有接触过AI大模型的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。(全套教程扫描领取哈)
👉2.AGI大模型配套视频👈
很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,每个章节都是当前板块的精华浓缩。
👉3.大模型实际应用报告合集👈
这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。(全套教程扫描领取哈)
👉4.大模型落地应用案例PPT👈
光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。(全套教程扫描领取哈)
👉5.大模型经典学习电子书👈
随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。(全套教程扫描领取哈)
👉6.大模型面试题&答案👈
截至目前大模型已经超过200个,在大模型纵横的时代,不仅大模型技术越来越卷,就连大模型相关的岗位和面试也开始越来越卷了。为了让大家更容易上车大模型算法赛道,我总结了大模型常考的面试题。(全套教程扫描领取哈)
👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;
• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;
• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;
• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习
这份完整版的 AI 大模型学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费】
😝有需要的小伙伴,可以Vx扫描下方二维码免费领取🆓