AI开发者急需看的大语言模型基本原理

在学习大语言模型的基本原理的时候,发现遇到了很多问题,比如一个个单词是怎么转换为向量的,是提前得到的还是训练过程中得到?Transformer的输出向量又是怎么转化为自然语言的?Finetune的时候不是只需要输入和输出吗,为什么FineTune的脚本做了那么多的处理?找了很多资料发现基本都是在讲Transformer的原理,缺乏顶层视角的原理,最后不得已阅读了一下HuggingFace上关于LLaMA的代码才得到答案。

就像程序员也需要知道计算机硬件的基本原理一样,一个AI开发者也需要知道大语言模型的基本原理。本文主要是从AI开发者需要知道的角度来写,所以本文不会去涉及太底层的数学逻辑。下面一起来探讨一下。

整体架构

整体架构

整体框架分为两部分

  1. 分词器(Tokenizer) :将自然语言转化为TokenID的形式,大体可以理解为每个单词对应一个数字。(实际中稍有差异不过不影响理解,后面会详细说明)
  2. 模型:输入是TokenID,输出也是TokenID。大名鼎鼎的Transformer是这里面的一部分,当然了是最核心的部分。

为了便于理解,我们看一下用huggingface的transformers库来写代码是什么样的,做一下对比理解。

python
from transformers import AutoTokenizer, LlamaForCausalLM

# 加载模型
model = LlamaForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf")

#加载分词器
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")

prompt = "Who is LogicBit?"

#对输入的自然语言进行分词,转化为list[TokenID]
inputs = tokenizer(prompt, return_tensors="pt")

# 模型推理,得到list[TokenID]
generate_ids = model.generate(inputs.input_ids, max_length=30)

# 将模型的输出list[TokenID]转化为自然语言
tokenizer.batch_decode(generate_ids, skip_special_tokens=True, clean_up_tokenization_spaces=False)[0]

从上面可以看出基本是和上面画的整体架构是一致的。使用接口上也是分为了分词器和模型。下面依次看一下具体的细节。

Tokenizer

目的:在计算的时候只能使用数字来进行表示,所以需要将自然语言转化为数字。
编码: 输入一个句子(str),输出:对应的TokenID的列表(List[TokenID]
解码:编码的逆向操作。
基本原理:基于训练样本,通过某种算法得到一个词汇表,然后针对每个词汇进行编号就得到单词与TokenID(也就是编号)的对应关系。

举个例子

假如我的训练样本只有who is LogicBit这句话,那么我的算法就可以直接是每个单词对应一个ID。由于在英文里面空格就是区分两个单词的,所以空格我们就可以不要了。去掉空格相当于只有三个单词。

python

#注意一下以下的代码是一个逻辑上的意思,无法运行。
#按单词出现的顺序进行编号
tokenID['who'] = 1
tokenID['is'] = 2
tokenID['LogicBit'] = 3

#编码
tokenizer.encode('who is LogicBit') = [1, 2, 3]
#解码
tokenizer.decode([1, 2, 3]) = 'who is LogicBit'

#Too Simple, right?
扩展一下

实际使用中,其实没有上面这么简单,训练的算法是比较复杂的。因为这里面有很多的考量。比如为了提高表示效率,一个单词可能对应多个TokenID。
举个例子,look这个单词就有很多状态的词汇,现在进行时looking,过去分词looked,而watch也同样有watchedwatching。如果按照一个词汇对应一个ID,我们的词汇表就有6个['looking', 'looked', 'looking', 'watch', 'watched', 'watching'],但是如果按照词根来的话就可以表示为[look, watch, ed, ing],只需要4个即可表示。这个时候比如说looking就会对应两个TokenID, ['look', 'ing']。下面具体来看个实际的例子。

python

from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")

tokenizer.encode("who is LogicBit?")
#output:[1, 1058, 338, 4522, 293, 21591, 29973]
# 1 是llama词汇表中一个句子的起始字符,对应'<s>',每个句子都会有,自动加上去的。
# who      -> 1058
# is       -> 338
# LogicBit -> [4522, 293, 21591] ,这里就出现了一个单词对应多个tokenid的情况。
# ?        -> 29973

模型

image.png

模型整体的输入输出:输入也就是上面分词器得到的List[TokenID],输出也是List[TokenID]Embedding模块: 将每个tokenID转化为一个向量,向量的维度是模型定义的(看模型大小)。 Transformer:输入一排向量,输出另一排向量(向量的个数是一样的,向量的维度可能不一样) Output Translation:将Transformer的输出转为TokenID。

Embedding模块

image.png

  1. TokenID转化为向量

由于一个数字无法有效的衡量一个单词的含义,比如['who', 'error']对应[1058, 1059],但是你不能说whoerror是很像的东西吧,只能说毫无关系。由于一开始不知道哪个关系更近,所以就用一个向量来表示。先假设各个单词之间没有关系,然后在训练中学习。

python
## 还是前面的例子
tokenID['who'] = 1
tokenID['is'] = 2
tokenID['LogicBit'] = 3

#假设三个单词没有关系,由于词汇表容量是3,就可以用一个三维的向量来表示。
Vector['who'] = [1, 0, 0]
Vector['is'] = [0, 1, 0]
Vector['LogicBit'] = [0, 0, 1]

为什么要用这种方式? 因为这种表示方法在数学上是正交的,模型在计算相关度的时候一般用cosincosincosin的方式来做,这样子各个单词相关度都为0.

  1. Embedding

前面假设各个单词是没有关系,现实里面却是有关系的,所以我们还是需要学习这个关系。

Embedding=W∗VtokenEmbedding = W*V_{token}Embedding=W∗Vtoken​

VtokenV_{token}Vtoken​即为上面的tokenID转化后的向量。W为需要学习的参数矩阵,[DoutDim,DvocSize][D_{outDim},D_{vocSize}][DoutDim​,DvocSize​],DoutDimD_{outDim}DoutDim​是由Transformer定义的向量维度,像LLaMA就是768维,DvocSizeD_{vocSize}DvocSize​就是词汇表的大小。

Transformer

由于我们主要是讲LLM的顶层原理,所以Transformer的原理不是我们的重点,我们这里主要讲一下Transformer给我们提供的能力。(感兴趣的可以自己可以看下李宏毅老师的视频,讲得非常清楚)

transformer

我们这里只画了Decoder,是因为现在大部分生成式的模型都是用的Decoder。
输入输出:都是一排向量。

Output Translation

由于transformer的输出是每个token对应一个向量,但是我们需要的是tokenID,才能转化为自然语言。

输出转换

输出是一个tokenID,其实是一个分类问题,只不过我们这里的类别比较多,和词汇表的大小一致。如何将一个向量转换为一个类别,机器学习里面有一个通用的做法,就是把这个向量的每个维度看成是一个类别,值代表概率。

  1. 线性转换:由于Transformer的输出的向量维度一般和词汇表的大小不一致,所以需要先转化为词汇表的大小维度,这个有点像是前面embedding的反向操作。经过转换后得到维度为词汇表大小的向量。

output=w∗zoutput = w*zoutput=w∗z

其中w的维度为(Dimvoc,DimT)(Dim_{voc},Dim_{T})(Dimvoc​,DimT​),z为transformer的输出,维度为(DimT,1)(Dim_T,1)(DimT​,1).

  1. Softmax:将各个维度进行一次计算得到每个维度的概率。其实也可以不做这个操作,只是原来的数值加起来可能大于1,或者小于1,不方便后续算法的处理而已。

假设输出向量x=[x1x2…xn]假设输出向量 x= \begin{bmatrix} x_1\x_2\…\x_n \end{bmatrix}假设输出向量x=​x1​x2​…xn​​​

那么第i个类别的概率p(i)=exi∑k=1nexk那么第i个类别的概率 p(i) = \frac{e{x_i}}{\sum_{k=1}ne^{x_k}}那么第i个类别的概率p(i)=∑k=1n​exk​exi​​

  1. 选择:选择概率最高的作为输出的值即可。(注意一下,实际上大语言模型在生成答案的时候会加入随机性,并不一定选择概率最高的,只不过概率最高的被选中的几率更大)

预训练

给定上文,预测下文。简单来说就是预测下一个词是什么?举个例子,假设样本里面有一句话['I', 'am', 'happy'],针对这句话的任务如下:

输入I,预期输出am
输入I am,预期输出 happy
:上面只是为了方便理解,实际上并不是真的将一句话拆分成多次预测任务,而是并行计算,也就是输入I am happy, 输出 I am happy,然后算法在计算某个位置的输出的时候不会考虑后面的结果是什么,也就达到了基于上文去预测的效果。

收集大量的句子按照如上进行训练。

Finetune

给定一个输入输出对的数据集,基于这个数据集在预训练的模型上面做微调。举个例子来说明一下:

输入:who are you? 输出:I am a llm.
之前一直认为就是直接按照这个输入输出进行微调的。
其实并不是,这个看上面的预训练就可以理解了,在预训练的时候llm的输入输出是一样,所以在微调的时候输入输出应该也是一样的(不然transformer的attention计算会出问题,这个留给各位思考一下为什么? )。所以需要将上面两句话合并,也就是输入输出都是who are you? I am a llm.一般Finetune的脚本都会做这个处理。
这里可能又会产生一个疑问?如果是这样子的话,那大语言模型的输出不是会把我们的问题带上吗,但是使用像chatgpt的时候,输出并没有包括输入的问题。这个是因为在对话的时候会做特殊处理,输出的内容会将问题过滤掉。但是原始的输出是会包括输入的内容的。

python

#使用huggingface的generate没有做处理的时候,就可以看到输出是带了输入的。
model.generate()

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

在这里插入图片描述

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

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

😝有需要的小伙伴,可以Vx扫描下方二维码免费领取==🆓

在这里插入图片描述

  • 12
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值