Transformer面试问题汇总
Transformer面试问题汇总¶
本又讨论了Transtormer面试相关问题及答案,涵盖模型结构、原理、优缺点、交互机制等多方面内容,关键要点包括:
Transformer编码器结构:由六个相同层构成,每层主要子层有多头自注意力机制和前馈神经网络,还有层归一化和残差连接,能处理顺序数据任务。
Transformer优缺点:优点是有并行处理能力、能捕捉长距离依赖、灵活性和泛化能力强、可扩展性好、性能佳;缺点是计算资源密集、可解释性不足、有过拟合风险、训练需精心调优、处理长序列有挑战。
编码器和解码器交互:通过“编码器-解码器注意力”或“交叉注意力”机制,编码器处理输入序列,解码器自注意力层处理先前输出,交叉注意力层让解码器考虑输入序列上下文。
Transformer使用LN原因:层归一化独立于批大小、适合处理动态长度序列、计算和内存效率高、训练和推理行为一致,更适合Transformer处理序列数据。
编码器和解码器自注意力区别:编码器不使用遮蔽,关注输入数据编码;解码器使用前瞻遮蔽,关注已生成输出序列,防止信息未来泄露和保持自回归特性。
Transformer计算量大的部分:多头自注意力机制计算量最大,涉及点积注意力计算、线性变换、多头注意力、缩放因子应用和Softmax计算。
处理超长文本方法:有分段处理、层次化注意力、使用长序列Transformer变体、滑动窗口、稀疏注意力机制、提取关键信息、多任务学习、利用外部知识库等。
Attention机制,Transformer面试问题参考答案¶
1、Transformer Encoder 有什么子层?
2、Transformer self-attention的公式是什么?
Attention( $ Q, K, V $) = Softmax( $ \frac{QK^{T}}{\sqrt{d_{k}}} $) V
3、 Transformer的优缺点有哪些?¶
具有并行处理能力:与基于循环的模型(如LSTM和GRU)相比,Transformer可以并行处理整个序列,大大提高了训练效率。
长距离依赖:借助多头自注意力机制,Transformer能够有效捕捉序列中长距离的依赖关系,这对于理解文本等复杂序列数据至关重要。
灵活性和泛化能力:Transformer模型在多种任务上都表现出色,包括机器翻译、文本生成、语音识别等。可扩展性:Transformer模型可以通过增加层数来提高其复杂性和学习能力,使其适用于大规模数据集和复杂任务。
更好的性能:在许多NLP任务中,Transformer模型超越了以往的技术,设立了新的性能标准。缺点计算资源密集:尽管Transformer允许并行化,但其自注意力机制涉及大量的计算,对计算资源(尤其是内存)的需求很高。
可解释性不足:与某些传统模型相比,Transformer的决策过程更难解释和理解。过拟合风险:Transformer模型因其大量的参数而容易过拟合,尤其是在数据较少的情况下。
训练需要精心调优:由于模型的复杂性,找到最佳的训练参数(如学习率、层数、头数等)可能需要大量的实验和调整。
长序列挑战:尽管Transformer在处理长距离依赖方面表现出色,但处理非常长的序列时,性能可能会下降,因为自注意力机制的计算成本随序列长度的增加而显著增加。
尽管Transformer有一些局限性,但其在处理复杂序列任务方面的优势使其成为当前最流行和最有效的深度学习架构之一。
局部信息的获取不如RNN和CNN强:Transformer关注的全局关系,而RNN在计算过程中更关注局部,对距离更加敏感。
4、 Encoder端和Decoder端是如何进行交互的?¶
编码器处理输入序列:编码器首先处理输入序列,通过自注意力和前馈网络生成一系列上下文表示。这些表示包含了输入序列中每个元素的信息,以及它们之间的相对关系。
解码器自注意力层:在解码器端,每个解码器层首先通过自注意力机制处理先前生成的输出(例如,在序列生成任务中的先前生成的单词)。这个过程与编码器中的自注意力相似,但有一个关键差异:为了保证自回归属性(即只能使用当前位置之前的信息),解码器在自注意力计算中应用了掩码(masking)
交叉注意力层:这是编码器和解码器交互的关键部分。在这一层,解码器的每个元素(或步骤)会对编码器的所有输出进行注意力计算。简而言之,解码器在生成每个元素时都会考虑整个输入序列的上下文信息。
查询(Query):来自解码器的表示。
键(Key)和值(Value):来自编码器的表示。
5、 Transformer中为什么需要线性变换?¶
6、Transformer attention的注意力矩阵的计算为什么用乘法而不是加法?
7、transformer中的attention为什么scaled?
8、Transformer attention计算注意力矩阵的时候如何对padding做mask操作的?
9、 介绍一下Transformer的残差结构及意义¶
残差结构的介绍¶
层内处理:输入首先通过层内的主要操作(如自注意力或前馈神经网络)。
加上残差:将这个操作的原始输入直接加到操作的输出上。
层归一化:在大多数情况下,加法操作之后会接一个层归一化(Layer Normalization)步骤。
残差结构的意义¶
缓解梯度消失问题:深度神经网络中常见的问题之一是梯度消失,这会使得训练过程变得困难。残差连接允许梯度直接流过网络,有助于保持梯度的稳定性,从而缓解梯度消失问题。
加速收敛:由于残差连接的帮助,网络可以更快地学习,加速收敛过程。这是因为它允许网络在训练早期阶段更有效地传播信息和梯度。
促进深层网络训练:残差连接使得构建更深层的网络变得可行,因为它们减少了训练过程中的复杂性和困难。
保留信息:残差连接确保了即使经过多个层的处理,输入信息也不会被完全替代或丢失。这在处理长序列时尤其重要,因为信息需要在整个网络中有效传递。
支持特征重用:残差连接通过将较低层的特征直接传递到后面的层,支持了特征的重用。这意味着网络可以学习使用并重用早期层的特征,而不是每次都重新学习。
10、 Transformer为什么使用LN而不是BN?¶
独立于批大小:
LN:层归一化对每个样本独立进行,不依赖于批大小。这使得 LN 在处理不同长度的序列或小批量数据时表现更稳定。
BN:批归一化依赖于整个批次的数据统计信息。在小批量数据或批量大小变化时,BN 的效果可能会受到影响。
序列数据的动态长度:
在处理序列数据(特别是长度不一的序列)时,LN的独立性使其更适合。因为BN需要整个批次的数据统计,不同长度的序列可能会导致统计信息不准确。
计算效率:¶
LN可以在单个样本级别上进行计算,这对于自然语言处理中常见的动态长度序列特别有用。另一方面,BN需要在批次级别上进行计算,可能不适合长度变化大的序列。
训练和推理一致性:
BN 在训练和推理阶段的行为不同(训练时使用当前批次的统计信息,推理时使用整个数据集的统计信息)这可能导致不确定性。而 LN 在训练和推理时的行为是一致的,因为它总是基于单个样本进行归一化。
内存效率:¶
在处理大规模序列数据时,使用 BN 可能会增加内存消耗,因为需要存储整个批次的统计信息。LN 由于其样本独立的特性,在这方面更加高效。
11、 Decoder阶段的多头自注意力和encoder的多头自注意力有什么区别?/为什么decoder自注意力需要进行sequence mask?¶
遮蔽(Masking)的应用
编码器多头自注意力:在编码器中的多头自注意力机制不使用遮蔽。这意味着在计算每个元素的注意力时,它可以看到输入序列中的所有其他元素。
解码器多头自注意力:解码器中的多头自注意力机制使用了所谓的"前瞻遮蔽"(Look-ahead
Masking)或"因果遮蔽"(Causal Masking)。这种遮蔽确保在预测一个元素时,只能使用该元素之前的元素信息,从而避免信息的未来泄露。这对于序列生成任务(如文本生成)至关重要,因为在生成当前词时,模型不应该知道后续的词。
关注点的不同¶
编码器多头自注意力:编码器的自注意力层主要关注的是如何对输入数据中的元素进行编码,包括元素之间的关系和上下文信息。
解码器多头自注意力:解码器的自注意力层则更加关注于已生成的输出序列,即如何基于目前已生成的序列内容来决定下一个元素。
输入来源的不同¶
编码器多头自注意力:编码器的自注意力层处理的输入来自于原始输入序列(例如,待翻译的句子)。
解码器多头自注意力:解码器的自注意力层处理的输入来自于之前的解码器输出(例如,在文本生成任务中,之前生成的文本序列)。
解码器中额外的交叉注意力层
虽不直接是自注意力的一部分,但值得一提的是,解码器中除了自注意力层之外,还包含了交叉注意力层(也是多头注意力),其中解码器利用编码器的输出来进一步指导生成过程。这是解码器和编码器之间唯一的直接交互,也是解码器结构的一个重要组成部分。
12、 Transformer的并行化体现在哪里,Decoder可以做并行化嘛?¶
13、 Transformer计算量最大的部分是哪里?¶
点积注意力计算:在自注意力机制中,对于每个元素,都需要计算其与序列中所有其他元素的点积。这种全对全的操作导致计算量随序列长度的平方增长。
线性变换:在计算注意力之前和之后,需要对查询(Query)、键(Key)和值(Value)进行线性变换。这些变换本身也是计算密集型的,尤其是当模型的维度和头数较大时。
多头注意力:Transformer 中使用的是多头注意力机制,这意味着上述计算需要被复制多次(每个头一次),进一步增加了总体计算量。
缩放因子的应用:在计算点积后,还需要应用一个缩放因子(通常是维度的平方根的倒数),虽然这部分计算量相对较小,但也是计算过程的一部分。
Softmax 计算:计算完点积后,还需要对每个元素的分数应用 softmax 函数以获得最终的注意力权重。这个过程涉及到指数和归一化步骤,对于长序列来说也是计算密集型的。
14、 Transformer、LSTM和单纯的前馈神经网络比,有哪些提升?¶
15、 有哪些处理超长文本的方法?¶
分段处理(Chunking)
层次化注意力(Hierarchical Attention)
长序列Transformer变体
Transformer-XL:使用循环机制和相对位置编码来处理长序列。
Reformer:使用局部敏感哈希(Locality-Sensitive Hashing, LSH)注意力和可逆层来减少计算和内存需求。
Longformer:引入了局部窗口式的自注意力机制,并结合了全局注意力,使其能够处理长文本。
Big Bird:采用了稀疏注意力机制,结合随机、局部和全局注意力。
滑动窗口(Sliding Window)
稀疏注意力机制
提取关键信息
多任务学习
利用外部知识库
16、 Transformer为何不使用一个头而使用多头注意力机制?¶
| N | $ d_{model} $ | $ d_{ff} $ | h | $ d_{k} $ | $ d_{v} $ | $ P_{drop} $ | $ \epsilon_{ls} $ | train steps | PPL (dev) | BLEU (dev) | params $ \times 10^{6} $ | |
| base | 6 | 512 | 2048 | 8 | 64 | 64 | 0.1 | 0.1 | 100K | 4.92 | 25.8 | 65 |
| (A) | 1 | 512 | 512 | 5.29 | 24.9 | |||||||
| 4 | 128 | 128 | 5.00 | 25.5 | ||||||||
| 16 | 32 | 32 | 4.91 | 25.8 | ||||||||
| 32 | 16 | 16 | 5.01 | 25.4 | ||||||||
| (B) | 16 | 5.16 | 25.1 | 58 | ||||||||
| 32 | 5.01 | 25.4 | 60 | |||||||||
| (C) | 2 | 6.11 | 23.7 | 36 | ||||||||
| 4 | 5.19 | 25.3 | 50 | |||||||||
| 8 | 4.88 | 25.5 | 80 | |||||||||
| 256 | 32 | 32 | 5.75 | 24.5 | 28 | |||||||
| 1024 | 128 | 128 | 4.66 | 26.0 | 168 | |||||||
| 1024 | 5.12 | 25.4 | 53 | |||||||||
| 4096 | 4.75 | 26.2 | 90 | |||||||||
| (D) | 0.0 | 5.77 | 24.6 | |||||||||
| 0.2 | 4.95 | 25.5 | ||||||||||
| 0.0 | 4.67 | 25.3 | ||||||||||
| 0.2 | 5.47 | 25.7 | ||||||||||
| (E) | positional embedding instead of sinusoids | 4.92 | 25.7 | |||||||||
| big | 6 | 1024 | 4096 | 16 | 0.3 | 300K | 4.33 | 26.4 | 213 | |||
17、Transformer为什么Q和K使用不同的权重矩阵,不能使用同一个值进行自身的点乘操作?
18、深度学习中有哪些常用的注意力机制?
1. Soft Attention(软注意力)¶
Bahdanau Attention (Additive Attention)
Luong Attention (Multiplicative Attention)
2. Hard Attention(硬注意力)¶
经典例子:图像描述生成(Image Captioning)。在生成描述时,仅关注图像中的特定区域。
3. Self-Attention(自注意力)¶
Scaled Dot-Product Attention
Multi-Head Attention
4. Hierarchical Attention(层次注意力)¶
经典例子:文档分类(Document Classification)。在文档分类任务中,首先对句子中的词进行注意力计算,然后对文档中的句子进行注意力计算。
5. Local Attention(局部注意力)¶
经典例子:语音识别(Speech Recognition)。在语音识别任务中,仅关注当前时间窗口内的特征。
6. Cross-Attention(交叉注意力)¶
经典例子:视觉问答(Visual Question Answering)。在视觉问答任务中,计算问题和图像之间的关联。
经典例子:文生图。Stable Diffusion中有交叉注意力机制。
7. Graph Attention(图注意力)¶
经典例子:图神经网络(Graph Neural Networks, GNNs)。在图结构数据中,对节点的邻居节点进行加权求和。
8. Convolutional Attention(卷积注意力)¶
SENet (Squeeze-and-Excitation Network)
CBAM (Convolutional Block Attention Module)
9. Temporal Attention(时序注意力)¶
经典例子:时间序列预测(Time Series Forecasting)。在多变量时间序列预测任务中,关注时间序列中的模式。
10. Dual Attention(双重注意力)¶
经典例子:多模态学习(Multimodal Learning)。在场景分割任务中,同时关注空间特征和通道特征。
11. Residual Attention(残差注意力)¶
经典例子:图像分类。在残差网络中引入注意力机制,提升图像分类的性能。
12. Transformers¶
Vanilla Transformer
BERT(Bidirectional Encoder Representations from Transformers)
GPT (Generative Pre-trained Transformer)
13. Adaptive Attention(自适应注意力)¶
经典例子:视觉问答(Visual Question Answering)。在图像描述生成任务中,自适应地调整注意力范围。
14. Multi-Scale Attention(多尺度注意力)¶
经典例子:视频分析(Video Analysis)。在视频理解任务中,对不同时间尺度的信息进行关注。
15. Co-Attention(协同注意力)¶
经典例子:视觉问答(Visual Question Answering)。在视觉问答任务中,计算问题和图像之间的关联。
16. Self-Supervised Attention(自监督注意力)¶
经典例子:图像分类和对比学习(Image Classification and Contrastive Learning)。用于视觉任务的自监督学习框架,引入注意力机制进行特征对比学习。
19、 注意力机制计算时,QKV的维度必须相同吗?¶
QKV的N和head默认是必须相同的
Q和K的embeddings必须相同,(一般QKV的embeddings都是相同的)
K和V的序列长度len必须相同,Q与(K和V)序列长度可以不同。
def forward(self, values, keys, query, mask): N = query.shape[0] value_len, key_len, query_len = values.shape[1], keys.shape[1], query.shape[1]
# Split the embedding into self.heads different pieces
values = values.reshape(N, value_len, self.heads, self.head_dim)
keys = keys.reshape(N, key_len, self.heads, self.head_dim)
queries = query.reshape(N, query_len, self.heads, self.head_dim)
values = self.values(values)
keys = self.keys(keys)
queries = self.queries(queries)
energy = torch.einsum("nqhd,nkhd->nhqk", [queries, keys])
if mask is not None:
energy = energy.masked_fill(mask == 0, float("-1e20"))
attention = torch.softmax(energy / (self.embed_size ** (1 / 2)), dim=3)
out = torch.einsum("nhql,nlhd->nqhd", [attention, values]).reshape(N, query_len, self.heads * self.head_dim)
out = self.fc_out(out)
return out