llm的inference(一)

前提

对LLM(大语言模型)的推理不太清楚,自己把遇到的和推理相关的知识做个总结,如有错误,还请大家多多指导。

LLM

LLM可以分为:闭源和半开源。闭源就是什么都没有,只有接口供用户使用,例如GPT系列;半开源就是提供了权重文件,但是没有训练的代码,我们可以使用这个权重进行推理,例如llama系列。

LLM结构

现代的LLM模型基本上都是在Transformer结构上进行展开的。原生Transfromer结构如下:
在这里插入图片描述

在《Attention is All Your Need》这篇文章中,Encoder和Decoder的层数 N = 6 N=6 N=6
不同的LLM的架构架构有所区别,主要分为以下三种:

1.Encoder-only

只使用Encoder部分,没有Decoder部分,这样就可以看成是我们之前了解的自编码器。它可以对数据进行维度压缩、特征提取等等。Bert就使用的是Encoder-only的架构。

2.Encoder-Decoder

同时使用编码-解码器,编码器将输入编码为中间表达,然后解码器对中间表达进行解码。输入是序列,输出也是序列,所以它可以应对翻译,生成这样的任务。使用这种架构的llm有GLM、T5、Bart等。

3.Decoder-only

只使用Decoder部分,没有Encoder。通常用于条件生成任务,给定一些条件信息作为输入,模型通过解码器生成相应的输出,例如图像描述生成,文本生成任务。使用这种架构的llm有GPT系列,llama系列等。常见的chat模型都是基于Decoder-only。

宏观层面的LLM推理过程

先从宏观层面了解一下llm的推理过程,llm的推理是一个token一个token往出崩的,也就是串行输出的。总的来说:LLM推理的过程是一个自回归的过程,也就是说前i次的token会作为第i+1次的预测数据送入模型,拿到第i+1次的推理token。如下图所示:
在这里插入图片描述

起始输入的token是china,输出的token是is;在接下里的这次回归过程中,会将上一次的输出ischina进行拼接后再一起送入模型,以此类推,直到遇到条件中止。
宏观上LLM就是这么进行推理的。

宏观推理过程的进一步详细说明

上面的过程是宏观的过程,那么这个过程中大概的数据流是什么样呢?接下来我们对此做个简单的介绍。

从字符串输入到网络的输出

假设我们正在和GPT3进行对话,我们输入"Lionel Messi is a",则input="Lionel Messi is a"。我们知道神经网络只能输入数字(也就是tensor),那么从input开始是如何变为tensor的,它的维度又是多少,网络输出的维度又是多少呢?在下文我们一一解答。

  1. 首先会对input进行tokenizer,也就是将input划分为不同的token,并将其转换为对应的ID。在openAI 网站中可以给我们一个直观的解释。
    在这里插入图片描述
    tokenizerinput划分为6个Tokens,并为每个Token赋予了一个ID:
    在这里插入图片描述
    所以经过tokenizer后,input变为了[43, 295, 417, 36128, 318, 257]
  2. 进行one-hot编码。可以确定的是在GPT3中总共使用了50257个词汇,因此将上面的input进行one-hot编码,编码后的维度为[6,50257]。
  3. embedding(词嵌入)。可以看到50257维度有些太大了,并且大部分都为0,浪费了很多空间。所以可以试图将输入向量进行压缩(也就是映射到低维空间),减小维度。GPT压缩后的维度为12288,具体的过程就是:[6,50257]*[50257,12888] = [6,12288]。其中[50257,12288]这个矩阵的权重已经提前训练好了。
  4. 最终网络的输入为[6,12888],经过网络的推理后维度仍为[6,12288],然后我们对其进行反映射(乘以另一个权重矩阵,大小为[12888,50257]),最终得到的输出大小为[6,50257],然后我们取最后一个行向量即为网络预测的结果,然后从其中取概率最大的token作为网络的输出。

注意:这里我们的输入只有6个token,但是在实际的代码运行过程中会将这6个token填补到2048大小(GPT3),使用"空"值填补其它位置。参考一些解答:说是主要为了positional embeding,因此位置信息编码是固定的。

相关代码如下:

# copy from https://zhuanlan.zhihu.com/p/630832593
import torch
from transformers import GPT2LMHeadModel, GPT2Tokenizer
model = GPT2LMHeadModel.from_pretrained("gpt2", torchscript=True).eval()

# tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
in_text = "Lionel Messi is a"
in_tokens = torch.tensor(tokenizer.encode(in_text))
print(in_tokens)

# inference
token_eos = torch.tensor([198]) # line break symbol
out_token = None
i = 0
with torch.no_grad():
    while out_token != token_eos:
        print("input tokens shape:", in_tokens.shape)
        logits, _ = model(in_tokens)
        out_token = torch.argmax(logits[-1, :], dim=0, keepdim=True)
        in_tokens = torch.cat((in_tokens, out_token), 0)
        text = tokenizer.decode(in_tokens)
        print(f'step {i} input: {text}', flush=True)
        i += 1

out_text = tokenizer.decode(in_tokens)
print(f'Input: {in_text}')
print(f'Output: {out_text}')

可以看到,大模型预测结果是一个token一个token串行进行预测的,它只会拿预测概率最高的token。

总结

上面我们首先介绍了llm的几种架构,从宏观层面分析了LLM的推理过程,并对其中的一些数据流做了简单的分析,接下来我们要从工程方面分析大模型如何进行推理以及推理过程中的一些指标。

参考链接

  1. https://zhuanlan.zhihu.com/p/630832593
  2. https://zhuanlan.zhihu.com/p/174782647
  • 30
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值