佛山智唯网站建设/广告推广投放平台

佛山智唯网站建设,广告推广投放平台,动态网站建设 作业,wordpress页面构造器Grouped-Query Attention(GQA)详解 Grouped-Query Attention(GQA) 是 Multi-Query Attention(MQA) 的改进版,它通过在 多个查询头(Query Heads)之间共享 Key 和 Value&am…

Grouped-Query Attention(GQA)详解


Grouped-Query Attention(GQA)Multi-Query Attention(MQA) 的改进版,它通过在 多个查询头(Query Heads)之间共享 Key 和 Value,在 Multi-Head Attention(MHA)MQA 之间找到了一种折中方案。GQA 旨在在 推理速度模型质量 之间取得更好的平衡,减少 MQA 带来的模型质量下降问题,同时仍然保留比 MHA 更快的推理速度。

在这里插入图片描述
Source: https://arxiv.org/pdf/2305.13245


1. 为什么需要 Grouped-Query Attention?

在理解 GQA 之前,我们先回顾 MHA 和 MQA 的核心区别。

(1) Multi-Head Attention(MHA)

  • 每个 Query 头都有独立的 Key 和 Value
  • 优势
    • 允许不同的 Query 头关注不同的 Key-Value 信息,提高模型的表达能力。
    • 更适合复杂任务,如长序列建模和复杂推理任务。
  • 劣势
    • 推理速度慢,因为在每一步都要存储和读取 所有 Query 头的 Key 和 Value,导致 KV 缓存(KV Cache)非常大,占用大量显存和内存带宽。

(2) Multi-Query Attention(MQA)

  • 所有 Query 头共享相同的 Key 和 Value
  • 优势
    • 推理速度快,因为只需要存储和读取一个 Key-Value 组,而不是多个。
    • 显存占用低,适用于 大规模语言模型推理(如 ChatGPT)
  • 劣势
    • 不同 Query 头会关注相同的信息,导致模型表达能力下降,尤其是在长序列建模任务上(如机器翻译、摘要生成)。
    • 可能导致训练不稳定,特别是长序列输入时,训练容易出现 Loss spikes(损失值剧烈波动)

(3) GQA 的改进点

Grouped-Query Attention(GQA) 介于 MHA 和 MQA 之间:

  • GQA 不是让所有 Query 头共享同一个 Key-Value,而是分组共享
  • 假设一个模型有 8 个 Query 头
    • MHA:8 个 Query 头,每个头有自己的 Key 和 Value。
    • MQA:8 个 Query 头,所有头共享 1 组 Key 和 Value。
    • GQA(例如 GQA-4):8 个 Query 头被分成 4 组,每组共享一组 Key 和 Value。

因此,GQA 允许:

  • 部分 Query 头共享 Key-Value,但仍然保持了一定的多样性。
  • 推理速度比 MHA 快,但比 MQA 慢
  • 模型质量比 MQA 高,但比 MHA 略低

2. GQA 的数学表达

假设:

  • h 是 Query 头的总数(如 8)。
  • G 是 GQA 分组的数量(如 G=4)。
  • k, v 分别是 Key 和 Value 的维度。

对于 MHA:
Q h = X P Q , h , K h = M P K , h , V h = M P V , h Q_h = X P_{Q,h}, \quad K_h = M P_{K,h}, \quad V_h = M P_{V,h} Qh=XPQ,h,Kh=MPK,h,Vh=MPV,h
logits h = Q h K h T , weights h = softmax ( logits h ) \text{logits}_h = Q_h K_h^T, \quad \text{weights}_h = \text{softmax}(\text{logits}_h) logitsh=QhKhT,weightsh=softmax(logitsh)
O h = weights h V h , Y = ∑ h O h P O , h O_h = \text{weights}_h V_h, \quad Y = \sum_{h} O_h P_{O,h} Oh=weightshVh,Y=hOhPO,h

对于 MQA:
Q h = X P Q , h , K = M P K , V = M P V Q_h = X P_{Q,h}, \quad K = M P_K, \quad V = M P_V Qh=XPQ,h,K=MPK,V=MPV
logits h = Q h K T , weights h = softmax ( logits h ) \text{logits}_h = Q_h K^T, \quad \text{weights}_h = \text{softmax}(\text{logits}_h) logitsh=QhKT,weightsh=softmax(logitsh)
O h = weights h V , Y = ∑ h O h P O , h O_h = \text{weights}_h V, \quad Y = \sum_{h} O_h P_{O,h} Oh=weightshV,Y=hOhPO,h

对于 GQA(分组共享 K/V)
Q h = X P Q , h , K g = M P K , g , V g = M P V , g , g = ⌊ h / G ⌋ Q_h = X P_{Q,h}, \quad K_g = M P_{K,g}, \quad V_g = M P_{V,g}, \quad g = \lfloor h/G \rfloor Qh=XPQ,h,Kg=MPK,g,Vg=MPV,g,g=h/G
logits h = Q h K g T , weights h = softmax ( logits h ) \text{logits}_h = Q_h K_g^T, \quad \text{weights}_h = \text{softmax}(\text{logits}_h) logitsh=QhKgT,weightsh=softmax(logitsh)
O h = weights h V g , Y = ∑ h O h P O , h O_h = \text{weights}_h V_g, \quad Y = \sum_{h} O_h P_{O,h} Oh=weightshVg,Y=hOhPO,h

其中:

  • 在 GQA 中,每个 Query 头属于一个组 ( g g g ),每个组 共享 Key 和 Value
  • 当 ( G = 1 G = 1 G=1 ) 时,GQA 退化为 MQA。
  • 当 ( G = h G = h G=h ) 时,GQA 退化为 MHA。

3. 代码解析

GQA 代码与 MQA 类似,只是 Key 和 Value 现在是 按组分配的

def GroupedQueryAttention(X, M, mask, P_q, P_k, P_v, P_o, num_groups):"""Grouped-Query Attention 实现Args:X: 输入查询 [b, n, d]M: 输入键值存储 [b, m, d]mask: 注意力掩码 [b, h, n, m]P_q: 查询投影矩阵 [h, d, k]P_k: 共享键投影矩阵 [num_groups, d, k]P_v: 共享值投影矩阵 [num_groups, d, v]P_o: 输出投影矩阵 [h, d, v]Returns:Y: 输出张量 [b, n, d]"""# 计算 QueryQ = tf.einsum("bnd, hdk->bhnk", X, P_q)# 计算 Key 和 Value,每个组共享K = tf.einsum("bmd, gdk->bmgk", M, P_k)  # g = num_groupsV = tf.einsum("bmd, gdv->bmgv", M, P_v)# 计算注意力 logitslogits = tf.einsum("bhnk, bmgk->bhng", Q, K)# 计算 softmax 权重weights = tf.nn.softmax(logits + mask)# 计算最终的加权 ValueO = tf.einsum("bhng, bmgv->bhnv", weights, V)# 计算最终输出Y = tf.einsum("bhnv, hdv->bnd", O, P_o)return Y

4. GQA 的性能分析

论文中的实验表明:

  • 质量上,GQA 的 BLEU 得分几乎接近 MHA,明显优于 MQA。
  • 推理速度上,GQA 仅比 MQA 略慢,但比 MHA 快得多。
  • 适用于大模型推理,如 T5、GPT-4、Gemini,减少 KV 访问,提高吞吐量。

实验表明,GQA-8(8 组)质量和速度最优的选择,可以接近 MHA 的质量,同时拥有 MQA 级别的推理速度。


5. 总结

GQA 结合了 MHA 的高质量和 MQA 的高效推理,具有:

  • 更低的 KV 存储需求,推理更快。
  • 更高的模型表达能力,减少 MQA 的信息冗余问题。
  • 适用于大规模语言模型(如 LLaMA、PaLM、GPT-4)推理优化

GQA 目前已被 Google 等研究团队广泛应用于大模型推理优化,是 MQA 的重要改进方案。


Grouped-Query Attention(GQA)PyTorch 实现

以下是 Grouped-Query Attention(GQA)PyTorch 实现,它不使用 einsum,而是采用 矩阵乘法(@)、bmm() 方式进行计算,保证代码可以直接运行。

import torch
import torch.nn as nn
import torch.nn.functional as Fclass GroupedQueryAttention(nn.Module):def __init__(self, embed_dim, num_heads, num_groups, dropout=0.1):"""Grouped-Query Attention 实现Args:embed_dim: 词嵌入维度 dnum_heads: 查询头的数量 hnum_groups: 组的数量 G (1 表示 MQA, h 表示 MHA)dropout: dropout 率"""super(GroupedQueryAttention, self).__init__()assert num_heads % num_groups == 0, "num_heads 必须是 num_groups 的整数倍"self.embed_dim = embed_dimself.num_heads = num_headsself.num_groups = num_groupsself.head_dim = embed_dim // num_heads  # 每个头的维度 k# 查询(Q)投影矩阵,每个头独立self.q_proj = nn.Linear(embed_dim, embed_dim, bias=False)# 键(K)和值(V)投影矩阵,每组共享self.k_proj = nn.Linear(embed_dim, (embed_dim // num_heads) * num_groups, bias=False)self.v_proj = nn.Linear(embed_dim, (embed_dim // num_heads) * num_groups, bias=False)# 输出投影self.o_proj = nn.Linear(embed_dim, embed_dim, bias=False)# dropoutself.dropout = nn.Dropout(dropout)def forward(self, query, key, value, mask=None):"""前向传播Args:query: 查询张量,形状 [batch, seq_len, embed_dim]key: 键张量,形状 [batch, seq_len_kv, embed_dim]value: 值张量,形状 [batch, seq_len_kv, embed_dim]mask: 掩码张量,形状 [batch, 1, 1, seq_len_kv],默认 NoneReturns:输出张量,形状 [batch, seq_len, embed_dim]"""batch_size, seq_len, _ = query.shape_, seq_len_kv, _ = key.shape# 计算 Query,每个头独立Q = self.q_proj(query)  # [batch, seq_len, embed_dim]Q = Q.view(batch_size, seq_len, self.num_heads, self.head_dim)  # [batch, seq_len, num_heads, head_dim]Q = Q.permute(0, 2, 1, 3)  # [batch, num_heads, seq_len, head_dim]# 计算 Key 和 Value,按组共享K = self.k_proj(key)  # [batch, seq_len_kv, num_groups * head_dim]V = self.v_proj(value)  # [batch, seq_len_kv, num_groups * head_dim]K = K.view(batch_size, seq_len_kv, self.num_groups, self.head_dim)  # [batch, seq_len_kv, num_groups, head_dim]V = V.view(batch_size, seq_len_kv, self.num_groups, self.head_dim)  # [batch, seq_len_kv, num_groups, head_dim]K = K.permute(0, 2, 1, 3)  # [batch, num_groups, seq_len_kv, head_dim]V = V.permute(0, 2, 1, 3)  # [batch, num_groups, seq_len_kv, head_dim]# 计算注意力权重 (Q @ K^T),Query 按照组进行索引匹配group_size = self.num_heads // self.num_groupsQ_grouped = Q.view(batch_size, self.num_groups, group_size, seq_len, self.head_dim)  # [batch, num_groups, group_size, seq_len, head_dim]# 计算点积注意力attn_logits = torch.matmul(Q_grouped, K.transpose(-2, -1))  # [batch, num_groups, group_size, seq_len, seq_len_kv]# 归一化attn_logits /= self.head_dim ** 0.5# 应用掩码if mask is not None:attn_logits = attn_logits.masked_fill(mask == 0, float("-inf"))# 计算 softmax 注意力分布attn_weights = F.softmax(attn_logits, dim=-1)  # [batch, num_groups, group_size, seq_len, seq_len_kv]attn_weights = self.dropout(attn_weights)# 计算注意力加权的 ValueO = torch.matmul(attn_weights, V)  # [batch, num_groups, group_size, seq_len, head_dim]# 重新排列回原始形状O = O.permute(0, 3, 1, 2, 4).contiguous()  # [batch, seq_len, num_groups, group_size, head_dim]O = O.view(batch_size, seq_len, self.embed_dim)  # [batch, seq_len, embed_dim]# 通过最终的线性变换Y = self.o_proj(O)  # [batch, seq_len, embed_dim]return Y

5. 代码解读

  1. 参数解释

    • embed_dim: 输入嵌入维度(即 d)。
    • num_heads: 注意力头的数量(即 h)。
    • num_groups: 组的数量(如果 num_groups=1,则相当于 MQA;如果 num_groups=num_heads,则相当于 MHA)。
    • dropout: Dropout 率。
  2. 计算 Query

    • Query 使用独立的投影矩阵 self.q_proj 计算,每个 Query 头仍然是独立的。
  3. 计算 Key 和 Value

    • Key 和 Value 共享,但按照 num_groups 进行分组,每组有 head_dim 维度。
  4. 计算注意力

    • Q @ K^T 计算注意力分数。
    • softmax 归一化并应用 dropout。
    • attention_weights @ V 计算加权 Value。
  5. 重塑输出

    • 由于每个 Query 头仍然是独立的,计算完后需要重新排列回原始形状。
    • 通过 self.o_proj 进行最终的线性投影。

6. 运行示例

你可以用下面的代码来测试 GQA:

# 初始化模型
embed_dim = 64
num_heads = 8
num_groups = 4
batch_size = 2
seq_len = 10
seq_len_kv = 12gqa = GroupedQueryAttention(embed_dim, num_heads, num_groups)# 生成随机输入
query = torch.randn(batch_size, seq_len, embed_dim)
key = torch.randn(batch_size, seq_len_kv, embed_dim)
value = torch.randn(batch_size, seq_len_kv, embed_dim)# 前向传播
output = gqa(query, key, value)
print("Output shape:", output.shape)  # 预期输出 [batch_size, seq_len, embed_dim]

7. 总结

GQA 的 PyTorch 实现:

  • 完全可运行,不依赖 einsum,使用 matmul 进行计算。
  • 适用于推理优化,减少 KV 存储,提高 LLM 推理效率。
  • 兼容 MHA/MQA,通过 num_groups 控制:
    • num_groups = 1 时,相当于 MQA
    • num_groups = num_heads 时,相当于 MHA
    • num_groups = 4 时,找到 质量与推理速度的最佳平衡

这个实现可以直接用于 大模型推理加速,如 LLaMA、GPT-4、Gemini 等模型的优化!🚀

Grouped-Query Attention(GQA)结合 KV Cache 的推理优化


大语言模型(LLM) 的自回归推理过程中,每生成一个新 token,都需要计算 注意力(attention)。然而,标准 Multi-Head Attention(MHA) 需要存储并加载 所有 Key(K)和 Value(V),这会带来 显存占用过大内存带宽受限 的问题。

Grouped-Query Attention(GQA) 结合 KV Cache(Key-Value 缓存) 可以 减少存储、提高推理速度,特别适用于 GPT-4、Gemini 等大模型


1. 为什么推理时需要 KV Cache?

Transformer 自回归推理 中:

  • 训练时,模型可以并行计算整个序列(一次性输入所有 token)。
  • 推理时,只能逐步生成新 token,每次只能访问过去的 Key-Value 并计算新的 Query。

标准 MHA 推理(带 KV Cache)

在推理时:

  • 之前生成的 tokens 的 Key 和 Value 可以缓存,不需要重新计算。
  • 新的 Query 需要与 缓存中的 Key/Value 计算注意力

对于 标准 MHA

  • 每个头都有独立的 Key/Value,所以 缓存大小为
    KV Cache Size = O ( b × h × seq_len × d k ) \text{KV Cache Size} = \mathcal{O}(b \times h \times \text{seq\_len} \times d_k) KV Cache Size=O(b×h×seq_len×dk)
    这对于 大模型推理来说,KV 缓存占用显存过大,特别是 h=32 或更大时。

2. GQA 如何优化推理中的 KV Cache?

Grouped-Query Attention(GQA) 中:

  • 每个 Query 组共享同一个 Key 和 Value
  • 减少了 KV 缓存大小,让推理更高效。

对于 GQA(num_groups = G)

  • 只需要 G 组 Key-Value,而不是 h 组
  • 缓存大小降低 (h/G) 倍
    KV Cache Size = O ( b × G × seq_len × d k ) \text{KV Cache Size} = \mathcal{O}(b \times G \times \text{seq\_len} \times d_k) KV Cache Size=O(b×G×seq_len×dk)
  • 例如:
    • MHA(h=32) → 需要存储 32 组 K/V
    • GQA(G=8) → 只需要存储 8 组 K/V,减少 4 倍显存占用。

这样,GQA 在推理时可以大幅减少 KV Cache 访问和存储,提高解码速度!


3. PyTorch 实现:GQA 推理(结合 KV Cache)

下面是完整的 PyTorch 实现,支持 KV Cache,并可用于 增量推理

import torch
import torch.nn as nn
import torch.nn.functional as Fclass GroupedQueryAttention(nn.Module):def __init__(self, embed_dim, num_heads, num_groups, dropout=0.1):"""Grouped-Query Attention 结合 KV CacheArgs:embed_dim: 词嵌入维度 dnum_heads: 查询头的数量 hnum_groups: 组的数量 G (1 表示 MQA, h 表示 MHA)dropout: dropout 率"""super(GroupedQueryAttention, self).__init__()assert num_heads % num_groups == 0, "num_heads 必须是 num_groups 的整数倍"self.embed_dim = embed_dimself.num_heads = num_headsself.num_groups = num_groupsself.head_dim = embed_dim // num_heads  # 每个头的维度 k# 查询(Q)投影矩阵,每个头独立self.q_proj = nn.Linear(embed_dim, embed_dim, bias=False)# 键(K)和值(V)投影矩阵,每组共享self.k_proj = nn.Linear(embed_dim, (embed_dim // num_heads) * num_groups, bias=False)self.v_proj = nn.Linear(embed_dim, (embed_dim // num_heads) * num_groups, bias=False)# 输出投影self.o_proj = nn.Linear(embed_dim, embed_dim, bias=False)# dropoutself.dropout = nn.Dropout(dropout)def forward(self, query, key, value, kv_cache=None, mask=None):"""推理时结合 KV CacheArgs:query: 查询张量 [batch, 1, embed_dim] (推理时单个 token)key: 当前 token 的键 [batch, 1, embed_dim]value: 当前 token 的值 [batch, 1, embed_dim]kv_cache: 之前的 Key-Value 缓存 (字典: {'key': K, 'value': V})mask: 注意力掩码 [batch, 1, 1, seq_len_kv]Returns:输出张量 [batch, 1, embed_dim]更新后的 KV Cache"""batch_size, _, _ = query.shape# 计算 Query,每个头独立Q = self.q_proj(query)  # [batch, 1, embed_dim]Q = Q.view(batch_size, 1, self.num_heads, self.head_dim)  # [batch, 1, num_heads, head_dim]Q = Q.permute(0, 2, 1, 3)  # [batch, num_heads, 1, head_dim]# 计算当前步的 Key 和 Value,按组共享K_new = self.k_proj(key).view(batch_size, 1, self.num_groups, self.head_dim)  # [batch, 1, num_groups, head_dim]V_new = self.v_proj(value).view(batch_size, 1, self.num_groups, self.head_dim)  # [batch, 1, num_groups, head_dim]K_new = K_new.permute(0, 2, 1, 3)  # [batch, num_groups, 1, head_dim]V_new = V_new.permute(0, 2, 1, 3)  # [batch, num_groups, 1, head_dim]# 更新 KV Cacheif kv_cache is None:K = K_newV = V_newelse:K = torch.cat([kv_cache['key'], K_new], dim=2)  # [batch, num_groups, seq_len_kv, head_dim]V = torch.cat([kv_cache['value'], V_new], dim=2)# 计算注意力 logitsgroup_size = self.num_heads // self.num_groupsQ_grouped = Q.view(batch_size, self.num_groups, group_size, 1, self.head_dim)  # [batch, num_groups, group_size, 1, head_dim]attn_logits = torch.matmul(Q_grouped, K.transpose(-2, -1))  # [batch, num_groups, group_size, 1, seq_len_kv]attn_logits /= self.head_dim ** 0.5# 应用掩码if mask is not None:attn_logits = attn_logits.masked_fill(mask == 0, float("-inf"))# 计算 softmax 注意力分布attn_weights = F.softmax(attn_logits, dim=-1)  # [batch, num_groups, group_size, 1, seq_len_kv]attn_weights = self.dropout(attn_weights)# 计算注意力加权的 ValueO = torch.matmul(attn_weights, V)  # [batch, num_groups, group_size, 1, head_dim]O = O.permute(0, 3, 1, 2, 4).contiguous()  # [batch, 1, num_groups, group_size, head_dim]O = O.view(batch_size, 1, self.embed_dim)  # [batch, 1, embed_dim]# 通过最终的线性变换Y = self.o_proj(O)  # [batch, 1, embed_dim]return Y, {'key': K, 'value': V}

4. 结论

GQA 结合 KV Cache

  • 减少存储,比 MHA 降低 ( h/G ) 倍 KV Cache 占用
  • 加速推理,减少 Key-Value 访问,适用于 大模型优化(GPT-4、Gemini)
  • PyTorch 实现可直接运行,适用于 增量推理(Streaming Inference)

GQA+KV Cache 是当前 LLM 高效推理的重要优化方向!🚀

Grouped-Query Attention(GQA)中 matmul(Q_grouped, K.transpose(-2, -1)) 的计算解析


GQA 计算注意力 logits 的过程中,我们使用了:

attn_logits = torch.matmul(Q_grouped, K.transpose(-2, -1))  

这个操作的核心是计算 Query 和 Key 之间的点积注意力分数,即:
logits = Q ⋅ K T \text{logits} = Q \cdot K^T logits=QKT
但在 GQA 中,由于 Query 头是按组共享 Key 的,因此计算方式比标准 MHA 更复杂。


1. 形状分析

首先,我们看看 Q_groupedK 的形状:

  • Q_grouped(Grouped Query)

    Q_grouped = Q.view(batch_size, num_groups, group_size, 1, head_dim)  
    

    形状变为:
    ( b a t c h , num_groups , group_size , 1 , head_dim ) (batch, \text{num\_groups}, \text{group\_size}, 1, \text{head\_dim}) (batch,num_groups,group_size,1,head_dim)
    其中:

    • num_groups:查询被分成的组数。
    • group_size:每个组的 Query 头数(num_heads / num_groups)。
    • 1:表示当前推理的单个 token(因为推理是自回归的,每次只计算一个新 token)。
    • head_dim:每个头的维度。
  • K(Key 缓存)

    K = K.transpose(-2, -1)  # 转置 K,使其可以与 Q 进行点积
    

    形状为:
    ( b a t c h , num_groups , seq_len_kv , head_dim ) (batch, \text{num\_groups}, \text{seq\_len\_kv}, \text{head\_dim}) (batch,num_groups,seq_len_kv,head_dim)
    其中:

    • seq_len_kv:当前 Key-Value 缓存中的 token 数量。
    • head_dim:每个 Key 头的维度。

2. matmul(Q_grouped, K.transpose(-2, -1)) 计算过程

现在,我们来看点积计算:

attn_logits = torch.matmul(Q_grouped, K.transpose(-2, -1))  

这个操作等价于:
logits = Q × K T \text{logits} = Q \times K^T logits=Q×KT

矩阵计算规则

假设:

  • Q_grouped 形状为 (batch, num_groups, group_size, 1, head_dim)
  • K^T 形状为 (batch, num_groups, head_dim, seq_len_kv)

由于 矩阵乘法的规则
( A ∈ R m × k ) × ( B ∈ R k × n ) = C ∈ R m × n (A \in \mathbb{R}^{m \times k}) \times (B \in \mathbb{R}^{k \times n}) = C \in \mathbb{R}^{m \times n} (ARm×k)×(BRk×n)=CRm×n
所以计算后:
logits ∈ R batch , num_groups , group_size , 1 , seq_len_kv \text{logits} \in \mathbb{R}^{\text{batch}, \text{num\_groups}, \text{group\_size}, 1, \text{seq\_len\_kv}} logitsRbatch,num_groups,group_size,1,seq_len_kv

即:

  • batch:批大小,不变。
  • num_groups:每个组独立计算注意力分数。
  • group_size:组内的 Query 头。
  • 1:当前 Query 的 token 数(因为推理时每次处理一个 token)。
  • seq_len_kv:Key 缓存的长度(即 Query 需要关注的所有历史 tokens)。

3. 举例计算

假设输入数据

  • Query Q_grouped

    • 形状:(batch=1, num_groups=2, group_size=2, 1, head_dim=3)
    • 假设值:
      Q_grouped = torch.tensor([[[  # Group 1[[1, 2, 3]],   # Query Head 1[[4, 5, 6]]    # Query Head 2],[  # Group 2[[7, 8, 9]],   # Query Head 3[[10, 11, 12]] # Query Head 4]]
      ], dtype=torch.float32)
      
  • Key K

    • 形状:(batch=1, num_groups=2, seq_len_kv=2, head_dim=3)
    • 假设值:
      K = torch.tensor([[[  # Group 1[0, 1, 0],  # Key 1[1, 0, 1]   # Key 2],[  # Group 2[1, 1, 1],  # Key 1[2, 2, 2]   # Key 2]]
      ], dtype=torch.float32)
      

计算步骤

  1. Key 转置K.transpose(-2, -1)

    K_T = K.transpose(-2, -1)
    

    变为:

    K_T = torch.tensor([[[  # Group 1[0, 1],  # Key Head 1[1, 0],  [0, 1]   ],[  # Group 2[1, 2],  # Key Head 2[1, 2],[1, 2]]]
    ], dtype=torch.float32)
    
  2. 矩阵乘法

    attn_logits = torch.matmul(Q_grouped, K_T)
    

    计算方式如下:

Group 1
Query Head 1 ([1, 2, 3]) 与 Key 矩阵点积:
[ 1 , 2 , 3 ] ⋅ [ 0 1 1 0 0 1 ] = [ 2 , 4 ] [1, 2, 3] \cdot \begin{bmatrix} 0 & 1 \\ 1 & 0 \\ 0 & 1 \end{bmatrix} = [2, 4] [1,2,3] 010101 =[2,4]
Query Head 2 ([4, 5, 6]):

[ 4 , 5 , 6 ] ⋅ [ 0 1 1 0 0 1 ] = [ 5 , 9 ] [4, 5, 6] \cdot \begin{bmatrix} 0 & 1 \\ 1 & 0 \\ 0 & 1 \end{bmatrix} = [5, 9] [4,5,6] 010101 =[5,9]

Group 2

Query Head 3 ([7, 8, 9]):
[ 7 , 8 , 9 ] ⋅ [ 1 2 1 2 1 2 ] = [ 24 , 48 ] [7, 8, 9] \cdot \begin{bmatrix} 1 & 2 \\ 1 & 2 \\ 1 & 2 \end{bmatrix} = [24, 48] [7,8,9] 111222 =[24,48]
Query Head 4 ([10, 11, 12]):
[ 10 , 11 , 12 ] ⋅ [ 1 2 1 2 1 2 ] = [ 33 , 66 ] [10, 11, 12] \cdot \begin{bmatrix} 1 & 2 \\ 1 & 2 \\ 1 & 2 \end{bmatrix} = [33, 66] [10,11,12] 111222 =[33,66]


最终结果

计算出的 attn_logits

attn_logits = torch.tensor([[[[[2, 4]],  # Query Head 1[[5, 9]]   # Query Head 2],[[[24, 48]], # Query Head 3[[33, 66]]  # Query Head 4]]
], dtype=torch.float32)
  • 形状:(batch=1, num_groups=2, group_size=2, 1, seq_len_kv=2)

4. 结论

  • GQA 中,Query 按组匹配共享 Key,减少计算复杂度。
  • KV 缓存中仅存储 num_groups 组 Key,而非 num_heads 组 Key,节省显存。
  • 矩阵计算遵循 Query-Key 点积规则,matmul(Q_grouped, K.transpose(-2, -1)) 计算注意力分数

后记

2025年2月23日10点08分于上海,在GPT4o大模型辅助下完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/70771.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ReentrantLock 用法与源码剖析笔记

📒 ReentrantLock 用法与源码剖析笔记 🚀 一、ReentrantLock 核心特性 🔄 可重入性:同一线程可重复获取锁(最大递归次数为 Integer.MAX_VALUE)🔧 公平性:支持公平锁(按等…

基于 DeepSeek LLM 本地知识库搭建开源方案(AnythingLLM、Cherry、Ragflow、Dify)认知

写在前面 博文内容涉及 基于 Deepseek LLM 的本地知识库搭建使用 ollama 部署 Deepseek-R1 LLM知识库能力通过 Ragflow、Dify 、AnythingLLM、Cherry 提供理解不足小伙伴帮忙指正 😃,生活加油 我站在人潮中央,思考这日日重复的生活。我突然想&#xff0c…

PCB设计常用布局布线方法

PCB设计常用布局布线方法 **1.模块化布局,**先放大器件再放小器件。 立创在原理图框完后,在PCB快捷shiftp 2.布局对齐美观 3.重要信号线优先处理 分类再画 4.减少Stub布线:就是避免为连接的线段,防止产生“天线效应”&#xff…

Mac 版 本地部署deepseek ➕ RAGflow 知识库搭建流程分享(附问题解决方法)

安装: 1、首先按照此视频的流程一步一步进行安装:(macos版)ragflowdeepseek 私域知识库搭建流程分享_哔哩哔哩_bilibili 2、RAGflow 官网文档指南:https://ragflow.io 3、RAGflow 下载地址:https://github.com/infi…

OpenIPC开源FPV之Adaptive-Link安装

OpenIPC开源FPV之Adaptive-Link安装 1. 源由2. 介绍2.1 天空端安装2.2 地面端安装 3. 问题汇总3.1 安装脚本问题3.2 网络安装问题3.3 非SSC30KQ/SSC338Q硬件3.4 代码疑问 4. 总结5. 后续 1. 源由 鉴于飞行过程,发现一些马赛克现象,且60FPS桌面30FPS的录…

解析第十一页

多选707、如图所示组网,SWA、SWB、SWC、SWD运行RSTP,则以下说法正确的是? A、可以在SWB的GE0/0/2端口开启边缘端口,让连接终端的接口快速进入转发状态 B、边缘端口收到BPDU之后会重新参与生成树的计算 C、可以在SWC的GEO/0/2端口开启边缘端口,让连接终端的接口快速进入转…

我的AI工具箱Tauri版-FluxCharacterGeneration参考图像生成人像手办(Flux 版)

本教程基于自研的AI工具箱Tauri版进行ComfyUI工作流FluxCharacterGeneration参考图像生成人像手办(Flux 版)。 我的AI工具箱Tauri版 - FluxCharacterGeneration参考图像生成人像手办(Flux版) 基于先进的FLUX模型,通过…

【前端基础】Day 2 HTML

目录 1.表格标签 2.列表标签 3.表单标签 4.综合案例 5.查阅文档 1.表格标签 <body><table align"center" border"1" cellpadding"0" cellspacing"0" width"500" height"100"><thead> …

R与RStudio简介及安装

目录 一、R与RStudio关系 二、R简介 2.1. 发展历史 2.2. R语言特点 三、安装指南 3.1 R安装指南 3.2 R studio安装指南 一、R与RStudio关系 R是统计领域广泛使用的工具&#xff0c;属于GNU系统的一个自由、免费、源代码开放的软件&#xff0c;是 用于统计计算和统计绘图…

20分钟 Bash 上手指南

文章目录 bash 概念与学习目的第一个 bash 脚本bash 语法变量的使用位置参数管道符号&#xff08;过滤条件&#xff09;重定向符号条件测试命令条件语句case 条件分支Arrayfor 循环函数exit 关键字 bash 脚本记录历史命令查询文件分发内容 bash 概念与学习目的 bash&#xff0…

django校园互助平台~源码

博主介绍&#xff1a;✌程序猿徐师兄、8年大厂程序员经历。全网粉丝15w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

易基因:RNA甲基化修饰和R-loop的交叉调控:从分子机制到临床意义|深度综述

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 R-loop&#xff08;RNA-DNA杂合结构&#xff09;是转录调控、DNA复制和修复等关键细胞过程的重要组成部分。但R-loop异常积累可能会破坏基因组完整性&#xff0c;从而导致多种疾病的发生…

多智能体框架

多个不同的角色的Agent&#xff0c;共同完成一份复杂的工作。由一个统筹管理的智能体&#xff0c;自主规划多个智能体分别做什么&#xff0c;以及执行的顺序。 agent 应该包含的属性 执行特定任务 根据其角色和目标做出决策 能够使用工具来实现目标 与其他代理沟通和协作 保留…

Metal 学习笔记四:顶点函数

到目前为止&#xff0c;您已经完成了 3D 模型和图形管道。现在&#xff0c;是时候看看 Metal 中两个可编程阶段中的第一个阶段&#xff0c;即顶点阶段&#xff0c;更具体地说&#xff0c;是顶点函数。 着色器函数 定义着色器函数时&#xff0c;可以为其指定一个属性。您将在本…

pycharm技巧--鼠标滚轮放大或缩小 Pycharm 字体大小

1、鼠标滚轮调整字体 设置 Ctrl 鼠标滚轮调整字体大小 备注&#xff1a; 第一个是活动窗口&#xff0c;即缩放当前窗口 第二个是所有编辑器窗口&#xff0c;即缩放所有窗口的字体 2、插件 汉化包&#xff1a; Chinese Simplified 包

硬件工程师入门教程

1.欧姆定律 测电压并联使用万用表测电流串联使用万用表&#xff0c;红入黑出 2.电阻的阻值识别 直插电阻 贴片电阻 3.电阻的功率 4.电阻的限流作用 限流电阻阻值的计算 单位换算关系 5.电阻的分流功能 6.电阻的分压功能 7.电容 电容简单来说是两块不连通的导体加上中间的绝…

edge浏览器将书签栏顶部显示

追求效果&#xff0c;感觉有点丑&#xff0c;但总归方便多了 操作路径&#xff1a;设置-外观-显示收藏夹栏-始终

【SPIE出版,见刊快速,EI检索稳定,浙江水利水电学院主办】2025年物理学与量子计算国际学术会议(ICPQC 2025)

2025年物理学与量子计算国际学术会议&#xff08;ICPQC 2025&#xff09;将于2025年4月18-20日在中国杭州举行。本次会议旨在汇聚全球的研究人员、学者和业界专家&#xff0c;共同探讨物理学与量子计算领域的最新进展与前沿挑战。随着量子技术的快速发展&#xff0c;其在信息处…

谷歌浏览器更新后导致的刷新数据无法显示

这几天突然出现的问题&#xff0c;就是我做了一个网站&#xff0c;一直用Google展示&#xff0c;前两天突然就是刷新会丢失数据&#xff0c;然后再刷新几次吧又有了&#xff0c;之前一直好好的&#xff0c;后端也做了一些配置添加了CrossOrigin注解&#xff0c;然而换了edge浏览…

软件需求管理办法,软件开发管理指南(Word原件)

1. 目的 2. 适用范围 3. 参考文件 4. 术语和缩写 5. 需求获取的方式 5.1. 与用户交谈向用户提问题 5.1.1. 访谈重点注意事项 5.1.2. 访谈指南 5.2. 参观用户的工作流程 5.3. 向用户群体发调查问卷 5.4. 已有软件系统调研 5.5. 资料收集 5.6. 原型系统调研 5.6.1. …