跳转至

【华为】 大模型技术面经

某大厂大模型技术面经

本文讨论了某大厂大模型技术面经,涵盖大模型教程、就业现状、技术体系、常见问题及解决办法、主流开源大模型、微调方法、检索模型、训练优化技巧等多方面内容。关键要点包括:

教程与就业:有 AI 大模型全套及企业级应用开发等教程,探讨大模型工程师就业现状、方向、门槛及学习方法。

RAG 技术体系:思路为数据预处理、分块、文本与 query 向量化、向量检索、重排、输入 LLM 输出;可克服遗忘等问题;通过检索和生成环节评估效果。

常见问题及解决办法:幻觉问题可引入外挂知识库等解决;复读机问题可丰富数据集等解决;分别阐述了出现这两个问题的原因。

主流开源大模型:Meta 的 LLaMA 影响广、生态好,采用 Transformers 架构并做改动。

SFT 方法:包括全微调、Adapter Tuning 等多种方法,lora 微调是在原始 PLM 旁增加旁路。

训练优化技巧:解决 OOM 问题可采用梯度累积等方法;让大模型处理更长文本可分块处理等。

模型介绍:介绍了 ChatGLM、GLU 和 SwiGLU 激活函数、LLaMA1/2 异同、Deepspeed 机制、混合精度训练等内容。

数据预处理->分块(这一步骤很关键,有时候也决定了模型的效果)->文本向量化->query向量化->向量检索->重排->query+检索内容输入LLM->输出

使用外挂知识库主要为了解决什么问题?

克服 遗忘 问题

提升回答的准确性、权威性、时效性

解决通用模型针对一些小众领域没有涉猎的问题

提高可控性和可解释性,提高模型的可信度和安全性

如何评价RAG项目效果的好坏?

MMR 平均倒排率:查询(或推荐请求)的排名倒数

Hits Rate 命中率:前k项中,包含正确信息的项的数目占比

NDCG

非量化:完整性、正确性、相关性

量化:Rouge-L


大模型的幻觉问题、复读机问题是什么?

幻觉问题:即生成的内容是无意义的或不忠实于提供的源内容

复读机问题:重复生成某些话

针对问题幻觉问题、复读机问题有没有什么解决办法?

丰富数据集的多样性,预处理时尽量过滤重复无意义的文本

同义词替换等做数据增强

温度参数调整

后处理与过滤

出现幻觉问题、复读机问题的原因有哪些?

生成结果与数据源不一致,自相矛盾

用户问题超出了大模型的认知

当前主流的开源大模型是哪个,其架构具体是怎样的?

当前开源影响范围最广,生态建设最好的开源大模型是 Meta 的 LLaMA 。

其依旧采用Transformers架构,并做了如下改动:

为了提高训练稳定性,对每个子层做输入前置归一化,归一化函数为RMSNorm(受GPT-3启发)

为了提升性能,SwiGLU激活函数替换ReLU激活函数(受PaLM启发)

从绝对位置嵌入,改为旋转嵌入(受GPT-neo启发)

使用causal multi-head attention的一个高效实现来减少内存占用和运行时间

有哪几种SFT方法?(重点)

全微调

Adapter Tuning

Prefix Tuning

Prompt Tuning

P-Tuning v1

lora

RLHF


什么是lora微调?

在原始 PLM (Pre-trained Language Model) 旁边增加一个旁路,做一个降维再升维的操作,来模拟 $ \underline{\text{所谓的 intrinsic rank}} $。训练的时候固定 PLM 的参数,只训练降维矩阵A与升维矩阵B。而模型的输入输出维度不变,输出时将BA与PLM的参数叠加。 $ \underline{\text{用随机高斯分布初始化A,用0矩阵初始化B,保证训练的开始此旁路矩阵依然是0 矩阵}} $。

RAG的检索阶段,常见的向量检索模型有哪些?

ANN算法

乘积向量

暴力搜索

hnswlib

KD树

针对通用的RAG,你觉得还有哪些改进点?

query侧:做query的纠错、改写,规范化和扩展

对向量数据库做层次索引,提高检索效率和精度

对 LLM 模型微调,针对当前垂直领域引入知识库,提升回答的专业性、时效性和正确性

对最终输出做后处理,降低输出的不合理case

什么是LangChain?

LangChain为大型语言模型提供了一种 $ \underline{\text{全新的搭建和集成方式}} $,通过这个强大的框架,我们可以将复杂的技术任务简化,让创意和创新更加易于实现。 $ \underline{\text{有点类似于神经网络开发与tensorflow/pytorch之间的关系}} $

LangChain的常用模块有哪些?

document_loaders 文档加载

text_splitter 文档分块

embedding.huggingface 向量化

vectorstores 向量存储

chain.RetrievalQA 检索问答

SFT和RLHF优劣对比


方法优点缺点
SFT1. 启动简单,仅需要问答对数据就可以进行训练;1. 模型的效果非常依赖于SFT数据的质量,天花板取决于SFT数据标注的质量;
RLHF1. 直接利用人类偏好来进行指导大模型的训练,使大模型的输出更能满足人们的要求;1. 训练消耗大量的显存;

大模型训练经常出现一些 OOM 问题,在现有硬件基础下,有什么性能提升 trick

混合精度训练

减轻模型参数

分布式训练

减少批量大小

增加硬件资源

数据处理与加载优化(例如,可以使用数据流水线技术来并行加载和处理数据,减少内存中同时存在的数据量)

LLaMA模型输入句子理论上可以无限长吗?

不可以

受限于计算资源

训练阶段长句子会导致梯度消失或者梯度爆炸(因为它依赖前面的词进行最大似然估计作为损失函数,这个最大似然估计化简一下就是连乘的形式,容易造成梯度消失或者梯度爆炸)

推理阶段会增加预测错误率

如何让大模型处理更长的文本?

分块处理,同时重叠保证连贯性

增加模型参数量,复杂化模型架构,提高对更长文本的捕捉与表达能力

大模型推理时,显存中有那几部分数据?

模型参数

输入数据


计算中间结果

内存管理 策略:某些 深度学习框架 在推理时采用了一种延迟释放显存的策略,即显存不会立即释放,而是保留一段时间以备后续使用。这种策略可以减少显存的分配和释放频率,提高推理效率,但也会导致显存一直占用的现象。

介绍下ChatGLM

首先要说起它的基座 GLM , GLM 既可以做 Encoder 也可以做 Decoder

[gmask]:gpt 形式,mask末尾的长span

在 chatglm 里面做生成任务时,是用 [gmask]。 chaglm2 中完全采用 gmask 来进行预训练

位置编码:从BERT的训练式位置编码转变为旋转位置编码

激活函数:从BERT中的GeLU转变为GLU,在ChatGLM2中又变成了SwiGLU

LayerNormalization:采用的是DeepNorm,是对post-Normalization的改进,即在残差之后做Normalization。在ChatGLM中,把layer-normalization改为RMSNormalization。

FlashAttention:利用显存和内存来做加速

Multi-Query Attention:多个头只采用一个KV对,通过参数共享来降低显存占用

介绍下 GLU激活函数 和 SwiGLU激活函数

GLU 的核心思想是通过门控机制来过滤信息,进而提高网络的表达能力和泛化能力(门控机制有助于长距离建模)

SwishGLU 的核心思想是将 Swish 和 GLU 结合起来,SwishGLU 实际上只是多乘了一个 g(x)

LLaMA1/2的异同

$ \lambda $ 2.0 为 2.0T, $ \lambda $ 1 是 1.4T

其次是上下文长度, $ \lambda_{1} $是2k, $ \lambda_{2} $是4k

位置编码:二者都采用了旋转位置编码

Normalization:二者都采用pre-normalization,只不过1.0中采用原始的LayerNormalization,2.0

中采用的是 RMSNorm

激活函数:采用SwiGLU

模型在训练和推理的时候各占用显存的多少?

一般来说,训练占用模型参数量的16倍大小(优化器、梯度、模型本身)


推理占用模型参数量的2倍大小(fp16是一个单位参数大小对应两个字节,int8是一个单位参数大小对应一个字节)

详细说说Deepspeed的机制

是一种数据并行的方法,采用的ring all reduce方式。

传统的parameter server是server和client的方式,client通过计算分配给自己的数据,产生梯度,传给server,server做聚合,然后把聚合后的参数再传给client,这个方式的弊端是server容易成为瓶颈,server通信量太大。另外可能一个client失败,会导致其他client等待。

Zero包括3种方案,逐步递进:

zero1:将adam的参数分割成N份,这样一个GPU上只能保存一份adam参数:这对于forward没啥影响,gradient需要进行一次all-reduce,但是只能更新一部分参数,所以W需要进行一次all-gather,通信量为3Nsita,存储为12sita/N + 4*sita

zero2: 将adamw,gradient都分割成N份,梯度就不需要all-gather了,只需要scatter了,w需要all-gather,通讯量为2N*sita

zero3: 将参数,adam 和 gradient 都分割,forward 的时候,需要将 w all-gather,backward 时,还需要把 w all-gather 回来,计算梯度,丢掉不属于自己的 w,然后对梯度做 reduce scatter,更新 w,通讯量为 $ 3N \times \text{sita} $。

最后采用采用stage3:用1.5倍的通讯开销,换回近120倍的显存

另外,还有ZeRO-Offload是基于Zero2,将adam和gradient放到内存中,在cpu内起了N个线程计算。其中的一条主线是gradient总是需要scatter的,感觉这个数据并行标志。这里需要注意一点不管是forward 还是backward,都是需要有完整的w的。另外有了gradient,以及adamW的参数,才能更新W。

什么是混合精度训练?

FP64用8个字节共64位,FP32用4个字节共32位,FP16用2个字节共16位。

在神经网络模型的训练过程中,通常默认使用单精度(FP32)浮点数据类型来表示网络模型的权重和其他参数。

内存占用减少:FP16的位宽是FP32的一半,所以权重等参数占用的内存也减少了一半,这样就可以训练更大的网络模型或者使用更多的数据。

通讯效率提高:对于分布式训练,特别是大模型训练,通讯的开销是一个性能瓶颈,通讯的位宽减少了一半,就可以加快通讯速度,减少等待时间,提高数据流通效率。

计算效率更高:在一些专门的AI加速芯片上,使用FP16的计算性能比FP32更快。

数据溢出和

舍入误差


权重备份(Weight Backup)

损失放大(Loss Scaling)

精度累加(Precision Accumulated)

什么是 prefix LLM 和 casual LLM

prefix LM:token可以相互看到,输入双向注意力,输出单向注意力(ChatGLM、ChatGLM2、UPaLM)

casualLM:严格自回归,从左到右的单向注意力(LLaMA-7B、LLaMa 衍生物、Qwen)

说一说针对 MHA 后续的一些计算优化工作

KV cache,核心思想:因为transformers是自回归,每一个token的预测包含大量前文的重复冗余计算。优化点是将需要重复利用的中间结果存下来,避免重复计算

MQA,核心思想:虽然SRAM的带宽很大,但是容量很小(A100只有大概20M),所以要进一步减少需要缓存的数据。MQA中的多头只有Q是不一样的,K、V完全相同。

GQA,核心思想:进一步减少需要缓存的数据大小,K、V分组复制,数据大小介于MQA和MHA之间。

FlashAttention,核心思想:将Q、K、V切分为更小的块,从HBM中加载到SRAM,需要计算的时候直接从SARM中读

说说attention几种常见的计算方式

self-attention

din的attention计算在得到权重之后,没有进行softmax归一化操作,而是保留了权重原始的信号强度