仅用于站内搜索,没有排版格式,具体信息请跳转上方微信公众号内链接
在当今人工智能领域,大型语言模型(LLM)的开发已经成为一个热门话题。这些模型通过学习大量的文本数据,能够生成自然语言文本,完成各种复杂的任务,如写作、翻译、问答等。
https ://github.com/FareedKhan-dev/train-llm-from-scratch
本文将为你提供一个简单直接的方法,从下载数据到生成文本,带你一步步构建大院模型。
在开始训练语言模型之前,你需要对面向对象编程(OOP)、神经网络(NN)和PyTorch有基本的了解。
训练语言模型需要强大的计算资源,尤其是GPU。不同的GPU在内存容量和计算能力上有所不同,适合不同规模的模型训练。以下是一个详细的GPU对比表,帮助你选择合适的硬件。
GPUName
Memory
DataSize
2BLLMTraining
13MLLMTraining
MaxPracticalLLMSize(Training)
NVIDIAA100
40GB
Large
✔
✔
~6B–8B
NVIDIAV100
16GB
Medium
✘
✔
~2B
NVIDIARTX3090
24GB
Large
✔
✔
~3.5B–4B
NVIDIARTX3080
10GB
Medium
✘
✔
~1.2B
NVIDIAQuadroRTX8000
48GB
Large
✔
✔
~8B–10B
NVIDIARTX4090
24GB
Large
✔
✔
~4B
参数规模:1300万参数。
应用场景:适合初学者和小型项目,例如简单的文本生成、情感分析或语言理解任务。
硬件需求:相对较低。大多数中高端GPU(如NVIDIARTX3060或更高)都可以胜任。
特点:训练速度快,资源消耗低,适合快速迭代和实验。
参数规模:20亿参数。
应用场景:适合更复杂的任务,如高质量的文本生成、多语言翻译或更高级的语言理解任务。
硬件需求:较高。需要至少16GB内存的GPU,如NVIDIARTX3090或更高配置。
特点:能够生成更流畅、更自然的文本,但训练时间长,资源消耗大。
在开始之前,我们需要导入一些必要的Python库。这些库将帮助我们处理数据、构建模型以及训练模型。
ThePile数据集是一个大规模、多样化的开源数据集,专为语言模型训练设计。它由22个子数据集组成,涵盖了书籍、文章、维基百科、代码、新闻等多种类型的文本。
最终处理好的数据集格式如下:
Transformer通过将文本分解成更小的单元,称为“标记”(token),并预测序列中的下一个标记来工作。Transformer由多个层组成,这些层被称为Transformer块,它们一层叠一层,最后通过一个最终层来进行预测。
每个Transformer块包含两个主要组件:
自注意力头的作用是确定输入中哪些部分对模型来说最为重要。例如,在处理一个句子时,自注意力头可以突出显示单词之间的关系,比如代词与其所指代的名词之间的关系。通过这种方式,模型能够更好地理解句子的结构和语义。
多层感知器是一个简单的前馈神经网络。它接收自注意力头强调的信息,并进一步处理这些信息。MLP包含:
输入层:接收来自自注意力头的数据。
隐藏层:为处理过程增加复杂性。
输出层:将处理结果传递给下一个Transformer块。
输入嵌入与位置编码:输入的文本被分解为标记(tokens),然后转换为嵌入向量(embeddings)。同时,加入位置编码(positionembeddings)以提供标记的位置信息。
Transformer块堆叠:模型由多个(例如64个)相同的Transformer块组成,这些块依次对数据进行处理。
多头注意力机制:每个Transformer块首先通过多头注意力机制(例如16个头)分析标记之间的关系,捕捉不同类型的关联。
MLP处理:注意力机制处理后的数据通过一个MLP(多层感知器)进行进一步处理,先扩展到更大维度(例如4倍),再压缩回原始维度。
残差连接与层归一化:每个Transformer块中使用残差连接(residualconnections)和层归一化(layernormalization),以帮助信息流动并稳定训练。
最终预测:理后的数据通过最终层,转换为词汇表大小的预测结果,生成下一个最有可能的标记。
文本生成:模型通过反复预测下一个标记,逐步生成完整的文本序列。
多层感知器(MLP)是Transformer架构中前馈神经网络(Feed-ForwardNetwork,FFN)的核心组成部分。它的主要作用是引入非线性特性,并学习嵌入表示中的复杂关系。在定义MLP模块时,一个重要的参数是n_embed,它定义了输入嵌入的维度。
MLP的整个序列转换过程使得它能够对注意力机制学习到的表示进行进一步的精细化处理。具体来说:
引入非线性:通过ReLU激活函数,MLP能够捕捉到嵌入表示中的复杂非线性关系。
特征增强:隐藏层的扩展操作为模型提供了更大的空间来学习更丰富的特征。
维度一致性:投影线性层确保MLP的输出维度与输入维度一致,便于后续的Transformer块继续处理。
注意力头(AttentionHead)是Transformer模型的核心部分,其主要作用是让模型能够专注于输入序列中与当前任务最相关的部分。在定义注意力头模块时,有几个重要的参数:
head_size:决定了键(key)、查询(query)和值(value)投影的维度,从而影响注意力机制的表达能力。
n_embed:输入嵌入的维度,定义了这些投影层的输入大小。
context_length:用于创建因果掩码(causalmask),确保模型只能关注前面的标记,从而实现自回归(autoregressive)特性。
在注意力头内部,我们初始化了三个无偏置的线性层(nn.Linear),分别用于键、查询和值的投影。此外,我们注册了一个大小为context_lengthxcontext_length的下三角矩阵(tril)作为缓冲区(buffer),以实现因果掩码,防止注意力机制关注未来的标记。
多头注意力(Multi-HeadAttention)是Transformer架构中的关键机制,用于捕捉输入序列中多样化的关联关系。通过将多个独立的注意力头(attentionheads)并行运行,模型能够同时关注输入的不同方面,从而更全面地理解序列信息。
n_head:决定了并行运行的注意力头的数量。每个注意力头独立处理输入数据,从而让模型能够从多个角度捕捉输入序列中的关系。
上下文长度context_length定义了输入序列的长度,用于创建因果掩码(causalmask),确保模型只能关注前面的标记,从而实现自回归特性。
n_head:多头注意力中并行注意力头的数量。
n_embed:输入嵌入的维度,也是层归一化的参数维度。
context_length:上下文长度,用于定义序列的长度,并创建因果掩码。
每个Transformer块包含以下部分:
多头注意力层(Multi-HeadAttention):负责捕捉输入序列中不同位置之间的关系。
前馈网络(MLP):用于进一步处理多头注意力层的输出,引入非线性特性。
层归一化(LayerNormalization):在每个子层之前应用,有助于稳定训练。
残差连接(ResidualConnections):在每个子层之后应用,帮助信息流动并缓解深层网络训练中的梯度消失问题。
现在我们已经完成了模型的编码工作,接下来需要定义训练参数,包括注意力头的数量、Transformer块的数量等,以及数据路径等相关配置。
VOCAB_SIZE:词汇表大小,表示词汇表中唯一标记的数量。
CONTEXT_LENGTH:模型能够处理的最大序列长度。
N_EMBED:嵌入空间的维度,决定了标记嵌入和位置嵌入的大小。
N_HEAD:每个Transformer块中的注意力头数量。
N_BLOCKS:模型中Transformer块的数量,决定了模型的深度。
T_BATCH_SIZE:训练时每个批次的样本数量。
T_CONTEXT_LENGTH:训练批次的上下文长度。
T_TRAIN_STEPS:总训练步数。
我们使用AdamW优化器,这是一种改进版的Adam优化器,适用于深度学习任务。
高初始损失:20亿参数模型在训练初期的损失值通常非常高。这是因为模型的参数量巨大,初始权重随机分布,导致模型在开始时对数据的理解非常有限。
剧烈波动:在训练的前几轮,损失值可能会出现剧烈波动。这是因为模型需要在庞大的参数空间中寻找合适的权重组合,而初始的学习率可能过高,导致优化过程不稳定。
快速下降:尽管初始损失很高,但随着训练的进行,损失值通常会迅速下降。这是因为模型逐渐开始学习数据中的模式和结构。
波动调整:在快速下降之后,损失值可能会出现一些波动。这是因为模型在调整权重时,可能会在不同的局部最优解之间徘徊。这种波动表明模型在寻找更稳定的全局最优解。
接下来,我们将创建一个函数generate_text,用于从保存的模型中生成文本。该函数接受保存的模型路径和输入文本作为输入,并返回生成的文本。我们还将比较数百万参数模型和数十亿参数模型在生成文本时的表现。
#学习大模型&讨论Kaggle#
△长按添加竞赛小助手
每天大模型、算法竞赛、干货资讯
与36000+来自竞赛爱好者一起交流~