【AI 学习日报】大模型微调 核心知识点详解 - 2026-03-21
📚 【AI 学习日报】
主题:大模型微调 | 分类:AI 进阶提升
📅 2026年03月21日
🎯 今日学习目标
今天我们将深入学习 大模型微调 相关的核心知识。
📖 核心内容详解
大模型微调总结绝密伏击《揭秘大模型:从原理到实战》、《推荐系统技术原理与实践》作者1151 赞同19 评论3440 收藏 var _______ssr_track_zm_page_view = 'https%3A//sugar.zhihu.com/ad-track/dream%3Fat%3Dpage_view%26brd%3D%26chl%3D%26cid%3D%26ct%3D2%26ctid%3D%26md%3D%26os%3D4%26pi%3D%26si%3D%26tk%3D%26cot%3D%26clid%3Dba16fb72-fa97-44e1-ab1f-3e93e6784ffa'; var _______ssr_lt_zm_page_view = 'undefined'; true && fetch(unescape(_______ssr_track_zm_page_view), { method: 'GET', mode: 'cors', headers: {'x-zm-96': '6f06ab7c0aa715f018356bf92b29a392', 'x-zm-93': 'custom'}}) false && fetch(unescape(_______ssr_lt_zm_page_view), { method: 'GET', mode: 'cors', headers: {'x-zm-96': '', 'x-zm-93': 'custom'}}) 打个小广告 ☻,知乎专栏《大模型前沿应用》的内容已经收录在新书《揭秘大模型:从原理到实战》中。感兴趣的朋友可以购买,多谢支持!♥♥
最近,深度学习的研究中出现了许多大型预训练模型,例如 GPT-3、ChatGPT、GPT4、ChatGLM-130B 等,这些模型可以在多种自然语言处理任务中取得优异的性能表现。而其中,ChatGPT 模型因为在对话生成方面的表现而备受瞩目,成为了自然语言处理领域的热门研究方向。
然而,这些大型预训练模型的训练成本非常高昂,需要庞大的计算资源和大量的数据,一般人难以承受。这也导致了一些研究人员难以重复和验证先前的研究成果。为了解决这个问题,研究人员开始研究 Parameter-Efficient Fine-Tuning (PEFT) 技术。PEFT 技术旨在通过最小化微调参数的数量和计算复杂度,来提高预训练模型在新任务上的性能,从而缓解大型预训练模型的训练成本。这样一来,即使计算资源受限,也可以利用预训练模型的知识来迅速适应新任务,实现高效的迁移学习。因此,PEFT 技术可以在提高模型效果的同时,大大缩短模型训练时间和计算成本,让更多人能够参与到深度学习研究中来。
2019年谷歌的研究人员首次在论文《Parameter-Efficient Transfer Learning for NLP》提出针对 BERT 的 PEFT微调方式,拉开了 PEFT 研究的序幕。他们指出,在面对特定的下游任务时,如果进行 Full-Fintuning(即预训练模型中的所有参数都进行微调),太过低效;而如果采用固定预训练模型的某些层,只微调接近下游任务的那几层参数,又难以达到较好的效果。
于是他们设计了如下图所示的 Adapter 结构,将其嵌入 Transformer 的结构里面,在训练时,固定住原来预训练模型的参数不变,只对新增的 Adapter 结构进行微调。同时为了保证训练的高效性(也就是尽可能少的引入更多参数),他们将 Adapter 设计为这样的结构:
2021年斯坦福的研究人员在论文《Prefix-Tuning: Optimizing Continuous Prompts for Generation》中提出了 Prefix Tuning 方法。与Full-finetuning 更新所有参数的方式不同,该方法是在输入 token 之前构造一段任务相关的 virtual tokens 作为 Prefix,然后训练的时候只更新 Prefix 部分的参数,而 Transformer 中的其他部分参数固定。该方法其实和构造 Prompt 类似,只是 Prompt 是人为构造的“显式”的提示,并且无法更新参数,而Prefix 则是可以学习的“隐式”的提示。
同时,为了防止直接更新 Prefix 的参数导致训练不稳定的情况,他们在 Prefix 层前面加了 MLP 结构(相当于将Prefix 分解为更小维度的 Input 与 MLP 的组合后输出的结果),训练完成后,只保留 Prefix 的参数。
embedding = torch.nn.Embedding(num_virtual_tokens, token_dim) transform = torch.nn.Sequential( torch.nn.Linear(token_dim, encoder_hidden_size), torch.nn.Tanh(), torch.nn.Linear(encoder_hidden_size, num_layers * 2 * token_dim), )3. Prompt TuningPrompt Tuning 是2021年谷歌在论文《The Power of Scale for Parameter-Efficient Prompt Tuning》中提出的微调方法。
该方法可以看作是 Prefix Tuning 的简化版本,只在输入层加入 prompt tokens,并不需要加入 MLP 进行调整来解决难训练的问题,主要在 T5 预训练模型上做实验。似乎只要预训练模型足够强大,其他的一切都不是问题。作者也做实验说明随着预训练模型参数量的增加,Prompt Tuning的方法会逼近 Fine-tune 的结果。
固定预训练参数,为每一个任务额外添加一个或多个 embedding,之后拼接 query 正常输入 LLM,并只训练这些 embedding。左图为单任务全参数微调,右图为 Prompt tuning。
from peft import PromptTuningConfig, get_peft_model peft_config = PromptTuningConfig(task_type="SEQ_CLS", num_virtual_tokens=10) model = AutoModelForCausalLM.from_pretrained(model_name_or_path, return_dict=True) model = get_peft_model(model, peft_config)4. P-Tuning v1P-Tuning 方法的提出主要是为了解决这样一个问题:大模型的 Prompt 构造方式严重影响下游任务的效果。
P-tuning 依然是固定 LLM 参数,利用多层感知机和 LSTM 对 Prompt 进行编码,编码之后与其他向量进行拼接之后正常输入 LLM。注意,训练之后只保留 Prompt 编码之后的向量即可,无需保留编码器。
self.lstm_head = torch.nn.LSTM( input_size=self.input_size, hidden_size=self.hidden_size, num_layers=num_layers, dropout=lstm_dropout, bidirectional=True, batch_first=True, ) self.mlp_head = torch.nn.Sequential( torch.nn.Linear(self.hidden_size * 2, self.hidden_size * 2), torch.nn.ReLU(), torch.nn.Linear(self.hidden_size * 2, self.output_size), ) self.mlp_head(self.lstm_head(input_embeds)[0])4.1 与Prefix-Tuning的区别P-Tuning 和 Prefix-Tuning 差不多同时提出,做法其实也有一些相似之处,主要区别在:
于是就有了v2版本:《P-Tuning v2: Prompt Tuning Can Be Comparable to Fine-tuning Universally Across Scales and Tasks》。
具体来说,通过奇异值分解将权重矩阵分解为增量矩阵,并根据新的重要性度量动态地调整每个增量矩阵中奇异值的大小。这样可以使得在微调过程中只更新那些对模型性能贡献较大或必要的参数,从而提高了模型性能和参数效率。
万字长文之提示学习和微调大模型(Prompt Learning & Prompt Tuning)253 赞同2 评论748 收藏前言Self-Attention 和 Transformer 自从问世就成为了自然语言处理领域的新星。得益于全局的注意力机制和并行化的训练,基于 Transformer 的自然语言模型能够方便的编码长距离依赖关系,同时在大规模自然语言数据集上并行训练成为可能。但由于自然语言任务种类繁多,且任务之间的差别不太大,所以为每个任务单独微调一份大模型很不划算。
本文主要根据综述文章《Pre-train, Prompt, and Predict: A Systematic Survey of Prompting Methods in Natural Language Processing》[1] 以及相关论文整理而来,在此基础之上,总结了一些现有的对 prompt learning 的相关讨论(如其缺陷,与其他学习方法的比较等)。望承前人之高屋建瓴,增添后之砖瓦。希望大家能批判性地阅读,如有误处,恳请斧正。
由于监督学习需要大量的数据学习性能优异的模型,而在 NLP 中大规模训练数据(指为特定任务而标注好的数据)是不足的,因此在深度学习出现之前研究者通常聚焦于特征工程(feature engineering),即利用领域知识从数据中提取好的特征;
在深度学习出现之后, 由于特征可以从数据中习得,因此研究者转向了结构工程(architecture engineering),即通过通过设计一个合适的网络结构来把归纳偏置(inductive bias)引入模型中,从而有利于学习好的特征。
在 2017-2019 年,NLP 模型开始转向一个新的模式(BERT),即预训练 + 微调(pre-train and fine-tune)。在这个模式中, 先用一个固定的结构预训练一个语言模型(language model, LM),预训练的方式就是让模型补全上下文(比如完形填空)。关于大模型的微调方法可以参加以下文章:
📝 今日实践任务
任务要求:
- 理解概念:仔细阅读上述内容,理解 大模型微调 的核心原理
- 动手实践:运行上面的代码示例,理解每一行的作用
- 拓展练习:修改代码参数,观察输出结果的变化
- 总结笔记:记录关键知识点和自己的理解
📝 代码实践
import torch
from transformers import AutoModelForSequenceClassification
# 加载模型
model = AutoModelForSequenceClassification.from_pretrained("bert-base-uncased")
# 动态量化
model_quantized = torch.quantization.quantize_dynamic(
model, {torch.nn.Linear}, dtype=torch.qint8
)
# 比较大小
print(f"原始模型参数量:{sum(p.numel() for p in model.parameters()):,}")
print(f"量化后参数量:{sum(p.numel() for p in model_quantized.parameters()):,}")
# 保存量化模型
torch.save(model_quantized.state_dict(), "model_quantized.pt")
print("量化模型已保存!")
💡 练习提示:运行上述代码,尝试修改参数观察结果变化,理解每一行的作用。
💡 提示:
建议投入 1-2 小时完成今天的学习。理解概念后一定要动手实践!