小白学大模型:四种文本解码策略

news2024/11/23 20:17:22

在大型语言模型(LLM)的迷人世界中,模型架构、数据处理和优化常常成为关注的焦点。但解码策略在文本生成中扮演着至关重要的角色,却经常被忽视。

在这篇文章中,我们将通过深入探讨贪婪搜索和束搜索的机制,以及采用顶K采样和核采样的技术,来探索LLM是如何生成文本的。

https://mlabonne.github.io/blog/posts/2022-06-07-Decoding_strategies.html

https://colab.research.google.com/drive/19CJlOS5lI29g-B3dziNn93Enez1yiHk2?usp=sharing

基础知识

为了开始,我们先举一个例子。我们将文本“I have a dream”输入到GPT-2模型中,并让它生成接下来的五个词(单词或子词)。

from transformers import GPT2LMHeadModel, GPT2Tokenizer
import torch

device = 'cuda' if torch.cuda.is_available() else 'cpu'
model = GPT2LMHeadModel.from_pretrained('gpt2').to(device)
tokenizer = GPT2Tokenizer.from_pretrained('gpt2')
model.eval()

text = "I have a dream"
input_ids = tokenizer.encode(text, return_tensors='pt').to(device)

outputs = model.generate(input_ids, max_length=len(input_ids.squeeze())+5)
generated_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(f"Generated text: {generated_text}")

句子“I have a dream of being a doctor”似乎是由GPT-2生成的。然而,GPT-2并没有完全生成这句话。

接下来我们将深入探讨各种解码策略,包括贪婪搜索、束搜索以及采用顶K采样和核采样的技术。通过这些策略,我们可以更好地理解GPT-2是如何生成文本的。

人们常常误解认为像GPT-2这样的大型语言模型(LLM)直接生成文本。实际上并非如此。相反,LLM会计算对其词汇表中每个可能的词元分配的分数,这些分数称为logits。为了简化说明,以下是这个过程的详细分解:

图片

首先,分词器(在本例中是字节对编码)将输入文本中的每个词元转换为相应的词元ID。然后,GPT-2使用这些词元ID作为输入,尝试预测下一个最有可能的词元。最终,模型生成logits,这些logits通过softmax函数转换为概率。

例如,模型给“of”这个词元在“I have a dream”之后出现的概率分配了17%。这个输出本质上表示了潜在下一个词元的排序列表。更正式地,我们将这个概率表示为。

自回归模型(如GPT)根据前面的词元预测序列中的下一个词元。考虑一个词元序列 。这个序列的联合概率 可以分解为:

对于序列中的每个词元 , 表示在所有前面的词元 给定的情况下 出现的条件概率。GPT-2 为其词汇表中的50,257个词元中的每一个计算这个条件概率。

贪婪搜索(Greedy Search)

贪婪搜索是一种解码方法,在每一步中选择最可能的词元作为序列中的下一个词元。简单来说,它在每个阶段只保留最可能的词元,舍弃所有其他潜在选项。以我们的例子为例:

  • 步骤 1: 输入: “I have a dream” → 最可能的词元: ”of”
  • 步骤 2: 输入: “I have a dream of” → 最可能的词元: ”being”
  • 步骤 3: 输入: “I have a dream of being” → 最可能的词元: ”a”
  • 步骤 4: 输入: “I have a dream of being a” → 最可能的词元: ”doctor”
  • 步骤 5: 输入: “I have a dream of being a doctor” → 最可能的词元: “.”

尽管这种方法听起来很直观,但需要注意的是,贪婪搜索是短视的:它只考虑每一步中最可能的词元,而不考虑对整个序列的整体影响。这个特性使得它速度快且高效,因为它不需要跟踪多个序列,但也意味着它可能错过那些包含稍微不那么可能的下一个词元的更好序列。

接下来,让我们使用 graphviznetworkx 来说明贪婪搜索的实现。我们选择得分最高的词元ID,计算其对数概率(我们取对数以简化计算),并将其添加到树中。我们将重复这个过程五次以生成五个词元。

def greedy_search(input_ids, node, length=5):
    if length == 0:
        return input_ids

    outputs = model(input_ids)
    predictions = outputs.logits

    # Get the predicted next sub-word (here we use top-k search)
    logits = predictions[0, -1, :]
    token_id = torch.argmax(logits).unsqueeze(0)

    # Compute the score of the predicted token
    token_score = get_log_prob(logits, token_id)

    # Add the predicted token to the list of input ids
    new_input_ids = torch.cat([input_ids, token_id.unsqueeze(0)], dim=-1)

    # Add node and edge to graph
    next_token = tokenizer.decode(token_id, skip_special_tokens=True)
    current_node = list(graph.successors(node))[0]
    graph.nodes[current_node]['tokenscore'] = np.exp(token_score) * 100
    graph.nodes[current_node]['token'] = next_token + f"_{length}"

    # Recursive call
    input_ids = greedy_search(new_input_ids, current_node, length-1)
    
    return input_ids

束搜索(Beam Search)

与仅考虑下一个最可能词元的贪婪搜索不同,束搜索会考虑前 个最可能的词元,其中表示束的数量。这个过程会重复进行,直到达到预定义的最大长度或者出现序列结束词元为止。此时,具有最高整体得分的序列(或“束”)将被选择为输出。

我们可以调整之前的函数,以考虑前 个最可能的词元而不仅仅是一个。在这里,我们将维护序列得分 ,即每个束中每个词元的对数概率的累计和。我们通过序列长度对这个得分进行归一化,以防止对较长序列的偏向(这个因素可以调整)。同样,我们将生成五个额外的词元以完成句子“I have a dream”。

def beam_search(input_ids, node, bar, length, beams, sampling, temperature=0.1):
    if length == 0:
        return None

    outputs = model(input_ids)
    predictions = outputs.logits

    # Get the predicted next sub-word (here we use top-k search)
    logits = predictions[0, -1, :]

    if sampling == 'greedy':
        top_token_ids = greedy_sampling(logits, beams)
    elif sampling == 'top_k':
        top_token_ids = top_k_sampling(logits, temperature, 20, beams)
    elif sampling == 'nucleus':
        top_token_ids = nucleus_sampling(logits, temperature, 0.5, beams)

    for j, token_id in enumerate(top_token_ids):
        bar.update(1)

        # Compute the score of the predicted token
        token_score = get_log_prob(logits, token_id)
        cumulative_score = graph.nodes[node]['cumscore'] + token_score

        # Add the predicted token to the list of input ids
        new_input_ids = torch.cat([input_ids, token_id.unsqueeze(0).unsqueeze(0)], dim=-1)

        # Add node and edge to graph
        token = tokenizer.decode(token_id, skip_special_tokens=True)
        current_node = list(graph.successors(node))[j]
        graph.nodes[current_node]['tokenscore'] = np.exp(token_score) * 100
        graph.nodes[current_node]['cumscore'] = cumulative_score
        graph.nodes[current_node]['sequencescore'] = 1/(len(new_input_ids.squeeze())) * cumulative_score
        graph.nodes[current_node]['token'] = token + f"_{length}_{j}"

        # Recursive call
        beam_search(new_input_ids, current_node, bar, length-1, beams, sampling, 1)

顶K采样(Top-k Sampling)

顶K采样是一种利用语言模型生成的概率分布,从最可能的前K个选项中随机选择一个词元的技术。

图片

假设我们有 𝑘=3,四个词元A、B、C和D,具有以下概率:

  • 𝑃(A) = 30%
  • 𝑃(B) = 15%
  • 𝑃© = 5%
  • 𝑃(D) = 1%

在顶K采样中,词元D会被忽略,算法将以以下概率输出:

  • A 60%的时间
  • B 30%的时间
  • C 10%的时间

这种方法确保我们优先考虑最可能的词元,同时在选择过程中引入了一定的随机性。

另一种引入随机性的方法是温度的概念。温度𝑇是一个从0到1的参数,它影响softmax函数生成的概率,使最可能的词元更具影响力。在实践中,它仅仅是将输入的logits除以一个我们称之为温度的值:

核采样(Nucleus Sampling)

核采样,也称为采样,与采样采用不同的方法。与选择最可能的前个词元不同,核采样选择一个截断值,使得被选择的词元的概率总和超过。这样就形成了一个“核”词元集合,从中随机选择下一个词元。

换句话说,模型按概率从高到低检查其最可能的词元,并不断将它们添加到列表中,直到总概率超过阈值。与采样不同,核中包含的词元数量可以根据每一步的不同而变化。这种变异性通常会导致更具多样性和创造性的输出,使得核采样在文本生成任务中非常受欢迎。

如何学习AI大模型?

作为一名热心肠的互联网老兵,我决定把宝贵的AI知识分享给大家。 至于能学习到多少就看你的学习毅力和能力了 。我已将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

一、全套AGI大模型学习路线

AI大模型时代的学习之旅:从基础到前沿,掌握人工智能的核心技能!

img

二、640套AI大模型报告合集

这套包含640份报告的合集,涵盖了AI大模型的理论研究、技术实现、行业应用等多个方面。无论您是科研人员、工程师,还是对AI大模型感兴趣的爱好者,这套报告合集都将为您提供宝贵的信息和启示。

img

三、AI大模型经典PDF籍

随着人工智能技术的飞速发展,AI大模型已经成为了当今科技领域的一大热点。这些大型预训练模型,如GPT-3、BERT、XLNet等,以其强大的语言理解和生成能力,正在改变我们对人工智能的认识。 那以下这些PDF籍就是非常不错的学习资源。

img

四、AI大模型商业化落地方案

img

作为普通人,入局大模型时代需要持续学习和实践,不断提高自己的技能和认知水平,同时也需要有责任感和伦理意识,为人工智能的健康发展贡献力量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2127944.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电机驱动开发之主控板

目录 1.主要器件选型2.原理图设计电源调理最小系统通讯接口显示器 3.PCB绘制4.打板验证5.总结 1.主要器件选型 器件参数理由MCUSTM32CBT6资源丰富价格低廉LDOASM1117(5V-3.3V)常见CANSIT1057T常见UARTType-C CH340使用常见Type-c线通讯即可屏幕ips TFT资…

sheng的学习笔记-AI-话题模型(topic model),LDA模型,Unigram Model,pLSA Model

AI目录:sheng的学习笔记-AI目录-CSDN博客 基础知识 什么是话题模型(topic model) 话题模型(topic model)是一族生成式有向图模型,主要用于处理离散型的数据(如文本集合)​,在信息检索、自然语言处理等领域有广泛应用…

【赵渝强老师】大数据主从架构的单点故障

大数据体系架构中的核心组件都是主从架构,即:存在一个主节点和多个从节点,从而组成一个分布式环境。下图为展示了大数据体系中主从架构的相关组件。   视频讲解如下: 大数据主从架构的单点故障 【赵渝强老师】大数据主从架构的…

【大模型专栏—入门篇】科研论文疑惑汇总

大模型专栏介绍 😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本文为大模型专栏子篇,大模型专栏将持续更新,主要讲解大模型从入门到实战打怪升级。如有兴趣,欢迎您的阅读。 &#x1f4…

【多线程】手把手带你学习定时器那些事

💐个人主页:初晴~ 📚相关专栏:多线程 / javaEE初阶 在软件开发中,有一些代码逻辑并不需要立马就被执行,可能需要等一段时间在执行。就好像我们会用闹钟来提醒我们过一段时间后要做某事一样,代码…

裸土检测算法、裸土检测算法样本标注,裸土覆盖检测算法

裸土检测算法主要用于环境保护、土地管理和农业等领域,通过图像识别技术来检测地表上的裸露土壤区域。这种技术对于土地退化监测、水土流失预防、农田管理等方面有着重要意义。以下是关于裸土检测算法的技术实现、应用场景及优势的详细介绍。 应用场景 裸土检测算法…

kafka原理剖析及实战演练

一、消息系统概述 一)消息系统按消息发送模型分类 1、peer-to-peer(单播) 特点: 一般基于pull或polling接收消息发送对队列中的消息被一个而且仅仅一个接收者所接收,即使有多个接收者在同一队列中侦听同一消息即支持异…

JVM - GC垃圾回收

文章目录 目录 文章目录 1. 自动垃圾回收 1.1 垃圾回收区域 2. 方法区回收 3. 堆回收 3.1 对象已死? 3.1.1 引用计数算法 3.1.2 可达性分析算法 3.1.3 再谈引用 强引用 软引用 弱引用 虚引用 3.2 垃圾收集算法 3.2.1 分代收集理论 3.2.2 垃圾回收算…

Android U 多任务启动分屏——Launcher流程(下分屏 更新中)

前文 Android U 多任务启动分屏——Launcher流程(上分屏) 最近任务onClick事件的监听 在最近任务中每个任务都是一个TaskView,对TaskView操作,就是每个任务的操作。 代码路径:packages/apps/Launcher3/quickstep/…

安装Anaconda(过程)

Anaconda是一个开源的Python发行版本,用来管理Python相关的包,安装Anaconda可以很方便的切换不同的环境,使用不同的深度学习框架开发项目,本文将详细介绍Anaconda的安装。 一、安装 1、安装方式 官网:“https://www.…

C#环境搭建和入门教程--vs2022之下

目录 1.环境搭建 2.先让程序跑起来 3.C#代码结构 4.变量,输入输出介绍 5.内容输入和类型转换 1.环境搭建 我们的这个c#基础学习主要就是在这个vs2022上面进行的,我们的这个c/c使用的都是这个平台 我们首先检查一下我们的这个环境是不是完全的配置了…

什么是API网关(API Gateway)?

1. 什么是API网关(API Gateway)? 在微服务体系结构中,客户端可能与多个前端服务进行交互。 API 网关位于客户端与服务之间。 它充当反向代理,将来自客户端的请求路由到服务。 它还可以执行各种横切任务,例…

技术美术一百问(01)

———————————————————问题篇———————————————————— 基础: 解释BRDF? 什么是Lightmap? 游戏里的各种液体怎么实现? 渲染流水线中,屏幕中的一个像素是怎么绘制出来的&#xff…

【推荐100个unity插件之33】比 Unity 自带协程更高效的异步处理方式,提供一个高性能和0GC的async/await异步方案——UniTask插件

文章目录 前言github地址GC(Garbage Collection,垃圾回收)GC 的影响 UniTask优缺点使用案例案例完结 前言 UniTask 是一个轻量级的异步编程库,专门为 Unity 设计,旨在提供比 Unity 自带协程更高效的异步处理方式。它是…

(11)(2.1.1) PWM、OneShot和OneShot125 ESC(一)

文章目录 前言 1 PWM 2 OneShot 3 参数说明 前言 大多数 ArduPilot 飞行器使用由无刷电机 ESC 控制的无刷电机。这些 ESC 使用的最常见协议是PWM、OneShot、OneShot125 和 DShot。本页介绍前三种(PWM、OneShot 和OneShot125)。 !Warning…

中间件安全(一)

本文仅作为学习参考使用,本文作者对任何使用本文进行渗透攻击破坏不负任何责任。 一,中间件。 1,什么是中间件。 是一类能够为一种或多种应用程序合作互通、资源共享,同时还能够为该应用程序提供相关的服务的软件。中间件是一类…

哈尔滨的珍同学

写在前面 10225 字 | 朋友 | 旅行 | 友谊 | 情感 | 感触 | 思考 | 消极内容 全文篇幅过于庞大,请慎重考虑是否阅读。 与佳芯小姐的短文,将另行发布。 TL;DR 我不知道我和珍的关系还能维持多久。 按理来说,与朋友见面应当是一件开心的事情。这…

Linux系统连接蓝牙、WiFi方法分享,适用瑞芯微RK3562、RK3568、RK3588等开发板

本文适用于瑞芯微RK3562、RK3568、RK3588等各类开发板。本教程使用到的是深圳触觉智能开发的RK3562开发板,型号EVB3562,RK3562采用四核Cortex-A53 CPU,频率可达2.0GHz;最大支持 8GB 内存;内置独立的 NPU,可用于轻量级人…

卷轴模式系统源码开发:探索游戏世界——游戏模式的设计

在电子游戏的发展历程中,卷轴模式(Scrolling Mode)作为一种经典且广泛应用的游戏界面呈现方式,为玩家提供了沉浸式的探索体验。从早期的《超级马里奥兄弟renxb001》到现代的《塞尔达传说》系列,卷轴模式不仅定义了众多…

PPT中的图形与图片:插入、调整与格式设置技术详解

目录 引言 一、图形与图片的插入 1. 插入图形 2. 插入图片 二、图形与图片的调整 1. 调整大小与位置 2. 裁剪与旋转 3. 图形与图片的合并与组合 三、图片格式与布局设置 1. 图片格式设置 2. 图片布局设置 示例案例:制作产品展示PPT 四、结论 引言 在现…