赞
踩
对LLM(大语言模型)的推理不太清楚,自己把遇到的和推理相关的知识做个总结,如有错误,还请大家多多指导。
LLM可以分为:闭源和半开源。闭源就是什么都没有,只有接口供用户使用,例如GPT系列;半开源就是提供了权重文件,但是没有训练的代码,我们可以使用这个权重进行推理,例如llama系列。
现代的LLM模型基本上都是在Transformer结构上进行展开的。原生Transfromer结构如下:
在《Attention is All Your Need》这篇文章中,Encoder和Decoder的层数
N
=
6
N=6
N=6。
不同的LLM的架构架构有所区别,主要分为以下三种:
只使用Encoder部分,没有Decoder部分,这样就可以看成是我们之前了解的自编码器。它可以对数据进行维度压缩、特征提取等等。Bert就使用的是Encoder-only的架构。
同时使用编码-解码器,编码器将输入编码为中间表达,然后解码器对中间表达进行解码。输入是序列,输出也是序列,所以它可以应对翻译,生成这样的任务。使用这种架构的llm有GLM、T5、Bart等。
只使用Decoder部分,没有Encoder。通常用于条件生成任务,给定一些条件信息作为输入,模型通过解码器生成相应的输出,例如图像描述生成,文本生成任务。使用这种架构的llm有GPT系列,llama系列等。常见的chat模型都是基于Decoder-only。
先从宏观层面了解一下llm的推理过程,llm的推理是一个token一个token往出崩的,也就是串行输出的。总的来说:LLM推理的过程是一个自回归的过程,也就是说前i次的token会作为第i+1次的预测数据送入模型,拿到第i+1次的推理token。如下图所示:
起始输入的token是china
,输出的token是is
;在接下里的这次回归过程中,会将上一次的输出is
和china
进行拼接后再一起送入模型,以此类推,直到遇到条件中止。
宏观上LLM就是这么进行推理的。
上面的过程是宏观的过程,那么这个过程中大概的数据流是什么样呢?接下来我们对此做个简单的介绍。
假设我们正在和GPT3进行对话,我们输入"Lionel Messi is a",则input="Lionel Messi is a"
。我们知道神经网络只能输入数字(也就是tensor),那么从input
开始是如何变为tensor的,它的维度又是多少,网络输出的维度又是多少呢?在下文我们一一解答。
input
进行tokenizer,也就是将input划分为不同的token,并将其转换为对应的ID。在openAI 网站中可以给我们一个直观的解释。tokenizer
将input
划分为6个Tokens,并为每个Token赋予了一个ID:tokenizer
后,input变为了[43, 295, 417, 36128, 318, 257]
。注意:这里我们的输入只有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的推理过程,并对其中的一些数据流做了简单的分析,接下来我们要从工程方面分析大模型如何进行推理以及推理过程中的一些指标。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。