想象你是一位综艺导演,要在一场选秀比赛中从成千上万名选手里挑出“最动听的一句歌词”。比赛规则很特别:选手不能一口气唱完,只能一个词一个词地接龙演唱——你听到第一个字后决定谁唱第二个字,听到前两个字后再定第三个字,直到有人唱出终止符“谢幕”。台下的评委团(模型)会给每一个候选词打分,但真正棘手的是:你永远不知道现在选的词,会不会让后面的整句垮掉。 一个只顾眼前的导演,会每轮只留下评分最高的那位选手继续唱(贪心搜索);而真正老练的导演会采用“多队晋级赛”策略——每轮保留 K 位最有潜力的选手,让他们各自接龙展示,直到整首歌结束,再从这批完整歌单里选出总冠军。这个策略,就是自然语言处理中大名鼎鼎的 Beam Search(束搜索)。它不保证一定找到完美歌词,但总能在“看得人多”与“舞台装得下”之间取得巧妙平衡。

岗位关联

理解 Beam Search 是走向 NLP 工程实战的必经之路。无论做机器翻译、语音识别还是文本摘要,解码环节选对搜索策略,直接决定生成质量与推理速度的平衡,是每位 AI 从业者的基本功。

目录
  1. 可视化演示
  2. 序列生成困境
  3. 贪心搜索的局限
  4. Beam Search 核心机制
  5. 分数计算与长度惩罚
  6. 束宽调参的艺术
  7. 应用与实战
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示Beam Search的核心机制,通过开始/执行/监控/完成四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

Beam Search:Beam Beam Search基本原理 Beam Width对生成质量 核心机制可视化 Beam Search整体架构与关键组件

序列生成困境

选秀导演遇到的第一个难题,是“候选歌单”多到离谱。假设参赛选手只能用 10 万个词库接龙,一句 20 个字的歌词,理论上就有 10 万的 20 次方种组合——这个数字比宇宙中的原子还多。导演不可能让所有组合都唱一遍再打分,只能让选手一个词一个词地唱,每唱完一个词就评估一次,这就是“逐步解码”。

在 Seq2Seq 模型中,解码器正是这样工作的:它拿到编码器压缩好的源句语义向量后,从起始符 <SOS> 出发,每步根据“已经生成的词”预测“下一个词的概率分布”,然后挑词、拼接、继续,直到吐出终止符 <EOS>。这个过程本质上是在巨大的组合空间里做一次搜索,而搜索策略的优劣,直接决定了最终句子的质量。

![序列生成困境](0)

搜索问题的数学本质可以这样看:假设词表大小为 $V$,目标句子的长度为 $L$,那么候选句子总数是:

回到导演的视角:组合爆炸意味着“全部听完再打分”永远不可能。于是导演们退而求其次,设计各种“边走边看”的搜索策略——有的只看眼前,有的多留几条后路。Beam Search 就是其中最有名的一种“多留后路”策略。

候选句数=∣V∣L\text{候选句数} = |\mathcal{V}|^{L}
词表大小 $V$ 的 $L$ 次方,就是所有可能的句子数量。这个数随句子长度指数爆炸,所以我们必须用聪明的搜索算法去逼近最优解。
  1. 词表大小 $|\mathcal{V}|$词表就是选手们能用的所有词语集合,它的规模决定了每一步有多少种选择。
    ∣V∣|\mathcal{V}|
  2. 句子长度 $L$生成目标包含 $L$ 个词,每多一个词,组合数就多乘一次词表大小。
    LL
  3. 指数关系整个式子是 $|\mathcal{V}|$ 自乘 $L$ 次,长度每增加 1,候选数就扩大 $V$ 倍,这就是“组合爆炸”。
    ∣V∣L|\mathcal{V}|^{L}

贪心搜索的局限

如果导演是个急性子,他会采用最省事的办法:每轮只让当前得分最高的那位选手继续唱,其他选手全部淘汰。这就是“贪心搜索”——每一步都选择当下概率最大的词,不考虑这个词会把整句带向何方。它快、省内存,但常常酿成“一步错、步步错”的悲剧。

比如翻译 “I love you“ 时,第一个词 ”I“ 的候选分布里 ”我“(0.5)和 ”爱“(0.3)分列前二,贪心会毫不犹豫选 ”我“;但如果某一步模型给 ”的“ 打了较高分,贪心就会脱口而出 ”我爱你的“ 这种别扭的句子,而真正合理的 ”我爱的家” 在早期可能因为某步落后被早早淘汰,再也回不了头——因为被淘汰的路径不会重新进入候选池。

![贪心搜索示意图](0)

贪心搜索的决策规则可以写成:每一步都直接取概率最大的那个词。

所以贪心导演省了心,却输了质量。聪明的导演开始思考:与其孤注一掷,不如每轮同时保留几位有潜力的选手,让他们各自唱下去,最后再整体比较——这正是下一节 Beam Search 的核心思想。

yt=arg⁡max⁡y∈VP(y∣x,y1,…,yt−1)y_{t} = \arg\max_{y \in \mathcal{V}} P(y \mid x, y_{1}, \dots, y_{t-1})
这个公式说的是:给定源句 $x$ 和已生成的前 $t-1$ 个词,选择使下一个词条件概率最大的词 $y$。它只看局部,完全不关心未来。
  1. $\arg\max$ 的含义在所有词里找出“让概率最大”的那个词,相当于评委举牌选出本轮最高分。
    arg⁡max⁡y∈V\arg\max_{y \in \mathcal{V}}
  2. 条件概率 $P(y \mid x, y_{1}, \dots, y_{t-1})$这是“在已知源句和前文的情况下,下一个词是 $y$ 的概率”,它是解码器给出的核心信号。
    P(yt∣x,y<t)P(y_t \mid x, y_{<t})
  3. 下标 $t$ 与 $t-1$$t$ 表示当前生成到第几个词,$y_{<t}$ 表示已经生成的前缀,贪心每一步都只基于这个前缀决策。
    y1,…,yt−1y_{1}, \dots, y_{t-1}

Beam Search 核心机制

导演终于想通了:把选秀改成“多队晋级赛”。每轮比赛结束后,只保留 K 位表现最好的选手(而不是 1 位),让他们各自带着自己的“歌词前缀”进入下一轮,继续接龙。这个 K 就是束宽(beam width),而整场比赛就是 Beam Search。

具体过程是这样的:假设词表有 $V$ 个词,当前有 K 条存活路径。每走一步,每条路径都要尝试接上词表里的每一个词,于是生成 $K \times V$ 个候选;评委团给所有候选打分排序,只留下分数最高的 K 条进入下一轮。如此反复,直到候选句子都以 <EOS> 结尾,或者达到预设的最大长度。

![Beam Search 树形展开](0)

每一条候选路径的分数,是所有已生成词的对数概率之和。

回到选秀现场:K=3 意味着每轮有 3 位选手同时备战,每人试唱 V 个候选词,但最终只有 3 个名额能留下。这份“广撒网”的从容,让最终获胜的歌词往往比贪心导演选出的更连贯、更自然——因为每条路径都完整唱完后,才由总冠军统一加冕。

S(Y)=∑t=1Tlog⁡P(yt∣x,y<t)S(Y) = \sum_{t=1}^{T} \log P(y_t \mid x, y_{<t})
这条公式把“整句概率的连乘”变成“对数概率的连加”。为什么要取对数?因为每一步的概率都小于 1,连乘起来会小到浮点数无法表示;取对数之后,分数变成负数累加,数值稳定且便于排序。
  1. 累计分数 $S(Y)$一个候选句子 $Y$ 的总分,是所有词对数概率的总和,分数越高代表模型越认可。
    S(Y)S(Y)
  2. 对数概率 $\log P(y_t \mid x, y_{<t})$把每一步的条件概率取自然对数,得到的是一个非正数;连乘变成连加,避免了下溢。
    log⁡P(yt∣x,y<t)\log P(y_t \mid x, y_{<t})
  3. 求和范围 $t=1$ 到 $T$从第一个词累加到最后一个词(含 <EOS>),这就是完整路径的累计得分。
    ∑t=1T\sum_{t=1}^{T}

分数计算与长度惩罚

导演很快发现一个新问题:选手唱得越长,评委打的累计分就越吃亏。这很好理解——每个词的对数概率都是负数,唱 10 个词的歌手累计 -20 分,唱 6 个词的歌手可能只有 -12 分,可这并不代表短歌词更优秀。如果不做处理,Beam Search 会系统性偏爱短句,机器翻译里就会出现“漏译”。

解决思路也很朴素:像田径比赛按体重分级一样,给分数除以一个与句子长度相关的量,让不同长度的句子站在同一起跑线上。这就是“长度惩罚”(length penalty)。

![长度惩罚平衡长短句](0)

加入长度惩罚后的评分公式为:

有了长度惩罚,评委的记分牌终于公平了:短小精悍的歌词不会因为词少就占便宜,洋洋洒洒的长句也不会因为词多而被误杀。工程实践里,这一项往往是翻译质量提升的“免费午餐”。

Snorm(Y)=1∣Y∣α∑t=1Tlog⁡P(yt∣x,y<t)S_{\text{norm}}(Y) = \frac{1}{|Y|^{\alpha}} \sum_{t=1}^{T} \log P(y_t \mid x, y_{<t})
其中 $|Y|$ 是句子长度,$\alpha$ 是惩罚强度(通常取 0.6~1.0)。分母越大,长句被抬高的幅度越大,从而抵消长句天然的分数量级劣势,让长短句可以公平比较。
  1. 句子长度 $|Y|$候选句子的总词数(含终止符),它代表“歌手总共唱了多少个词”。
    ∣Y∣|Y|
  2. 惩罚指数 $\alpha$控制惩罚力度的大小。$\alpha=0$ 时不做惩罚,$\alpha$ 越大,长句获得的补偿越多,相当于给长跑选手加权重。
    ∣Y∣α|Y|^{\alpha}
  3. 归一化分数 $S_{\text{norm}}(Y)$把原始累计对数分数除以 $|Y|^{\alpha}$,得到的可比较分数;选择最终结果时,比较的就是这个归一化分数。
    1∣Y∣α∑t=1Tlog⁡P(yt∣x,y<t)\frac{1}{|Y|^{\alpha}} \sum_{t=1}^{T}\log P(y_t \mid x, y_{<t})

束宽调参的艺术

既然 K 越大,同时考察的选手越多,是不是无脑调大 K 就行?导演会告诉你:舞台是有成本的。每轮要试唱的候选数量是 $K \times V$,K 翻倍,计算量和内存几乎也翻倍。更微妙的是,当 K 增加到一定程度后,生成质量的提升会快速饱和,甚至会引入更多“高分但重复”的套话。

经验法则通常是这样:K=1 时退化为贪心搜索;K=5~10 是大多数翻译、摘要系统默认甜区;K 超过 50 以后,质量曲线几乎走平,而推理延迟让用户无法接受。实际工程中还要结合“最大生成长度”和“长度惩罚”一起调,像调音师一样反复试听。

![束宽与质量的关系](0)

单步扩展的计算量可以写成:

选秀导演的经验是:先调 K,再调 $\alpha$,最后看具体任务。K 不是越大越好,而是“够用就好”——找到那个质量曲线开始走平、开销还能接受的甜蜜点,就是束宽调参的全部艺术。

每步计算量=O(K×∣V∣)\text{每步计算量} = O(K \times |\mathcal{V}|)
这条式子说明:Beam Search 每前进一步,要评估的候选数量约等于束宽乘以词表大小。它是指数级穷举搜索与线性贪心之间的一个“可调旋钮”。
  1. 束宽 $K$每轮保留的路径条数,是算法唯一的“旋钮”,直接决定并行考察的规模。
    KK
  2. 词表大小 $|\mathcal{V}|$每条路径都要在完整词表上扩展一遍,所以词表也线性影响计算量。
    ∣V∣|\mathcal{V}|
  3. 大 $O$ 记号 $O(\cdot)$表示数量级。$K \times V$ 意味着计算开销随 K 线性增长,K 变大没有指数灾难,但也绝非免费。
    O(K×∣V∣)O(K \times |\mathcal{V}|)

应用与实战

这套“多队晋级赛”如今是各大 AI 舞台的标配。机器翻译里,Google 神经翻译系统用 Beam Search 解码,配合长度惩罚显著提升译文流畅度;语音识别中,LAS、Whisper 等模型在声学特征上跑束搜索,把“听到的声音”变成“最可能的文本”;文本摘要和对话生成里,BART、T5 也用束搜索从候选摘要中挑出信息最完整的那一条。

![Beam Search 应用](0)

在所有这些任务中,最终结果的选择可以统一写成:在所有走完的候选路径(束)中,挑选归一化分数最高的一条。

从选秀舞台到生产环境,Beam Search 的核心逻辑始终如一:不把鸡蛋放在一个篮子里,也不无限扩大篮子。理解了 K、累计分数、长度惩罚这三板斧,你就掌握了 NLP 解码的核心武器,接下来在 Python 演示中亲手实现一个束搜索解码器,一切都会水到渠成。

Y^=arg⁡max⁡Y∈BSnorm(Y)\hat{Y} = \arg\max_{Y \in \mathcal{B}} S_{\text{norm}}(Y)
这里 $\mathcal{B}$ 是所有完整生成的候选句子集合。工程实现时,我们会维护一个优先队列,边生成边剪枝,最后从这个“总决赛名单”里选出总冠军。
  1. 候选集合 $\mathcal{B}$束搜索过程中所有以 <EOS> 结尾的完整句子,相当于总决赛的选手名单。
    B\mathcal{B}
  2. 归一化分数 $S_{\text{norm}}(Y)$每条候选经过长度惩罚后的最终得分,是评委手中的决定性票数。
    Snorm(Y)S_{\text{norm}}(Y)
  3. $\arg\max$ 选择从候选集合里挑出分数最高者,这就是模型最终输出的句子。
    Y^=arg⁡max⁡Y∈BSnorm(Y)\hat{Y} = \arg\max_{Y \in \mathcal{B}} S_{\text{norm}}(Y)

AI 应用场景

机器翻译解码

阶段:推理/解码阶段(Encoder-Decoder 模型的生成端)

解决的问题:传统贪心解码在翻译长句时容易“漏译”和“倒挂”,比如把 “I love you“ 译成 ”我爱你的”;纯随机采样则输出不稳定。Beam Search 通过同时维护多条候选译文,再按长度惩罚后的总分选出最佳译文,显著提升 BLEU 分数与人工观感。

具体案例:Google 神经机器翻译(GNMT)在在线翻译系统中使用束宽 4~8 的 Beam Search 解码,配合长度惩罚($\alpha \approx 0.6$),在千万级句对上保持毫秒级响应,同时避免短句偏好。

语音识别文本化

阶段:声学模型后处理/解码阶段

解决的问题:语音识别需要把声学特征序列转成文本,候选路径在音素层就存在大量歧义。束搜索可以在解码时同时考虑声学分数与语言模型分数,保留多条候补句子,避免“听错一个字、整句跑偏”。

具体案例:Whisper 等语音识别模型在解码阶段采用带时间戳的 Beam Search,逐帧对齐音频与文本;耳语模型针对长音频还引入了分帧束搜索,保证每个片段都能输出稳定文本。

文本摘要与对话生成

阶段:生成式模型的解码阶段

解决的问题:摘要生成要求“信息完整且长度适中”,贪心解码常漏掉关键实体;对话生成则要求回复自然不重复。Beam Search 配合长度惩罚(以及工程中常见的重复惩罚)可以筛选出信息密度与流畅度俱佳的候选。

具体案例:BART 在 CNN/DailyMail 摘要任务上使用束宽 4~6 的解码器,配合三gram重复惩罚,生成的摘要 ROUGE 分数远超贪心基线;企业客服机器人也用它控制回复质量与延迟的平衡。

Python 演示

python71 行
# -*- coding: utf-8 -*-"""Beam Search 解码演示:在模拟概率表上搜索最优序列"""import mathfrom heapq import nlargest VOCAB = ["我", "爱", "你", "的", "家", "<EOS>"]  def next_probs(prefix):    """模拟解码器:根据已有前缀返回下一个词的 log 概率列表"""    table = {        (): [("我", -0.7), ("爱", -1.2), ("你", -1.8)],        ("我",): [("爱", -0.6), ("的", -1.6), ("<EOS>", -2.4)],        ("爱",): [("你", -0.8), ("的", -1.9), ("<EOS>", -1.5)],        ("你",): [("的", -0.5), ("家", -1.4), ("<EOS>", -2.2)],        ("我", "爱"): [("你", -0.4), ("<EOS>", -2.6)],        ("我", "的"): [("家", -0.9), ("<EOS>", -1.3)],        ("爱", "你"): [("的", -0.7), ("<EOS>", -1.1)],        ("爱", "的"): [("家", -1.0), ("<EOS>", -0.8)],        ("你", "的"): [("家", -0.6), ("<EOS>", -1.5)],        ("你", "家"): [("<EOS>", -0.3)],        ("我", "爱", "你"): [("的", -0.5), ("<EOS>", -1.0)],        ("我", "爱", "你", "的"): [("<EOS>", -0.2)],        ("我", "的", "家"): [("<EOS>", -0.3)],        ("爱", "你", "的"): [("家", -0.4), ("<EOS>", -0.9)],        ("你", "的", "家"): [("<EOS>", -0.4)],    }    return table.get(prefix, [("<EOS>", 0.0)])  def greedy_decode(max_len=6):    """贪心解码:每步只选概率最大的词"""    seq = ()    score = 0.0    for _ in range(max_len):        best = max(next_probs(seq), key=lambda x: x[1])        seq = seq + (best[0],)        score += best[1]        if best[0] == "<EOS>":            break    return score, seq  def beam_search(beam_width=3, max_len=6, alpha=0.0):    """Beam Search 解码:每轮保留 beam_width 条最高分路径"""    beam = [(0.0, ())]  # (累计log概率, 已生成序列)    finished = []    for _ in range(max_len):        candidates = []        for log_prob, seq in beam:            for word, lp in next_probs(seq):                new_seq = seq + (word,)                new_score = log_prob + lp                if word == "<EOS>":                    if alpha > 0:                        new_score = new_score / ((len(new_seq)) ** alpha)                    finished.append((new_score, new_seq))                else:                    candidates.append((new_score, new_seq))        if not candidates:            break        beam = nlargest(beam_width, candidates, key=lambda x: x[0])    finished.sort(reverse=True)    return finished[0] if finished else beam[0]  if __name__ == "__main__":    print("贪心解码:         ", greedy_decode())    for k in [1, 3, 5]:        print("Beam K=%d 无惩罚:  " % k, beam_search(k, alpha=0.0))    print("Beam K=3 alpha=0.6:", beam_search(3, alpha=0.6))
目的:用一个小型“伪解码器”在固定概率表上对比贪心搜索与不同束宽、不同长度惩罚下的 Beam Search 解码结果。
  1. table = {...}用字典模拟解码器输出的条件概率分布,键是已生成前缀,值是候选词及其对数概率;真实项目中这里是神经网络预测。
  2. beam = [(0.0, ())]束的初始状态:起始符前缀为空,累计分数为 0。
  3. for word, lp in next_probs(seq):每条存活路径在词表上扩展出所有候选词,对应文中“每步扩展 K×V 个候选”。
  4. new_score = log_prob + lp累计对数概率:连乘转为连加,越长的句子分数越负,这就是长句吃亏的原因。
  5. if word == "<EOS>":遇到终止符的路径不再参与下一轮扩展,而是进入 finished 决赛名单。
  6. new_score = new_score / ((len(new_seq)) ** alpha)长度惩罚:用长度幂次做除法,公平化长短句之后才计入最终比较。
  7. beam = nlargest(beam_width, candidates, key=lambda x: x[0])从所有扩展候选中挑出分数最高的 K 条,这就是“每轮只留 K 位选手”。
  8. finished.sort(reverse=True)对完整句子按最终分数排序,取第一名作为整场选秀的总冠军。

常见误区

误区K 就是搜索精度,直接设成 100,模型一定生成得更好,反正服务器性能强。

正解束宽 K 代表每轮保留的路径数,每步要评估的候选是 K×V 个。K 越大,计算和内存线性增长;更关键的是,质量提升会迅速饱和,K 从 5 涨到 50 往往只带来微小收益,却可能让推理慢一个数量级。这就像选秀海选留下 1000 人,评委疲惫不堪,反而选出大量相似套话。工程上默认 5~10 才是性价比高峰。

为何常见:人们直觉认为“看得越多越稳”,忽略了搜索质量的边际递减效应和计算成本的线性增长,两相叠加后 K 存在明显甜点。

误区Beam Search 每一步都保留 K 条路径,肯定能覆盖全局最优解,是精确搜索。

正解Beam Search 是典型的启发式剪枝搜索。每轮被淘汰出前 K 的路径,即使未来可能“低开高走”成为最优,也永远没有翻身机会。全局最优只有在穷举全部 $V^L$ 条路径或使用动态规划(如隐马尔可夫的维特比算法)时才能保证。Beam Search 只是用 K 条路径去“大概率逼近”最优解。

为何常见:看到“Beam“一词容易联想到”广覆盖”,且实验结果通常明显优于贪心,于是误认为它等价于穷举,忽略了它本质上仍是剪枝近似。

误区模型输出的概率就是可信度,把整句概率连乘得到的就是最终分数,凭什么要除一个长度?

正解每个词的概率都小于 1,连乘出的整句概率随长度指数级衰减。两句同样流畅的译文,长句的累计概率天然远低于短句,不惩罚就会让解码器系统性偏爱短句,导致翻译漏词。长度惩罚用 $|Y|^\alpha$ 做除法,本质是把“分数量级”和“语义质量”解耦,让长短句在公平规则下竞技。

为何常见:初学时只盯着“概率高=好”的直觉,没有意识到连乘对长度的天然不公,直到发现模型总输出过短句子才反应过来。

误区K=5 就代表每一步生成 5 个词,然后从里面挑一个。

正解K 是每轮结束后保留的完整路径条数,不是生成的词数。每一步是让 K 条路径各在词表 V 个词上扩展,产生 K×V 个候选,再筛回 K 条。K=5 意味着同时有 5 个“半成品句子”在并行生长,而不是一步吐出 5 个词。

为何常见:把“每步候选数”和“每步保留路径数”混为一谈,实际上前者是 K×V,后者才是 K,这两个数量级完全不同。

面试题

Q1. 当 beam width K=1 时,Beam Search 等效于哪种解码方式?

单选题 · easy

  • A.贪心搜索← 正确答案
  • B.随机采样
  • C.纯束搜索
  • D.维特比解码

答案:A。K=1 表示每轮只保留 1 条最高分路径,行为与每步取 argmax 的贪心搜索完全一致。随机采样会引入随机性,维特比解码是动态规划,都不等价。所以正确答案是 A。

Q2. Beam Search 每一轮结束后保留的路径数量是多少?

单选题 · easy

  • A.词表大小 V
  • B.束宽 K← 正确答案
  • C.句子最大长度
  • D.仅 1 条

答案:B。束宽 K 定义的就是“每轮从 K×V 个扩展候选中保留的最高分路径条数”。词表大小 V 是每步可选的词数,与保留路径数无关;贪心才只保留 1 条。所以选 B。

Q3. 解码打分时使用 log 概率而非原始概率连乘,最主要的原因是?

单选题 · mid

  • A.数值更稳定,避免下溢← 正确答案
  • B.把负分数变成正分数
  • C.词表可以无限扩大
  • D.不再需要长度惩罚

答案:A。整句概率是大量小于 1 的数连乘,在浮点运算中会迅速下溢为 0;取对数后连乘变连加,数值稳定且单调性不变。log 概率是负数,不会变正;词表与长度惩罚都与是否取 log 无关。所以选 A。

Q4. 如果不做长度惩罚,Beam Search 可能出现哪些现象?(多选)

多选题 · mid

  • A.偏好较短句子← 正确答案
  • B.长句累计分数偏低← 正确答案
  • C.计算变得更慢
  • D.必现重复词语

答案:AB。每个词的对数概率为负,句子越长累加越负,因此长句系统性被低估,解码器偏向短句,A、B 正确。长度惩罚不直接影响计算速度(C 错);重复词是另一类问题,通常由重复惩罚处理,不是长度惩罚缺失的必然结果(D 错)。

Q5. 束宽 K 从 1 增大到 8,最直接的变化是什么?

单选题 · mid

  • A.搜索质量提升且开销更低
  • B.候选路径更多,质量通常提升,开销变大← 正确答案
  • C.每步只生成一个词
  • D.彻底消除局部最优

答案:B。K 增大意味着每轮保留更多候选路径,单步扩展量从 1×V 变为 8×V,质量通常改善、计算和内存线性增长。贪婪的“开销更低”是 K=1 的特征;Beam Search 是近似搜索,不能“彻底消除”局部最优。所以选 B。

Q6. 关于 Beam Search 能找到全局最优解的说法,正确的是?

单选题 · hard

  • A.一定能找到全局最优
  • B.不一定,因为低分路径被提前剪枝← 正确答案
  • C.束宽越小越容易找到
  • D.只有 K=1 时能找到

答案:B。Beam Search 每轮只保留 K 条路径,被剪掉的低分路径即使未来成为最优也无缘复活,因此它是启发式近似而非精确搜索。束宽越大越接近最优而非越小;K=1 等价贪心,恰恰最不可能找到全局最优。所以选 B。

Q7. 关于长度惩罚的作用,正确的理解有哪些?(多选)

多选题 · hard

  • A.让长句分数更公平← 正确答案
  • B.修正长句被低估← 正确答案
  • C.让分数变为正数
  • D.取代累计对数概率

答案:AB。长度惩罚用 $|Y|^\alpha$ 做除法,抵消长句因项数多而累积的负分,让长短句可以公平比较,A、B 正确。log 概率非正,除以正数后仍非正,不会变正(C 错);它只是对累计分数的后处理,并不取代累计对数概率(D 错)。

Q8. Seq2Seq 模型中,Beam Search 何时停止生成?

单选题 · easy

  • A.达到束宽 K
  • B.所有候选都以 EOS 结尾或达到最大长度← 正确答案
  • C.贪心搜索完成一步
  • D.词表中的词全部用完

答案:B。解码终止条件是候选路径输出 <EOS> 或达到预设最大生成长度。束宽 K 不是长度概念(A 错);贪心与否与终止无关(C 错);词表是候选来源而非终止依据(D 错)。所以选 B。

Q9. 关于贪心搜索与 Beam Search 的对比,正确的有哪些?(多选)

多选题 · mid

  • A.贪心每步只保留一条路径← 正确答案
  • B.Beam 每步保留 K 条路径← 正确答案
  • C.贪心可能陷入局部最优← 正确答案
  • D.束宽不影响计算开销

答案:ABC。贪心是 K=1 的特例,每步唯一,容易因为局部最优而错失全局(A、C 对);Beam 每步保留 K 条,覆盖面更广(B 对)。束宽直接决定单步扩展量 K×V,明显影响计算开销(D 错)。

Q10. 词表 V=10000、束宽 K=5 时,单步扩展产生的候选数量约为多少?

单选题 · mid

  • A.约 5 万个← 正确答案
  • B.约 50 个
  • C.约 1 万个
  • D.约 25 个

答案:A。每一步需要让 K=5 条存活路径各自在 V=10000 的词表上扩展,候选总数 = K×V = 50000,即约 5 万个。50 是“每轮保留数”被误当成扩展数;10000 忽略束宽;25 是 K² 的误解。所以选 A。