对应:Stanford CS224N Winter 2026 Lecture 9(Efficient Adaptation)与 Lecture 18(嘉宾讲座:LoRA and Fine-tuning);Winter 2025 Lecture 11(Efficient Adaptation)。和同目录 CME295 的提示与微调部分有重叠,可以互相参照。 配套代码:
code/lecture11/(03 号文件导入第 9 讲的lm_utils.py,并加载第 9 讲预训练的迷你 GPT;04 号文件的演示 6 加载第 7 讲训练的迷你 GPT) 预计阅读时间:4–5 小时(第 3.3 节和第 6 节的推导值得在纸上推一遍)
0. 本讲导航
0.1 学完本讲,你应该能够
- 说出让一个预训练模型适应新任务的三条路(提示、参数高效微调、全量微调),以及它们各自的代价。
- 写出零样本和少样本提示的结构,解释提示为什么脆弱(例子的选择、顺序、格式,三种偏差),以及上下文校准怎么修正偏差。
- 从三个角度解释上下文学习:示例到底教了模型什么、贝叶斯视角(用例子定位任务)、机制视角(归纳头;注意力可以实现梯度下降)。
- 算清全量微调的显存账(每个参数约 16 字节),说出参数高效微调(PEFT)的总体思路和三大类方法。
- 解释适配器、前缀微调 / 提示微调、BitFit 的做法和取舍。
- 详细解释 LoRA:低秩假设和内在维度、公式、初始化、缩放、合并、放在哪些层,以及低秩假设什么时候不成立。
- 解释量化的基本做法(absmax、分块)、NF4 和双重量化,以及 QLoRA 为什么能在一张显卡上微调 650 亿参数的模型。
- 面对一个具体场景,在提示、PEFT 和全量微调之间做出选择。
0.2 先修知识
| 知识点 | 用在哪里 | 最低要求 |
|---|---|---|
| 第 9 讲 | 全讲 | 预训练 → 微调;零样本分类;冻结主体 + 线性头 |
| 第 10 讲 | 第 2、8 节 | 指令微调;对话模型 |
| 第 7 讲 | 第 3、5、6 节 | 自注意力的 Q、K、V;Transformer 块的结构;参数量 |
| 线性代数 | 第 6 节 | 矩阵的秩、奇异值分解(SVD)的直观含义 |
| 概率 | 第 3.2 节 | 贝叶斯公式:后验 ∝ 先验 × 似然 |
0.3 本讲地图
第1节 动机:让一个大模型做新任务,有哪几条路?
第2节 提示:零样本与少样本 ← 代码 01(演示 2)
第3节 上下文学习是怎么发生的? ← 代码 01(演示 1、3)
第4节 全量微调的代价与 PEFT 的思路
第5节 加法式与选择式:适配器、提示微调、BitFit ← 代码 03
第6节 LoRA(本讲重点) ← 代码 02、03
第7节 量化与 QLoRA ← 代码 04
第8节 怎么选:提示、PEFT 还是全量微调?
第9–13节 小结、与作业的关系、练习、延伸阅读、下一讲预告
关于本讲的实验数字:01、02、04 号代码运行很快(几秒到十几秒),编写讲义时都完整运行过,讲义引用的是它们的实际输出。03 号代码要训练约 20 个分类器,编写时只做了冒烟测试,讲义中只描述预期的趋势,具体数字请以你自己运行的结果为准。
1. 动机:让一个大模型做新任务,有哪几条路?
第 9、10 讲之后,我们手里有了一个预训练好(也许还做过后训练)的语言模型。现在来了一个新任务:给客服邮件分类、把病历摘要成固定格式、用公司内部的术语回答问题……怎么让模型做这件事?
有三条路,按”改动模型的程度”从小到大排:
不改参数 改一小部分参数 改所有参数
│ │ │
提示(prompting) 参数高效微调(PEFT) 全量微调
零样本、少样本、 适配器、提示微调、 (第 9 讲的做法)
提示工程 BitFit、LoRA、QLoRA
│ │ │
零训练成本; 训练便宜;每个任务 效果上限最高;
每次调用都要带上 只存几 MB 的"补丁" 但贵,每个任务
长长的提示 存一份完整模型
为什么不总是全量微调?对一个 70 亿参数的模型,全量微调要一百多 GB 的显存(第 4 节会算这笔账),需要多张高端显卡;每个任务还要存一份 14 GB 的模型副本。如果要服务一千个客户、每个客户一个定制版本,就要存 14 TB 的模型。更别提千亿参数的模型,很多人根本拿不到它的权重(只能通过 API 调用),这时候提示就是唯一的选择。
本讲沿着这条轴从左往右走:先讲提示和上下文学习(第 2、3 节),再讲参数高效微调(第 4–7 节),最后讨论怎么选(第 8 节)。
2. 提示:零样本与少样本
2.1 从零样本到少样本
第 9 讲第 8 节已经见过零样本(zero-shot)的想法(GPT-2,Radford 等 2019):不训练,只把任务写成”续写”的形式。例如情感分类:
Review: the plot was gripping and the acting superb.
Sentiment:
然后看模型续写 “positive” 还是 “negative” 的概率高。
GPT-3 的论文(Brown 等 2020,标题就是 Language Models are Few-Shot Learners)往前走了一步:在提示里放几个示例(demonstrations):
Review: a waste of time. Sentiment: negative
Review: i loved every minute of it. Sentiment: positive
Review: the dialogue was painfully dull. Sentiment: negative
Review: the plot was gripping and the acting superb.
Sentiment:
这叫少样本提示(few-shot prompting),模型从提示里的例子”学会”任务的现象叫上下文学习(in-context learning,ICL)。注意:模型的参数一点都没变,“学习”完全发生在一次前向传播之内;换一个提示,模型就”忘了”。
GPT-3 论文的关键发现是:少样本的能力随模型规模急剧增长。小模型从例子里获益很少,1750 亿参数的模型在不少任务上,只靠几十个例子就接近了当时专门微调过的模型。这让”一个模型、不训练、做所有任务”第一次显得可行。
一个提示通常由三部分组成:
- 任务描述(可选):用自然语言说明要做什么(“判断下面评论的情感”);
- 示例(零样本时没有):若干个”输入 → 输出”对;
- 查询:要模型处理的新输入,以及引出答案的格式(“Sentiment:”)。
用模型给出答案也有两种方式:生成(让模型自由续写,再从文字里解析答案)和打分(像第 9 讲那样比较几个候选答案词的概率,叫 verbalizer)。分类任务常用打分,开放式任务只能生成。
2.2 提示为什么脆弱
上下文学习的结果对提示的细节非常敏感,这是它在实践中最大的麻烦:
- 例子的选择:用哪几个例子,结果可以差很多。选和查询相似的例子(比如用检索找最近邻)通常更好(Liu 等 2022)。
- 例子的顺序:Lu 等(2022)发现,同样的几个例子只换顺序,GPT-3 的准确率就能从接近瞎猜变化到接近最好的水平。
- 格式:Sclar 等(2023)发现,改变分隔符、大小写、空格这些对人来说毫无意义的格式细节,LLaMA-2-13B 的少样本准确率最多能差 76 个百分点。
- 三种偏差(Zhao 等 2021,Calibrate Before Use):
- 多数标签偏差:例子里哪个标签多,模型就倾向于预测哪个;
- 近因偏差:倾向于预测最后几个例子的标签;
- 常见词偏差:倾向于预测在预训练语料里更常见的答案词。
代码 01 的演示 2 用一个按假设写出来的模型模拟这三种偏差(对数几率 = 评论本身的证据 + 三项偏差,见代码里的 simulated_log_odds),看它们的破坏力有多大。没有偏差时这个模型的准确率是 93.4%;4 个例子的 16 种标签序列下:
| 设置 | 最低 | 平均 | 最高 |
|---|---|---|---|
| 16 种例子标签序列,不校准 | 51.8% | 74.8% | 91.5% |
| 其中 2 正 2 负的 6 种顺序 | 76.4% | 83.9% | 91.4% |
| 16 种序列,上下文校准之后 | 93.4% | 93.4% | 93.4% |
| 偏差还和输入有关时,校准之后 | 84.6% | 91.3% | 93.4% |
四个例子全是正面时,模型几乎什么都预测成正面(51.8%);即使正负各半,只是顺序不同(“负负正正”和”正正负负”),准确率也差了 15 个百分点(76.4% 对 91.4%)。
2.3 上下文校准
Zhao 等提出的修正办法很简单:先问一个”没有内容”的问题。把查询换成 “N/A”(或空字符串)喂给模型,这时模型对各个标签的偏好只可能来自偏差——输入里没有任何证据。然后把这个偏好从每个真实查询的打分里”除掉”:
在对数几率上,就是减去 “N/A” 的对数几率。上表第三行:只要偏差是一个”和输入无关的常数”,校准就能把它完全修掉,16 种序列都回到 93.4%。
但校准不是万能的。如果偏差本身和输入有关(表的最后一行:我们让长评论上的多数标签偏差更强、短评论上相反),一个常数修不掉,校准后平均 91.3%,最差 84.6%。
【边界】 演示 2 的模型是我们按 Zhao 等观察到的现象假设出来的,它说明的是”如果模型有这样的偏差,校准能修多少”,而不是证明真实模型的偏差就是这个形式。真实模型上校准的效果因任务、因模型而异。
2.4 提示工程的要点
后训练过的对话模型(第 10 讲)能直接听懂指令,“提示工程”更多是在把话说清楚。几条经过大量实践检验的原则:
- 把任务说具体:要什么、不要什么、给谁看、多长、什么格式。“总结一下”不如”用三条要点总结,每条不超过 20 个字,面向没有技术背景的读者”。
- 给足背景:模型不知道你知道的事。说明数据从哪里来、结果用在哪里、有哪些约束。
- 给例子:格式要求复杂时,一两个例子胜过一大段描述(但例子会被模仿,包括它们的缺点)。
- 用分隔符标出结构:把指令、资料、例子用标签或标题分开(比如
<document>…</document>),减少混淆。 - 让模型先想再答:复杂问题要求模型先写出推理过程(这是第 14 讲”思维链”的主题)。
- 拆成多步:一个复杂任务拆成几个简单的提示,前一步的输出作为后一步的输入。
- 用评估集迭代:准备几十个有标准答案的例子,每改一次提示就测一次。凭感觉改提示,很容易”按下葫芦浮起瓢”。
提示也可以自动优化:让模型自己生成、评估、改写候选提示(APE,Zhou 等 2022),或者把一个多步骤的提示流程写成程序、用数据自动调整其中的提示和例子(DSPy,Khattab 等 2023)。
2.5 提示的局限
- 每次调用都要付费:几十个例子的提示,每次查询都要重新处理一遍(提示缓存能缓解一部分)。
- 能放的例子有限:上下文窗口是有限的。长上下文模型出现后,放几百上千个例子(“多样本上下文学习”,Agarwal 等 2024)确实还能继续提升,但成本也随之上升。
- 脆弱:第 2.2 节的各种敏感性。
- 天花板:模型在预训练和后训练里没学会的能力,提示很难”变”出来。任务和预训练分布差得越远,提示的效果越差,这时就需要训练(第 4–7 节)。
3. 上下文学习是怎么发生的?
参数没有变,模型怎么就”学会”了新任务?这个问题至今没有完整的答案,但有三个互相补充的视角。
3.1 示例到底教了模型什么?
Min 等(2022)做了一个出人意料的实验:把少样本提示里示例的标签换成随机的(输入还是原来的输入,标签随便给),很多模型在很多分类任务上的准确率只掉了一点点。他们进一步发现,示例真正重要的是:
- 输入的分布:例子长什么样(让模型知道”现在处理的是哪类文本”);
- 标签的空间:可能的答案有哪些(“positive / negative”);
- 格式:输入和标签怎么排列。
而”每个输入配对的标签是否正确”反而没那么重要。
但 Wei 等(2023)给这个结论加了重要的限定:他们把标签全部反转(正面标成负面、负面标成正面),发现小模型基本不理会,仍然按自己预训练学到的语义做题;足够大的模型却会跟着例子学会反转后的规则,准确率掉到远低于 50%。也就是说,模型越大,越能”从例子里学到新东西”,而不只是”被例子提醒去做一个已经会的任务”。
这两个发现看起来矛盾,下一节的贝叶斯视角可以把它们统一起来。
3.2 贝叶斯视角:用例子定位任务
Xie 等(2021)提出:预训练语料是由很多种”潜在的任务 / 概念”生成的(一篇影评、一段代码、一份问答……)。为了把下一个词预测好,模型必须学会从上下文推断”现在是哪种任务”。少样本提示里的例子,就是在帮模型做这个推断:
然后按后验对各个任务的预测加权平均,得到对查询的回答。这就是隐式的贝叶斯推断。
代码 01 的演示 1 把这个想法变成一个能精确计算的小模型:输入是 48 个形容词,“预训练时见过的任务”有 5 种,每种有一个先验(“情感”最常见,0.70;“情感反转”几乎不存在,0.01;“按长度分类”0.10……)。模型还有一个参数 :它认为”例子的标签写错了”的概率。 小表示模型很信任例子的标签, 接近 0.5 表示几乎不看标签。
(a) 例子能让模型做一个不常见的任务。 例子的标签按”长度”任务给出(先验只有 0.10),在其余词上的准确率:
| 例子数 | 0 | 1 | 2 | 4 | 8 | 16 |
|---|---|---|---|---|---|---|
| (信任标签) | 58.3% | 69.0% | 79.1% | 93.5% | 99.5% | 100% |
| (不太信任) | 58.3% | 58.3% | 59.0% | 62.1% | 78.3% | 98.9% |
没有例子时,模型只能按先验去做最常见的情感任务,它在长度任务上的准确率(58.3%)恰好等于两个任务标签一致的比例。例子越多,后验越集中到长度任务上。不太信任标签的模型需要多得多的例子才能被说服。
(b) 随机标签和反转标签。 情感任务,但例子的标签分别是正确的、随机的、全部反转的(准确率按真实情感计算):
| 正确标签 | 随机标签 | 反转标签 | |
|---|---|---|---|
| , | 100% | 98.4% | 86.7% |
| , | 100% | 88.1% | 0.1% |
| , | 100% | 67.8% | 7.2% |
| , | 100% | 59.0% | 0.0% |
- 不太信任标签的模型,例子不多时随机标签几乎不影响它(98.4%)——它主要靠先验做题,这就是 Min 等看到的现象。但反转的例子足够多时,它也会被说服(贝叶斯模型里,只要 ,证据终究会压过先验)。
- 很信任标签的模型,只要 4 个反转的例子就改用反转的规则(7.2%)——这就是 Wei 等在大模型上看到的现象。
所以两个发现不矛盾:它们对应”模型在多大程度上相信例子的标签”这个参数的两端。
【边界】 这个贝叶斯模型是一个解释框架,不是真实模型的内部机制。它解释不了为什么模型越大越信任例子,也假设了”任务”是有限的几种。真实的预训练里,“任务”是连续而模糊的。
3.3 机制视角:注意力里藏着一个学习算法
贝叶斯视角回答”做了什么”,没有回答”用什么电路做的”。这方面有两条重要的线索。
线索一:归纳头(induction head)。 Olsson 等(2022)在 Transformer 里找到一种由两个注意力头组成的电路:第一个头把”前一个词是什么”的信息写进每个位置,第二个头用当前词去查找”上下文里前面哪里出现过这个词”,然后把那个位置后面的词复制过来。效果是完成”……[A][B]……[A] → [B]“这样的模式补全。这是最朴素的上下文学习:从上下文里找到模式并照着做。他们发现归纳头在训练中突然形成的时刻,恰好是模型上下文学习能力突然提升的时刻。(第 17 讲”可解释性”会在小 Transformer 里找归纳头。)
线索二:注意力可以实现梯度下降。 考虑一个干净的任务:上下文里给出 个线性回归的例子 ,(每个任务的 都不同),要求预测查询 的 。这是一个真正的”学习”问题:模型必须从上下文里的例子估计出 。
von Oswald 等(2023)证明:一层线性自注意力(去掉 softmax),配上特定的权重,恰好等于在上下文的例子上做一步梯度下降。 推导并不难:
把每个例子写成一个词元 ,最后一维 是”当前的残差”,一开始 (相对于 的预测);查询词元是 。取
那么 ,。线性注意力加残差后,每个词元最后一维的更新是
再看梯度下降:损失 ,从 走一步得 。新的残差
和注意力的更新一模一样。查询词元的最后一维按同样的公式变成 ,也就是负的预测。叠 层就是走 步。
代码 01 的演示 3 数值验证了这一点(1、2、5 层注意力和 1、2、5 步梯度下降的预测之差都在 量级,只是浮点误差),并比较了 8 维线性回归上,上下文里有 个例子时的平均平方误差:
| 不看例子 | 1 层 | 3 层 | 10 层 | 最小二乘 | |
|---|---|---|---|---|---|
| 4 | 7.45 | 5.36 | 4.56 | 4.16 | 3.89 |
| 8 | 8.21 | 4.45 | 3.32 | 2.00 | 0.00 |
| 16 | 7.81 | 2.93 | 1.33 | 0.30 | 0.00 |
| 32 | 7.97 | 1.79 | 0.37 | 0.01 | 0.00 |
| 64 | 8.09 | 1.10 | 0.13 | 0.00 | 0.00 |
例子越多、层数越多,预测越准,逐渐接近最小二乘(这个任务上最好的算法)。von Oswald 等还发现,在这类任务上从头训练的线性 Transformer,学到的权重和这个构造几乎一样;Garg 等(2022)、Akyürek 等(2022)也发现 Transformer 能在上下文中学会线性回归,表现接近最优算法。
【边界】 这是一个构造性的存在证明:注意力能够实现梯度下降。没人证明真实的大语言模型在处理语言任务时”就在做梯度下降”。它的价值在于说明”前向传播里藏着一个学习算法”在原理上是完全可能的,上下文学习并不神秘。
3.4 三种视角放在一起
| 视角 | 回答的问题 | 结论 |
|---|---|---|
| 示例的作用(3.1) | 示例里什么信息重要? | 格式、输入分布、标签空间;标签对不对的重要性因模型而异 |
| 贝叶斯(3.2) | 模型在做什么推断? | 用例子在预训练学到的任务里定位当前任务 |
| 机制(3.3) | 用什么电路做的? | 归纳头复制模式;注意力可以实现梯度下降这样的学习算法 |
4. 全量微调的代价与 PEFT 的思路
提示有天花板。任务足够重要、数据足够多时,我们还是想训练模型。先算一算全量微调有多贵。
4.1 显存账本
用混合精度和 Adam 训练时,每个参数要存:
| 内容 | 格式 | 字节 |
|---|---|---|
| 权重(前向、反向用) | bf16 | 2 |
| 梯度 | bf16 | 2 |
| 主权重(更新时用,保证精度) | fp32 | 4 |
| Adam 的一阶矩 | fp32 | 4 |
| Adam 的二阶矩 | fp32 | 4 |
| 合计 | 16 |
一个 70 亿参数的模型: 字节 ≈ 112 GB,还不算激活值。而推理只需要 bf16 的权重,14 GB。训练的大头是梯度和优化器状态(详见 CS336 第 2、5 讲)。
4.2 存储与服务
每个任务一份完整的模型副本:10 个任务就是 140 GB,1000 个客户的定制模型就是 14 TB。服务时,每切换一个任务就要把 14 GB 的权重换进显存。
4.3 灾难性遗忘
全量微调会修改所有参数,模型在新任务上变好的同时,可能忘掉预训练学到的一般能力(McCloskey & Cohen 1989 称之为灾难性遗忘)。数据少的时候,全量微调还容易过拟合。
4.4 参数高效微调的思路
参数高效微调(parameter-efficient fine-tuning,PEFT)的核心想法:
冻结预训练模型的全部参数,只训练很少量的新参数(或一小部分旧参数)。
好处直接对应上面三个问题:
- 显存:冻结的参数不需要梯度和优化器状态,只剩 bf16 权重的 2 字节/参数;
- 存储:每个任务只存新参数,几 MB 到几十 MB;
- 遗忘:原模型不变,换回去就是原样;参数少也不容易过拟合。
按”新参数加在哪里”,PEFT 方法大致分三类:
| 类别 | 做法 | 代表 |
|---|---|---|
| 加法式 | 往模型里加新的模块或向量 | 适配器、前缀微调、提示微调 |
| 选择式 | 只训练原有参数的一个子集 | BitFit(只训练偏置) |
| 重参数化式 | 把权重的变化量写成参数更少的形式 | LoRA |
配套代码 peft.py 在第 7 讲的 TransformerLM 上从零实现了这几种方法,每种只有几十行。
5. 加法式与选择式:适配器、提示微调、BitFit
5.1 适配器(Adapter)
Houlsby 等(2019)在每个 Transformer 子层(注意力、前馈网络)的输出后面插入一个小的瓶颈网络:
为什么这样设计?
- 瓶颈( 远小于 ):参数只有约 个。
- 自带残差、 初始化为 0:插入的瞬间 ,模型行为完全不变,训练从预训练模型出发,而不是从一个被随机扰动过的模型出发。(LoRA 的 是同一个道理。)
在 GLUE 上,适配器每个任务只训练约 3.6% 的参数,就和全量微调差不到 0.4 个百分点。
缺点:适配器是串联在主路径上的,推理时每一层都要多算两个小矩阵乘法,而且没法省掉。对大模型的小批量推理(比如在线对话),这点额外延迟会很明显。
5.2 前缀微调与提示微调
第 2 节的”提示工程”是人去找一串好用的词。词是离散的,没法求梯度。能不能把提示放宽成连续的向量,用梯度下降去找”最好的提示”?
- 提示微调(prompt tuning,Lester 等 2021):在输入词向量序列的前面拼接 个可训练的 维向量(“软提示”),模型完全冻结。参数只有 个(我们的迷你 GPT 上, 时只有 512 个)。
- 前缀微调(prefix tuning,Li & Liang 2021):在每一层注意力的键和值前面都拼接可训练的向量,参数多一些(约 层数),在中小模型上更稳定。
软提示不必对应任何真实的词,它可以是词向量空间里任意一个点。
Lester 等最重要的发现是”规模的力量”:在 T5 上,模型小的时候提示微调远不如全量微调,但随着模型增大差距不断缩小,到约 110 亿参数时两者几乎相当。直观理解:模型越大,“只改输入”能调动的能力越多。
缺点:小模型上效果差、训练不稳定、对初始化敏感(用真实词的词向量初始化比随机初始化好);软提示占用了上下文长度。
5.3 BitFit
Ben Zaken 等(2021)的 BitFit 只训练模型里所有的偏置项(bias),在 BERT 上只占约 0.1% 的参数。偏置只是给每个神经元加一个常数,但它能整体地”挪动”每一层的激活值。在不少分类任务上,BitFit 接近全量微调;在更难的任务上就不够了。它说明了一件事:适配一个预训练模型需要的改动,可能比想象的少得多。 第 6 节的 LoRA 把这个观察变成了一个有理论依据、又非常实用的方法。
6. LoRA(本讲重点)
6.1 低秩假设从何而来:内在维度
一个模型有一亿个参数,适配一个新任务真的需要调整一亿个”自由度”吗?
Li 等(2018)提出了一个测量方法:不直接训练参数 ,而是只在一个随机的 维子空间里训练:
逐渐增大 ,看需要多大的 才能达到全量训练效果的 90%,这个 叫任务的内在维度(intrinsic dimension)。
Aghajanyan 等(2020)把它用在预训练语言模型的微调上,发现:
- 内在维度非常低:RoBERTa-large 在 MRPC(句子复述判断)上,只训练 200 个参数(投影回全部参数空间)就能达到全量微调效果的 90%;
- 预训练越充分、模型越大,内在维度越低。预训练把模型带到了一个”离很多任务都很近”的位置。
代码 02 的演示 4 在一个小例子上复现了这个规律。模型是”词袋 → 32 维 → 2 类”的 MLP(5,922 个参数),任务是用 200 条餐厅点评做情感分类。两种出发点:所有参数随机初始化;或者隐藏层用在 2000 条影评上训练过的参数,分类头重新随机初始化(和微调 BERT 一样:主体是预训练的,任务头是新的)。两者出发时都接近瞎猜(52.6% 和 51.8%)。
| 子空间维度 | 1 | 2 | 4 | 8 | 16 | 32 | 64 | 256 | 全部参数 |
|---|---|---|---|---|---|---|---|---|---|
| 随机初始化 | 52.3% | 53.9% | 57.3% | 61.3% | 64.6% | 76.1% | 78.2% | 80.4% | 80.9% |
| 影评上预训练 | 68.1% | 70.0% | 75.4% | 83.6% | 83.7% | 83.9% | 83.3% | 84.0% | 83.0% |
达到全量训练准确率的 90%:随机初始化需要 ,预训练过的只需要 。只用 4 个随机方向,就能把一个预训练过的模型适配到新领域。
(实现细节:随机方向在每组参数里各自归一化,否则随机方向几乎全落在参数最多的第一层上,分类头几乎动不了。Aghajanyan 等的 SAID 方法也按层分配子空间。)
Hu 等(2021)由此提出 LoRA 的假设:既然适配需要的自由度很少,那么微调带来的权重变化量 也应该是低秩的。 与其在随机子空间里训练,不如直接学一个低秩的 。
6.2 做法
对一个冻结的权重矩阵 ,LoRA 把它换成
只训练 和 。 的秩最多是 (通常取 1~64)。
x ─────────────► W0(冻结)─────────────┐
│ ▼
└──► A(r × d_in)──► B(d_out × r)──► ×α/r ──► (+) ──► h
降到 r 维 升回 d_out 维
参数量:全量微调这个矩阵要 个参数,LoRA 只要 个。代码 02 的演示 1:一个 4096 × 4096 的矩阵, 时只要 0.39% 的参数。
计算顺序:先算 (降到 维),再算 ,计算量是 ,而不是先算出 的 。
6.3 三个设计细节
① 初始化为 0, 随机。 让训练开始时 ,模型和预训练模型完全一样。
为什么 不能也是 0? 对 (省略缩放),设 ,则
如果 ,两个梯度都是 0,参数永远停在原地。代码 02 的演示 2 验证了这一点:标准初始化训练 300 步后损失从 0.9617 降到 0.0000; 时损失纹丝不动,仍是 0.9617。所以必须有一个是随机的。(反过来,、 随机也能训练,只是惯例是 。)
② 缩放 。 原论文把 固定为第一次尝试的 ,之后不再调。这样换一个 时, 的大致量级不变,不用重新调学习率。(后来有工作认为 在 很大时更合适,即 rsLoRA。)
③ 加在哪些层? 原论文在 GPT-3 上只给注意力的 、 加 LoRA,发现在固定的参数预算下,“多加几个矩阵、每个的 小一点”比”只加一个矩阵、 大一点”更好, 甚至可以小到 1 或 2。后来的实践(例如 QLoRA)发现,给所有线性层(包括前馈网络)都加上,效果更稳定地接近全量微调。
6.4 合并:零推理开销
训练完之后,可以把 直接加回原来的权重:
之后模型就是一个普通的模型,结构、速度和原来一模一样,推理没有任何额外开销。这是 LoRA 相对适配器(串联、无法合并)的一大优势。代码 02 演示 2 中合并前后的输出最大差别是 (浮点误差)。
需要切换任务时,减掉 再加上另一个任务的 即可。更进一步,服务系统可以不合并:在显存里只放一份基座,同一批请求里不同的请求用不同的 LoRA 补丁(S-LoRA,Sheng 等 2023,能在一张显卡上同时服务上千个补丁)。代码 03 的演示 3 演示了”一个基座 + 两个任务的补丁”的保存、切换和合并。
6.5 低秩假设什么时候成立?
LoRA 不是魔法,它依赖一个经验事实:微调需要的变化接近低秩。代码 02 的演示 3 在一个线性层上做了对照实验:“预训练”的权重 (64 × 64),新任务的真实权重 ,比较全量微调和不同秩的 LoRA 在新任务上的测试误差(已减去噪声,0 = 完美):
| 的秩 | 样本 | 噪声 | 全量微调 | |||||
|---|---|---|---|---|---|---|---|---|
| 2 | 1000 | 0.1 | 0.0007 | 0.3188 | 0.0001 | 0.0001 | 0.0001 | 0.0003 |
| 64(满秩) | 1000 | 0.1 | 0.0007 | 0.9511 | 0.8995 | 0.8031 | 0.6372 | 0.3931 |
| 2 | 200 | 1.0 | 0.4642 | 0.3339 | 0.0253 | 0.0747 | 0.1583 | 0.2751 |
三行各说明一件事:
- 变化是低秩时,很小的 就够: 和全量微调一样好; 少了一个方向,不够。
- 变化是满秩时,LoRA 不够: 的误差仍是全量微调的几百倍。所以,如果新任务和预训练差得很远(比如教模型一门全新的语言、大量新知识),LoRA 可能明显不如全量微调。
- 数据少、噪声大时,低秩反而更好:全量微调有 4096 个自由参数,把噪声也拟合了进去(误差 0.46);秩合适的 LoRA 只有几百个参数,被迫只学”主要的变化”(误差 0.025,小了近 20 倍)。低秩也是一种正则化。 但 取大了,这个好处就逐渐消失。
这和实践中的观察一致:Biderman 等(2024)的论文标题就是 LoRA Learns Less and Forgets Less——在代码、数学这类需要大量新知识的持续预训练上,LoRA 明显不如全量微调;但它对原有能力的破坏也小得多。
6.6 LoRA 有多省
代码 02 演示 1 的数字(只算加 LoRA 的线性层;括号里是 16 位存储的大小):
| 模型 | 总参数 | LoRA 只加在 、 | LoRA 加在所有线性层 |
|---|---|---|---|
| GPT-2 small() | 0.12B | 0.29M(0.238%,1 MB) | 1.33M(1.070%,3 MB) |
| 7B,LLaMA 结构() | 6.74B | 4.19M(0.062%,8 MB) | 19.99M(0.297%,40 MB) |
| GPT-3 175B() | 175B | 18.87M(0.011%,38 MB) | 84.93M(0.049%,170 MB) |
GPT-3 的完整检查点(16 位)约 350 GB,LoRA 补丁只有几十 MB(论文报告约 35 MB)。LoRA 论文报告:在 GPT-3 上,可训练参数减少到约万分之一,训练时的显存减少到约三分之一,效果和全量微调相当甚至更好。
一个常见误解:LoRA 不会让每一步训练快很多。前向传播仍要经过完整的模型,反向传播时梯度仍要穿过所有冻结的层传回来(只是不用为冻结的参数存梯度)。它省的主要是显存(梯度和优化器状态)和存储。
6.7 在迷你 GPT 上比较
代码 03 在第 9 讲预训练的迷你 GPT(167,872 个参数)上,学一个预训练时没见过的新任务:褒贬混合检测(3 类:只有贬 / 只有褒 / 有褒有贬;测试集里三类约 25% / 25% / 50%,多数类基线约 50%)。每种做法都在最后一个词的隐藏状态上接一个新的分类头,比较 9 种做法在 100 条和 1000 条标注数据下的测试准确率(编写讲义时只做了冒烟测试,表格请你运行后填写):
| 做法 | 可训练参数(含分类头) | 100 条 | 1000 条 |
|---|---|---|---|
| 只训练分类头 | 195(0.12%) | ||
| 全量微调 | 168,067(100%) | ||
| BitFit | 2,371(1.41%) | ||
| 提示微调() | 707(0.42%) | ||
| 适配器() | 6,771(4.03%) | ||
| LoRA (注意力) | 1,347(0.80%) | ||
| LoRA (注意力) | 4,803(2.86%) | ||
| LoRA (注意力) | 18,627(11.10%) | ||
| LoRA (所有线性层) | 12,483(7.44%) |
预期会看到:
- 只训练分类头最差:预训练的目标是预测下一个词,最后一个位置的隐藏状态里不一定线性地编码了”前面出现过褒和贬”。这是一个新任务,主体需要调整(和第 9 讲”冻结 + 线性头”对情感分类还不错形成对比:情感是预训练时就必须理解的东西,“是否混合”不是)。
- LoRA、适配器只训练百分之几的参数,应该接近全量微调;数据少时可能更好(6.5 节第 3 点)。
- 从 1 增加到 16,提升通常不大。
- 提示微调在这么小的模型上通常明显落后(5.2 节”规模的力量”)。
- 训练用时差别不大(6.6 节的”常见误解”)。
代码 03 的演示 4 还检查了全量微调改变的权重 是不是低秩的:对每个线性层算 的奇异值,看前 4 个方向占了多少”能量”(奇异值平方和的比例),并和同样形状的随机矩阵比较。预期 比随机矩阵集中得多。
【边界】 解读演示 4 要小心:训练步数很少时, 是少数几次梯度更新的累加,而一个线性层的单步梯度 本身就是低秩的(秩不超过这一批的词元数)。所以” 低秩”有一部分来自优化过程本身,不全是任务的性质。Hu 等在 GPT-3 上做的分析更有说服力: 和 的 LoRA 学到的最主要的几个方向高度重合。
6.8 LoRA 的变体
LoRA 之后出现了大量变体,几个有代表性的:
- QLoRA(Dettmers 等 2023):基座量化成 4 位,见第 7 节;
- DoRA(Liu 等 2024):把权重分解成”大小”和”方向”两部分,方向用 LoRA 更新,更接近全量微调的更新模式;
- LoRA+(Hayou 等 2024): 和 用不同的学习率( 的大一些);
- rsLoRA:缩放改为 ,让大 也能稳定训练。
7. 量化与 QLoRA
LoRA 解决了”可训练参数”的问题,但冻结的基座仍然要整个放进显存:650 亿参数的模型,bf16 也要 130 GB。QLoRA 的想法是:把冻结的基座量化成 4 位,在它上面训练 16 位的 LoRA。 基座不训练,所以低精度带来的误差不会在训练中累积;LoRA 的参数是高精度的,可以”补偿”一部分量化误差。
7.1 浮点数格式
| 格式 | 符号 | 指数 | 尾数 | 最大值 | 1 附近的间隔 |
|---|---|---|---|---|---|
| fp32 | 1 | 8 | 23 | 约 | |
| fp16 | 1 | 5 | 10 | 65504 | |
| bf16 | 1 | 8 | 7 | 约 |
指数位决定范围,尾数位决定精度。代码 04 的演示 1:70000 在 fp16 里变成 inf(溢出), 变成 0(下溢);在 bf16 里都没问题,但 1.001 变成了 1。深度学习对精度不太敏感、对溢出非常敏感,所以今天的大模型训练和推理大多用 bf16(它就是 fp32 的高 16 位)。
7.2 量化的基本做法
absmax 量化(对称量化):用一组数里绝对值最大的那个决定刻度,
8 位时 。存的是整数 和一个缩放因子 。
离群值的破坏力:代码 04 演示 2,4096 个服从 的权重量化到 int8,相对误差 0.89%,用到了 191 个不同的整数。加入一个等于 1.0 的离群值(是普通权重的 50 倍)后,刻度被放大 50 倍,普通权重全挤在 0 附近,只用到 19 个不同的整数,误差暴涨到 8.96%。
这不是假想的问题:Dettmers 等(2022,LLM.int8())发现,参数超过约 60 亿的模型里会出现数值大几十倍的”离群特征”,朴素的 int8 量化会让模型性能崩溃。
分块量化:每 64 个数一块,各自一个缩放因子。离群值只影响它所在的那一块,误差回到 1.28%。代价是每块要多存一个缩放因子。
7.3 NF4:按分布设计码本
4 位只有 16 个可能的值。放在哪里最好?均匀的 int4 把它们等间隔地放在 上。但权重大致服从正态分布:靠近 0 的地方权重最密集,却只分到几个值;两端几乎没有权重,却也占了好几个值。
NF4(4-bit NormalFloat)让每个量化值”负责”的概率相同:取标准正态分布的等间隔分位数,再加上一个精确的 0,归一化到 。代码 04 演示 3 从零算出的 16 个值和 QLoRA 公布的数值一致:
-1.000 -0.696 -0.525 -0.395 -0.284 -0.185 -0.091 0.000 0.080 0.161 0.246 0.338 0.441 0.563 0.723 1.000
可以看到它们在 0 附近密、两端稀。在 128,000 个正态分布的权重上(每 64 个一块),NF4 的均方误差是均匀 int4 的 72%。
7.4 双重量化与分页优化器
每 64 个权重存一个 fp32 缩放因子,平均每个参数多 比特,对一个 4 比特的格式来说是 12.5% 的额外开销。双重量化把这些缩放因子再量化成 8 位(每 256 个一块,再存一个 fp32 的二级缩放因子):
每个参数省下约 0.373 比特,对 650 亿参数的模型约 3 GB。代码 04 演示 4 中,量化误差几乎不变(均方误差从 变成 )。
分页优化器:利用 GPU 和 CPU 内存之间的统一内存,显存不够时把优化器状态临时换出到内存(类似操作系统的虚拟内存分页),避免训练中遇到一条特别长的序列时显存溢出。
7.5 显存账本
代码 04 演示 5(只算模型状态,不含激活值;LoRA ,加在所有线性层上,即 QLoRA 论文的设置):
| 模型 | LoRA 参数 | 推理(bf16) | 全量微调 | LoRA | QLoRA |
|---|---|---|---|---|---|
| 7B | 160M(2.4%) | 13 GB | 107 GB | 16 GB | 6 GB |
| 13B | 250M(1.9%) | 26 GB | 208 GB | 30 GB | 11 GB |
| 33B | 488M(1.5%) | 65 GB | 520 GB | 73 GB | 25 GB |
| 65B | 800M(1.2%) | 130 GB | 1043 GB | 143 GB | 46 GB |
65B 的 QLoRA 拆开看:4 位基座(含缩放因子)33.6 GB,加上 LoRA 参数的训练状态 12.8 GB。再用梯度检查点和分页优化器处理激活值,一张 48 GB 的显卡就能微调 650 亿参数的模型,这正是 QLoRA 论文的核心结论。他们用这种方法训练的 Guanaco 模型,在当时的 Vicuna 基准上达到了 ChatGPT 水平的 99.3%(由 GPT-4 评判,第 13 讲会讨论这种评估的偏差)。
注意:QLoRA 省显存、不省计算。前向计算前要把 4 位权重反量化回 bf16 再做矩阵乘法,所以它甚至比 16 位的 LoRA 慢一些。
7.6 量化对一个真实模型的影响
代码 04 演示 6 把第 7 讲训练好的迷你 GPT 的所有二维权重矩阵(112,512 个数)量化再反量化:
| 格式 | 测试集困惑度 | 主谓一致(2 个修饰语) |
|---|---|---|
| 不量化(fp32) | 4.272 | 100.0% |
| bf16 | 4.272 | 100.0% |
| int8,整个矩阵一个缩放因子 | 4.273 | 100.0% |
| int4,整个矩阵一个缩放因子 | 4.304 | 100.0% |
| int4,每 64 个一块 | 4.289 | 100.0% |
| NF4,每 64 个一块 | 4.295 | 100.0% |
| int2(3 个值),每 64 个一块 | 14.180 | 83.2% |
bf16 和 int8 几乎无损;4 位有一点损失,但仍然很小;2 位就明显坏掉了。两点要诚实地说明:
- 在这个小模型上,NF4 并不比分块 int4 好。NF4 假设权重服从正态分布,这里的权重(尤其是词嵌入)不完全是,而且两者的差别本身就很小。
- 小模型没有大模型那样的极端离群值,所以”整个矩阵一个缩放因子”也不算太糟。在几十亿参数以上的模型上,它会差得多。
量化本身是一个很大的话题(GPTQ、AWQ 等训练后量化方法、量化感知训练、KV 缓存量化……),系统层面的细节见 CS336 的相关讲次。本讲只讲 QLoRA 用到的部分。
8. 怎么选:提示、PEFT 还是全量微调?
| 情况 | 推荐 | 理由 |
|---|---|---|
| 只能通过 API 使用模型 | 提示(+ 检索,第 12 讲) | 拿不到权重 |
| 快速做原型、任务经常变 | 提示 | 零训练成本,改提示即可 |
| 有几百到几万条标注数据,任务固定 | LoRA / QLoRA | 便宜、稳定、接近全量微调 |
| 要服务很多任务或很多用户的定制版本 | LoRA | 一个基座 + 很多小补丁 |
| 显存很有限(单张消费级显卡) | QLoRA | 4 位基座 |
| 要教模型大量新知识或新语言,数据和算力都充足 | 全量微调(或继续预训练) | 低秩假设可能不成立(6.5 节) |
| 特别在意保留原有能力 | LoRA | 原模型不变,遗忘更少 |
实践中这些方法经常组合使用:用 LoRA 做指令微调或领域适配,再在使用时配合精心设计的提示和检索。
还有一点:提示和微调并不是”二选一”的关系,而是同一件事的两种形式。少样本提示可以看作”在前向传播里做的、只持续一次的微调”(第 3.3 节);而微调可以看作”把很多提示的效果永久地写进参数里”。
9. 本讲小结
- 三条路:提示(不改参数)、参数高效微调(改很少的参数)、全量微调(改所有参数),代价和效果上限依次增加。
- 提示:零样本、少样本;结构是任务描述 + 示例 + 查询。很脆弱:例子的选择、顺序、格式,多数标签 / 近因 / 常见词三种偏差。上下文校准用”没有内容的输入”估计偏差再减掉,对常数偏差有效。提示工程的核心是把话说清楚,并用评估集迭代。
- 上下文学习的三种视角:示例主要传递格式、输入分布和标签空间;贝叶斯视角是”用例子定位任务”,统一了”随机标签影响不大”和”大模型会跟着反转标签走”;机制视角有归纳头,以及”一层线性注意力恰好等于一步梯度下降”的构造。
- 全量微调的代价:每个参数约 16 字节的显存;每个任务一份完整模型;灾难性遗忘。
- PEFT:冻结原模型,只训练很少的参数。适配器(串联瓶颈,零初始化,有推理延迟)、提示微调 / 前缀微调(连续的提示,大模型上才好用)、BitFit(只训练偏置)。
- LoRA:;来源于”内在维度很低”的发现;、 随机;缩放 ;训练完可合并,推理零开销;低秩假设成立时效果接近全量微调,数据少时还有正则化作用,需要大量新知识时不够。
- 量化与 QLoRA:absmax 量化怕离群值,分块解决;NF4 按正态分位数放置量化值;双重量化把缩放因子的开销从 0.5 降到约 0.127 比特/参数;4 位基座 + 16 位 LoRA,让 65B 模型在一张 48 GB 显卡上微调。
10. 与作业的关系
- 期末项目:默认项目要在下游任务上微调 GPT-2(第 20 讲),LoRA 是一个很自然的扩展方向:比较全量微调和 LoRA 的效果、显存和速度,正是一个好的项目实验。很多自选项目受限于算力,也会用 LoRA / QLoRA 微调开源模型。
- Winter 2026 的作业 4(大语言模型的基准测试与评估):评估时用到的少样本提示,本讲第 2 节讲的敏感性问题(例子顺序、格式)会直接影响你测出的分数,第 13 讲会继续讨论。
- 本讲代码只用到 PyTorch;实际项目中常用 Hugging Face 的
peft库(LoRA、提示微调、适配器等)和bitsandbytes(4 位、8 位量化),它们的接口和我们从零实现的版本概念上一一对应。
作业的具体题目以当年官方发布的版本为准。
11. 练习
练习 1(LoRA 参数量)★:一个 的前馈网络矩阵,。(a) LoRA 有多少参数?占原矩阵的百分之几?(b) 合并之后,推理时这一层的计算量和原来相比如何?
参考答案
(a) 个参数;原矩阵 个,占约 0.54%。 (b) 完全一样:合并后就是一个普通的 矩阵。
练习 2(初始化)★:(a) 写出 和 (忽略缩放)。(b) 如果反过来,、 随机,能训练吗?训练开始时 是多少?(c) 如果 、 都随机(都不是 0),会有什么问题?
参考答案
(a) 设 ,,。 (b) 能。开始时 ;,所以 先动起来,之后 的梯度也不再是 0。只是惯例是 。 (c) 训练开始时 ,模型被随机扰动了,不再等于预训练模型。微调就不是从预训练模型出发,而是从一个”被弄坏了一点”的模型出发,需要先花力气把扰动修回来。
练习 3(显存)★★:一个 130 亿参数的模型。(a) 按每参数 16 字节,全量微调要多少显存(不含激活值)?(b) LoRA(bf16 基座)呢?假设 LoRA 有 2.5 亿个参数,每个按 16 字节算。(c) QLoRA 呢(按每参数 0.516 字节)?(d) 一张 24 GB 的消费级显卡能做哪些?
参考答案
(a) GB。 (b) GB。 (c) GB。 (d) 只有 QLoRA 放得下(还要给激活值留空间)。这就是 QLoRA 让个人也能微调大模型的原因。
练习 4(贝叶斯视角)★★:只有两个任务,先验 、,。给了 2 个例子,它们都和 一致、都和 矛盾。(a) 计算后验 。(b) 如果 呢?(c) 解释这和”大模型更会跟着反转标签走”的关系。
参考答案
(a) 似然: 为 , 为 。后验 ,。两个例子就把先验 0.1 翻成了 0.9。 (b) 似然: 和 。后验 ,,模型仍然倾向于 。 (c) 越”信任”例子( 越小),越少的例子就能压过先验。大模型跟着反转标签走,相当于它的有效 更小。这个模型只描述了现象,没有解释为什么大模型更信任例子。
练习 5(提示微调 vs 前缀微调)★★:一个 24 层、 的模型。(a) 提示微调用 个软提示,有多少参数?(b) 前缀微调在每一层的键和值前都加 20 个向量,有多少参数?(c) 为什么前缀微调在中等大小的模型上通常比提示微调效果好?
参考答案
(a) 。 (b) (论文里还会用一个 MLP 对前缀重参数化来稳定训练,训练完丢掉)。 (c) 提示微调只能在输入层施加影响,后面每一层都要靠模型自己”传递”这个影响;前缀微调在每一层都直接提供可调的键和值,能更直接地改变每一层的注意力,表达能力更强。模型足够大时,输入层的影响已经足够,两者差距缩小。
练习 6(线性注意力 = 梯度下降)★★:在第 3.3 节的构造中,我们让查询词元不作为键被关注(只有 个例子作为键)。(a) 如果查询词元也作为键,第一层的结果会变吗?(b) 第二层呢?
参考答案
(a) 不会。第一层时查询词元的最后一维 ,它作为键时贡献的值向量是 。
(b) 会。第一层之后 ,第二层时它作为键会贡献 ,相当于把查询点也当成了一个”标签为 0 的训练样本”,偏离了梯度下降。所以构造里要用掩码把它排除(代码里的 K[:n_ctx])。
练习 7(量化)★:对向量 做 int8 absmax 量化()。(a) 写出 和 。(b) 前三个数的相对误差大约多大?(c) 如果分成两块 和 分别量化呢?
参考答案
(a) 缩放因子 2.0。;。 (b) 分别约 5.5%、2.4%、5.5%。 (c) 第一块缩放因子 0.2:,,误差不到 1%;第二块里的 0.05 仍然和 2.0 在一起,误差不变。分块只能隔离”不在同一块里”的离群值。
练习 8(上下文校准)★:模型在 “N/A” 上给出 ,在某条评论上给出 。校准之后预测是什么?
参考答案
按 :正面 ,负面 ,归一化后 ,预测负面。模型本来就有 0.7 的偏向,这条评论只给了 0.6,说明它实际上把预测往负面拉了。
练习 9(怎么选):为下面三个场景各选一种做法并说明理由:(a) 一个创业公司要给 500 个企业客户各做一个定制的客服模型,每个客户有几千条历史对话;(b) 一个研究者想让一个 7B 的英文模型学会斯瓦希里语,有 100 亿词的斯瓦希里语语料和一个 GPU 集群;(c) 一个学生想在自己的笔记本电脑(16 GB 内存,没有独立显卡)上尝试不同的提示做情感分析。
参考答案
(a) LoRA(或 QLoRA):每个客户一个几十 MB 的补丁,服务时一个基座 + 按请求切换补丁。 (b) 全量的继续预训练:要学一门新语言,需要的变化不是低秩的(6.5 节),数据和算力也充足;词表可能也要扩展(第 16 讲)。 (c) 提示(零样本 / 少样本),用一个能在 CPU 上跑的小模型或 API;没有训练的条件,也没必要训练。
练习 10(动手):
(a) 运行代码 03,把结果填进第 6.7 节的表格。和预期一致吗?哪种 PEFT 方法在 100 条数据时最好?
(b) 在代码 02 的演示 3 中,把第三行的噪声从 1.0 改成 0.1,LoRA 的正则化优势还在吗?为什么?
(c) 在 peft.py 里实现前缀微调:在每一层的注意力里给键和值前面拼接可训练的向量(提示:需要修改 MultiHeadSelfAttention.forward,或者写一个包装类),在代码 03 里和提示微调比较。
(d) 在代码 03 里给 LoRA 的 、 用不同的学习率( 的学习率是 的 4 倍或 16 倍,即 LoRA+),结果有变化吗?
(e) 在代码 01 的演示 1 里加一个”语义无关标签”的实验:把标签 1/0 换成两个和情感无关的符号(模型不知道哪个代表褒义)。在贝叶斯模型里应该怎么表示这种情况?
12. 延伸阅读
- Brown et al.,Language Models are Few-Shot Learners(2020):GPT-3 与少样本提示。
- Zhao et al.,Calibrate Before Use: Improving Few-Shot Performance of Language Models(2021);Lu et al.,Fantastically Ordered Prompts and Where to Find Them(2022);Sclar et al.,Quantifying Language Models’ Sensitivity to Spurious Features in Prompt Design(2023)。
- Min et al.,Rethinking the Role of Demonstrations: What Makes In-Context Learning Work?(2022);Wei et al.,Larger Language Models Do In-Context Learning Differently(2023)。
- Xie et al.,An Explanation of In-context Learning as Implicit Bayesian Inference(2021)。
- Olsson et al.,In-context Learning and Induction Heads(2022)。
- von Oswald et al.,Transformers Learn In-Context by Gradient Descent(2023);Garg et al.,What Can Transformers Learn In-Context?(2022);Akyürek et al.,What Learning Algorithm Is In-Context Learning?(2022)。
- Houlsby et al.,Parameter-Efficient Transfer Learning for NLP(2019):适配器。
- Li & Liang,Prefix-Tuning(2021);Lester et al.,The Power of Scale for Parameter-Efficient Prompt Tuning(2021)。
- Ben Zaken et al.,BitFit(2021)。
- Aghajanyan et al.,Intrinsic Dimensionality Explains the Effectiveness of Language Model Fine-Tuning(2020);Li et al.,Measuring the Intrinsic Dimension of Objective Landscapes(2018)。
- Hu et al.,LoRA: Low-Rank Adaptation of Large Language Models(2021)。
- Dettmers et al.,QLoRA: Efficient Finetuning of Quantized LLMs(2023);LLM.int8()(2022)。
- Biderman et al.,LoRA Learns Less and Forgets Less(2024)。
- Sheng et al.,S-LoRA: Serving Thousands of Concurrent LoRA Adapters(2023)。
- Anthropic、OpenAI 等的官方提示工程指南:实践经验的系统总结。
13. 下一讲预告
到目前为止,模型的知识都”长”在参数里:预训练时学到什么就知道什么,学错了就一直错,训练结束之后的事一概不知。问它一个预训练语料里没有的问题,它可能一本正经地编造一个答案。
下一讲(智能体、工具使用与检索增强生成)换一个思路:不把所有知识塞进参数,而是让模型去查。
- 问答:从抽取式问答(SQuAD)到开放域问答;
- 检索:稀疏检索(TF-IDF、BM25)与稠密检索(双塔编码器),各自擅长什么;
- 检索增强生成(RAG):先检索、再阅读、再回答,并给出出处;
- 工具使用与智能体:让模型调用搜索、计算器、代码解释器,在”思考—行动—观察”的循环中一步步完成任务,以及这种循环会怎样失败。