当前位置: 首页 > news >正文

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 的基本步骤:

  1. 初始化:从一个初始序列(通常为空或特殊起始标记)开始,设定束宽 k k k,初始化候选序列集 B 0 = { start } B_0 = \{ \text{start} \} B0={start}
  2. 迭代生成:对于当前所有候选序列 B t − 1 B_{t-1} Bt1,扩展一个新的词汇或符号,生成所有可能的下一个词汇组合,并计算每个序列的概率。
  3. 选择顶束:从所有扩展的候选序列中,选择得分最高的 k k k 个序列,作为下一步的候选序列 B t B_t Bt
  4. 终止条件:当所有候选序列都生成了结束标记(如 <eos>)或达到设定的最大长度 T T T 时,停止生成。
  5. 选择最终序列:从最终的候选序列集中,选择得分最高的序列作为输出。

:以GPT为例,扩展实际对应于去获取 tokens 的概率。

举个例子

  1. 初始化

    • 束宽 ( 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)}
  2. 扩展 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)}

  3. 仅扩展 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)}
  4. 后续步骤

    • 继续扩展:重复上述过程,直到所有候选序列都生成了 <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 个候选序列。

image-20240915235014101

实际应用中的 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?深入理解模型生成策略

是不是总感觉很熟悉&#xff1f; 在之前第5&#xff0c;7&#xff0c;8篇文章中&#xff0c;我们都曾经用到过与它相关的参数&#xff0c;而对于早就有着实操经验的同学们&#xff0c;想必见到的更多。这篇文章将从示例到数学原理和代码带你进行理解。 Beam Search 对应的中文翻…...

Spring自定义注解

目录 一、interface 关键字 二、元注解 三、简单实现 四、使用切面执行自定义注解逻辑 1) 首先将刚才的注解修改成放在方法上的&#xff1a; 2) 定义一个切面类&#xff1a; 3&#xff09;将注解放入到接口方法中测试&#xff1a; 五、切点表达式 一、interface 关键字 …...

微信小程序:wx.login或调用uni.login时报错the code is a mock one

微信小程序&#xff0c;调用wx.login或调用uni.login方法&#xff0c;返回the code is a mock one 原因与解决 原因:没有关联真实的 appid&#xff0c;解决办法&#xff1a;绑定真实的微信小程序的appid...

URL的执行流程

基本概念&#xff1a; URL&#xff08;统一资源定位符&#xff0c;Uniform Resource Locator&#xff09;的执行流程是指当你在浏览器中输入一个URL并按下回车键时&#xff0c;从输入URL到最终在浏览器中显示网页的完整过程。 1.解析协议 URL 以协议开头&#xff0c;如 http…...

双指针算法专题(2)

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

加密与安全_优雅存储用户密码的最佳实践

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

【多线程】深入剖析线程池的应用

&#x1f490;个人主页&#xff1a;初晴~ &#x1f4da;相关专栏&#xff1a;多线程 / javaEE初阶 还记得我们一开始引入线程的概念&#xff0c;就是因为进程太“重”了&#xff0c;频繁创建销毁进程的开销是非常大的。而随着计算机的发展&#xff0c;业务上对性能的要求越来越…...

『功能项目』切换职业面板【48】

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

【EasyExcel】@ColumnWidth(value = 20) EasyExcel设置列宽不生效

经过测试发现&#xff0c;只有XLS&#xff0c;ColumnWidth注解才会生效&#xff0c;选择CSV和XLSX都不会生效 //对应的导出实体类 EasyExcel.write(outputStream, Result.class)//excel文件类型&#xff0c;包括CSV、XLS、XLSX.excelType(ExcelTypeEnum.XLS)...

CPU 和 GPU:为什么GPU更适合深度学习?

目录 什么是 CPU &#xff1f; 什么是 GPU &#xff1f; GPU vs CPU 差异性对比分析 GPU 是如何工作的 &#xff1f; GPU 与 CPU 是如何协同工作的 &#xff1f; GPU vs CPU 类型解析 GPU 应用于深度学习 什么是 CPU &#xff1f; CPU&#xff08;中央处理器&#xff09;…...

【机器学习】:解锁数据背后的智慧宝藏——深度探索与未来展望

欢迎来到 破晓的历程的 博客 ⛺️不负时光&#xff0c;不负己✈️ 文章目录 引言一、深入机器学习的内在机制二、最新进展与趋势三、对未来社会的深远影响结语 引言 在上一篇博客中&#xff0c;我们初步探讨了机器学习如何成为解锁数据背后智慧的关键工具。现在&#xff0c;让…...

【Kubernetes】常见面试题汇总(十八)

目录 55.简述 Kubernetes 共享存储的作用&#xff1f; 56.简述 Kubernetes 数据持久化的方式有哪些&#xff1f; 57.简述 Kubernetes PV 和 PVC &#xff1f; 58.简述 Kubernetes PV 生命周期内的阶段&#xff1f; 55.简述 Kubernetes 共享存储的作用&#xff1f; Kubernet…...

无限边界:现代整合安全如何保护云

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

HTML贪吃蛇游戏

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

HTML 揭秘:HTML 编码快速入门

HTML 揭秘&#xff1a;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是一个功能强大、开源且跨平台的计算机视觉库&#xff0c;适用于多种编程语言和操作系统&#xff0c;能够帮助开发者构建各种视觉项目。其模块众多&#xff0c;提供了诸多功能&#xff0c;能够进行图像处理、视频处理等等。比如&#xff1a;Highgui模块提供图像用户…...

移情别恋c++ ദ്ദി˶ー̀֊ー́ ) ——13.mapset

1. 关联式容器 在初阶阶段&#xff0c;我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector、list、deque、 forward_list(C11)等&#xff0c;这些容器统称为序列式容器&#xff0c;因为其底层为线性序列的数据结构&#xff0c;里面 存储的是元素本身。那什么是关…...

【webpack4系列】webpack基础用法(二)

文章目录 entryoutputloaderpluginmode前端构建基础配置关联HTML插件html-webpack-plugin构建 CSS 解析 ES6和React JSX解析 ES6解析 React JSX 解析CSS、Less和Sass解析CSS解析Less解析sass 解析图片和字体资源解析&#xff1a;解析图片资源解析&#xff1a;解析字体资源解析&…...

Python Pyvis库创建交互式网络图 高级功能详解

文章目录 动态网络图图布局调整扩展到大规模网络动态网络图 Pyvis支持创建动态网络图,通过时间轴展示网络图的演化过程。 需要使用set_options函数,参数必须为json格式。动态网络图支持添加点和边。 下面是一个简单的动态网络图示例: # 动态网络图示例 from pyvis.networ…...

Linux服务器上安装git lfs命令

有时候&#xff0c;需要批量下载数据集时要用到git lfs命令 首先&#xff0c;使用pip install git-lfs安装&#xff0c;会发现使用时仍然提示&#xff1a;git: lfs is not a git command. See git --help. 这就意味着安装不成功。 因此&#xff0c;需要通过如下途径手动安装&a…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

保姆级教程:在无网络无显卡的Windows电脑的vscode本地部署deepseek

文章目录 1 前言2 部署流程2.1 准备工作2.2 Ollama2.2.1 使用有网络的电脑下载Ollama2.2.2 安装Ollama&#xff08;有网络的电脑&#xff09;2.2.3 安装Ollama&#xff08;无网络的电脑&#xff09;2.2.4 安装验证2.2.5 修改大模型安装位置2.2.6 下载Deepseek模型 2.3 将deepse…...

A2A JS SDK 完整教程:快速入门指南

目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库&#xff…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

Golang——9、反射和文件操作

反射和文件操作 1、反射1.1、reflect.TypeOf()获取任意值的类型对象1.2、reflect.ValueOf()1.3、结构体反射 2、文件操作2.1、os.Open()打开文件2.2、方式一&#xff1a;使用Read()读取文件2.3、方式二&#xff1a;bufio读取文件2.4、方式三&#xff1a;os.ReadFile读取2.5、写…...