1. Beam Search算法概述
在自然语言处理领域,序列生成任务(如机器翻译、文本摘要、对话生成)的核心挑战之一是如何在解码阶段找到最优的输出序列。Beam Search作为一种启发式搜索算法,已经成为大多数序列生成模型的标准解码方法。
我第一次接触Beam Search是在开发一个中文诗歌生成系统时。当时使用贪心搜索(Greedy Search)生成的诗歌经常出现重复和语义断裂的问题,而穷举所有可能性的完全搜索又计算量过大。Beam Search恰好在这两个极端之间找到了平衡点 - 它既不像贪心搜索那样目光短浅,也不像完全搜索那样计算昂贵。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Beam Search核心原理
2.1 基本工作流程
Beam Search的核心思想是在解码的每一步保留多个(beam width)最有希望的候选序列,而不是像贪心搜索那样只保留一个最优选择。具体来说:
- 初始化阶段:从起始标记(如
<s>)开始,生成第一个词的概率分布 - 扩展阶段:对当前每个候选序列,保留top-k个最可能的扩展
- 剪枝阶段:从所有扩展后的候选序列中选择整体概率最高的k个继续下一步
- 终止条件:当任何候选序列生成结束标记(如
</s>)或达到最大长度时停止
关键点:beam width参数k决定了搜索的广度和计算量。k=1时退化为贪心搜索,k越大结果越好但计算成本越高。
2.2 概率计算与评分
序列的评分通常使用对数概率和来避免数值下溢:
score(y₁,...,yₜ) = Σ log P(yᵢ|y₁,...,yᵢ₋₁,x)
实际操作中还需要考虑长度归一化,防止算法偏向短序列:
norm_score = score/(length^α)
其中α是长度惩罚系数,通常设为0.6-1.0之间。我在中文生成任务中发现α=0.7效果最佳。
3. 算法实现细节
3.1 基础Python实现
python复制def beam_search(model, input_seq, beam_width=5, max_len=50):
# 初始化
candidates = [([START_TOKEN], 0.0)]
for _ in range(max_len):
