前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >大语言模型-01-语言模型发展历程-01

大语言模型-01-语言模型发展历程-01

作者头像
用户2225445
发布2025-03-15 21:58:59
发布2025-03-15 21:58:59
3900
代码可运行
举报
文章被收录于专栏:IT从业者张某某IT从业者张某某
运行总次数:0
代码可运行

简介

本博客内容是《大语言模型》一书的读书笔记,该书是中国人民大学高瓴人工智能学院赵鑫教授团队出品,覆盖大语言模型训练与使用的全流程,从预训练到微调与对齐,从使用技术到评测应用,帮助学员全面掌握大语言模型的核心技术。并且,课程内容基于大量的代码实战与讲解,通过实际项目与案例,学员能将理论知识应用于真实场景,提升解决实际问题的能力。

1.1语言模型发展历程

大模型的能力

范围广泛的世界知识: 例如,了解历史事件如2024年巴黎奥运会的详细情况,包括参赛国家、主要比赛项目和获奖者的信息;或者解释科学理论,比如量子计算的基本原理及其对未来计算机技术的影响。这里为知道谁是老子,以及老子的思想。 较强的人类指令遵循能力: 如果用户询问:“请帮我查找一下如何在家制作一杯拿铁咖啡的方法”,系统应该能够提供详细的步骤指导,从准备所需材料到具体的制作流程,确保用户可以轻松跟随操作。这里为给出本题的答案B 改进的复杂任务推理能力: 比如分析复杂的经济模型,预测某一政策变动对不同行业的影响。这涉及到理解宏观经济指标、市场趋势以及各行业的相互关系,并基于这些信息做出合理的推测。这里为基于老者的话推出老者的思想,并给出与之匹配的政治理念提出者 较强的通用任务解决能力:例如,帮助用户规划一次国际旅行,不仅包括预订机票和酒店,还需要考虑签证申请、当地交通安排、旅游景点推荐等多个方面的问题,确保整个旅程顺利。 较好的人类对齐能力: 在与用户的对话中,能够理解并回应用户的情感状态。如果用户表达出失望或困惑的情绪,系统应能以同理心回应,并提供适当的支持或建议,比如当用户提到因为错过一场重要会议而感到沮丧时,系统可以提供一些时间管理技巧或鼓励的话语。 较强的多轮对话交互能力: 支持深入且连贯的对话。例如,在讨论一个项目的计划时,用户可以逐步提出不同的问题或要求更详细的信息,系统能够保持上下文的理解,持续给出相关的回答和建议,而不是每次都需要重新输入背景信息。这里没有继续问,一问一个不吱声

大语言模型的百花齐放时代
语言模型发展历程

语言模型通常是指能够建模自然语言文本生成概率的模型。 从语言建模到任务求解,这是科学思维的一次重要跃升。 语言模型的发展历程如下:

统计语言模型(Statistical Language models,SLM)

➢ 主要建立在统计学习理论框架,通常使用链式法则建模句子序列 ➢ 例如:

n-gram 语言模型:

n-gram 语言模型:基于马尔科夫假设,当前词概率仅与前𝑛 − 1个词有关

➢ 如果使用二元语言模型,则上述示例概率计算变为

这里的p(I,am,fime)表示这个句子在语料库中出现的概率,概率越大,说明这个句子约合理。p(fine|am)表示语料库中,am后面出现fine的概率,概率越大,说么这个am后面越可能加fine。

语料库的样例如下: 参考:https://bcc.blcu.edu.cn/zh/search/0/%E6%88%91%E5%BE%88

基于频率的估计方法 (最大似然估计)

➢ 四元语言模型估计示例

➢ 主要问题

➢ 解决办法-加一平滑 (又称为 Laplace smoothing )

➢ 回退 (back-off)

➢ 插值 (interpolation)

可以证明,仍然能够保证语言模型的概率性质 通常这种方式可以结合不同阶数估计方法的优势 但仍然不能从根本解决数据稀疏性问题

神经语言模型(Neural Language Models,NLM)

在自然语言处理领域,NLM 指神经语言模型(Neural Language Models)。它利用神经网络来学习和表示语言的概率分布,能够更加精确地理解、处理和生成自然语言。通过深度学习和神经网络的结合,从大量的文本数据中学习语言的统计规律和上下文信息,从而捕捉到词语之间的关联和语义信息,提高对自然语言的理解能力。 这种模型通常采用循环神经网络(RNN)、长短时记忆网络(LSTM)和变压器(Transformer)等结构,以建模文本序列并预测下一个单词或字符的概率分布。 神经语言模型在自然语言处理领域的应用越来越广泛,涵盖了机器翻译、语音识别、文本生成等多个任务。

早期工作(MLP或NNLP)原理

早期工作MLP(Multilayer Perceptron,MLP,多层感知机): NNLM(Neural Network Language Model,神经网络语言模型),单词映射到词向量,再由神经网络预测当前时刻词汇。是一种通过神经网络进行语言建模的技术,通常用于预测序列中的下一个词。

NNLM的核心思想是使用词嵌入(word embedding)将词转换为低维向量,并通过神经网络学习语言中的词序关系。 NNLM的基本结构包括以下几个部分:

输入层:输入一个固定长度的词窗口,例如 n 个词的上下文(前 n - 1 个词)作为输入。 嵌入层:将每个输入词映射到一个低维空间,得到词向量。这一层的权重矩阵通常表示为词嵌入矩阵。 隐藏层:一个或多个隐藏层可以捕获词之间的关系,一般是全连接层。 输出层:用于预测下一个词的概率分布,通常使用softmax函数。

A goal of statistical language modeling is to learn the joint probabilityfunction of sequences of words. 统计语言建模的一个目标是学习单词序列的联合概率函数。 This is intrinsically difficult because ofthe curse of dimensionality:we propose to fight it with its own weapons. 这本质上是困难的,因为维度诅咒:我们建议用自己的武器来对抗它。 In the proposed approach one learns simultaneously(1)a distributed rep-resentation for each word (i.e.a similarity between words)along with(2)the probability function for word sequences,expressed with these repre-sentations. 在所提出的方法中,人们同时学习(1)每个单词的分布式表示(即单词之间的相似性)以及(2)用这些表示表示的单词序列的概率函数。 Generalization is obtained because a sequence of words that has never been seen before gets high probability, if it is made of words that are similar to words forming an already seen sentence. 之所以获得泛化,是因为如果一个以前从未见过的单词序列是由与已经见过的句子中的单词相似的单词组成的,那么它的概率很高。 We report onexperiments using neural networks for the probability function,showingon two text corpora that the proposed approach very significantly im-proves on a state-of-the-art trigram model. 我们报告了一项使用神经网络进行概率函数的实验,在两个文本语料库上表明,所提出的方法在最先进的三元组模型上得到了非常显著的改进。

该模型主要任务是

该模型的计算过程如下:

早期工作(MLP或NNLP)代码实现

参考: https://blog.csdn.net/weixin_62472350/article/details/143448417 https://www.bilibili.com/video/BV1AT4y1J7bv/ NNLM 的 PyTorch 实现

代码语言:javascript
代码运行次数:0
运行
复制
# 1.导入必要的库
import torch
import torch.nn as nn
import torch.optim as optimizer
import torch.utils.data as Data
 
# 2.数据准备
sentences = ["I like milk",
             "I love hot-pot",
             "I hate coffee",
             "I want sing",
             "I am sleep",
             "I go home",
             "Love you forever"]
 
word_list = " ".join(sentences).split()     # 获取个句子单词
word_list = list(set(word_list))            # 获取单词列表
 
word_dict = {w: i for i, w in enumerate(word_list)}     # 单词-位置索引字典
number_dict = {i: w for i, w in enumerate(word_list)}   # 位置-单词索引字典
 
vocab_size = len(word_list)         # 词汇表大小
 
# 3.X-生成输入和输出数据
def make_data():
    input_data = []
    output_data = []
 
    for sen in sentences:
        word = sen.split()
        input_temp = [word_dict[n] for n in word[:-1]]
        output_temp = word_dict[word[-1]]
 
        input_data.append(input_temp)
        output_data.append(output_temp)
 
    return input_data, output_data
 
 
input_data, output_data = make_data()
input_data, output_data = torch.LongTensor(input_data), torch.LongTensor(output_data)   # 数据转换:将 input_data 和 output_data 转换为 LongTensor,以便用于模型训练。
dataset = Data.TensorDataset(input_data, output_data)       # 建数据集:Data.TensorDataset 将输入和输出配对为数据集
loader = Data.DataLoader(dataset, 4, True)                  # 数据加载器:DataLoader,使用批量大小为 2,随机打乱样本
 
 
# 4.初始化参数
m = 2
n_step = 2
n_hidden = 10
 
 
# 5.模型定义
class NNLM(nn.Module):
    def __init__(self):
        super(NNLM, self).__init__()
        self.C = nn.Embedding(vocab_size, m)
        self.H = nn.Linear(n_step * m, n_hidden, bias=False)
        self.d = nn.Parameter(torch.ones(n_hidden))
        self.U = nn.Linear(n_hidden, vocab_size, bias=False)
        self.W = nn.Linear(n_step * m, vocab_size, bias=False)
        self.b = nn.Parameter(torch.ones(vocab_size))
 
    def forward(self, X):
        X = self.C(X)               # X = [batch_size, n_step, m]
        X = X.view(-1, n_step * m)  # 展平 X = [batch_size, n_step * m]
        hidden_output = torch.tanh(self.d + self.H(X))
        output = self.b + self.W(X) + self.U(hidden_output)
        return output
 
# 6.定义训练过程
model = NNLM()
optim = optimizer.Adam(model.parameters(), lr=1e-3)
criterion = nn.CrossEntropyLoss()
 
# 7.模型训练
for epoch in range(5000):
    for batch_x, batch_y in loader:
        pred = model(batch_x)
        loss = criterion(pred, batch_y)
        if (epoch + 1) % 1000 ==0:
            print(epoch+1, loss.item())
        optim.zero_grad()
        loss.backward()
        optim.step()
 
# 8.模型测试
pred = model(input_data).max(1, keepdim=True)[1]
print([number_dict[idx.item()] for idx in pred.squeeze()])

代码解释 1.最开始导入一些必要的库

代码语言:javascript
代码运行次数:0
运行
复制
# 1.导入必要的库
import torch
import torch.nn as nn
import torch.optim as optimizer
import torch.utils.data as Data

2.首先需要准备一些数据,用于模型训练并测试

代码语言:javascript
代码运行次数:0
运行
复制
word_list = " ".join(sentences).split()

①对于文本数据,肯定要进行一个分词操作,先使用" ".join(sentences).split()来切分每一个句子的每个单词,这时候获得的word_list列表就是:

[‘I’, ‘like’, ‘milk’, ‘I’, ‘love’, ‘hot-pot’, ‘I’, ‘hate’, ‘coffee’, ‘I’, ‘want’, ‘sing’, ‘I’, ‘am’, ‘sleep’, ‘I’, ‘go’, ‘home’, ‘Love’, ‘you’, ‘forever’]

②但是这里得到的单词可能会有重复的情况,我们需要得到不重复的单词列表,为后面的创建词典提供方便。

代码语言:javascript
代码运行次数:0
运行
复制
word_list = list(set(word_list))  

set (word_list) :将 word_list 转换为集合(set),自动去除列表中的重复元素。 list(set (word_list) ):再将集合转换回列表,这样可以保持原数据类型一致(即 word_list 仍然是一个列表)。

[‘milk’, ‘coffee’, ‘sing’, ‘hot-pot’, ‘home’, ‘you’, ‘am’, ‘I’, ‘sleep’, ‘love’, ‘want’, ‘hate’, ‘go’, ‘forever’, ‘like’, ‘Love’]

③然后就是构造词典:单词到位置的索引字典、位置到单词的索引字典。

代码语言:javascript
代码运行次数:0
运行
复制
word_dict = {w: i for i, w in enumerate(word_list)}     # 单词-位置索引字典
number_dict = {i: w for i, w in enumerate(word_list)}   # 位置-单词索引字典

word_dict: {‘sleep’: 0, ‘go’: 1, ‘home’: 2, ‘milk’: 3, ‘hate’: 4, ‘Love’: 5, ‘love’: 6, ‘am’: 7, ‘want’: 8, ‘sing’: 9, ‘forever’: 10, ‘hot-pot’: 11, ‘I’: 12, ‘like’: 13, ‘you’: 14, ‘coffee’: 15}

number_dict:{0: ‘sleep’, 1: ‘go’, 2: ‘home’, 3: ‘milk’, 4: ‘hate’, 5: ‘Love’, 6: ‘love’, 7: ‘am’, 8: ‘want’, 9: ‘sing’, 10: ‘forever’, 11: ‘hot-pot’, 12: ‘I’, 13: ‘like’, 14: ‘you’, 15: ‘coffee’}

代码语言:javascript
代码运行次数:0
运行
复制
    这里使用enumerate是因为 enumerate 函数可以方便地同时获取列表元素的索引和对应的值。也就是我们想要的字典。

④然后就是获得词汇表大小,在模型搭建中需要用到。

3.有了初始数据,我们需要构建出数据X,也就是输入数据和目标输出数据。

代码语言:javascript
代码运行次数:0
运行
复制
def make_data():
    input_data = []
    output_data = []
 
    for sen in sentences:
        word = sen.split()
        input_temp = [word_dict[n] for n in word[:-1]]
        output_temp = word_dict[word[-1]]
 
        input_data.append(input_temp)
        output_data.append(output_temp)
 
    return input_data, output_data

①先构建空的输入数据input_data和输出数据output_data。

②将每个句子的前 n-1个单词的位置添加到输入数据input_data中,第 n 个单词的位置添加到输入数据output_data中,得到每个输入 x 和输出 y 在词汇表中的顺序:

input_data:[[12, 13], [12, 6], [12, 4], [12, 8], [12, 7], [12, 1], [5, 14]]

output_data:[3, 11, 15, 9, 0, 2, 10]

这是个二维的矩阵,行元素代表一个句子中用于训练输入/测试输出的单词在词汇表中的位置索引;列元素是不同的句子。 每个句子都是3个单词,前2个作为前文信息作为输入,第3个作为预测输出,我们前面给的一共是7个句子。

4.初始化参数

这里的m指的是维度,也就是一个单词要嵌入到多少维度,由于这里的数据量比较小,每个句子也只有3个单词,所以这给出的维度选个很低的2。

n_step=2,指的是用两个单词来预测下一个目标单词。 n_hidden=10,指的是隐藏层的数量。

5.前面的数据已经初步定义好了,这里就要搭建NNLM模型了。

代码语言:javascript
代码运行次数:0
运行
复制
class NNLM(nn.Module):
    def __init__(self):
        super(NNLM, self).__init__()
        self.C = nn.Embedding(vocab_size, m)
        self.H = nn.Linear(n_step * m, n_hidden, bias=False)
        self.d = nn.Parameter(torch.ones(n_hidden))
        self.U = nn.Linear(n_hidden, vocab_size, bias=False)
        self.W = nn.Linear(n_step * m, vocab_size, bias=False)
        self.b = nn.Parameter(torch.ones(vocab_size))
 
    def forward(self, X):
        X = self.C(X)               # X = [batch_size, n_step, m]
        X = X.view(-1, n_step * m)  # 展平 X = [batch_size, n_step * m]
        hidden_output = torch.tanh(self.d + self.H(X))
        output = self.b + self.W(X) + self.U(hidden_output)
        return output

①def _init_(self):定义各层和参数:

self.C:词嵌入层,将输入词转换为词向量。 vocab_size 定义词汇表的大小,m 是词嵌入的维度,表示每个词将被嵌入成 m 维的向量。

self.H:线性层,将展平后的输入映射到隐藏层。 n_step * m 是展平后的输入大小,n_hidden 是隐藏层的维度,用来控制隐藏层输出的特征数量。

self.d:偏置向量,用于隐藏层的输出。 n_hidden 是偏置项的维度,与隐藏层输出匹配,用于提升隐藏层的表达能力。

self.U:线性层,将隐藏层输出映射到词汇表空间。 n_hidden 是隐藏层输出的大小,vocab_size 是词汇表大小,用于将隐藏层的特征映射到每个词的预测空间。

self.W:线性层,从输入直接映射到词汇表空间。 n_step * m 是展平后的输入大小,vocab_size 是词汇表大小,用于将输入直接映射到词汇表的预测空间。

self.b:偏置向量,用于最终输出层的分数调整。 vocab_size 是词汇表的大小,用作最终输出层的偏置。

这里分别用了Embedding、Linear和Parameter:

Embedding:嵌入层,用于将离散的词汇索引(如单词的整数表示)映射到连续的稠密向量空间。 Linear:全连接层(线性层),用于将输入的特征通过线性变换映射到输出空间。 Parameter:可学习的参数。

②def forward(self,X):定义神经网络在前向传播过程中的计算步骤

代码语言:javascript
代码运行次数:0
运行
复制
X = self.C(X)

首先通过嵌入层将输入的词索引(X)转换为词向量表示,这个时候得到是三维度的:[batch_size, n_step, m]。

代码语言:javascript
代码运行次数:0
运行
复制
X = X.view(-1, n_step * m)

然后将 X 从三维张量展平为二维张量 [batch_size, n_step * m],方便输入到全连接层 self.H。

代码语言:javascript
代码运行次数:0
运行
复制
hidden_output = torch.tanh(self.d + self.H(X))

接着,利用公式

h=tanh(W_hX+d)

计算得到隐藏层输出。

代码语言:javascript
代码运行次数:0
运行
复制
output = self.b + self.W(X) + self.U(hidden_output)

最后,利用公式

output=b+WX+Uh

得到最终的输出。

6.定义训练过程

这里初始化model,并且设置优化器为Adam,并且使用了交叉熵损失。

7.模型训练

代码语言:javascript
代码运行次数:0
运行
复制
for epoch in range(5000):
    for batch_x, batch_y in loader:
        pred = model(batch_x)
        loss = criterion(pred, batch_y)
        if (epoch + 1) % 1000 ==0:
            print(epoch+1, loss.item())
        optim.zero_grad()
        loss.backward()
        optim.step()

这里从数据加载器中加载数据,将当前批次的输入数据batch_x传入模型中得到预测结果,同时计算预测值与真实值的损失loss,每1000个epoch打印损失。然后梯度清零、反向传播计算梯度、更新模型参数。

8.模型测试

代码语言:javascript
代码运行次数:0
运行
复制
pred = model(input_data).max(1, keepdim=True)[1]

model(input_data):将输入数据传递给模型,获取每个类别的得分(logits)。 max(1, keepdim=True)[1]: max(1):对每个样本找出最大得分的类别索引。 keepdim=True:保持输出维度不变。 [1]:提取每个样本的最大值索引(预测类别)。

代码语言:javascript
代码运行次数:0
运行
复制
print([number_dict[idx.item()] for idx in pred.squeeze()])

pred.squeeze():移除维度为 1 的维度,得到一维张量。 [idx.item() for idx in pred.squeeze()]:将每个索引转换为整数。 number_dict[idx.item()]:通过索引查找可读标签。 print([…]):打印出模型预测的类别标签。

输出: 1000 0.05966342240571976 1000 0.034198883920907974 2000 0.005526650696992874 2000 0.009151813574135303 3000 0.0021409429609775543 3000 0.0015856553800404072 4000 0.0006656644982285798 4000 0.0005017295479774475 5000 0.00018937562708742917 5000 0.00020660058362409472 [‘milk’, ‘hot-pot’, ‘coffee’, ‘sing’, ‘sleep’, ‘home’, ‘forever’]

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 简介
  • 1.1语言模型发展历程
    • 大模型的能力
    • 大语言模型的百花齐放时代
    • 语言模型发展历程
      • 统计语言模型(Statistical Language models,SLM)
      • 神经语言模型(Neural Language Models,NLM)
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档