一、Transformer篇
1. Transformer的结构是什么
Transformer 由 编码器(Encoder) 和 解码器(Decoder) 两部分组成,两部分都包含目标嵌入层、位置编码、多头注意力层、前馈网络,且有残差连接和层归一化,注意:解码器使用的是掩码多头。
2. Transformer的核心优势是什么
- 并行能力强:不同于RNN,transformer的自注意力机制消除了序列数据的时间依赖,允许模型并行训练。
- 超长序列建模能力:自注意力机制可以直接捕捉序列中任意位置的依赖关系,而不受距离的限制。
- 灵活性和扩展性:transformer在CV、NLP都有很好的表现,自编码、自回归、T5架构涌现很多高级模型。
3. 什么是Transformer绝对位置编码?
- 为什么Transformer需要位置编码:Transformer架构完全基于自注意力机制,并不具备像RNN和CNN那样有保存顺序信息。因此,为了让模型能够知道每个输入元素在序列中的位置,必须显式地为每个输入添加额外的位置信息。
- 什么是绝对位置编码:是最常见的做法,通过为每个位置(每个token)分配一个独特的向量表示该位置的信息,这些位置编码会被加入到输入的词向量中。这样,模型可以根据每个位置的编码来推断元素的相对或绝对位置。
- 绝对位置编码优势:
①:固定且确定:最初的 Transformer 使用的是 正弦和余弦函数 来计算每个位置的编码,能确保位置编码不会因训练而变化。
②:适用长序列:不同频率的正弦和余弦函数,能够捕捉到非常细致的位置信息。 - 绝对位置编码的局限性:
①无法直接表达相对位置关系:比如位置5,6,与位置100,101的位置编码是相似的,但它们之间的相对距离对模型是不可见的。
②:难以泛化到极长序列:对于超出训练序列长度范围的序列,它们的信息就会丢失。
4.位置编码有哪些?它们各有什么不同
- 绝对位置编码:使用 正弦和余弦函数 来为每个位置生成唯一的编码,最早在原始transformer论文中提出。
- 相对位置编码:试图解决绝对位置编码的局限性,尤其在长序列处理和相对位置关系非常重要的任务中。它是依赖元素间的相对位置,实现方式一般是在计算注意力得分时,将位置差值作为额外偏置项加入。优点是:更加适用于长序列,缺点是:增加了模型的复杂性。
- 旋转位置编码RoPE:是一种创新的相对位置编码。通过旋转嵌入空间的向量,将相对位置关系融入自注意力计算过程中。优点:能显式的捕捉相对位置关系,缺点是:相对复杂,需要进行额外的旋转操作。
- 可学习位置编码:位置编码不再是固定函数生成,而是学习得到,在训练过程中优化位置编码的值。优点是:灵活度高,缺点是:训练不稳定,缺乏可解释性。
5.LLaMa为什么用旋转位置编码:
- 长序列的高效处理:相比传统的绝对位置编码,旋转位置编码更加灵活、有效的处理长序列。
- 相对位置的表达能力:能更好的捕捉元素间的相对位置关系,从而更好的学习长程依赖。
- 计算效率和简洁性:相比正弦余弦编码更加高效,计算成本更低。
- 迁移学习的优势:具有更强的迁移能力,在不同长度的序列上均能稳定工作。
6.为什么transformer块使用LayerNorm而不是BatchNorm?
BatchNorm | LayerNorm | |
---|---|---|
面向的数据 | 整个批次样本 | 单一的样本 |
归一化维度 | 整个批次样本中对每一层、每个特征(通道)进行归一化 | 对每个样本的所有特征(通道)进行归一化 |
应用方式 | 计算整个批次数据的均值和方差 | 只使用当前样本计算均值和方差 |
- 变长序列问题:对于长度不一致的输入,BatchNorm很难在一个批次中计算一致的信息,而LayerNorm只依赖单个样本,可独立计算均值和方差。
- 并行处理:transformer的自注意力机制需要并行处理序列任意位置元素之间的关系,BatchNorm难以并行化。
- 训练与推理的不一致性:BatchNorm训练时是使用当前批次的均值和方差,而推理用的是整训练数据的统计信息,会造成统计偏移。
7.如何优化transformer模型的性能
模型架构优化:
- 自注意力机制优化:
①. 局部注意力:为解决长序列计算代价,可以限制注意力范围只关注临近几个token来减少计算量,如Linformer、Reformer。
②. 稀疏注意力:通过限制计算的注意力头,或使用可学习的注意力模式Performer,来减少不必要的计算量。
③. 跨层共享:在不同transformer层之间共享注意力权重,减少模型复杂度。 - 改进位置编码:
①. 相对位置编码替代绝对位置编码,可以更好捕获长距离依赖。
②. 混合位置编码:结合绝对和相对位置编码,互补优势 。 - 激活函数与优化器:使用更高效的激活函数(Swish、GeLU),比ReLU更加平滑。使用更先进的优化器AdamW。
训练过程优化:
- 学习率调度:学习率预热,学习率衰减、动态学习率调整。
- 混合精度计算:使用FP16精度训练,加速计算节省内存。
- 正则化和dropout:防止过拟合
- 梯度累积:减少计算
- 混合内存优化:GPU与CPU同时处理训练
- 数据并行、模型并行:
模型后处理:
- 模型蒸馏:
- 模型量化:
- 模型剪枝:
硬件性能优化
- 多GPU分布式训练
- TensorRT、ONNX
9. Transformer有哪些加速收敛的操作
- 学习率调度:学习率预热,学习率衰减。
- 混合精度训练:使用FP16精度训练,加速计算节省内存。
- 激活函数、优化器:
- 预训练 + 微调策略:能显著加速模型的收敛。
10. Transformer有哪些防止过拟合的操作
- 数据端:数据增强,同义替换。
- 正则化:Dropout、L2正则化
- 归一化:层归一化layernorm、批次归一化batchnorm
- 早停:一定周期内无显著提升,可停止训练
11. 在transformer中,同一个词可以有不同的注意力权重吗
当然是的。因为每个词会根据输入的上下文信息动态计算注意力权重,而不仅仅是对其他位置的词进行统一的计算
二、大模型应用篇
1. 大模型开发的6个核心技术
- Prompt提示词工程:交流的指令,越清晰越好;
- function call函数调用外部API工具:外部力量,比如抽水我们知道找抽水泵,出门看天气知道查询天气预报;
- RAG检索增强:开卷考试;
- Agent智能体:谋定而后动,事先规划,再落地行动;
- Fine-tuning微调:知识学霸,将书上的知识全部学到大脑中;
- LLM大模型:预训练一个无所不知的智者;
越往下越底层,难度越高,成本越大,实施风险越大
2. 大模型性能优化方向
- 算法层面:利用模型量化、知识蒸馏、模型剪枝等技术,减小模型的大小和计算的复杂度;
- 软件层面:
<1>: 计算图优化:数据并行(切分数据,文章末尾有详细解释);模型并行(切分模型,文章末尾有详细解释);
<2>:模型编译优化:使用ONNX支持的框架(PyTorch/TF/Keras)训练好模型后,将其导出为ONNX格式,再使用ONNX Runtime或TensorRT进行优化,从而提高模型在GPU上的执行效率; - 硬件层面:英伟达H系列后就支持FP8(float point 8-bit)精度训练,相较于float32和float16,FP8进一步减少了数据存储空间和计算量,而且FP8兼顾FP16的稳定性 + int8的速度;
3. RAG与Agent的区别
- RAG的本质:是为了弥补大模型在特定领域知识的不足。整个过程相对稳定,LLM可发挥的空间较少;
- Agent的本质:是为了解决复杂的任务。不同模型对任务的理解、拆解相差较大,所以Agent对LLM的能力要求较高;
实际项目中会使用Agent + RAG的方式,对Agent中的每一个【任务n】都走一遍RAG流程;
4. RAG与微调的应用场景
微调场景:
- 定制大模型的能力:
- 对响应时间有要求:
- 智能设备中的应用:
对开源模型做微调,影响的权重也只占1%~5%左右,微调数据与原本数据是否能相容、新模型的鲁棒性是否有提高都比较难把控,所以在实际项目中,能不使用微调就不微调。有兴趣可以试试LLaMA-Factory大模型微调平台;
RAG场景:
- 数据需要保密:
- 无反应时间要求:
5. 模型量化、蒸馏、剪枝
大语言模型在训练和使用中都会占据大量计算资源和存储空间,为了能在有限的资源下,保证大模型的性能,一般会使用模型压缩技术,一般的模型压缩的方式有以下三种:
- 模型量化(Quantization):主要是牺牲模型精度,用低精度的参数代替高精度参数参与计算,从而降低模型大小和计算复杂度;
- 模型蒸馏(Distillation):实施在数据端,用最强模型的输出反馈做数据蒸馏,微调自身小模型具备最强模型的输出能力;
- 模型剪枝():落地效果不好,很少用,实施在模型端,移除模型中不重要的权重,减小模型大小和计算复杂度;
模型量化:
举例:一个6B的模型(60亿参数),参数精度是float16(一个参数占2字节),那么它模型大小就是12G左右。不同参数精度所占的字节数不同,一般有四个等级的参数精度(8bit等于1字节):
- FP32(单精度32位浮点数):高精度,一个参数占4字节,更大的内存占用和更长的计算时间;
- FP16(半精度16位浮点数):常用精度,一个参数占2字节,资源占用与精度相对均衡;
- FP8:英伟达H系列后就支持FP8精度,兼顾FP16的精度和INT8的速度;
- INT8(将浮点数转换为8位整数):精度较低,一个参数占1字节,但可以显著减少存储和计算的需求
- INT4(将浮点数转换为4位整数):精度很低,一个参数占0.5字节,很激进的量化方式,很可能导致模型失真;
GPT3.5有1750亿个参数,以float16精度为例,模型就有350G左右,对于模型加载、训练、测试都不是很方便,选择合适的量化方式,在模型精度与资源占用中寻找合适的平衡;
常见的模型量化方法:详情请看链接:GPTQ 、GGUF 、AWQ
模型蒸馏:
模型蒸馏(Knowledge Distillation)是一种通过压缩大型模型(如GPT_dream)的知识来训练小模型的技术,使得小模型能够在推理速度、资源占用等方面有所提升,同时尽量保持大模型的性能;
- 数据准备:首先收集一个涵盖广泛问题的数据集,这个数据集可以来自真实场景,也可以通过设计各种问题覆盖不同的任务和领域;
- 教师模型输出:使用大模型(GPT_dream)作为教师模型,对这些问题进行推理,生成对应的输出。记录下这些问题-答案对,形成新的QA数据集。这个数据集由问题作为输入,教师模型的输出作为目标标签;
- 学生模型训练:将生成的QA数据用作小模型的训练数据。训练过程中,学生模型学习教师模型的行为和输出方式,使得其表现逐渐接近教师模型;
- 损失函数:分两类
<1>. 硬目标损失:学生模型的输出与训练数据的真实标签进行比较(标准分类损失);
<2>. 软目标损失:学生模型的输出与教师模型的输出概率分布进行比较(Kullback-Leibler散度等),从而让学生模型的输出更接近教师模型;(软目标说明:教师模型输出[0.7, 0.2, 0.1],表示类别A的概率为0.7,类别B的概率为0.2,类别C的概率为0.1,如果是硬目标就直接选择类别A,但如果是软目标,学生模型输出的概率分布为[0.6, 0.3, 0.1],KL散度会计算这两个概率分布之间的差异) - 微调训练:通过反复迭代,学生模型逐渐在性能上逼近教师模型,同时保持轻量化优势;
蒸馏的好处:
- 提升效率:相比于大模型,小模型在推理速度和内存使用上有显著的提升,适合资源有限的场景(如移动设备、边缘计算等)。
- 保留性能:尽管模型变小,但通过蒸馏可以保留大部分的模型性能,保证输出的质量和准确性不会显著下降。
- 应用灵活:模型蒸馏可以应用于不同任务和模型架构,特别适合像GPT类的大模型在性能、响应时间要求高的环境中使用。
2019年10月的DistilBERT模型就是BERT的精炼版,速度提高了 60%,内存减少了 40%,但仍然保留了 BERT 97% 的性能;
6. temperature、top_p、top_k
在生成模型中,temperature、top_p 和 top_k 是控制生成文本随机性和多样性的参数:
- Temperature:调整输出的分布平滑度。较低的温度(<1)使得模型输出更确定性,倾向于选择高概率的词;较高的温度(>1)增加随机性,使输出更多样化。
- Top-p (Nucleus Sampling):从累积概率达到 p 的词中采样。例如,设置 top_p=0.9,模型会考虑所有使累积概率达到 90% 的词,只有这些词会被选中,从而保证生成的文本既丰富又合理。
- Top-k:限制可选词汇的数量,只考虑概率最高的 k 个词进行采样。这样可以减少低概率词对生成结果的影响。
这三者的结合可以实现更灵活的文本生成,适应不同的应用需求
7. 大模型幻觉
大模型幻觉主要有哪些:
- 荒谬回复、违背事实:例如人类生活在火星
- 上下文自相矛盾:
- 答非所问:
大模型为什么会出现幻觉:
- 数据质量:训练数据包含错误、偏见、不一致信息,模型可能会学习并放大这些问题;
- 训练过程:预训练或者微调时候,过分拟合了训练数据中的异常值;
- 生成过程:提示词设计不当,或模型过小、模型有缺陷、输出长度太短;
如何解决、规避大模型幻觉问题:主要就是限定回答的范围
- 根据权威信息回复;
- 根据企业文档回复;
- 连接数据库信息;
- 配合知识图谱:向量数据库会弱化对象之间的关系,所以与向量文本互补使用;
数据并行(Data Parallelism)
让同一个模型的不同实例在不同设备上并行处理不同的数据子集,而模型的参数在这些设备之间保持同步。
一般有如下几个步骤:
- 数据划分:在每个训练迭代中,将训练数据分为多个小批次(mini-batch),并将每个小批次分配给不同的设备(GPU/TPU)。例如,如果有4个GPU,batch_size=64,那么每个GPU将处理 64/4=16 个样本。
- 模型复制:每个GPU设备上都有一份完全相同的模型副本,且每个GPU设备只处理分配到的那部分数据,独立计算那部分数据的损失和梯度,进行反向传播。
- 梯度同步:各设备计算的梯度会通过梯度同步(通常通过all-reduce操作)进行聚合(如取平均值或求和),再将聚合后的梯度发送至每个GPU设备上。
数据并行常见的实现方法:
- PyTorch DistributedDataParallel (DDP):PyTorch提供了DistributedDataParallel接口,自动处理数据切分、梯度同步和参数更新。DDP是数据并行的标准实现。
- Horovod:是由Uber开发的分布式训练框架,支持TensorFlow、PyTorch等。Horovod基于all-reduce算法进行梯度同步,能够在多个GPU或多个节点上高效运行。
- DeepSpeed:是微软开发的分布式深度学习库,支持大规模模型的训练,并提供了一系列优化手段,提升分布式数据并行的效率。
数据并行存在的挑战:
- 通信开销:梯度同步时,设备之间的数据通信开销可能较大,为此可以使用压缩通信技术(如梯度裁剪、混合精度训练)或减少通信频率的技术(如梯度积累)。
- 负载均衡:设备之间的计算负载需要尽量均衡,避免某些设备过于忙碌,而其他设备处于等待状态。
数据并行的优化策略:
- 梯度积累(Gradient Accumulation):在小批量数据训练时可以通过梯度积累减少同步次数,模拟大批量训练。
- 混合精度训练:通过使用混合精度(FP16+FP32),可以降低显存占用和通信开销,提高分布式数据并行的效率。
- 通信压缩:通过梯度压缩(例如只同步重要梯度,或用低精度表示梯度)减少通信的带宽占用。
模型并行(Model Parallelism)
当模型过大无法在单个设备(如GPU)内存中完整训练时,它将模型的不同部分分布在多个设备上进行训练,相比于数据并行,模型并行的核心思想是将模型的不同部分拆分并分布到不同的设备上进行计算,而不是切分数据。
方式1:层级模型并行(Layer-wise Model Parallelism)
- 描述:模型的不同层分布在不同的设备上。例如,神经网络的前几层可以在第一个GPU上计算,后几层在另一个GPU上计算。在前向传播过程中,数据流依次通过每个设备,完成层级计算。
- 使用场景:适合顺序结构的神经网络,如深度卷积神经网络(CNN)或多层感知机(MLP)
方式2:张量切分模型并行(Tensor Model Parallelism)
- 描述:将模型中的权重矩阵(张量)分成若干部分,并分配到不同设备。每个设备只计算部分张量的结果,最终结果需要通过通信整合。例如,处理大型全连接层时,将权重矩阵拆分到多个设备,分别进行部分计算。
- 使用场景:适合Transformer类模型中非常大的全连接层、嵌入层等。
方式3:流水线并行(Pipeline Parallelism)
- 描述:模型的不同部分(通常是不同的层)分配到不同的设备上,每个设备依次接收不同的批次,并进行流水线式处理。通过这种方式,可以同时计算多个批次的数据,使计算资源得到最大化利用。
- 使用场景:流水线并行非常适合深层神经网络,如大型Transformer模型(如GPT系列模型)。