LLM NOTE CHAPTER 03
第三章:编码注意力机制 代码仓库: rasbt/LLMs-from-scratch 本章探讨自注意力机制的基本原理及其在自然语言处理中的实现,从简单注意力逐步推进到多头注意力。我们将通过Python代码一步步实现这些概念。 1. 通过自注意力关注输入的不同部分 自注意力机制允许模型根据输入序列中各部分的关联性动态调整关注焦点。以下是一个简易实现的步骤分解。 1.1 简单注意力机制 简单注意力机制通过三个步骤计算上下文向量:输入嵌入到注意力得分,注意力得分到注意力权重,再到上下文向量。 步骤 1:输入嵌入 -> ω (注意力得分) 目标:通过点积计算查询(Query)与每个输入token的相关性得分(ω)。 实现: 输入是一个嵌入矩阵inputs,形状为(num_tokens, d_in)。 对每个token,计算其与查询向量的点积。 方法: 手动实现:使用for循环,计算torch.dot(inputs[i], query)。 示例代码(假设query已定义): omega = torch.zeros(num_tokens) for i in range(num_tokens): omega[i] = torch.dot(inputs[i], query) 步骤 2:ω (注意力得分) -> α (注意力权重) 目标:将注意力得分归一化,使其和为1,得到注意力权重(α)。 目的:防止数值过大,提高数值稳定性。 实现: 手动计算:alpha = omega / omega.sum()。 推荐方法:使用torch.softmax(omega, dim=0)自动归一化。 代码: attn_weights = torch.softmax(omega, dim=0) 步骤 3:α (注意力权重) -> z (上下文向量) 目标:根据注意力权重对输入token进行加权求和,生成上下文向量(z)。 实现: 手动实现:使用for循环计算加权和。 示例代码: context_vec = torch.zeros(d_in) for i in range(num_tokens): context_vec += attn_weights[i] * inputs[i] 1.2 为所有输入token计算注意力权重 为了提高效率,我们可以一次性计算所有token的注意力权重,避免逐个计算。 ...