
1. 项目缘起当推理速度成为瓶颈最近在折腾本地部署的大语言模型从7B参数到70B参数的模型都试了个遍。硬件从消费级显卡换到专业卡显存占用和计算延迟的问题算是缓解了但一个新的瓶颈越来越突出生成速度。尤其是在需要长文本、多轮对话或者批量处理的场景下模型“思考”和“吐出”下一个词的速度直接决定了用户体验和系统吞吐量。我们常说的“推理优化”大家第一反应可能是量化、算子融合、KV Cache这些底层技术。这些确实重要是基础。但今天想聊的是一个更“上层”的优化点解码策略。模型计算出下一个词的概率分布后我们怎么从这个分布里选词这个选择过程本身对生成质量、速度和多样性有巨大影响。最常见的策略是贪心搜索Greedy Search和核采样Top-p/Nucleus Sampling。贪心搜索每次都选概率最高的词速度快但容易陷入重复、枯燥的循环核采样引入随机性生成更丰富但有时会“跑偏”。而在一些对连贯性和准确性要求更高的任务比如代码生成、翻译中集束搜索Beam Search因其能保留多个候选序列、找到全局更优解而备受青睐。不过它的计算和内存开销也大beam width设大了速度骤降。就在研究如何平衡Beam Search的质量与效率时我注意到了学术界和工业界开始讨论的一种新方法Tilted Sampling倾斜采样。它被描述为一种试图结合采样随机性与搜索确定性的混合策略。光看论文标题和摘要感觉它像是来“踢馆”Beam Search的。那么在实际的本地大模型推理场景下这两种策略到底孰优孰劣Tilted Sampling是噱头还是真有奇效这就是我进行这次对比分析的初衷。2. 核心概念拆解Beam Search的“重”与Tilted Sampling的“巧”在深入对比之前我们必须先抛开晦涩的数学公式用工程师能懂的语言把这两个策略到底在干什么讲清楚。理解它们的机制是后续分析性能差异的基础。2.1 Beam Search步步为营的“多线程”规划你可以把文本生成想象成走迷宫。贪心搜索是每到一个岔路口只看眼前最亮概率最高的那条路头也不回地走下去。这样很容易走进死胡同或者绕圈子。Beam Search则聪明一些。它设定了一个“光束宽度”Beam Width, 记为b。在每一步生成每一个token时它不再是只看一条路而是同时维护b条最有希望的路径。具体过程如下初始化从起始词如bos开始这算作一条路径其得分为0或1取对数后为0。扩展对于当前维护的b条路径每条路径都让模型预测下一个词的概率分布。这样我们会得到b * vocab_size个可能的下一步候选vocab_size是词表大小。排序与剪枝计算每个“路径新词”组合的累积得分通常是每一步预测概率的对数之和。然后从这海量的候选里只保留总得分最高的b条路径。重复用这新的b条路径继续第2步直到生成结束符或达到最大长度。为什么说它“重”计算量每一步都需要模型前向传播b次如果做了KV Cache优化一次前向可以同时计算b个序列的下一个token但注意力计算等开销仍与b成正比。内存开销需要同时存储b个序列的KV Cache显存占用大约是贪心搜索的b倍。延迟由于每一步都要处理b个序列并排序即使并行化其延迟也显著高于贪心搜索。它的优势在于“前瞻性”。通过保留多条路径它更有可能避免早期的一个局部最优选择比如一个看似概率高但会导致后续无话可说的词从而找到整体概率更高的输出序列。这在需要严格遵循语法、格式或事实的任务中表现很好。2.2 Tilted Sampling给概率分布“加杠杆”的智能随机Tilted Sampling 的核心思想非常直观我们不进行复杂的多序列维护和排序而是通过巧妙地扭曲原始的概率分布让一次采样行为就能“模仿”出某种搜索的效果。具体来说在得到模型输出的下一个词的概率分布P(x)后Tilted Sampling 不会直接从这个分布中采样如核采样也不会只取最大值如贪心而是先对这个分布进行一个“倾斜”变换P_tilted(x) ∝ P(x)^(1/τ)这里的τ是一个关键的温度参数但作用和传统温度采样相反。当τ 1时1/τ 1相当于对概率进行了一次“锐化”。高概率的词会变得概率更高低概率的词会更低。当τ - 0时P_tilted会趋近于一个one-hot分布即贪心搜索。这使采样行为更“确定”偏向高概率词。当τ 1时1/τ 1相当于对概率进行了一次“平滑”。概率分布变得更均匀低概率词有更多机会被选中。这使采样行为更“随机”探索性更强。而Tilted Sampling的“巧”在于它可以根据生成过程动态调整τ。一种常见的策略是在生成初期使用较小的τ更确定在生成后期使用较大的τ更随机。这样设计的逻辑是什么初期确定小τ文本的开头至关重要它决定了后续内容的范围和基调。此时采用更确定性的选择有助于锚定一个高质量、连贯的起点类似于Beam Search在初期保留高概率路径。后期随机大τ当主题和框架已经确立后引入更多的随机性可以增加结尾的多样性和创造性避免陷入模板化的枯燥表达。为什么说它“巧”计算轻量它只需要一次模型前向传播和贪心、核采样一样然后进行一次分布变换和采样。计算开销和内存开销与贪心搜索几乎无异。效果模拟它试图通过单序列采样的方式模拟出多路径搜索的某些好处——初期追求质量后期追求多样性。那么一个很自然的问题就出现了这个“廉价”的Tilted Sampling其生成质量真的能媲美“昂贵”的Beam Search吗这就是我们接下来要通过实测来探究的。3. 实验设计与环境搭建在本地复现对比战场理论分析需要实验验证。为了得到可信的结论我设计了一套尽可能控制变量的对比实验。所有实验均在我的本地工作站进行以确保环境一致。硬件与软件环境CPU: Intel i9-13900KGPU: NVIDIA RTX 4090 (24GB VRAM)内存: 64GB DDR5软件栈: Ubuntu 22.04, Python 3.10, PyTorch 2.1, Transformers 4.36, 使用vLLM作为推理引擎因其对注意力优化和KV Cache管理极为高效。模型选择为了结论的普适性我选择了两个不同尺寸和架构的流行开源模型Llama 3 8B Instruct: Meta最新推出的中等尺寸模型指令跟随能力强代表当前SOTA的中小模型。Qwen 1.5 32B Chat: 阿里通义千问的模型参数量大能力更强用于检验策略在不同模型规模下的表现。解码策略配置Beam Search (BS): Beam Widthb分别设置为 2, 4, 8。启用长度惩罚length_penalty0.6以缓解长文本生成时Beam Search倾向于生成过短序列的问题。Tilted Sampling (TS): 实现一个动态温度调度器。我参考了相关论文采用线性调度τ τ_start (τ_end - τ_start) * (step / max_length)。经过初步网格搜索设定τ_start 0.5(更确定)τ_end 1.5(更随机)。采样方式为Top-p采样p0.9结合倾斜后的分布以保证基础质量。基线对比:Greedy Search: 贪心解码。Nucleus Sampling (Top-p): p0.9温度T1.0作为随机采样的主流基线。评估任务与数据集我选择了三个有代表性的文本生成任务以覆盖不同需求代码生成 (偏重准确性、确定性): 使用HumanEval数据集的一个子集要求模型根据函数签名和文档字符串补全Python代码。创意写作 (偏重多样性、新颖性): 给定一个故事开头如“在量子计算机产生自我意识的那天早晨…”要求续写300字。知识问答与摘要 (偏重事实性、连贯性): 从CNN/DailyMail数据集中选取新闻片段要求生成摘要。评估指标质量指标:代码生成: 通过执行测试用例的通过率Pass1。创意写作 摘要: 采用基于BERT的文本相似度BERTScore评估与参考文本的语义贴合度同时由我和一名同事进行人工可读性、连贯性和创意性的主观评分1-5分。效率指标:生成延迟: 平均每个token的生成时间ms/token。吞吐量: 在固定批次大小batch_size4下每秒能生成的token数tokens/s。GPU内存占用: 峰值显存使用量。所有实验均重复5次取平均值以减少随机波动。实验代码的核心部分Tilted Sampling 调度器如下所示方便大家复现class DynamicTiltedSampler: def __init__(self, tau_start0.5, tau_end1.5, top_p0.9): self.tau_start tau_start self.tau_end tau_end self.top_p top_p def __call__(self, logits, step, max_length): 对logits进行倾斜变换并采样 # 计算当前步的动态温度τ tau self.tau_start (self.tau_end - self.tau_start) * (step / max_length) # 倾斜变换logits / tau tilted_logits logits / tau # 将logits转换回概率 probs F.softmax(tilted_logits, dim-1) # 应用Top-p过滤 sorted_probs, sorted_indices torch.sort(probs, descendingTrue) cumulative_probs torch.cumsum(sorted_probs, dim-1) sorted_indices_to_remove cumulative_probs self.top_p sorted_indices_to_remove[..., 1:] sorted_indices_to_remove[..., :-1].clone() sorted_indices_to_remove[..., 0] 0 indices_to_remove sorted_indices_to_remove.scatter(-1, sorted_indices, sorted_indices_to_remove) probs probs.masked_fill(indices_to_remove, 0.0) probs probs / probs.sum(dim-1, keepdimTrue) # 重新归一化 # 采样 next_token torch.multinomial(probs, num_samples1) return next_token4. 性能对比结果效率与质量的博弈经过数天的批量运行和数据收集我将结果整理如下。为了更直观我将关键数据做成了表格。表1代码生成任务HumanEval性能对比 (模型: Llama 3 8B)解码策略配置Pass1 (%)延迟 (ms/token)吞吐量 (tokens/s)峰值显存 (GB)Greedy-52.312.1330.68.7Top-pp0.9, T1.048.712.5320.08.7Beam Searchb255.623.8168.110.1Beam Searchb457.945.288.511.8Beam Searchb856.488.745.114.5Tilted Samplingτ0.5→1.554.113.0307.78.7结果分析质量Pass1Beam Search (b4) 取得了最高的代码通过率比贪心搜索高出5.6个百分点证明了其在需要精确性的任务上的优势。Tilted Sampling的表现非常亮眼达到了54.1%显著优于贪心搜索和核采样并且非常接近b2时的Beam Search。这说明其“初期确定性”策略有效地帮助模型锚定了正确的代码结构和API调用。效率这是最震撼的部分。Tilted Sampling的延迟13.0 ms/token和吞吐量307.7 tokens/s几乎与贪心搜索持平比b4的Beam Search快了3.5倍吞吐量高了3.5倍。其显存占用与贪心搜索完全相同。Beam Width的影响对于Beam Searchb从2增加到4时质量有提升但b8时反而略有下降可能因为长度惩罚或过拟合而延迟和显存开销几乎成倍增长。这体现了Beam Search调参的敏感性。表2创意写作任务主观评分与效率对比 (模型: Qwen 1.5 32B)解码策略配置连贯性 (1-5)新颖性 (1-5)综合评分 (1-5)延迟 (ms/token)Greedy-4.22.03.145.3Top-pp0.9, T1.03.84.54.246.1Beam Searchb44.52.83.7167.5Tilted Samplingτ0.5→1.54.04.14.147.0结果分析质量在创意写作上核采样Top-p因其高随机性在新颖性上得分最高。Beam Search则因过于追求概率最优导致故事发展过于“安全”和“套路化”新颖性不足。Tilted Sampling展现出了极佳的平衡能力其连贯性接近Beam Search新颖性又逼近核采样综合评分与核采样并列最高。效率趋势与代码生成任务一致。Tilted Sampling的效率代价微乎其微而Beam Search的延迟是前者的3.6倍。对于32B大模型这个延迟差异120ms vs 47ms在交互式应用中感知非常明显。表3摘要生成任务 (BERTScore-F1) 对比解码策略Llama 3 8BQwen 1.5 32B平均延迟增幅 (vs Greedy)Greedy0.8510.8721.0x (基准)Top-p0.8430.868~1.02xBeam Search (b4)0.8630.881~3.7xTilted Sampling0.8580.878~1.05x结果分析在事实性摘要任务上Beam Search凭借其全局优化能力在BERTScore上依然领先。Tilted Sampling再次稳居第二且分数非常接近Beam Search差距在0.5-0.8个百分点内但速度仅比贪心慢5%。这是一个非常具有吸引力的性价比。综合结论从三个任务来看Tilted Sampling在质量上始终稳定地处于第二名的位置仅次于表现最好的Beam Search在创意任务上与核采样并列第一并且大幅领先于贪心搜索和普通核采样。而在效率上它几乎与最简单的贪心搜索持平与Beam Search相比有数倍的性能优势。这完美印证了其设计初衷用近乎免费的计算开销换取接近搜索算法的生成质量。5. 深入原理与调参实战如何用好Tilted Sampling看到这里你可能已经摩拳擦掌想试试Tilted Sampling了。别急它的效果高度依赖于τ_start和τ_end这两个参数的设置。理解其背后的原理才能有效调参。5.1 温度调度曲线的艺术τ的动态变化曲线是Tilted Sampling的“策略灵魂”。我实验了多种调度方案线性调度本次实验采用τ τ_start (τ_end - τ_start) * (step / max_length)。简单直接从确定平滑过渡到随机。指数衰减调度τ τ_end (τ_start - τ_end) * exp(-step / k)。初期快速下降至确定状态后期缓慢趋于随机。适合需要快速确立主线的任务。余弦调度τ τ_end 0.5 * (τ_start - τ_end) * (1 cos(π * step / max_length))。变化更平滑在中期也能保持一定的探索性。我的实操心得对于大多数通用聊天和创作任务线性调度是最好上手且效果稳定的选择。τ_start和τ_end的绝对值范围建议在0.3到2.0之间探索。一个不错的起点是(0.5, 1.5)。如果你希望输出更稳定、更可控如代码、翻译可以尝试(0.3, 1.2)如果希望更天马行空如诗歌、故事可以尝试(0.8, 2.0)。5.2 与Top-p采样的协同注意在我的实现中是先进行倾斜变换再进行Top-p采样。这个顺序很重要。先倾斜后Top-p倾斜变换改变了分布的“形状”Top-p在此基础上进行截断。这保证了我们始终从高概率区域采样避免了极端低概率的“垃圾”token。如果先Top-p后倾斜Top-p先筛选出了一个候选集倾斜变换只在这个子集内进行可能会过度放大或缩小候选词之间的差距导致行为不稳定。一个常见的坑是将τ设置得过于极端。例如τ_start0.1会使初期分布极其尖锐几乎退化为贪心失去了任何多样性萌芽的可能τ_end3.0会使后期分布过于平滑生成内容可能变得 incoherent不连贯。建议通过在小批量数据上观察生成文本来调整。5.3 对比Beam Search何时该坚持何时可放弃基于本次实验结果我可以给出一些清晰的决策建议坚持使用Beam Search的场景任务对绝对准确性要求极高例如编译器级别的代码补全、法律文书生成、精确数值推理。此时Beam Search多路径搜索带来的那一点点质量提升可能是至关重要的。生成长度较短50 token此时Beam Search的额外开销相对可接受而其质量优势可能更明显。拥有充足的计算资源在批处理、离线任务中如果吞吐量不是首要瓶颈追求极致质量可选Beam Search。可优先尝试Tilted Sampling的场景交互式应用聊天机器人、辅助编程低延迟是生命线。Tilted Sampling能以可忽略的速度损失提供显著优于贪心/核采样的质量。资源受限的端侧部署手机、边缘设备上显存和算力宝贵。Tilted Sampling不增加额外显存开销的特性是巨大优势。需要平衡质量与多样性的创意任务它是核采样的“增强版”在保持多样性的同时提高了连贯性。作为Beam Search的廉价替代品进行初步验证在算法开发早期可以用Tilted Sampling快速验证prompt和模型的效果待流程稳定后再用Beam Search进行最终生成。6. 局限性与未来展望当然Tilted Sampling并非银弹它也有其局限性缺乏真正的全局视野它本质仍是单序列采样无法像Beam Search那样在每一步都基于全局分数回溯和重选。对于结构非常复杂、前后依赖极强的长文本生成如长篇小说章节规划Beam Search可能仍有不可替代的优势。参数敏感度τ_start和τ_end需要根据具体任务和模型进行微调。虽然有一个合理的默认范围但找到最优值仍需一些实验。相比之下Beam Search的beam width参数直觉更强越大越慢越可能好。随机性的控制虽然通过动态温度引入了可控的随机性但其随机性的“质量”依然依赖于模型原始概率分布的准确性。如果模型在某些领域概率校准很差Tilted Sampling也无法从根本上解决这个问题。未来的优化方向我觉得可以关注以下几点自适应调度策略能否让模型自己感知生成阶段动态调整τ比如当检测到生成内容陷入重复时自动增大τ来“跳出来”。与推测解码Speculative Decoding结合Tilted Sampling负责快速生成草案draft用小模型或原模型的前向预测来验证和修正这可能进一步提速。更精细的分布变换除了简单的幂次变换是否可以引入更复杂的函数或者对分布的不同部分如头部高概率词、长尾词施加不同的变换策略折腾完这一大圈回到最初本地部署大模型遇到的推理速度瓶颈问题。我的结论是在解码策略这个层面Tilted Sampling 是目前我看到的最有潜力的“性价比之选”。它用几乎零附加成本带来了显著的质量提升。对于大多数不是追求极限准确性的应用场景它完全有资格成为默认的解码策略替代传统的贪心或核采样。而Beam Search则更像是工具箱里的一把精密手术刀在特定场景下才会请它出场。在实际项目中我现在会毫不犹豫地先把Tilted Sampling作为首选方案上线观察效果只有在明确需要且资源允许时才考虑启用Beam Search。这种从“重搜索”到“巧采样”的思路转变或许正是推理优化进入深水区后我们需要关注的新方向。