推理成本高、生成不可控、上下文一长就卡顿——这些问题在 LLM 应用落地时几乎人人都会遇到。工程上常见的对策是“剪枝”把权重稀疏化、把候选 token 截断、把 KV Cache 压缩。但剪枝的粒度停留在数值层面很少人追问模型到底依据什么语义规律决定哪些推理分支可以安全砍掉本文尝试把一个更偏理论的思考框架拆开来讲——语义热力学Semantic Thermodynamics与叙事引力Narrative Gravity。前者把 token 生成过程看成一种“语义系统的热力学演化”后者把上下文看成约束生成轨迹的引力场。两者结合能够为 LLM 推理剪枝提供一个比“只看概率大小”更完整的形式化视角。文章会先讲清楚这两个概念是什么再落到 LLM 推理链路的技术细节上最后给出一套可参考的工程映射与伪代码示例。适合对 LLM 推理优化、模型裁剪、可控文本生成感兴趣的开发者阅读不需要深入的物理学背景。1. 背景为什么 LLM 推理必须谈“剪枝”1.1 语言模型生成的高成本大语言模型采用自回归方式生成文本。每生成一个 token都要把当前已生成的全部 token 重新经过一次前向计算从词表中计算每个候选 token 的得分logits再通过 softmax 转成概率分布最后按某种采样策略选出下一个 token。这个过程有两个明显的成本来源词表很大但每一步只需要输出一个 token。比如词表 32K、64K 甚至 128K真正被选中的只有一个。其余候选的计算结果绝大多数被浪费了。上下文越长KV Cache 越大。注意力机制需要把历史 token 的 Key 和 Value 缓存起来每一步都要和这些缓存做计算。上下文长度翻倍KV Cache 也会随之增长。所以在推理阶段提高速度、降低内存占用几乎都离不开“剪掉某些不必要的东西”。1.2 剪枝的两层含义在 LLM 领域“剪枝”这个词其实有两层含义经常被混用层次对象目标典型手段权重剪枝模型参数减小模型体积、加速推理结构化稀疏、低秩分解、量化推理剪枝推理过程中的候选/缓存/计算路径降低单次生成延迟与内存top-k、top-p、KV Cache 压缩、提前终止本文讨论的重点是第二层推理剪枝。它不改变模型权重而是改变每次生成时的搜索空间与计算路径。1.3 从“局部贪心”到“全局语义约束”常见的推理剪枝策略比如 top-k 采样本质上是局部的只看当前步的概率分布把概率最低的 token 直接排除。但语言生成并不是一个局部事件。当前 token 的选择既受到前文约束也影响着后续所有 token 的生成空间。一个在局部看起来概率不低的 token可能把整段话引向语义崩坏一个局部概率中等的 token反而可能是让叙事继续推进的关键节点。这说明更合理的剪枝策略应该把“当前步”放到“全局语义轨迹”中评估。这也是语义热力学与叙事引力这两个概念真正有价值的地方——它们想把剪枝从“数值截断”升级为“语义约束”。2. 语义热力学与叙事引力两个核心概念2.1 先从热力学说起热力学研究的是大量微观粒子组成的宏观系统。温度、内能、熵、自由能这些概念描述的是系统整体状态。这里最值得关注的不是物理定律本身而是它的建模方式系统有大量微观状态每个微观状态都有对应的能量宏观上我们不逐一追踪每个粒子而是用统计规律刻画系统的概率分布。低频高能状态出现的概率低高频低能状态出现的概率高。这一套“微观状态 能量 概率分布”的语言和 LLM 生成文本的过程非常相似词表中的每个 token 是一个“微观状态”。logits 可以看成某种“能量”的负值。得分越高说明在当前上下文中该 token 被选中的倾向越强。softmax 的结果就是一个概率分布它定义了当前宏观状态上下文下各个微观状态出现的概率。2.2 语义热力学把文本生成当作热力学演化在语义热力学的视角下一段文本的生成过程可以理解为一个语义系统从高熵状态向低熵状态演化的过程。生成开始时模型只看到很少的上下文候选 token 范围宽分布比较平坦熵较高。随着上下文逐渐累积语义方向逐渐明确概率分布会越来越尖熵逐渐下降。最终生成的整段文本可以看成系统达到某个相对稳定的“语义平衡态”。这可以类比热力学中的自由能F U - TS其中 U 是“语义内能”可以理解成文本与上下文的语义契合程度S 是熵刻画候选分布的离散程度T 是“语义温度”控制系统对多样性或混乱状态的容忍度。自由能越低说明当前生成的文本在“符合语境”和“信息量/多样性”之间达到了较好的平衡。这个公式并不算严格的物理推导而是一种概念映射。它的价值在于提醒我们生成过程同时受到两股力量影响——一股力量把文本拉向高概率、低风险的“稳定语义状态”另一股力量让模型保持探索性不因为局部高概率就锁死整段文本。2.3 叙事引力上下文如何约束生成轨迹引力在物理中的核心是质量弯曲时空物体沿测地线运动。叙事引力借用了这个意象已经生成的文本构成一个“语义质量场”。它不直接决定下一个 token 一定要是什么而是改变了语义空间的结构——那些与既有叙事方向一致的 token处在更“低洼”的位置与当前叙事方向偏离较大的 token处在更陡峭、更不稳定的位置。注意力机制就是这种引力的一种工程化体现。某一时刻模型会把注意力集中在少量关键 token 上相当于那些 token 的质量最大对下一步生成方向有更强的牵引作用。KV Cache 里存的上文不只是字符串更是一个携带语义质量分布的“引力场”。用叙事引力的视角看LLM 生成时的每一步其实是候选 token 在当前语义引力场中做“定向坍缩”的过程。质量越大的前文概念越容易吸引后续 token 向它靠拢。2.4 为什么要形式化这两个概念如果只是停留在隐喻层面“语义热力学”和“叙事引力”就是两个漂亮的比喻对工程没有直接帮助。但一旦把它们形式化就可以得到可以用代码表达、用指标验证的剪枝规则可以定义语义熵来衡量当前生成状态的不确定性。可以定义语义势函数来衡量候选 token 与当前叙事的契合程度。可以定义自由能判据来决定哪些候选 token 值得保留、哪些应当剪掉。这就是标题中 “Formalizing” 的含义把比喻变成模型把模型变成算法。3. 环境与背景技术LLM 推理链路在把概念落到算法之前先快速过一遍 LLM 推理的关键环节以及剪枝策略常见的落点。3.1 自回归生成流程一次标准生成过程可以简化为输入 prompt得到最后一层隐藏向量。通过 LM Head 将隐藏向量映射到词表维度得到 logits。对 logits 做 softmax得到概率分布。按策略贪心、随机采样、beam search选择下一个 token。把新 token 拼接到输入更新 KV Cache进入下一步。剪枝策略可以作用于第 2、3、4、5 步在 logits 层面进行稀疏化。在概率分布层面截断低质量候选。在搜索路径上做剪枝。在 KV Cache 层面压缩历史信息。3.2 logits、温度、top-k、top-plogits 是模型输出的原始得分范围不固定。温度参数 T 会先缩放 logits再进入 softmaximport torch import torch.nn.functional as F def apply_temperature(logits, temperature1.0): if temperature 0: # 温度过低时直接走贪心 return logits.argmax(dim-1, keepdimTrue) return logits / temperature logits torch.tensor([[2.0, 1.0, 0.1, -1.0]]) logits apply_temperature(logits, temperature0.8) probs F.softmax(logits, dim-1) print(probs)温度越低分布越尖锐温度越高分布越平坦。top-k 只保留概率最高的 k 个候选top-pnucleus sampling保留累积概率超过 p 的最小候选集合。这些都是推理剪枝的经典手段但它们都只利用了概率分布本身的信息没有显式建模“语义引力”。3.3 注意力与 KV Cache在 Transformer 解码阶段每个 token 都会计算 Query和历史 token 的 Key 做点积得到注意力权重再对 Value 加权求和。历史 token 的 Key 和 Value 会被缓存下来避免每一步重复计算。注意力权重本身就是一个“质量分布”# 概念示例注意力权重分布 attention_weights torch.softmax(q k.transpose(-1, -2) / (head_dim ** 0.5), dim-1)注意力越集中的 token对当前生成的影响越大。这一点恰好对应叙事引力场中的“质量集中”。如果某些历史 token 在很长一段时间内注意力权重都接近 0说明它们对后续生成的贡献很低可以考虑在 KV Cache 中压缩或剪枝。3.4 剪枝策略的落点总结落点对应热力学/引力概念工程手段logits 层语义内能/势能logits 稀疏化、维度裁剪softmax 层温度/熵温度调节、分布平坦度约束采样层自由能判据top-k、top-p、语义约束采样注意力层引力场质量分布稀疏注意力、KV Cache 压缩上下文窗口语义场边界长文本截断、摘要压缩4. 核心机制将语义剪枝形式化下面给出一种概念性形式化方案。注意这不是某个开源库的官方定义而是一种“从隐喻走向算法”的建模思路。实际使用时需要结合具体模型和任务做调节。4.1 语义微状态与概率测度设当前上下文的语义状态为 C词表为 V。每个候选 token w ∈ V 都是一个语义微状态。模型的 logits 可以看作该微状态在当前语义场中的“负势能”U(w | C) -logits(w | C)采用 softmax 后候选 token 的生成概率为P(w | C) exp(-U(w | C)) / Σ_{v∈V} exp(-U(v | C))从这个角度理解logits 越大势能越小token 越容易被选中。4.2 语义熵与上下文信息量当前候选分布的熵定义为H(C) -Σ_w P(w | C) log P(w | C)熵高说明模型对下一步该生成什么没有明确把握候选分布平坦熵低说明语义方向已经比较收敛。语义熵可以作为剪枝的一个重要参考指标熵很低时说明当前语义方向非常明确剪枝可以激进一些保留少量候选即可。熵很高时说明上下文信息不足或语义存在明显分叉此时盲目截断低概率 token 可能丢掉未来关键的叙事分支剪枝要更保守。实际工程中你可以把每一步的熵记录到日志里观察模式def compute_entropy(probs: torch.Tensor) - torch.Tensor: # probs: shape [batch, vocab] log_probs torch.log(probs 1e-12) return -(probs * log_probs).sum(dim-1)4.3 叙事引力势函数叙事引力的核心假设是前文中的关键语义单元会对候选 token 产生“吸引”。我们可以定义一个势函数来衡量候选 token 与当前上下文语义场的引力作用。设前文共有 N 个 token每个 token t_i 的语义强度为 m_i可以取注意力权重的聚合值、TF-IDF 权重或嵌入向量的范数候选 token w 与 t_i 的语义相似度为 sim(w, t_i)。那么候选 token 的叙事引力势可以定义为G(w | C) Σ_{i1}^{N} m_i · sim(w, t_i)G(w) 越大说明候选 token 越容易被前文语义场“捕获”越符合当前叙事方向。计算相似度时可以用嵌入向量的余弦相似度也可以用注意力得分的聚合值实例化。在剪枝场景中我们不再只按原始概率排序而是把叙事引力势作为“语义偏置”叠加到候选得分上score(w) log P(w | C) λ · G(w | C)其中 λ 是引力强度系数控制前文语义对当前生成的约束程度。λ 越大生成越倾向于紧跟已有叙事λ 越小模型越自由。4.4 自由能剪枝判据结合前面的“语义内能”和“语义熵”可以构造一个自由能目标F(w) -score(w) - T · H(C)在剪枝时我们希望保留自由能较低的候选 token 集合同时控制候选集合的规模。一个简单的算法思路是计算所有候选 token 的原始 logits。计算语义熵 H(C)。计算候选 token 的叙事引力势 G(w)。得到修正后的 score(w)。按 score 排序累积保留概率剪掉尾部低分 token。这样得到的效果是剪枝不再只看当前步的概率大小还会考虑候选 token 是否与叙事方向一致、当前不确定性是否足够高。如果当前熵很高系统会自动“宽容”一些候选 token 进入保留集合如果熵很低剪枝就可以更果断。5. 工程映射可落地的剪枝策略概念需要代码来验证。下面给出一个概念性实现演示如何把上述形式化思路映射到一次采样过程中。5.1 概念性框架NarrativeGravityPruner 概念性示例基于叙事引力与语义熵的推理剪枝 仅用于说明思路需要根据实际模型结构做适配 from dataclasses import dataclass from typing import List, Optional import torch import torch.nn.functional as F dataclass class ContextState: 当前上下文状态记录语义质量与注意力分布 token_ids: List[int] attention_weights: torch.Tensor # shape [num_tokens, num_tokens] hidden_states: torch.Tensor # shape [num_tokens, hidden_dim] def compute_narrative_gravity( candidate_emb: torch.Tensor, context: ContextState, temperature: float 1.0, ) - torch.Tensor: 计算候选 token 与前文语义场之间的引力势。 这里用候选 token 嵌入与前文 token 嵌入的注意力相似度加权求和。 # candidate_emb: [num_candidates, hidden_dim] # context.hidden_states: [num_tokens, hidden_dim] # 使用缩放点积注意力作为相似度也可以用余弦相似度 scores candidate_emb context.hidden_states.T # [num_candidates, num_tokens] scores scores / (candidate_emb.shape[-1] ** 0.5) # 用注意力权重作为语义质量 mass context.attention_weights[-1] # 最后一步的注意力权重近似衡量前文质量 mass F.softmax(mass, dim-1) # 加权得到叙事引力势 gravity (scores * mass.unsqueeze(0)).sum(dim-1) # [num_candidates] return gravity / temperature def narrative_gravity_prune( logits: torch.Tensor, candidate_emb: torch.Tensor, context: ContextState, top_p: float 0.9, lambda_gravity: float 0.1, temperature: float 1.0, ): 基于叙事引力修正后的采样剪枝。 流程 1. 计算原始分布。 2. 计算叙事引力势。 3. 将引力势叠加到 logits 上。 4. 按 top-p 累积概率截断。 # 原始 logits 加温度 scaled_logits logits / temperature probs F.softmax(scaled_logits, dim-1) # 计算叙事引力势 gravity compute_narrative_gravity(candidate_emb, context, temperature) # 修正 logits保留原始语义内能同时叠加前文引力偏置 adjusted_logits scaled_logits lambda_gravity * gravity # 基于累积概率的 top-p 剪枝 sorted_logits, sorted_indices torch.sort(adjusted_logits, descendingTrue) sorted_probs F.softmax(sorted_logits, dim-1) cumsum_probs torch.cumsum(sorted_probs, dim-1) # 找到超过 top_p 的截断位置 cut_pos torch.searchsorted(cumsum_probs, top_p) 1 # 构造掩码只保留前 cut_pos 个候选 mask torch.zeros_like(adjusted_logits) mask.scatter_(-1, sorted_indices[:, :cut_pos], 1.0) # 未被剪掉的候选重新归一化 masked_logits adjusted_logits.masked_fill(mask 0, float(-inf)) final_probs F.softmax(masked_logits, dim-1) return final_probs, gravity这段代码是一个“思路示例”不是可以直接放进任何项目就跑的现成库。你需要根据具体模型获得候选 token 对应的嵌入向量。历史 token 的注意力权重。合适的相似度函数。但核心逻辑已经清楚先算原始分布再计算叙事引力势修正后做 top-p 剪枝。这样剪枝结果不仅受当前概率影响还受前文语义场约束。5.2 用语义熵指导温度调节另一个工程化思路是动态温度。传统做法是温度固定但语义熵高时固定温度容易让生成发散语义熵低时固定温度又可能让文本过于保守。可以在推理时维护一个动态温度def adaptive_temperature(entropy: float, base_temp: float, target_entropy: float): 熵高于目标时适当降低温度避免过度随机 熵低于目标时适当提高温度提升多样性。 diff entropy - target_entropy # 简单的线性调节实际项目中可以换成更平滑的策略 return base_temp 0.1 * diff这里有一个值得注意的细节温度作用于 logits但熵描述的是“当前分布的不确定性”。当模型本身对下一步没有把握也就是熵高时更高温度会让更多无关 token 进入候选范围。调节方向需要根据场景判断——如果目标是稳定长文本生成熵高时应该更保守而不是更随机。5.3 KV Cache 的“引力场剪枝”KV Cache 压缩是长文本推理的核心需求。传统做法基于 token 的注意力分数直接剪掉低分 token。结合叙事引力的思路可以多做一个语义层判断如果某个历史 token 的注意力权重低并且与当前上下文嵌入的相似度低说明它已经处在语义引力场边缘可以优先压缩。如果某个 token 注意力权重低但它承载着关键的叙事主题比如一段话的核心概念即使当前注意力不高也应该保留。这种“语义重要性”可以通过计算 token 嵌入在句向量方向上的投影得到。更简单的做法是给每个 token 维护一个长期重要性得分每步更新importance 0.9 * old_importance 0.1 * attention_weight当 importance 持续低于阈值时再考虑从 KV Cache 中淘汰。5.4 结合传统策略的推荐层级落到实际项目时建议按不同层级组合使用层级目标推荐策略候选 token 层控制采样空间动态 top-p 叙事引力校正分布层控制整体随机性基于熵的适应温度上下文层控制计算量注意力权重 语义重要性双指标压缩 KV Cache生成流程层控制长度当熵低且置信稳定时提前终止生成6. 常见问题与排查思路这里整理几个理解语义热力学与叙事引力时容易踩的误区。问题现象常见原因解决思路剪掉低概率 token 后生成质量反而下降只按概率剪枝丢弃了延续叙事的关键分支把语义相似度或叙事引力势加入排序依据固定低温生成文本过于保守温度过低导致分布过度尖锐多样性下降结合语义熵做动态温度调节长文本生成到中途开始偏题前文对后续方向约束不足叙事引力较弱加大 lambda_gravity或提高上下文关键 token 的语义质量KV Cache 压缩后生成不连贯只按注意力权重剪枝把关键主题 token 删掉了增加长期重要性得分别一次剪太多高熵状态下 top-p 截断仍然无效top-p 集合过大采样随机性仍然很高先降低温度再使用更小的 top-p或引入最小候选数量限制几个排查时可以重点确认的问题语义熵的计算是否使用了正确的分布如果 logits 还没有做温度缩放计算出的熵会失真。叙事引力势的相似度函数是否稳定不同嵌入空间里余弦相似度的分布范围差异很大最好做归一化。lambda_gravity 是否设置过大过大时生成会被前文“锁死”反复写同一个主题过小时又退化为普通 top-p 采样。KV Cache 剪枝是否逐层独立不同层的注意力分布差异很大最好按层设置不同阈值。7. 最佳实践与工程建议7.1 先定义场景目标再选剪枝策略剪枝不是越狠越好。不同场景的目标差异很大代码生成需要高确定性适合低温度 小 top-p 强叙事引力约束。剧情写作需要一定多样性适合中等温度 动态熵控制 弱引力约束。问答系统需要忠实于上下文适合强引力约束 严格 KV Cache 保留策略。头脑风暴需要探索性适合高温度 高熵容忍 弱剪枝。没有统一的“最佳剪枝配置”只有“最适合当前场景的配置”这一点在语义剪枝中体现得尤其明显。7.2 用指标验证不要凭感觉调参引入语义热力学与叙事引力后需要有三类指标支撑指标说明生成质量指标困惑度、BLEU、ROUGE或针对任务的自动化评估多样性指标文本间的重叠度、n-gram 多样性、语义距离方差效率指标延迟、KV Cache 内存、每 token 平均剪枝比例特别建议把每一步的语义熵、引力势最大值、剪枝比例记录下来。训练一个线上调试面板观察不同 prompt 下模型是快速收敛还是持续发散。这类日志信息比只看最终生成文本更容易定位问题。7.3 把叙事引力做成轻量级 rerank 层最稳妥的落地方案不是在现有采样逻辑上做大规模改造而是增加一个轻量级 rerank 层按原始概率采样生成一批候选 token。对候选 token 计算叙事引力势。在候选集合内做重新排序。最终从排序后的集合中选择。这样既不会干扰模型原本的 logits 计算也能随时开关线上回滚非常方便。它本质上是在“模型概率”和“语义约束”之间加了一个可调权重的中间层。7.4 注意安全边界与可控性任何涉及生成内容可控性的调整都需要考虑安全和合规边界不要为了“高确定性”而把生成内容锁死导致用户输入中的攻击性内容直接传递。不要为了“叙事引力”而无限强化前文中的偏见内容。剪枝策略一旦上线需要有安全兜底如果检测到生成内容存在风险立即切换回默认采样策略。这些建议不是形式化理论的附属品而是任何推理优化方案上线前都需要过的安检。8. 总结与学习路线本文围绕“语义热力学”和“叙事引力”这两个概念做了一次完整的拆解。重点内容包括推理剪枝不只是权重稀疏化还包括候选 token、KV Cache、采样路径上的剪枝。语义热力学用熵、温度、自由能来描述 token 分布的状态变化。叙事引力用“语义质量场”来解释前文对后续生成的约束。两者结合可以把剪枝从“只看当前概率”升级为“同时看语义方向与不确定性”。给出了可参考的概念性伪代码包括叙事引力修正、动态温度、KV Cache 双指标压缩。如果你想把这套思路真正落地下一步建议按这个顺序学习先掌握标准推理代码理解 logits、温度、top-k、top-p 在代码中的位置。在现有采样代码上增加语义熵日志先只记录不改行为。用真实业务数据观察不同场景下的熵分布找到高熵和低熵的分水岭。再尝试把叙事引力势作为一种 rerank 信号加入候选筛选。最后设置可回滚的线上实验用延迟和生成质量指标验证收益。如果你现在正好在优化 LLM 推理性能可以先把项目中每一步的语义熵打印出来观察一下。很多问题在熵分布图上会变得非常直观该收敛的地方没收敛该发散的地方被压得太死一眼就能看出来。希望这篇文章能帮你打开一个新的视角剪枝不只是工程上的省内存手段它也可以是一项有理论层次的建模工作。