
在在大型语言模型 (LLM) 时代,我们需要了解量化技术才能在本地 PC 上运行它们,由于它们的大小超级大。不过,存在许多实现量化的技术,因此像我这样的初学者很容易感到困惑。因此,在这篇博客中,我将介绍我们必须知道的主要量化技术,并解释如何在 Google Colab 环境中实现它们。
量化是一种将浮点数映射到低位整数的技术。它在减少 LLM 模型大小和推理成本方面超级有效。例如,当我们将 float32 中大约 4 x 7B = 28GB 大小的 7B 模型量化为 float16 时,我们可以减少 2 x 7B = 14GB 的大小。如果我们可以将 float32 模型量化为 int8,则大小将为 1 x 7B = 7GB!下图显示了每种数据类型的位表明。它们是用于 LLM 的常见数据类型。

LLM 使用的常见数据类型
目前,我们怎样才能真正减少位大小?答案是将值从一种数据类型“舍入”为另一种数据类型。为了具体理解量化概念,我们将学习两种舍入值的基本方法:零点量化和绝对最大量化。
Zero-point量化
零点量化将给定数据中的最小值和最大值映射到目标数据类型范围的最小值和最大值。让我们思考将 FP16 值转换为 Int8。此量化图示如下所示。

文献采用的零点量化图像
我们希望将数据缩放到 Int8 比例(本例中为 0 ~ 255)。因此,我们计算原始比例中的相对值,并通过乘以 Int8 比例(即 255)来重新缩放它们。公式可以描述如下。

零点量化的舍入公式
n是用于量化的位数(本例中为 8)。请注意,如果我们想将值重新缩放为 -127 ~ 127,我们会从上述结果中减去 127,然后对其进行舍入。
该方法可以比其他量化方法更准确地表明原始数据。另一方面,该方法需要更复杂的计算,因此必须在准确性和复杂度之间取得平衡。
Absolute maximum量化
绝对最大量化将给定数据中的最大绝对值映射到目标数据类型的有符号范围。再次,让我们思考将 FP16 值转换为 Int8。为简单起见,我们思考受限量化范围,即 -127 ~ 127。供您参考,完整量化范围为 -128 ~ 127。此量化图示如下所示。

文档改编的绝对最大量化图像
我们第一计算数据中的绝对最大值,并用它来重新调整原始数据。公式可以描述如下。

绝对矩阵量化的舍入公式
该方法在计算上比零点量化要简单,但是该方法受数据中的异常值影响较大,因此需要仔细检查我们的数据是否符合该方法。
这些方法属于四舍五入 (RTN) 量化系列。
另一方面,由于我们用更少的位数来削减信息,因此简单的量化存在精度下降的问题。因此,最近的量化技术尝试在减少位数的同时尽可能地减少这种下降。目前有两种主流的量化技术。
量化感知训练(QAT)
QAT 允许量化模型并应用微调来恢复量化导致的精度下降。虽然它可以比后面解释的 PTQ 方法保持更高的模型精度,但它一般需要额外的训练和昂贵的计算资源,例如 A100 或 H100 机器。
训练后量化(PTQ)
PTQ 允许对预训练模型进行量化,而无需额外训练。因此,它可以节省量化所需的 GPU VRAM 大小,并且对一般用户来说是一种更实用的解决方案。最近,许多研究人员都研究了此方向的量化,并开发了许多复杂的方法。
在本博客中,我们将学习流行的量化技术,如 GPTQ、AWQ 和 Bitsandbytes (QLoRA)。GPTQ 和 AWQ 被归类为 PTQ,QLoRA 被归类为 QAT。这些算法已经集成到 transformers 库中,因此用户可以有效地使用它们。在以下部分中,我们将简要介绍这些算法的理论。
分组精度调整量化(GPTQ)是 2022 年开发的早期成功量化算法之一。当时,该技术首次将具有 175B 的大型模型(例如 BLOOM 或 OPT-175B)量化为 4 位。
从技术上讲,GPTQ 独立量化权重矩阵的每一行,以找到最佳权重,从而最小化量化误差。对于准确量化,它利用 Hessian 矩阵计算剩余权重的最佳更新,从而减轻压缩过程造成的损失。请注意,GPTQ 将嵌入层和输出层保持在完整的 FP16 精度,以确保模型准确度。以下伪代码描述了 GPTQ 算法。

根据论文,使用单个 A100 GPU(80GB VRAM)大约需要四个小时就可以量化 175B 参数模型。OPT-175B 的量化结果如下表所示。

供您参考,困惑度衡量模型预测句子中下一个单词的能力。因此,困惑度值降低,意味着模型对其预测更有信心。在上表中,与 16 位精度相比,通过 GPTQ 量化的模型将困惑度值的增加保持在尽可能小的水平。
激活感知权重量化 (AWQ) 最近成为最流行的量化算法之一。该算法侧重于对 LLM 性能超级重大的显著权重。作者的研究表明,LLM 的权重比例很小(0.1~1%),对量化误差有显著影响。他们利用激活幅度来找到这一小部分权重,并应用每通道缩放来减轻显著权重带来的量化误差。此过程的说明如下图 (c) 所示。

论文改编的AWQ算法图解[2]
下表展示了 Llama-2 和 LLaMA 模型的 AWQ 结果。从中可以看出,AWQ 可以获得比舍入到最近 (RTN) 量化和 GPTQ 更好的困惑度。

对Llama量化结果对比
请注意,根据论文,对于某些模型(例如 Mistral 模型和指令调整模型),AWQ 有时不如 GPTQ。当我们量化 LLM 时,我们应该比较这些算法的结果并选择最佳算法。
BitsandBytes 是一个将模型量化为 8 位或 4 位的量化库,由于其便捷性和有效性,是最常见的量化库。
BitsandBytes 的 8 位量化基于 LLM.int8() 论文。为了减轻量化误差,它将模型权重的敏感异常值保留在 FP16 中,将其他值保留在 INT8 中,然后分别进行矩阵乘法。最后,将它们加在一起以返回 FP16 格式。下图显示了此过程。

改编的 LLM.int8() 架构
该技术可应用于高达 170B 规模的模型,但运行 170B 模型仍需要 8 x 24GB VRAM,运行 66B 模型则需要 4 x 24GB VRAM。在消费级 GPU 上运行大型模型依旧不够。
因此,开发了 4 位量化来解决这个问题。Bitsandbytes 的 4 位量化一般与 QLoRA 一起使用,以微调量化的 LLM。直观地说,QLoRA 以 4 位量化目标模型,使其冻结,然后使用 LoRA 对冻结的 4 位模型进行微调。以下是完全微调、LoRA 和 QLoRA 之间的比较。

论文中采用的全微调、LoRA 和 QLoRA 架构比较
从技术上讲,QLoRA 主要利用了以下特点。
4 位 NormalFloat 量化
该技术利用了预先训练的神经网络权重具有正态分布的实际,并引入了称为 4 位 NormalFloat 类型的新数据类型,从而确保每个量化箱中的预期值数量相等。
分页优化器
QLoRA 应用分页优化器来避免 GPU 内存突然激增。分页优化器使用 NVIDIA 统一内存功能自动在 CPU 和 GPU 之间切换页面到页面的传输(在这种情况下,您可以想象 GPU 页面类似于内存中的 CPU 页面)。
双重量化
当您将量化应用于模型权重时,您需要将量化常数设置为与模型权重一样的数据类型。由于 LLM 中有许多参数,因此量化常数也会增加内存空间负担。为了最大限度地减少每个参数的内存占用,作者对量化常数进行了量化。
下表显示了参数大小与 GPU VRAM 消耗的关系。

论文中调整的参数大小与内存消耗
请注意,内存列显示模型的内存要求,因此不包含微调部分。虽然这取决于数据集或超参数设置,但我们可以使用消费级 24GB VRAM 机器微调多达 13B 个参数的模型。
当零样本 LLM 准确率不足以完成目标任务时,我们应该使用 QLoRA。对于现实世界的 AI 项目,我们常常使用这种技术,由于基础模型一般不适用于特定领域数据。
尽管Unsloth不是量化方法,但我想介绍这个用于 LLM 的开源超高效微调库。Unsloth是一个完全集成参数高效微调方法(如 LoRA 和 QLoRA)的库。它针对开源著名 LLM 优化了每个内核,并实现了高达约 70% 的内存使用量减少!例如,它支持开源 LLMS,例如 Llama、Mistral、Phi、Qwen 和 Gemma。

官方仓库改编的 Unsloth 支持表
Unsloth 兼容 HuggingFace 和 vllm,可以在两者之间自由切换格式。在模型支持的情况下,使用 Unsloth 可以节省内存,提升性能。
就在最近(2024 年 12 月 4 日),Unsloth 发布了一种新的量化方法,称为 Unsloth — 动态 4 位量化。该技术建立在 BitsandBytes 4 位量化之上,并确定是否动态量化某些参数。目前,仅第一发布多模态模型的量化版本。随后将支持语言模型。
到目前为止,我们已经看到了流行的量化技术和库。总而言之,我们可以在以下情况下使用这些量化技术。
- 您想在零样本设置中使用 LLM → GPTQ 或 AWQ
- 您想使用经过微调的 LLM 和自己的数据 → QLoRA(BitsandBytes 或 Unsloth)
在本节中,我们将学习如何加载已量化的模型并量化我们自己的模型。GPTQ、AWQ 和 BitsandBytes 已集成到 HuggingFace Transformers 库中,因此我们将使用 Transformers 进行量化。我们将使用 Unsloth 库进行 Unsloth 量化。目前,让我们设置一个环境。
我们将使用 Google Colab Notebook 环境。我们试验了可在高达 24GB VRAM 上运行的模型。第一,我们安装以下库。
pip install auto-gptq autoawq trl bitsandbytes>=0.39.0pip install accelerate transformers optimum pip install git+https://github.com/unslothai/unsloth.git
如果遇到与 fsspec 库版本不兼容的错误,可以忽略它。所有必要的库都已安装。我会在 Colab 笔记本中附上库版本,以便您检查。
如何通过 GPTQ 加载预量化模型
要通过 GPTQ 加载预量化模型,只需将要使用的模型名称传递给 AutoModelForCausalLM 类。当您将 device_map 设置为“auto”时,系统会自动利用可用的 GPU。让我们使用以下代码加载 Mistral 7B 模型。
from transformers import AutoModelForCausalLM model_name_or_path = "TheBloke/Mistral-7B-Instruct-v0.1-GPTQ"model = AutoModelForCausalLM.from_pretrained(model_name_or_path, device_map="auto")
您可以看到,我们仅使用~5GB VRAM 即可加载量化的 7B 模型。

作者对 Mistral-GPTQ VRAM 的使用
加载模型部分已完成。
如何通过 GPTQ 对预量化模型进行推理
我们可以按照与非量化模型一样的程序进行推理。在这种情况下,我们可以使用名为apply_chat_template的标记器函数来制作LLM输入。我问量化模型如何烹制蛋黄酱。我们可以使用transformers API编写下面的代码。
messages = [ 
    { "role" : "user" , "content" : "您最喜爱的调味品是什么?" }, 
    { "role" : "assistant" , "content" : "嗯,我超级喜爱挤一点新鲜柠檬汁。无论我在厨房里烹饪什么,它都能为食物增添恰到好处的浓郁风味!" }, 
    { "role" : "user" , "content" : "您有蛋黄酱食谱吗?" } 
] 
codeds = tokenizer.apply_chat_template(messages, return_tensors= "pt" ) 
model_inputs =codeds.to(device) 
model.to(device) 
generated_ids = model.generate(model_inputs, max_new_tokens=1000, do_sample=False) 
coded = tokenizer.batch_decode(generated_ids) 
print(decoded[0])# 示范答案:# 哦,当然了!这里有一个简单快捷的经典蛋黄酱食谱,我信任你必定会喜爱:# # 配料:# - 2 个大蛋黄# - 1 汤匙第戎芥末# - 1/4 茶匙盐# - 2 汤匙白葡萄酒醋或柠檬汁# - 1 杯植物油或菜籽油# - 1/4 杯橄榄油# # 说明:# 1. 在搅拌机或食品加工机中,混合蛋黄、芥末和盐。# 2. 在机器运转时,慢慢倒入白葡萄酒醋或柠檬汁,直到混合物变稠。# 3. 缓慢而稳定地加入植物油,然后加入橄榄油,直到混合物呈光滑、奶油状。# 4. 品尝蛋黄酱,根据需要调整盐和酸的含量。# 5. 将蛋黄酱转移到密封容器中,放入冰箱冷藏,直到准备食用。
如你所见,该模型可以详细回答蛋黄酱配方。即使我们将模型量化为 4 位,模型依旧可以保持其准确性。
如何用GPTQ量化并保存我们自己的模型?
目前,让我们量化 Llama3.2 3B。我们需要定义用于 GPTQ 量化的 GPTQConfig 类。我们可以传递用于校准的数据集,并在 [“c4”, “wikitext2”, 'c4-new” 中选择。我们应该使用一样的数据集以避免过度拟合。由于 Llama 尚未透露使用哪个数据集进行训练,因此我选择 wikitext2 作为安全选项。以下代码显示了 GPTQ 量化。
from transformers import GPTQConfig, AutoModelForCausalLM, AutoTokenizer# setting model_id = "meta-llama/Llama-3.2-3B"tokenizer = AutoTokenizer.from_pretrained(model_id) gptq_config = GPTQConfig(bits=4, dataset="wikitext2", tokenizer=tokenizer)# run quantizationquantized_model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto", quantization_config=gptq_config)# save quantized modelquantized_model.save_pretrained(result_dir) tokenizer.save_pretrained(result_dir)
3B 模型的量化大约需要 30 分钟。当我们保存量化模型时,输出目录将是下图。

作者的输出目录图像
如何加载我们自己的量化模型?
我们可以加载自己的量化模型来传递保存的目录名。
model = AutoModelForCausalLM.from_pretrained(result_dir, device_map="auto")
是不是很简单呢?目前,我们已经学会了如何加载预量化模型、量化我们自己的模型,以及为 GPTQ 加载我们自己的量化模型。当量化其他模型时,只需更改模型名称即可传递给 AutoModelForCausalLM 类。
如何通过AWQ加载预量化模型?
要加载由 AWQ 预量化的模型,只需将要使用的模型名称传递给 AutoModelForCausalLM 类。当您将 device_map 设置为“auto”时,系统会自动利用可用的 GPU。让我们使用以下代码加载 Mistral 7B 模型。
model_name_or_path = "TheBloke/Mistral-7B-Instruct-v0.1-AWQ"model = AutoModelForCausalLM.from_pretrained(model_name_or_path, device_map="auto")
您可以看到,我们仅使用~5GB VRAM 即可加载量化的 7B 模型。

作者对 Mistral AWQ VRAM 的使用
如何通过AWQ对预量化模型进行推理?
我们可以使用预量化模型进行推理,就像普通的 CausalLM 推理一样。在这种情况下,标记器没有 chat_template,所以我们必须传递模板。推理代码如下所示。
prompt = "Tell me about blackhole."prompt_template=f'''{prompt}'''tokens = tokenizer(prompt_template, return_tensors="pt").input_ids.cuda()generated_ids = model.generate(                                tokens,                                 do_sample=True,                                temperature=0.7,                                top_p=0.95,                                top_k=40,                                max_new_tokens=512                              )decoded = tokenizer.decode(generated_ids[0])print(decoded)# The model answer:# A black hole is a region in space-time where gravity is so strong that nothing, not even light, can escape. # Black holes are formed from the collapse of massive stars and are characterized by their event horizon, # a boundary beyond which anything that crosses it is unable to return. # Black holes come in various sizes, with the smallest being only a few times the mass of the sun, # and the largest being billions of times more massive than the sun. They are invisible, # but their presence can be inferred from their gravitational effects on nearby objects, such as stars and galaxies. # The study of black holes provides important insights into the nature of gravity, space, and time.</s>
可以看出,该模型可以详细回答黑洞问题。它似乎保持了模型的准确性。
如何用AWQ量化并保存我们自己的模型?
目前,让我们量化 Llama3.2 3B。第一,我们需要将 AWQ 量化的配置定义为字典格式。我选择了 4 位量化和零点量化。此外,AWQ 模型有一个特定的类,因此我们需要使用模型名称加载它。以下代码显示了 AWQ 量化。
model_path = "meta-llama/Llama-3.2-3B"
 quant_config = { "zero_point" : True, "q_group_size" : 128, "w_bit" : 4, "version" : "GEMM" } 
# 加载模型model = AutoAWQForCausalLM.from_pretrained(model_path) 
tokenizer = AutoTokenizer.from_pretrained(model_path, trust_remote_code=True) 
# 量化model.quantize(tokenizer, quant_config=quant_config)3B 模型量化需要 15 分钟。要保存 AWQ 量化后的模型,我们需要修改模型的部分内容和配置,以兼容 transformers。
# 修改配置文件,使其与 transformers 集成兼容quantization_config = AwqConfig( bits=quant_config[ "w_bit" ], group_size=quant_config[ "q_group_size" ], zero_point=quant_config[ "zero_point" ], version=quant_config[ "version" ].lower(), ).to_dict() # 预训练的 transformers 模型存储在模型属性中 + 我们需要传递一个字典model.model.config.quantization_config = quantization_config # 保存模型权重model.save_quantized(result_dir) tokenizer.save_pretrained(result_dir)
当我们保存量化模型时,输出目录将是下图。它看起来像是 GPTQ 保存的量化模型的目录。

AWQ 输出目录图片由作者提供
如何加载我们自己的量化模型?
我们可以加载自己的量化模型来传递保存的目录名。
model = AutoModelForCausalLM.from_pretrained(result_dir, device_map="auto")
到此,我们已经学会了如何加载预量化模型、量化自己的模型以及为 AWQ 加载自己的量化模型。注意,在使用 AWQ 量化模型时,需要使用特定的类。
如何使用 BitsandBytes 实现 QLoRA?
在本节中,我们将使用 BitsandBytes 4 位量化实现 QLoRA。目前,我们在指令调整中将 llama3.2 3B 微调为聊天机器人。第一,我们需要配置 BitsandBytes 4 位配置。我们使用与 QLoRA 论文一样的设置,它具有 NormalFloat4 数据类型和双量化。
# 配置 BitsandBytes 配置以进行 4 位量化bnb_config = BitsAndBytesConfig (    load_in_4bit = True,   bnb_4bit_quant_type = “nf4”,   bnb_4bit_use_double_quant = True,   bnb_4bit_compute_dtype = torch.bfloat16 ) model_id =  “meta-llama/Llama-3.2-3B” model_nf4 = AutoModelForCausalLM.from_pretrained ( model_id,quantization_config = bnb_config,device_map = { “” : 0 } ) model_nf4.gradient_checkpointing_enable ()我们需要应用以下准备函数进行4位量化训练。
model_nf4 = prepare_model_for_kbit_training(model_nf4)
接下来,我们需要定义 LoRA 以进行模型微调。LoraConfig 中的以下参数是超参数,因此我们必须对其进行调整。我们可以通过应用 get_peft_model 函数来获取 LoRA 模型。
config = LoraConfig( r=16, lora_alpha=32, target_modules=["q_proj", "k_proj", "v_proj", "o_proj", "gate_proj", "up_proj", "down_proj"], lora_dropout=0.05, bias="none", task_type="CAUSAL_LM") model_nf4 = get_peft_model(model_nf4, config)
您可以看到,我们仅使用约 4 GB 的 VRAM 即可加载量化的 3B 模型。

Llama3.2 带 BitsandBytes 量化 VRAM 使用情况图像(作者提供)
对于指令调整数据集,我们使用了小学数学指令 [5]。我们可以通过数据集 API 加载它。
dataset = load_dataset("qwedsacf/grade-school-math-instructions", split='train')# sample data# Instruction:# 'This math problem has got me stumped: Natalia sold clips to 48 of her friends in April, and then she sold half as many clips in May. How many clips did Natalia sell altogether in April and May?
Can you show me the way?',# Answer:# 'Natalia sold 48/2 = 24 clips in May.
Natalia sold 48+24 = 72 clips altogether in April and May.')名为 trl 的库用于实现指令调整。为了方便起见,我们想使用 trl 库中的 Supervised FineTuning (SFT) Trainer,因此我们需要修改数据格式以适应 SFTTrainer。我们通过定义如下所示的格式函数来格式化数据。
def  formatting_prompts_func ( example ): 
    output_texts = [] 
    for i in  range ( len (example[ 'INSTRUCTION' ])): 
        text = f"### 问题:{example[ 'INSTRUCTION' ][i]} 
 ### 答案:{example[ 'RESPONSE' ][i]} "
         output_texts.append(text) 
    return output_texts接下来,我们定义排序器,使模型仅针对给定的数据集答案进行训练。有一个名为“
DataCollatorForCompleionOnlyLM”的类可以为其工作,因此我们只需使用答案模板实例化该类即可区分给定输入中的答案部分。
response_template = " ### 答案:" collat or = DataCollatorForCompletionOnlyLM(response_template=response_template, tokenizer=tokenizer, mlm= False )
最后,定义训练参数后,我们就可以进行训练了!训练整个数据集大约需要 2 个小时。在本博客中,数据量受到训练速度的限制。
output_dir = os.path.join(base_dir,"llama3.2-3B-qlora" ) per_device_train_batch_size = 8 gradient_accumulation_steps = 4 optim = "paged_adamw_32bit" save_steps = 500 logstash_steps = 100 learning_rate = 2e-4 max_grad_norm = 0.3 max_steps = 500 # int(len(dataset['train']) // per_device_train_batch_size) warmup_ratio = 0.03 lr_scheduler_type = "constant" training_arguments = TrainingArguments( output_dir=output_dir, per_device_train_batch_size=per_device_train_batch_size, gradient_accumulation_steps=gradient_accumulation_steps, optim=optim, save_steps=save_steps, logs_steps=logging_steps, learning_rate=learning_rate, fp16=True, max_grad_norm=max_grad_norm, max_steps=max_steps, warmup_ratio=warmup_ratio, group_by_length=True, lr_scheduler_type=lr_scheduler_type, report_to=None )trainer = SFTTrainer( model_nf4, args=training_arguments, train_dataset=dataset['train'], eval_dataset=dataset['test'], formatting_func=formatting_prompts_func, data_collator=collator,)trainer.train()
训练完之后我们需要保存模型,可以使用下面的方法。
# 保存模型trainer.save_model(output_dir)
我们可以保存 tokenizer 和 LoRA 模型权重。保存的目录如下图所示。

作者保存的目录图像
如何使用训练过的 QLoRA 模型进行推断?
当我们加载 QLoRA 模型时,我们只需传递 trainer.save_model() 的保存目录。
tokenizer = AutoTokenizer.from_pretrained(output_dir)tokenizer.pad_token = tokenizer.eos_token model = AutoModelForCausalLM.from_pretrained(output_dir,load_in_4bit = True,device_map = “auto”)
目前,使用测试数据集检查微调后的结果。我们使用以下问题比较结果。
There are 180 school days in the academic year. Aliyah packs a lunch half the time. Becky packs her lunch half as much as Aliyah. How many days a year does Becky pack her lunch?Find the solution.
基础模型推理如下所示。它无法捕捉整个问题的背景。
90天
QLoRA模型推理如下所示。
Aliyah准备午餐需要180 / 2 = 90天。Becky准备午餐需要90 / 2 = 45天。
如您所见,即使使用小型数据集,我们也可以微调模型!当我们的计算资源和数据有限时,QLoRA 超级有用。
如何使用 Unsloth 实现 QLoRA?
当我们使用 Unsloth 应用 QLoRA 时,流程与使用 BitsandBytes 应用 QLoRA 的过程超级类似。不同之处在于如何加载模型和 tokenizer。当我们使用 Unsloth 加载模型时,我们需要使用 Unsloth 包装器和 Unsloth 定义的模型,如下所示。您可以看到模型类和模型名称与上一节不同。
max_seq_length = 2048 # 任意选择!我们内部自动支持 RoPE 缩放! dtype = None # 自动检测为 None。Float16 表明 Tesla T4、V100,Bfloat16 表明 Ampere+ load_in_4bit = True # 使用 4 位量化来减少内存使用。可以为 False。model , tokenizer = FastLanguageModel.from_pretrained( model_name = "unsloth/Llama-3.2-3B-Instruct" , # 或选择 "unsloth/Llama-3.2-1B-Instruct" max_seq_length = max_seq_length, dtype = dtype, load_in_4bit = load_in_4bit, )
要加载 LoRA 适配器,我们还需要使用如下所示的 Unsloth 包装器。
model = FastLanguageModel.get_peft_model( model, r = 16 , # 选择任意数字 > 0 !提议的 8、16、32、64、128 target_modules = [ "q_proj" , "k_proj" , "v_proj" , "o_proj" , "gate_proj" , "up_proj" , "down_proj" ,], lora_alpha = 16 , lora_dropout = 0.05 , # 支持任意,但 = 0 是优化的 bias = "none" , # 支持任意,但 = "none" 是优化的 # [新] “unsloth” 使用的 VRAM 减少了 30%,适合 2 倍大的批量大小! use_gradient_checkpointing = "unsloth" , # 对于超级长的上下文,为 True 或 “unsloth” random_state = 3407 , use_rslora = False , # 我们支持等级稳定的 LoRA loftq_config = None , # 和 LoftQ )
您可以看到,我们仅使用~3GB VRAM 即可加载量化的 3B 模型。

Unsloth VRAM 使用情况图片由作者提供
除了上述设置外,其余几乎一样。我们使用 SFTTrainer 进行微调。完成整个数据集大约需要 2 小时。在本博客中,数据量受到训练速度的限制。
trainer = SFTTrainer( model, args=training_arguments, train_dataset=dataset['train'], formatting_func=formatting_prompts_func, data_collator=collator,)trainer.train()
训练完成后,我们需要保存模型,可以使用下面的方法,保存的目录如下图所示。
# 仅保存 LoRA 权重 model.save_pretrained( os . path .join(output_dir, "lora_model" )) tokenizer.save_pretrained( os . path .join(output_dir, "lora_model" ))

此方法保存了一个名为 adapter_config.json 的配置文件,用于加载模型。推理时,Unsloth 会自动读取设置,我们只需传递保存 LoRA 权重和配置的目录名即可。
model, tokenizer = FastLanguageModel.from_pretrained ( model_name = os.path.join ( output_dir,“lora_model” ),# 您用于训练的模型 max_seq_length = 512, dtype = None, load_in_4bit = True, ) FastLanguageModel.for_inference ( model ) # 启用本机 2 倍更快的推理
我们可以按照与标准 HuggingFace CausalLM 一样的方式推断给定的句子。
prompt = f"###问题:{dataset[ 'test' ][ 'INSTRUCTION' ][idx]} 
 ### 答案:"
 prompt_template= f''' {prompt} '''
 tokens = tokenizer(prompt_template, return_tensors= "pt" ).input_ids.cuda() 
output = model.generate( 
    input_ids=tokens,     temperature= 0.2 ,     top_p= 0.95 ,     max_new_tokens= 512
 ) 
print (tokenizer.batch_decode(outputs,skip_special_tokens= True )[ 0 ])这是 BitsandBytes QLoRA 部分中同一示例问题的结果。它可以正确回答问题!
Aliyah准备午餐需要180 / 2 = 90天。Becky准备午餐需要90 / 2 = 45天。
在这篇博客中,我们从基础开始学习最近流行的量化技术的概念。随着最近 LLM 规模的增长,量化的重大性变得越来越高。
 ¥40.00
 
                ¥40.00
            全新UI短网址源码,引流网站超多功能,类防封短域名源码,短网址生成_短链接在线生成
 ¥600.00
 
                ¥600.00
            同城分类信息平台源码|仿58同城分类信息源码|同城便民社区小程序|同城便民公众号系统
 ¥49.00
 
                ¥49.00
            展现页自适应APP下载页APP下载官网大气简洁HTML网站源码APP下载单页推广网页通用
 ¥40.00
 
                ¥40.00
            (带手机版数据同步)代理商记账财务注册公司类企业网站织梦模板 财务会计公司网站模板下载
 ¥40.00
 
                ¥40.00
            (自适应手机版)响应式餐饮投资管理企业织梦模板红色高端大气的美食餐饮集团网站模板下
 ¥40.00
 
                ¥40.00
            织梦dedecms经营工商资质注册办理代办服务代理商记账baoshu企业网站模板(带手机手机端b