9. 什么是 Beam Search?深入理解模型生成策略
是不是总感觉很熟悉?
在之前第5,7,8篇文章中,我们都曾经用到过与它相关的参数,而对于早就有着实操经验的同学们,想必见到的更多。这篇文章将从示例到数学原理和代码带你进行理解。Beam Search 对应的中文翻译为“集束搜索”或“束搜索”。你可以将其当作是贪心算法的拓展,其实是很简单的概念:贪心算法每次只选择最好的,而 Beam Search 会在多个候选中进行选择。通过这篇文章,你将了解到:
- Beam Width(束宽) 的实际作用,常对应于参数名
num_beams
。- 所有候选序列生成结束标记 的含义,常对应于参数名
early_stopping
。- Beam Search 的基本原理和工作机制。
强烈建议访问:Beam Search Visualizer,这是一个非常 Amazing 的交互式项目,在即将完成这个文章攥写的时候我通过官方文档发现了它,让理论与实际搭上了桥。
计划后续补上数学和与其他一些算法的比较。
Beam Search 的基本概念
Beam Search 是一种宽度优先搜索算法,通过保留多个候选序列(即“束”)来探索可能的输出空间。不同于贪心搜索(Greedy Search)每次只选择当前最优的一个候选序列,Beam Search 可以同时保留多个(由束宽 k k k 决定),从而减少陷入局部最优解的风险。
Beam Search 的工作原理
Beam Search 的核心思想是在每一步生成过程中,保留束宽 k k k 个最有可能的候选序列,而不是仅保留一个最优序列(这种是贪心算法,也就是说束宽 k k k 为 1 的时候 Beam Search 就是 Greedy Search)。以下是 Beam Search 的基本步骤:
- 初始化:从一个初始序列(通常为空或特殊起始标记)开始,设定束宽 k k k,初始化候选序列集 B 0 = { start } B_0 = \{ \text{start} \} B0={start}。
- 迭代生成:对于当前所有候选序列 B t − 1 B_{t-1} Bt−1,扩展一个新的词汇或符号,生成所有可能的下一个词汇组合,并计算每个序列的概率。
- 选择顶束:从所有扩展的候选序列中,选择得分最高的 k k k 个序列,作为下一步的候选序列 B t B_t Bt。
- 终止条件:当所有候选序列都生成了结束标记(如
<eos>
)或达到设定的最大长度 T T T 时,停止生成。 - 选择最终序列:从最终的候选序列集中,选择得分最高的序列作为输出。
注:以GPT为例,扩展实际对应于去获取 tokens 的概率。
举个例子
-
初始化
- 束宽 ( k k k): 2
- 当前候选集 ( B 0 B_0 B0): { (空) } \{\text{(空)}\} {(空)}
- 词汇表 { A , B , C , ‘<eos>‘ } \{A, B, C, \text{`<eos>`}\} {A,B,C,‘<eos>‘}
- 扩展(生成所有可能的下一个词汇):
扩展结果 概率 A 0.4 \textbf{0.4} 0.4 B 0.3 \textbf{0.3} 0.3 C 0.2 0.2 0.2 <eos>
0.1 0.1 0.1 - 选择顶束 ( k = 2 k=2 k=2):
- A A A( 0.4 0.4 0.4)
- B B B( 0.3 0.3 0.3)
- 新的候选集 ( B 1 B_1 B1): { A ( 0.4 ) , B ( 0.3 ) } \{A (0.4), B (0.3)\} {A(0.4),B(0.3)}
-
扩展 A A A 和 B B B
-
扩展 A A A:
- 生成概率: { A : 0.3 , B : 0.1 , C : 0.4 , ‘<eos>‘ : 0.2 } \{A: 0.3, B: 0.1, C: 0.4, \text{`<eos>`}: 0.2\} {A:0.3,B:0.1,C:0.4,‘<eos>‘:0.2}
扩展结果 概率计算 概率 A A AA AA 0.4 × 0.3 0.4 \times 0.3 0.4×0.3 0.12 \textbf{0.12} 0.12 A B AB AB 0.4 × 0.1 0.4 \times 0.1 0.4×0.1 0.04 0.04 0.04 A C AC AC 0.4 × 0.4 0.4 \times 0.4 0.4×0.4 0.16 \textbf{0.16} 0.16 A <eos> A\text{<eos>} A<eos> 0.4 × 0.2 0.4 \times 0.2 0.4×0.2 0.08 0.08 0.08 -
扩展 B B B:
- 生成概率: { A : 0.1 , B : 0.1 , C : 0.3 , ‘<eos>‘ : 0.5 } \{A: 0.1, B: 0.1, C: 0.3, \text{`<eos>`}: 0.5\} {A:0.1,B:0.1,C:0.3,‘<eos>‘:0.5}
扩展结果 概率计算 概率 B A BA BA 0.3 × 0.1 0.3 \times 0.1 0.3×0.1 0.03 0.03 0.03 B B BB BB 0.3 × 0.1 0.3 \times 0.1 0.3×0.1 0.03 0.03 0.03 B C BC BC 0.3 × 0.3 0.3 \times 0.3 0.3×0.3 0.09 \textbf{0.09} 0.09 B <eos> B\text{<eos>} B<eos> 0.3 × 0.5 0.3 \times 0.5 0.3×0.5 0.15 \textbf{0.15} 0.15 -
所有扩展序列及其概率:
序列 概率 A C AC AC 0.16 \textbf{0.16} 0.16 A A AA AA 0.12 0.12 0.12 B <eos> B\text{<eos>} B<eos> 0.15 \textbf{0.15} 0.15 B C BC BC 0.09 0.09 0.09 A <eos> A\text{<eos>} A<eos> 0.08 0.08 0.08 A B AB AB 0.04 0.04 0.04 B A BA BA 0.03 0.03 0.03 B B BB BB 0.03 0.03 0.03 -
选择顶束 ( k = 2 k=2 k=2):
- A C AC AC( 0.16 0.16 0.16)
- B <eos> B\text{<eos>} B<eos>( 0.15 0.15 0.15)
-
新的候选集 ( B 2 B_2 B2): { A C ( 0.16 ) , B <eos> ( 0.15 ) } \{AC (0.16), B\text{<eos>} (0.15)\} {AC(0.16),B<eos>(0.15)}
-
-
仅扩展 A C AC AC
- 生成概率: { A : 0.1 , B : 0.2 , C : 0.5 , ‘<eos>‘ : 0.2 } \{A: 0.1, B: 0.2, C: 0.5, \text{`<eos>`}: 0.2\} {A:0.1,B:0.2,C:0.5,‘<eos>‘:0.2}
扩展结果 概率计算 概率 A C A ACA ACA 0.16 × 0.1 0.16 \times 0.1 0.16×0.1 0.016 0.016 0.016 A C B ACB ACB 0.16 × 0.2 0.16 \times 0.2 0.16×0.2 0.032 0.032 0.032 A C C ACC ACC 0.16 × 0.5 0.16 \times 0.5 0.16×0.5 0.080 0.080 0.080 A C <eos> AC\text{<eos>} AC<eos> 0.16 × 0.2 0.16 \times 0.2 0.16×0.2 0.032 0.032 0.032 - 由于 B <eos> B\text{<eos>} B<eos> 已完成,我们选择扩展结果中的顶束:
- A C C ACC ACC( 0.064 0.064 0.064)
- 以某种规则选择 A C B ACB ACB 或 A C <eos> AC\text{<eos>} AC<eos>( 0.032 0.032 0.032)
- 新的候选集 ( B 3 B_3 B3): { A C C ( 0.064 ) , A C B ( 0.032 ) } \{ACC (0.064), ACB (0.032)\} {ACC(0.064),ACB(0.032)}
-
后续步骤
- 继续扩展:重复上述过程,直到所有候选序列都生成了
<eos>
或达到设定的最大长度。
- 继续扩展:重复上述过程,直到所有候选序列都生成了
现在是你访问它的最好时机:Beam Search Visualizer
处理 <eos>
的逻辑
在每一步生成过程中,如果某个序列生成了 <eos>
,则将其标记为完成,不再进行扩展。以下是处理 <eos>
的示例:
- 假设在某一步,序列 A C B ACB ACB 扩展出 A C B <eos> ACB\text{<eos>} ACB<eos>( 0.032 × 1 = 0.032 0.032 \times 1 = 0.032 0.032×1=0.032),则:
- A C B <eos> ACB\text{<eos>} ACB<eos> 保留在最终候选集,但不再扩展。
- Beam Search 继续扩展其他未完成的序列,直到所有序列完成或达到最大长度。
问题:如果有一个序列被标记为完成(生成了 <eos>
),在下一个扩展步骤中,Beam Search 应该扩展多少个候选序列?
答:束宽 k k k 个
示例图(k=3):
你可以在下图中看到,即便有一个序列生成了 <eos>
,下一个扩展步骤中还是会扩展 k=3 个候选序列。
实际应用中的 Beam Search
在机器翻译,文本生成,语音转识别等生成式模型领域,你都能看见Beam Search,它被广泛地应用。
代码示例
使用 Hugging Face Transformers 库的简单示例:
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch# 指定模型名称
model_name = "distilgpt2"# 加载分词器和模型
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModelForCausalLM.from_pretrained(model_name)# 移动模型到设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model.to(device)# 设置模型为评估模式
model.eval()# 输入文本
input_text = "Hello GPT"# 编码输入文本
inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)# 生成文本,使用 Beam Search
beam_width = 5
with torch.no_grad():outputs = model.generate(inputs,max_length=50,num_beams=beam_width, # 你可以看到 beam_width 对应的参数名为 num_beamsno_repeat_ngram_size=2,early_stopping=True # 开启 early_stopping,当所有候选序列生成<eos>停止)# 解码生成的文本
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
print("生成的文本:")
print(generated_text)
输出:
生成的文本:
Hello GPT.This article was originally published on The Conversation. Read the original article.
对比不同束宽的输出
# 输入文本
input_text = "Hello GPT"# 编码输入文本
inputs = tokenizer.encode(input_text, return_tensors="pt").to(device)# 设置束宽不同的生成策略
beam_widths = [1, 3, 5] # 使用不同的束宽# 生成并打印结果
for beam_width in beam_widths:with torch.no_grad():outputs = model.generate(inputs,max_length=50,num_beams=beam_width, no_repeat_ngram_size=2,early_stopping=True,)generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)print(f"束宽 {beam_width} 的生成结果:")print(generated_text)print('-' * 50)
束宽 1 的生成结果:
Hello GPT is a free and open source software project that aims to provide a platform for developers to build and use GPGP-based GPSP based GPCs. GPP is an open-source software development platform that is designed to
--------------------------------------------------
束宽 3 的生成结果:
Hello GPT.This article is part of a series of articles on the topic, and will be updated as more information becomes available.
--------------------------------------------------
束宽 5 的生成结果:
Hello GPT.This article was originally published on The Conversation. Read the original article.
--------------------------------------------------
参考链接
- Beam-search decoding
- Beam Search Visualizer
相关文章:

9. 什么是 Beam Search?深入理解模型生成策略
是不是总感觉很熟悉? 在之前第5,7,8篇文章中,我们都曾经用到过与它相关的参数,而对于早就有着实操经验的同学们,想必见到的更多。这篇文章将从示例到数学原理和代码带你进行理解。 Beam Search 对应的中文翻…...
Spring自定义注解
目录 一、interface 关键字 二、元注解 三、简单实现 四、使用切面执行自定义注解逻辑 1) 首先将刚才的注解修改成放在方法上的: 2) 定义一个切面类: 3)将注解放入到接口方法中测试: 五、切点表达式 一、interface 关键字 …...

微信小程序:wx.login或调用uni.login时报错the code is a mock one
微信小程序,调用wx.login或调用uni.login方法,返回the code is a mock one 原因与解决 原因:没有关联真实的 appid,解决办法:绑定真实的微信小程序的appid...
URL的执行流程
基本概念: URL(统一资源定位符,Uniform Resource Locator)的执行流程是指当你在浏览器中输入一个URL并按下回车键时,从输入URL到最终在浏览器中显示网页的完整过程。 1.解析协议 URL 以协议开头,如 http…...

双指针算法专题(2)
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: 优选算法专题 想要了解双指针算法的介绍,可以去看下面的博客:双指针算法的介绍 目录 611.有效三角形的个数 LCR 1…...

加密与安全_优雅存储用户密码的最佳实践
文章目录 Pre概述最佳实践避免使用MD5、SHA1等快速哈希算法加盐哈希 (不推荐)使用BCrypt、Argon2等慢哈希算法 (推荐)BCrypt Code1. 自动生成和嵌入盐2. 哈希结果的格式3. 代价因子 BCrypt特点 防止暴力破解1. 登录失败锁定2. 双因素认证(2FA…...

【多线程】深入剖析线程池的应用
💐个人主页:初晴~ 📚相关专栏:多线程 / javaEE初阶 还记得我们一开始引入线程的概念,就是因为进程太“重”了,频繁创建销毁进程的开销是非常大的。而随着计算机的发展,业务上对性能的要求越来越…...

『功能项目』切换职业面板【48】
我们打开上一篇47技能冷却蒙版的项目, 本章要做的事情是切换职业UI面板的功能 首先双击打开Canvas预制体在左上主角面板信息中新建一个button按钮 重命名(父物体是按钮Button,子物体Image即可) 创建一个Image 设计一下布局 复制三…...

【EasyExcel】@ColumnWidth(value = 20) EasyExcel设置列宽不生效
经过测试发现,只有XLS,ColumnWidth注解才会生效,选择CSV和XLSX都不会生效 //对应的导出实体类 EasyExcel.write(outputStream, Result.class)//excel文件类型,包括CSV、XLS、XLSX.excelType(ExcelTypeEnum.XLS)...

CPU 和 GPU:为什么GPU更适合深度学习?
目录 什么是 CPU ? 什么是 GPU ? GPU vs CPU 差异性对比分析 GPU 是如何工作的 ? GPU 与 CPU 是如何协同工作的 ? GPU vs CPU 类型解析 GPU 应用于深度学习 什么是 CPU ? CPU(中央处理器)…...

【机器学习】:解锁数据背后的智慧宝藏——深度探索与未来展望
欢迎来到 破晓的历程的 博客 ⛺️不负时光,不负己✈️ 文章目录 引言一、深入机器学习的内在机制二、最新进展与趋势三、对未来社会的深远影响结语 引言 在上一篇博客中,我们初步探讨了机器学习如何成为解锁数据背后智慧的关键工具。现在,让…...
【Kubernetes】常见面试题汇总(十八)
目录 55.简述 Kubernetes 共享存储的作用? 56.简述 Kubernetes 数据持久化的方式有哪些? 57.简述 Kubernetes PV 和 PVC ? 58.简述 Kubernetes PV 生命周期内的阶段? 55.简述 Kubernetes 共享存储的作用? Kubernet…...

无限边界:现代整合安全如何保护云
尽管云计算和远程工作得到广泛采用,零信任网络也稳步推广,但边界远未消失。相反,它已被重新定义。就像数学分形的边界一样,现代网络边界现在无限延伸到任何地方。 不幸的是,传统工具在现代无限边界中效果不佳。现代边…...

HTML贪吃蛇游戏
文章目录 贪吃蛇游戏 运行效果代码 贪吃蛇游戏 贪吃蛇是一款经典的休闲益智游戏。本文将通过HTML5和JavaScript详细解析如何实现一个简易版的贪吃蛇游戏。游戏的主要逻辑包括蛇的移动、碰撞检测、食物生成等功能。以下是游戏的完整代码及注释解析。(纯属好玩&#…...

HTML 揭秘:HTML 编码快速入门
HTML 揭秘:HTML 编码快速入门 一 . 前端知识介绍二 . HTML 介绍三 . HTML 快速入门四 . HTML 编辑器 - VSCode4.1 插件安装4.2 修改主题配色4.3 修改快捷键4.4 设置自动保存4.5 创建 HTML 文件4.5 书写 HTML 代码4.6 常见快捷键 五 . 基础标签5.1 字体标签5.1.1 col…...

Ubuntu22.04系统安装opencv步骤简述及问题解决方法
前言 opencv是一个功能强大、开源且跨平台的计算机视觉库,适用于多种编程语言和操作系统,能够帮助开发者构建各种视觉项目。其模块众多,提供了诸多功能,能够进行图像处理、视频处理等等。比如:Highgui模块提供图像用户…...

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset
1. 关联式容器 在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、 forward_list(C11)等,这些容器统称为序列式容器,因为其底层为线性序列的数据结构,里面 存储的是元素本身。那什么是关…...

【webpack4系列】webpack基础用法(二)
文章目录 entryoutputloaderpluginmode前端构建基础配置关联HTML插件html-webpack-plugin构建 CSS 解析 ES6和React JSX解析 ES6解析 React JSX 解析CSS、Less和Sass解析CSS解析Less解析sass 解析图片和字体资源解析:解析图片资源解析:解析字体资源解析&…...
Python Pyvis库创建交互式网络图 高级功能详解
文章目录 动态网络图图布局调整扩展到大规模网络动态网络图 Pyvis支持创建动态网络图,通过时间轴展示网络图的演化过程。 需要使用set_options函数,参数必须为json格式。动态网络图支持添加点和边。 下面是一个简单的动态网络图示例: # 动态网络图示例 from pyvis.networ…...

Linux服务器上安装git lfs命令
有时候,需要批量下载数据集时要用到git lfs命令 首先,使用pip install git-lfs安装,会发现使用时仍然提示:git: lfs is not a git command. See git --help. 这就意味着安装不成功。 因此,需要通过如下途径手动安装&a…...
Android 之 kotlin 语言学习笔记四(Android KTX)
一、Android KTX 简介 Android KTX 是包含在 Android Jetpack 及其他 Android 库中的一组 Kotlin 扩展程序。KTX 扩展程序可以为 Jetpack、Android 平台及其他 API 提供简洁的惯用 Kotlin 代码。为此,这些扩展程序利用了多种 Kotlin 语言功能,其中包括&…...
Ubuntu崩溃修复方案
当Ubuntu系统崩溃时,可依据崩溃类型(启动失败、运行时崩溃、完全无响应)选择以下修复方案。以下方法综合了官方推荐和社区实践,按操作风险由低到高排序: 一、恢复模式(Recovery Mode) 适用场景:系统启动卡顿、登录后黑屏、软件包损坏等。 操作步骤: …...
如何安全高效的文件管理?文件管理方法
文件的管理早已不只是办公场景中的需求。日常生活、在线学习以及个人收藏中,文件管理正逐渐成为我们数字生活中的基础。但与此同时,文件管理的混乱、低效以及安全性问题也频繁困扰着许多人。 文件管理的挑战与解决思路 挑战一:文件存储无序…...
【学习记录】深入解析 AI 交互中的五大核心概念:Prompt、Agent、MCP、Function Calling 与 Tools
📌 引言 随着大语言模型(LLM)的发展,AI 已经不再只是“回答问题”的工具,而是可以主动执行任务、调用外部资源、甚至构建完整工作流的智能系统。 为了更好地理解和使用这些能力,我们需要了解 AI 交互中几…...
java-springboot文件上传校验之只允许上传excel文件,且检查不能是脚本或者有害文件或可行性文件
四重验证机制: 文件扩展名检查(.xlsx/.xls)MIME类型检查文件魔数验证(真实文件类型)可执行文件特征检测 防御措施: 使用try-with-resources确保流关闭限制文件大小防止DoS攻击使用Apache POI的FileMagic进…...

仓颉语言---Socket编程
一、什么是Socket编程? 1.定义 Socket(套接字)可以被理解为网络上两个进程之间通信的端点。它是网络通信的抽象表示,封装了底层网络协议的复杂性,为应用程序提供了一个简单统一的接口。 Socket 编程是一种网络编程范式…...

基于SpringBoot的房屋租赁系统的设计与实现(thymeleaf+MySQL)
💗博主介绍💗:✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示:文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…...

Linux开发工具(apt,vim,gcc)
目录 yum/apt包管理器 Linux编辑器 vim 1.见一见vim 2.vim的多模式 3.命令模式底行模式等 4.vim的配置 Linux编译器 gcc/g 1.预处理(宏替换) 2.编译(生成汇编) 3.汇编(生成机器可识别代码) 4.连…...
Vim查看文件十六进制方法
在 Vim 中查看文件的十六进制格式,可以通过以下步骤实现: 方法 1:使用内置命令(无需插件) 用 Vim 以二进制模式打开文件: vim -b 文件名或打开文件后执行: :set binary转换为十六进制视图&…...
Spring IoC 详解:原理、实现与实战
Spring IoC 详解:原理、实现与实战 前言 Spring IoC(Inversion of Control,控制反转)是Spring框架的核心基础。它通过解耦对象的创建与依赖关系管理,极大提升了系统的可维护性和扩展性。本文将系统梳理Spring IoC的原…...