

代表模型:GPT 系列、LLaMA 系列、Qwen 系列等。 主要应用场景:自然语言生成任务,包括智能对话、文本创作、内容摘要、代码生成等。 核心特点:
代表模型:T5、BART、早期 Transformer 机器翻译模型等。 主要应用场景:序列到序列(Seq2Seq)任务,如机器翻译、文本摘要(尤其是抽取+生成结合)、问答系统、文本改写等。 核心特点:
代表模型:Switch Transformer,以及据信用于 GPT-4 的稀疏激活结构。 主要应用场景:超大规模语言模型,参数达千亿甚至万亿级,用于需要极致知识容量与多任务泛化能力的场景。 核心特点:
算力消耗的核心差异集中在 3 个维度:注意力机制设计、参数量规模、计算密度,我们逐个拆解,由浅入深。
注意力机制的算力复杂度,关键是先明确一个基础公式:
注意力机制算力复杂度 ≈ O (n² × d)
其中 n 是上下文长度(文本长度),d 是模型隐藏层维度。
由公式可知:上下文长度 n 对算力的影响是“平方级”的,长文本场景下会成为算力黑洞,而三种架构的注意力机制设计,直接决定了这个复杂度的实际落地值。
1.1 Decoder-only 架构的注意力机制
采用因果掩码自注意力,核心特点:
1.2 Encoder-Decoder 架构的注意力机制
1.3 MoE 架构的注意力机制
MoE 不是替代前两种架构,而是在 Decoder-only 或 Encoder-Decoder 基础上的模块升级,其注意力机制本身与基础架构一致,比如Switch Transformer 是 Decoder-only+MoE。
2.1 Decoder-only 架构
2.2 Encoder-Decoder 架构
2.3 MoE 架构
计算密度决定了 “算力是否被浪费”,直接影响实际的算力成本(同样的 FLOPs,计算密度高的模型能完成更多有效任务)。
3.1 Decoder-only 架构:计算密度最高
3.2 Encoder-Decoder 架构:计算密度中等
3.3 MoE 架构:计算密度有优势但存在瓶颈
MoE 的核心思想可以通俗理解为:“一个公司有 100 个专家(专家模块),处理一个任务时,只需要找 2 个最擅长的专家来完成,不需要所有专家都参与,这样既节省了人力(算力),又能保证任务质量(模型能力)”。
1.1 模块拆分:将密集模型的前馈网络(FFN)拆分为多个独立的专家模块
1.2 稀疏激活:通过门控网络选择少量专家参与计算
1.3 结果汇总:将激活专家的输出结果加权求和,作为最终输出
假设:
则 MoE 模型前馈网络的算力消耗为 F × s(注意力网络算力消耗与密集模型一致),当 E 很大(如 E=100),k 很小(如 k=2)时,s=0.02,前馈网络算力消耗仅为密集模型的 2%,整体算力消耗大幅降低。
如果要进一步提升模型能力,只需增加专家数量 E(总参数量增加),但稀疏系数 s 保持不变,算力消耗几乎不增加,这就是 MoE 模型“参数量与算力解耦”的核心优势。
长文本(如万字、十万字上下文)是大模型的重要场景,但也是公认的算力黑洞,其核心原因是注意力机制的平方级复杂度 和 KV 缓存的爆炸式增长。
如前文所述,注意力机制的算力复杂度是 O (n² × d),其中 n 是上下文长度,这个 “平方级” 是算力黑洞的核心来源。
通俗举例:

技术细节:长文本场景下,注意力机制的矩阵乘法会产生超大尺寸的矩阵(n×n),这个矩阵不仅计算量大,而且会占用大量显存存储矩阵中间结果,导致显存溢出,即使采用分布式存储,也会因为数据搬运开销过大而无法高效计算。
KV 缓存是推理阶段优化注意力算力的核心手段,但在长文本场景下,它会从优化手段变成存储黑洞,间接推高算力成本。

对于实际应用,选择哪种架构,核心是在“模型能力”和“算力成本”之间找到平衡,以下是针对不同场景的选型建议,结合算力消耗特点:
1. 优先选择 Decoder-only 架构的场景
2. 优先选择 Encoder-Decoder 架构的场景
3. 优先选择 MoE 架构的场景
import numpy as np
def calculate_attention_flops(n1, n2, d, architecture):
"""
计算三种架构的注意力机制算力复杂度(相对值,以FLOPs为单位)
:param n1: 输入序列长度(Encoder输入/Decoder-only上下文长度)
:param n2: 输出序列长度(Decoder输出,Decoder-only架构下n2=n1)
:param d: 模型隐藏层维度
:param architecture: 架构类型,可选["decoder_only", "encoder_decoder", "moe_decoder_only"]
:return: 相对算力复杂度(FLOPs)
"""
if architecture == "decoder_only":
# Decoder-only:因果掩码自注意力,复杂度 O(n1² × d)(n2=n1)
n = n1
flops = n ** 2 * d
return flops
elif architecture == "encoder_decoder":
# Encoder-Decoder:Encoder双向自注意力 + Decoder因果自注意力 + 跨注意力
# Encoder: O(n1² × d)
encoder_flops = n1 ** 2 * d
# Decoder因果自注意力: O(n2² × d)
decoder_self_flops = n2 ** 2 * d
# 跨注意力: O(n1 × n2 × d)
cross_flops = n1 * n2 * d
# 总算力
total_flops = encoder_flops + decoder_self_flops + cross_flops
return total_flops
elif architecture == "moe_decoder_only":
# MoE-Decoder-only:稀疏激活,稀疏系数s=0.02(k=2,E=100)
s = 0.02
n = n1
flops = s * (n ** 2 * d)
return flops
else:
raise ValueError("不支持的架构类型,请选择正确的架构")
# 设定实验参数(初学者可修改参数观察结果)
d = 4096 # 模型隐藏层维度(常见值:768、4096、8192)
n1_list = [512, 1024, 2048, 4096, 8192] # 输入序列长度/上下文长度
n2 = 1024 # 输出序列长度(Encoder-Decoder架构专用)
# 存储三种架构的算力结果
decoder_only_flops = []
encoder_decoder_flops = []
moe_decoder_only_flops = []
# 计算每种序列长度下的算力复杂度
for n1 in n1_list:
do_flops = calculate_attention_flops(n1, n2, d, "decoder_only")
ed_flops = calculate_attention_flops(n1, n2, d, "encoder_decoder")
moe_do_flops = calculate_attention_flops(n1, n2, d, "moe_decoder_only")
decoder_only_flops.append(do_flops)
encoder_decoder_flops.append(ed_flops)
moe_decoder_only_flops.append(moe_do_flops)
# 打印结果(格式化输出,更易读)
print("=" * 80)
print("三种架构注意力算力复杂度对比(相对值,隐藏层维度 d={},输出序列长度 n2={})".format(d, n2))
print("=" * 80)
print("{:<15} {:<20} {:<20} {:<20}".format("输入序列长度", "Decoder-only", "Encoder-Decoder", "MoE-Decoder-only"))
print("-" * 80)
for i, n1 in enumerate(n1_list):
do_f = f"{decoder_only_flops[i]:.2e}"
ed_f = f"{encoder_decoder_flops[i]:.2e}"
moe_do_f = f"{moe_decoder_only_flops[i]:.2e}"
print("{:<15} {:<20} {:<20} {:<20}".format(n1, do_f, ed_f, moe_do_f))输出结果:
===================================================================== 三种架构注意力算力复杂度对比(相对值,隐藏层维度 d=4096,输出序列长度 n2=1024) ===================================================================== 输入序列长度 Decoder-only Encoder-Decoder MoE-Decoder-only -------------------------------------------------------------------------------- 512 1.07e+09 7.52e+09 2.15e+07 1024 4.29e+09 1.29e+10 8.59e+07 2048 1.72e+10 3.01e+10 3.44e+08 4096 6.87e+10 9.02e+10 1.37e+09 8192 2.75e+11 3.14e+11 5.50e+09

结果解析:
import matplotlib.pyplot as plt
import numpy as np
# 沿用代码示例1的结果数据(如果已运行代码示例1,可直接使用;否则重新运行上述计算逻辑)
# 若未运行代码示例1,先执行以下初始化(保证代码独立运行)
d = 4096
n2 = 1024
n1_list = [512, 1024, 2048, 4096, 8192]
decoder_only_flops = []
encoder_decoder_flops = []
moe_decoder_only_flops = []
for n1 in n1_list:
do_flops = n1 ** 2 * d
encoder_flops = n1 ** 2 * d
decoder_self_flops = n2 ** 2 * d
cross_flops = n1 * n2 * d
ed_flops = encoder_flops + decoder_self_flops + cross_flops
moe_do_flops = 0.02 * (n1 ** 2 * d)
decoder_only_flops.append(do_flops)
encoder_decoder_flops.append(ed_flops)
moe_decoder_only_flops.append(moe_do_flops)
# 设置中文显示(解决matplotlib中文乱码问题)
plt.rcParams["font.sans-serif"] = ["SimHei"] # 用黑体显示中文
plt.rcParams["axes.unicode_minus"] = False # 正常显示负号
# 创建画布
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 6))
# 子图1:三种架构算力复杂度对比(普通坐标)
ax1.plot(n1_list, decoder_only_flops, label="Decoder-only", marker="o", linewidth=2, color="#1f77b4")
ax1.plot(n1_list, encoder_decoder_flops, label="Encoder-Decoder", marker="s", linewidth=2, color="#ff7f0e")
ax1.plot(n1_list, moe_decoder_only_flops, label="MoE-Decoder-only", marker="^", linewidth=2, color="#2ca02c")
ax1.set_title("三种架构注意力算力复杂度对比(普通坐标)", fontsize=14)
ax1.set_xlabel("输入序列长度/上下文长度", fontsize=12)
ax1.set_ylabel("相对算力复杂度(FLOPs)", fontsize=12)
ax1.legend(fontsize=10)
ax1.grid(True, alpha=0.3)
# 子图2:三种架构算力复杂度对比(对数坐标,更清晰展示MoE的优势)
ax2.plot(n1_list, decoder_only_flops, label="Decoder-only", marker="o", linewidth=2, color="#1f77b4")
ax2.plot(n1_list, encoder_decoder_flops, label="Encoder-Decoder", marker="s", linewidth=2, color="#ff7f0e")
ax2.plot(n1_list, moe_decoder_only_flops, label="MoE-Decoder-only", marker="^", linewidth=2, color="#2ca02c")
ax2.set_title("三种架构注意力算力复杂度对比(对数坐标)", fontsize=14)
ax2.set_xlabel("输入序列长度/上下文长度", fontsize=12)
ax2.set_ylabel("相对算力复杂度(FLOPs,对数刻度)", fontsize=12)
ax2.set_yscale("log") # 设置y轴为对数刻度
ax2.legend(fontsize=10)
ax2.grid(True, alpha=0.3)
# 调整布局,保存图片(保存到当前工作目录,格式为png)
plt.tight_layout()
plt.savefig("大模型架构算力对比图.png", dpi=300, bbox_inches="tight")
plt.show()
print("图片已保存为:大模型架构算力对比图.png")结果图示:

图例说明:
import matplotlib.pyplot as plt
import numpy as np
def simulate_moe_expert_load(expert_num, token_num, top_k=2):
"""
模拟MoE模型的专家负载不均衡情况
:param expert_num: 专家数量
:param token_num: token数量
:param top_k: 每个token选择的专家数量
:return: 每个专家的被激活次数(负载)
"""
# 初始化专家负载
expert_load = np.zeros(expert_num)
# 为每个token选择top_k个专家(模拟热点专家,部分专家被选中概率更高)
for _ in range(token_num):
# 生成专家概率分布(前10%的专家是热点专家,被选中概率更高)
expert_probs = np.ones(expert_num)
hot_expert_num = int(expert_num * 0.1)
expert_probs[:hot_expert_num] = 10 # 热点专家概率权重提升10倍
# 归一化概率分布
expert_probs = expert_probs / np.sum(expert_probs)
# 选择top_k个专家
selected_experts = np.random.choice(expert_num, size=top_k, replace=False, p=expert_probs)
# 更新专家负载
for expert in selected_experts:
expert_load[expert] += 1
return expert_load
# 设定实验参数
expert_num = 100 # 专家数量
token_num = 10000 # token数量
top_k = 2 # 每个token选择2个专家
# 模拟专家负载
expert_load = simulate_moe_expert_load(expert_num, token_num, top_k)
# 可视化专家负载
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False
fig, ax = plt.subplots(figsize=(12, 6))
# 绘制每个专家的负载
ax.bar(range(expert_num), expert_load, color="#1f77b4", alpha=0.7)
# 标注热点专家区域
ax.axvline(x=9, color="red", linestyle="--", label="热点专家与普通专家分界线(前10%)")
ax.set_title("MoE模型专家负载不均衡模拟(专家数量=100,Token数量=10000)", fontsize=14)
ax.set_xlabel("专家编号", fontsize=12)
ax.set_ylabel("被激活次数(负载)", fontsize=12)
ax.legend(fontsize=10)
ax.grid(True, alpha=0.3, axis="y")
# 保存图片
plt.tight_layout()
plt.savefig("MoE专家负载不均衡模拟图.png", dpi=300, bbox_inches="tight")
plt.show()
print("图片已保存为:MoE专家负载不均衡模拟图.png")
print("热点专家平均负载:{:.2f}".format(np.mean(expert_load[:10])))
print("普通专家平均负载:{:.2f}".format(np.mean(expert_load[10:])))输出结果:
热点专家平均负载:1040.90 普通专家平均负载:106.57
结果图示:

理解三种架构的算力差异,对于我们学习和选型都具有重要意义:
三种大模型架构的算力核心差异主要体现在注意力机制、参数量与计算密度上,整体算力消耗从高到低依次为 Encoder-Decoder、Decoder-only、MoE 架构。MoE 依靠稀疏激活,仅让少量专家参与计算来大幅节省算力,但也面临门控网络开销、专家负载不均、跨设备通信成本高三大瓶颈。长文本场景则因注意力平方级复杂度与 KV 缓存暴涨形成算力黑洞,主要依靠优化注意力结构、压缩缓存来缓解。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。