详解大模型推理:从基础知识讲起

在这里插入图片描述

导言

本文介绍了大型语言模型推理的各个方面。它首先解释了推理的基本概念,如预填充和解码阶段、在线和离线推理、基础(Grounding)等。然后详细讨论了推理性能的关键指标,包括延迟、吞吐量、第一个Token的时间(TTFT)和每个输出Token的时间(TPOT)。后面还深入探讨了模型内存使用情况,特别是KV Cache的重要性和计算方法。

参考英文资料链接:https://github.com/stas00/ml-engineering

大模型推理

预填充和解码

由于提示的所有token都是已知的,那么一次处理完整的提示长度(类似于训练)并缓存中间状态(KV缓存),可以让即使是1k的提示也可以在足够的内存下非常快地处理,并且几乎不会增加延迟。代价是会增加显存。

预填充的概念

在讨论大模型推理过程中的预填充阶段之前,我们首先需要了解“预填充”的概念。预填充通常指的是在进行序列处理任务(如自然语言处理中的文本生成、机器翻译等)时,将输入序列的一部分或全部提前加载到模型中,作为后续计算的基础。这个步骤对于确保模型能够正确理解和处理输入数据至关重要。

预填充阶段发生了什么

在大模型推理的上下文中,预填充阶段主要涉及以下几个方面:

  1. 输入准备:将待处理的数据(如一段文本)转换成模型可以理解的形式(通常是数值向量Token)。这包括对输入文本进行分词、编码等操作。

  2. 状态初始化:为模型创建一个初始状态,该状态可能包含一些默认值或是根据特定算法生成的起始点。这一步骤对于那些依赖于先前信息(例如循环神经网络RNN及其变体或者是GPT)的模型尤为重要。

  3. 加载到模型:将准备好的输入数据加载到模型中,开始执行前向传播过程。在此过程中,模型会基于当前输入和其内部状态来更新其权重和激活函数的输出。

预填充的作用与意义

  • 提高效率:通过预先准备好输入数据并将其加载到模型中,可以减少实际推理过程中的计算负担,从而加快整个处理流程。

  • 增强准确性:预填充允许模型更好地理解输入数据的整体结构和上下文信息,这对于需要长距离依赖的任务特别重要,比如文档级别的文本分析。

  • 支持复杂任务:在执行复杂的序列预测任务时,预填充提供了一个框架,使得模型能够在已知信息的基础上逐步构建出完整的响应或预测结果。

解码的概念

解码:新token的生成是基于所有先前的token(提示和迄今为止生成的任何新token)一次生成一个新token(回归方法)。因此,与预填充不同,这一阶段对生成的延迟贡献最大,因为解码无法并行化。

在线推理与离线推理

当用户实时发送查询时 - 这是在线推理,也称为部署。示例:聊天机器人、搜索引擎、通用REST API。在这种情况下,通常会运行一个推理服务器,并且可能有各种客户端连接到它。

当你有一个包含提示的文件需要进行推理时 - 这是离线推理。示例:基准评估、合成数据生成。在这种情况下,通常不需要推理服务器,推理直接在发送查询的同一程序中运行(客户端和服务器在一个应用程序中)。

基础Grounding

这是为预训练模型提供在训练期间不可用的额外信息的过程。例如,输入基础任务(input-grounded-tasks)在提示中为模型提供了大量额外信息。非零样本提示在示例中为模型提供基础,改变了默认的模型行为。提示工程的全部内容是使模型在推理期间以某种特定方式来推理。

检索增强生成(RAG)是为模型提供基础的主要技术之一,因为它为推理过程提供了与提示相关的额外数据。目的是使模型比其训练时的大量压缩信息更重视这些额外信息。

微调到不同的知识领域是另一种基础方法,我们更新模型,使其在一个新的数据集上有基础,这个数据集可能与基础模型训练的原始数据领域完全不同。

基础可以被认为是提供上下文。正如任何人都可以证明的那样,当一个人理解问题的上下文时,回答问题会更容易。模型生成也是如此。上下文越好,生成的输出就越相关。

在多模态使用情况下,图像或视频与文本提示一起提供可以作为基础或上下文。

任务(Tasks)

输入基础任务(Input-grounded tasks)

输入基础任务是那些生成响应主要来自提示的任务,即主要知识包含在提示中。这些包括:

  • 翻译
  • 摘要
  • 文档问答
  • 多轮对话
  • 代码编辑
  • 语音识别(音频转录)

批处理(Batching)

一次处理一个token的解码阶段对加速器来说是非常低效的。将多个查询一起批处理可以提高加速器的利用率,并使一次处理多个请求成为可能。

批处理的最大可能大小取决于在加载模型权重和填充KV缓存后剩余的内存量。

静态批处理(Static batching)

这是最简单直接的批处理方式,前N个查询一起批处理 - 问题在于,如果许多查询已经完成生成,它们将不得不等待最长的查询完成,然后才能返回给调用者 - 大大增加了延迟。

连续批处理或运行中的批处理(Continuous Batching or In-flight batching)

连续批处理或飞行中的批处理是一个过程,在这个过程中,生成引擎在生成完成后立即删除完成的查询,并用新查询替换它们,而不等待整个批处理完成。因此,批处理中位置0的序列可能正在生成其第10个token,而批处理中位置1的序列可能刚刚开始其第一个token生成,位置3的序列正在生成其最后一个token。

这提高了响应时间,当然,如果所有计算都忙于处理,并且没有新的空闲位置,那么一些请求将不得不等待计算开始处理它们。

分页注意力(Paged Attention)

分页注意力是推理服务器中非常流行的技术,因为它允许非常高效地利用加速器内存,通过接近加速器内存的方式使用分页,从而允许动态内存分配并防止内存碎片。

分页注意力的概念

分页注意力(Paged Attention) 是一种优化技术,主要用于处理大型模型中的长序列数据推理问题。在传统的Transformer架构中,自注意力机制需要对输入序列的所有元素进行配对比较以计算注意力分数,这对于非常长的序列来说,计算和内存开销都非常巨大。

作用

  • 降低计算成本:通过将输入序列分割成多个较短的段落或“页”,可以显著减少每次计算所需的资源。
  • 管理内存使用:对于超长序列,直接处理可能导致内存溢出错误。分页注意力允许模型按需加载和处理数据,有效控制内存占用。

分页注意力的过程

  • 分割阶段:原始输入序列被分成若干个子序列或“页”。这一步骤有助于限制每次注意力计算所涉及的数据量。

  • 局部计算:针对每个“页”单独执行标准的注意力机制计算。这意味着每一页内的元素之间会计算相互之间的注意力权重,但不同页间的直接交互在此步骤中是有限的或是不存在的。

  • 跨页连接:为了补偿由于分割而丢失的全局信息,不同的实现可能会采用各种策略来维持或重建跨页的信息流。例如,某些方法可能包括相邻页之间的重叠区域,或者是利用额外的机制如缓存来存储关键信息以便后续页面使用。

  • 整合输出:最后,所有单独计算的结果会被重新组合起来形成最终的输出。这个过程需要谨慎设计,确保从各个部分得到的信息能够无缝地集成在一起,同时尽可能保持原始未分割序列的特性。

通过这种方式,分页注意力能够在不过度牺牲性能的前提下,扩展模型处理更长序列的能力,使得大模型在实际应用中更加实用和高效。

解码方法(Decoding methods)

主要的解码方法有:贪心解码、束搜索和采样。

贪心解码(Greedy decoding)

贪心解码是模型总是选择概率最高的token。这是最快的解码方法,但它不一定生成最好的结果,因为它可能会选择一个不太理想的token路径,并错过一个很好的未来token序列。

贪心解码的主要问题是创建循环,即相同的句子被一遍又一遍地重复。

定义:
贪心解码是一种用于序列生成任务的简单策略,常见于自然语言处理(NLP)中的文本生成模型。它通过每一步选择当前时间步下概率最大的单词来逐步构建输出序列。

作用意义:

  • 简单高效: 由于其简单的决策过程,贪心解码计算成本低且易于实现。
  • 实时应用: 在需要快速响应的应用场景中,如即时翻译或对话系统,贪心解码因其效率而受到青睐。

贪心解码的过程

  1. 初始化: 从输入序列开始,通常是一个句子或段落,编码为向量表示。
  2. 第一步预测: 使用训练好的模型对输入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值