趋近智
参数 (parameter)高效微调 (fine-tuning)(PEFT)技术,例如 LoRA、QLoRA 和适配器,在训练阶段提供了很大的好处。与更新所有模型权重 (weight)相比,它们大幅减少了可训练参数的数量,降低了内存需求,并通常加快了微调过程。然而,这种效率在推理 (inference)时会带来轻微的代价。PEFT 方法通常需要加载原始基础模型权重以及独立的适配器权重。此外,前向传播涉及额外的计算,以合并基础层和适配器层的输出。
对于以推理延迟和吞吐量 (throughput)为主要考虑因素的部署情况,将学到的适应内容整合回基础模型的权重中通常是有益的。这个过程称为合并,它会创建一组单一的模型权重,这组权重表现得像一个传统微调过的模型,但包含了通过 PEFT 学到的适应内容。
合并的主要原因是为了优化推理 (inference)性能和简化部署:
我们来查看低秩适应(LoRA),这是合并所应用于的最常见的 PEFT 方法之一。在 LoRA 中,预训练 (pre-training)权重 (weight)矩阵 保持冻结。适应是通过两个低秩矩阵 和 学习的,其中秩 。修改后的前向传播为输入 计算输出 如下:
这里, 是一个缩放因子, 是秩(尽管有时缩放 会被吸收到权重中)。
合并涉及计算一个新的权重矩阵 ,它直接包含了适应内容:
一旦 被计算出来,它就会替代 。独立的 和 矩阵在推理 (inference)时不再需要。前向传播简单地变为:
对所有应用了 LoRA 适配器的层都执行此计算。结果是一个模型,它具有与基础模型相同的架构,但权重已修改。
图示说明了 LoRA 适配器合并前后的适配层的计算流程。合并简化了推理路径。
像 Hugging Face 的 PEFT 这样的库提供了直接的方法来执行此合并操作。通常,您会加载基础模型,然后使用 PeftModel 类在其之上加载适配器权重 (weight)。这个类通常包含一个类似 merge_and_unload 的函数。
from transformers import AutoModelForCausalLM, AutoTokenizer
from peft import PeftModel
import torch
# 定义模型名称和路径
base_model_id = "meta-llama/Llama-2-7b-hf"
adapter_model_id = "path/to/your/trained-lora-adapter" # 替换为您的适配器路径
merged_model_save_path = "./merged-llama-model"
# 设置设备(如果可用,使用 CUDA)
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 加载基础模型
print(f"正在加载基础模型: {base_model_id}")
base_model = AutoModelForCausalLM.from_pretrained(
base_model_id,
torch_dtype=torch.float16, # 如果适用,使用 float16 以提高内存效率
device_map='auto' # 如有需要,自动分配模型层
)
# 加载分词器
tokenizer = AutoTokenizer.from_pretrained(base_model_id)
# 在基础模型之上加载 PEFT 模型(适配器)
print(f"正在加载适配器: {adapter_model_id}")
model = PeftModel.from_pretrained(base_model, adapter_model_id)
print("PEFT 模型已加载。")
# 将适配器权重合并到基础模型中
print("正在合并适配器权重...")
model = model.merge_and_unload()
print("适配器已合并并卸载。")
# 'model' 变量现在包含合并后的模型。
# 这是一个标准的 Transformers 模型对象。
# 您现在可以保存合并后的模型以备后用
print(f"正在保存合并后的模型至: {merged_model_save_path}")
model.save_pretrained(merged_model_save_path)
tokenizer.save_pretrained(merged_model_save_path)
print("合并后的模型已保存。")
# 您现在可以直接使用 'model' 进行推理或进一步处理
# 示例:生成文本
# prompt = "马来西亚的首都是什么?"
# inputs = tokenizer(prompt, return_tensors="pt").to(device)
# outputs = model.generate(**inputs, max_new_tokens=20)
# print(tokenizer.decode(outputs[0], skip_special_tokens=True))
执行 merge_and_unload() 后,model 对象不再是 PeftModel,而是变回基础模型类(例如 LlamaForCausalLM),现在它包含更新后的权重。适配器层被移除,从架构角度看,模型表现得像一个标准的、完全微调 (fine-tuning)过的模型。
尽管合并提供了性能优势,但理解其影响非常重要:
合并 PEFT 适配器是模型训练和测试向优化部署转变中的一个实际步骤。通过将学到的修改整合到主要模型权重中,您可以精简推理过程,降低计算延迟,并简化提供您微调 (fine-tuning)过的大型语言模型服务的操作方面。
简洁的语法。内置调试功能。从第一天起就可投入生产。
为 ApX 背后的 AI 系统而构建
这部分内容有帮助吗?
merge_and_unload函数用于适配器合并的详细信息。© 2026 ApX Machine LearningAI伦理与透明度•