深度剪枝——整块拿走,以及怎么决定拿哪块
这一章讲三件事: 删整块为什么格外划算(答案出人意料);「删哪块」的静态与数据驱动两条路各长什么样、各信什么;以及一个 28 块小模型上的完整对比实验——同样的删块数,选法不同,成绩天差地别。 第 02 章欠的那个问题——「凭什么删最后两层」——本章正式回答,并且推翻它。
1. 这一章讲什么
第 02 章删层靠假设,这 一章给方法。核心主张一句话:块的重要性不是模型的固有属性,而是相对于你给它喂的数据和要它干的活的属性1。这句话把本书从「机械裁剪」带进「测量科学」:先用钩子看模型处理你的数据时每块实际改了多少信息,再决定谁下岗。
它在全书链条里的位置: 第 03 章认识了「块」,本章给块级手术装上瞄准镜;同一套瞄准镜(钩子+余弦相似度——第三章讲过的那把软尺)在第五章对准神经元,在第八章对准注意力层。
2. 顶层全景
为什么删整块划算
│ 真因:省的不是计算,是显存↔计算单元之间的搬运(内存墙)
▼
删哪块的三个路标
├─ 静态·位置:保头 4 尾 2(便宜,瞎猜成分高)
├─ 静态·幅度:权重范数小的删(便宜,仍不看你数据)
└─ 数据驱动:hooks 截输入输出 → 1 − 余弦相似度 = 重要性分
│
▼
评估:删 4/28 块的八种选法同台比武 → 选法决定生死(73.1% vs 9%)
先钉死术语,免得后文打架(书里的约定):块=完整重复部件(注意力+MLP 整套);模块=块内的功能件(self_attn、mlp);层=单个运算(一个 Linear、一次归一化——把数值拉回统一尺度的步骤)。
著名论文 ShortGPT 的重要性指标(给部件打分的那把尺)就叫 Block Influence——「块影响力」,用的正是这套叫法2。
3. 核心原理
3.1 为什么删块格外划算:瓶颈在搬运,不在计算
直觉说「删计算就快」,本书纠正:推理时 GPU 的大问题不是算不过来,是喂不上料——它有相当一部分算力在干等数据从显存赶路过来,数学单元(GPU 里真正做乘加运算的部件)的利用率常常只有五到七成3。这种「卡在搬运上」的状态有个名字:memory-bound(内存受限)。
删整块删掉的是一整套「从显存读进、算一遍、写回去」的循环:块数少一,这样的循环就少一轮4。体积上也有账:Qwen3-0.6B 里全部变换块占模型体积的 58%,平均一块 2.1%——删一块,加载模型就省 2.1%5。更要紧的是动态内存:每个块的注意力都要往 KV cache 里记账,删四分之一的层,每生成一个词就少涨四分之一的账——这本账在长对话里能超过模型本体6。
但代价必须同框说:提速只跟删几块有关,损伤才跟删哪块有关。书里用一组对照实验钉死这一点:同样删四块,提速幅度完全一样,成绩损失——掉多少分——却差出去很远7。所以本章的真正问题只有一个——删哪块。
3.2 静态选块:便宜,但 瞎
按位置删。 中间层被认为冗余最多(头层学基础表示,尾层做任务精化);28 层删中间 4 块,保住 85.7% 的深度。在它之上叠一层保护习惯:保住头四块和尾二块——这条规则由论文 Shortened LLaMA(Kim 等,2024)明确成文8。
按权重幅度删。 假设权重整体偏小的块改动数据少、贡献小:把每块所有参数的范数(可理解为「劲道」)加总,从最小的删起。代码十行,Qwen3-0.6B 选出来的四块是 8、2、7、69。
静态法的共同毛病,书里说得不留情面:不认识上下文。权重小可能只是训练数据没喂到那类模式,不代表对你的任务不重要;「尾层可弃」对经过多轮微调的模型也未必成立——不然也不需要专门发明保护规则。更麻烦的是,幅度几乎相同的两块可能干着完全不同的活10。
3.3 数据驱动选块:给块打重要性分
三个零件:钩子、标 尺、你的数据11。
钩子(PyTorch hook) 是框架提供的一种挂载机制:把一个函数挂到某个模块上,数据每次流过它就自动执行,不用改模型代码。挂在每个块上,把「进入块的张量」和「流出块的张量」都截下来12。截到的东西长什么样?一句八个词的输入,进块时是一个 [1, 8, 1024] 的张量——一批 1 条、8 个 token、每个 token 1024 维13。
标尺是余弦相似度(第 03 章末尾预告过):量两个向量方向有多一致,同向得 1,垂直得 0,反向得 −1。为什么不用更直觉的距离?因为距离同时被「长度」和「方向」影响,而长度变了不代表意思变了——方向才装着语义14。书里用三个句子演示(_embed 模型输出 384 维向量):「猫在沙发上打盹」和「猫咪安睡在躺椅」相似度 0.6106;和「公交在拐角停车」只有 0.056315。计算上就是先把向量归一化、再做点积——归一化后点积即余弦16。
拼起来:每块的重要性 = 1 − 平均余弦相似度。 某块进出几乎不变(相似度 0.99)→ 重要性 0.01,下岗候选;改动很大(相似度 0.60)→ 重要性 0.40,留着17。两个工程细节值得带走:padding 位要剔除再平均——补位处的输出几乎等于输入,会把分数人为抬高;跑全部校准数据取平均,平滑单条样本的偶然18。
3.4 主走查:28 块模型上的选块与比武
走查对象:Qwen3-0.6B(28 块),校准数据 WinoGrande(指代消解题)。 跑完重要性分析,分数长这样:
重要性最高的六块 重要性最低的六块
块 0 0.947(一骑绝尘) 块 25 0.025
块 1 0.130 块 26 0.025
块 2 0.129 块 24 0.030
块 3 0.122 块 23 0.031
块 4 0.120 块 13 0.045
块 27 0.111 块 22 0.046
(这些分数为原书实测,非编造)
图说:块 0 在做原始表示的第一次编码,改得最狠;
尾部聚着一窝「几乎是转发站」的块——直觉上它们最该删[^19]。
两道保护开关在此登场:保头四尾二(启发式保护)、不删相邻块(相邻保护)。书里对后者态度审慎——「删连续两块会挖掉一段不间断的通道,可能伤更重」这个直觉并没有硬证据,它被当作待检验的选项而非铁律19。开关组合出两种选法:不设保护选 [25, 26, 24, 23](扎堆尾部);双保护选 [25, 23, 13, 15](尾部两刀+中间两刀)20。
然后是全书这一章的重头戏:八种删法,同样删 4 块,同台比武。删完不恢复,直接考试(WinoGrande 测指代、LAMBADA 测长程语言,后者是没有随机底线的压力测试,崩了就近零)21:
| 删法(删的都是这 4 块) | WinoGrande 保留 | LAMBADA 保留 |
|---|---|---|
| 删尾 4 块 [24-27] | 92.2% | 9% |
| 删尾 4 块(保末块)[23-26] | 96.4% | 10.2% |
| 幅度法 [8,2,7,6] | 88.6% | 3.2% |
| 数据驱动·无保护 [25,26,24,23] | 96.4% | 10.2% |
| 中间连删 [12-15] | 96.1% | 63.7% |
| 中间散删 [11,13,15,17] | 88.7% | 34.6% |
| 数据驱动·双保护 [25,23,13,15] | 97.2% | 73.1% |
三行最值得盯着看:
- 删尾=自杀。 直觉以为尾层的「润色」最可有可无,实测长程能力掉到 9%——第 02 章那个「删末端安全」的假设,在「删得多」时翻车;
- 散删反而输给连删。 中间连删保住 63.7%,散开删只有 34.6%——「不删相邻」这条直觉在本模型上被数据打脸22;
- 冠军是双保护的数据驱动选法:尾部让一刀、中间补两刀,两个区域分摊损伤——尾块保持输出通路的连通,中块吸收结构代价23。
还 有一处诚实的注脚:不看校准数据的话,余弦分数根本跳不出「尾部扎堆」这个显眼目标——28 块的小模型上信号不够强;换大模型、块间分工更细,数据驱动对静态的优势才会拉开。同一套方法换 WikiText 校准,底部选块立刻不同(块 26 换成块 13):不同的数据,不同的信号,不同的模型24。
速度那半张成绩单(只跟删几块挂钩的再验证):删 4/28 块,推理时间 2.834 秒→2.43 秒,首 token 时间 64.5ms→54.4ms,吞吐(每秒产出多少词)17.65→20.61 token/秒,提升 12%-17%,两种选法几乎重合25。
4. 作者的判断与证据
给了证据的: 八模型对比表的全部数字来自原书 notebook(T4,可复现);重要性公式与 ShortGPT 的 Block Influence 同源——BI 就是 1 − 块输入输出的余弦相似度,本章手搓的正是它26。论文侧的硬数字:ShortGPT 剪 27.1% 的 Llama2-7B,不做任何恢复仍保留 86.3% 的平均成绩,同期 LLMPruner 和 SliceGPT 只有 72.8% 与 68.7%——一把「只需一次前向」的软尺打赢了需要梯度或反复多轮重跑的复杂方法27。相关性也验过:Llama2-7B 中层 BI 约 0.05,删了困惑度(衡量它读文字有多惊讶,越低越好)几乎不动;头层 BI 高于 0.4,一删就飙——这套指标验证到了 70B 模型28。
作者的判断(书里明说的取舍): 本章方案是缝合出来的,没有哪篇论文 100% 对应——Shortened LLaMA 贡献保护启发式,ShortGPT 贡献度量;作者的评论很坦诚:「很多时候我们不是在找新技术,是在给自己的主意找验证」——0.6B 上做实验,靠 70B 的论文确认它站得住29。
另一组论文数字(备查): Shortened LLaMA 把「删块 vs 删神经元」放到延迟上比:剪 35% 的 LLaMA-7B,深度剪枝延迟降 33%(2.4s→1.6s)、吞吐升 49%(53.7→80.1 token/秒),而宽度剪枝反而变慢——想提速,删块是对的杠杆30。它对比过的两种学术指标:困惑度法(逐块试删、各跑一遍推理,28 块就是 28 遍)和 Taylor 梯度法(要反向传播)——都比余弦贵31。
5. 边界与局限
- 校准数据的影子。 选块结果跟着数据走是特性也是风险:换数据就换答案,你需要对「我的校准集能代表生产流量」负责;书里只演示了两个数据集,没有给「怎么验证代表性」的方法。
- 相邻保护在本模型上无益,但不可一概而论。 作者明说这是「待研究的选项」;不同模型、不同删块率下的最优开关组合要自己测。
- 小模型的结论外推(拿小范围结果推大范围)有限。 0.6B 上数据驱动对静态的优势在底部才显现;书里用「效应随模型变大而增强」解释,但这本身是从论文数字推回小实验的判断。
- 本章不处理恢复。 删完掉的分,蒸馏能找回多少,是第六章的事;两篇论文各自的恢复路线(LoRA/继续预训练(接着用海量文本再练)/轻量 MLP 替补)在那里汇合32。
6. 可带走的
- 推理瓶颈是搬运不是计算:删块的直接收益是少一轮「读-算-写」,提速只问删几块,不问删哪几块;
- 块的重要性相对于数据:校准数据就是任务说明书,换数据等于换考卷;
- 余弦相似度量「改了多少方向」:1 − 相似度 = 重要性,同款公式即 ShortGPT 的 Block Influence;
- 保头四尾二是经验不是定律:删尾 4 块能把长程能力打到 9%,「尾层只是润色」在小删陈量下才成立;
- 「不删相邻块」这条直觉会 被数据打脸:先测,再信;
- padding 必须剔除:补位处的「输入≈输出」会污染重要性分;
- 选择题基准和生成基准要一起看:WinoGrande 贴着随机线看不出好坏,LAMBADA 才是压力测试;
- 要在论文里找一个「软尺」:一次前向就能算的指标,往往比需要梯度或多轮重跑的更划算。
7. 原文地图
| 主题 | 原书章 | 原文位置 |
|---|---|---|
| 深度剪枝定义与术语约定 | 4.1 Fundamentals and benefits of depth pruning | text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:7(搜「removing entire Transformer blocks」) · text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:26(搜「Block Influence」) |
| 深模型更扛剪 | 4.1 Fundamentals and benefits of depth pruning | text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:65(搜「functional redundancy」) |
| 内存墙与 memory-bound | 4.1 Fundamentals and benefits of depth pruning | text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:77(搜「data movement in memory」) · text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:83(搜「50-70%」) · text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:89(搜「memory-bound」) |
| 58%/2.1% 与 KV cache 账 | 4.1 Fundamentals and benefits of depth pruning | text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:95(搜「58%」) · text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:101(搜「exceed the size」) |
| 提速看数量、损伤看选择 | 4.1 Fundamentals and benefits of depth pruning | text/08-ch04-01-4-1-fundamentals-and-benefits-of-depth-pruning.txt:113(搜「regardless of which ones」) |
| 静态法与保护启发式 | 4.2 Static block selection | text/09-ch04-02-4-2-static-block-selection.txt:7(搜「zero computational cost」) · text/09-ch04-02-4-2-static-block-selection.txt:94(搜「85.7%」) · text/09-ch04-02-4-2-static-block-selection.txt:100(搜「preserve the first four」) |
| 幅度法与弱点 | 4.2 Static block selection | text/09-ch04-02-4-2-static-block-selection.txt:118(搜「magnitude of the weights」) · text/09-ch04-02-4-2-static-block-selection.txt:158(搜「8, 2, 7, 6」) · text/09-ch04-02-4-2-static-block-selection.txt:176(搜「ignorance of the context」) · text/09-ch04-02-4-2-static-block-selection.txt:195(搜「radically different roles」) |
| 重要性相对论 | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:7(搜「relative to the data」) |
| 钩子机制与张量形状 | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:132(搜「attach a function」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:236(搜「8, 1024」) |
| 余弦 vs 距离、三句演示 | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:279(搜「Euclidean distance」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:332(搜「all-MiniLM-L6-v2」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:407(搜「0.6106」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:420(搜「0.6*1」) |
| 重要性=1−相似度、padding | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:708(搜「importance of 0.40」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:714(搜「dilute the score」) |
| 分数分布与校准数据的影响 | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:853(搜「0.947226」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:903(搜「dominates the cosine ranking」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1015(搜「convergence at the top」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1062(搜「different data, different model」) |
| 两种保护开关与选块结果 | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:897(搜「weaker ground」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1144(搜「25, 23, 13, 15」) |
| 八模型对比与三行结论 | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:1272(搜「9%」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1342(搜「73.1%」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1413(搜「73.1%」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1419(搜「clean consecutive chunk」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1425(搜「not strong enough to escape」) |
| 速度收益 | 4.3 Data-Driven block selection | text/10-ch04-03-4-3-data-driven-block-selection.txt:1491(搜「17.65」) · text/10-ch04-03-4-3-data-driven-block-selection.txt:1532(搜「not which ones」) |
| 论文数字:Shortened LLaMA | 4.4 From paper to practice | text/11-ch04-04-4-4-from-paper-to-practice.txt:19(搜「2.4s to 1.6s」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:25(搜「shoots up」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:31(搜「Taylor」) |
| 论文数字:ShortGPT/BI | 4.4 From paper to practice | text/11-ch04-04-4-4-from-paper-to-practice.txt:37(搜「Block Influence」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:43(搜「86.3%」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:49(搜「68.7%」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:55(搜「around 0.05」) |
| 恢复路线与本书取舍 | 4.4 From paper to practice | text/11-ch04-04-4-4-from-paper-to-practice.txt:67(搜「above 40%」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:73(搜「Minitron」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:85(搜「fits 100%」) · text/11-ch04-04-4-4-from-paper-to-practice.txt:91(搜「validation of our idea」) |
| 动手练习(无新机制):三种删法对照、逐个关闭保护开关 | 4.5 Hands-on lab | text/12-ch04-05-4-5-hands-on-lab.txt:13(搜「Compare static versus data-driven」) |