【大模型篇】:GPT-Llama-Qwen-Deepseek
1、涌现
许多小实体相互作用后产生大实体,这个大实体展现了组成它的小实体所不具有的特性,如蚂蚁社群、神经网络等。
大模型的涌现可能由以下原因出现:
-
参数量规模(40%):
通用涌现阈值:在跨领域推理和零样本学习中,触发广泛涌现能力的典型门槛是百亿级参数,如100B-200B。
任务特异性涌现:大模型中的较小者,在特定任务(如数学推理)中,可通过数据优化、架构调整 在7B左右的参数 模拟涌现能力。 -
训练数据量与质量(30%):
数据规模:千亿级token(如GPT-3的300B tokens)是基础,数据多样性(文本、代码、多模态)提升泛化能力。
数据质量:经过清洗、筛选、优化的高质量训练数据有更好的效果。 -
模型架构创新(30%):
Attention:MHA、Flash Attention、MLA等
Rope:通过旋转位置编码,加入了相对位置信息,使得问题与上下文token越来越长
归一化与激活:RMSNorm、SwiGLU、GeGLU等的使用更符合大模型
MOE:更多更全面的能力,更快的推理速度
2、模型特性对比
特性 | GPT-3 (175B) | Llama 2 7B | Qwen-14B | DeepSeek-MoE-16B |
---|---|---|---|---|
参数量 | 175B | 7B | 14B | 16B(稀疏激活,等效稠密约4B) |
训练数据量 | 45TB | 2T Tokens(≈45TB) | 3T Tokens(50%中文) | 8T Tokens(高质量多语言) |
数据特点 | 原始爬取,未严格过滤 | 严格过滤,含5%代码 | 中文优化,含代码/多语言 | 逻辑密集型数据增强 |
- | - | - | - | - |
基础架构 | 稠密Decoder | 稠密Decoder | 稠密Decoder | MoE架构(16B参数,稀疏激活) |
位置编码 | 绝对编码 | RoPE | 动态NTK RoPE | XPos(外推优化版RoPE) |
注意力机制 | 标准MHA | MHA(70B用GQA) | 动态NTK RoPE | Hybrid Attention(局部+全局) |
归一化方法 | LayerNorm | RMSNorm | LayerNorm | RMSNorm(改进版) |
激活函数 | ReLU | SwiGLU | SwiGLU | GeGLU(门控扩展) |
训练目标 | 自回归 | 自回归 + RLHF | 自回归 + 多任务预训练 | 自回归 + 逻辑链预训练 |
上下文长度 | 2K | 4K(可扩展至16K) | 8K(可扩展至32K) | 32K(原生支持) |
关键创新 | 规模化验证Scaling Laws | 开源高效架构 | 中文长上下文优化 | MoE稀疏化 + 逻辑数据增强 |
3、【Rope】
- 传统【绝对】位置编码:
绝对位置编码为每个位置分配一个独立的向量,扩展token长度时需要重新训练,并且无法有效捕获相对位置信息,
加入不变的位置信息-失去【远程衰减性】,使用可学习的位置编码-失去【外推性】 - 传统【相对】位置编码:
加入大量矩阵操作,【计算效率低下】,并且kv cache的使用会变得复杂,
softmax(Q*K+Bij)加入大量矩阵操作,kv cache不可用,【框架结构被破坏】(Bij:位置i与j的可学习参数矩阵)
【RoPE】:
Rotary Position Embedding,旋转位置编码,加入了【相对位置信息】。
提出了一种【高效计算】相对位置编码的方法,【保持了原本的attention结构】。
方法拥有【远程衰减特性】,并具备一定的【外推能力】,为更远的外推提供了基础。
【计算与推导过程】
rope提出了一个满足下面方程的公式,使得rope可以有效利用【相对位置信息】:
⟨f_q(𝒙_m, m), f_k(𝒙_n, n)⟩ = g(𝒙_m, 𝒙_n, m−n)
这个公式的意思是:原始矩阵m位置上的向量x_m计算成Q,与原始矩阵n位置上的向量x_n计算成K,
它们的点积结果,只与x_m、x_n以及它们的相对位置m-n有关。
论文给出的解是:乘以一个【欧拉公式】。
f_q(𝒙_m, m) = (𝑾_q 𝒙_m) e^{i m θ} = [ cosmθ −sinmθ ][qm1] // (2x2 * 2x1)=[2x1]
[ sinmθ cosmθ ][qm2]
f_k(𝒙_n, n) = (𝑾_k 𝒙_n) e^{i n θ} = [ cosmθ −sinmθ ][kn1] // (2x2 * 2x1)=[2x1]
[ sinmθ cosmθ ][kn2]
⟨f_q(𝒙_m, m), f_k(𝒙_n, n)⟩ =(计算结果省略,有用到三角函数公式)
= [qm1 qm2][ cos(m-n)θ −sin(m-n)θ ] [kn1] // (1x2 *2x2 *2x1)=[1x1]
[ sin(m-n)θ cos(m-n)θ ] [kn2]
= Q*R(m-n)*K^T
【参数说明】
加入相对位置后的计算结果,仅相当于在原来Q*K之上,乘上了一个【与位置差(m-n)有关的三角函数矩阵】。
其中 【旋转基频】θ i =10000 ^(−2i/d),
d是每个注意力头的维度如1024(或128),i∈[0,d/2)即{0,1,2,…,511},
计算时QK矩阵中的每个【向量】,会被分为2/d个块,每个块2个元素,索引为i,
【旋转基频】这是一个i的【单调递减】函数,
靠前的θ i 比较大,旋转速度快,为高频分量,靠后的θ i 比较大,旋转速度慢,为低频分量。
【高效计算】:论文与实际代码实现中,有【高效计算】这个式子的方式,这里不展开。
【模型结构不改变】:这个形式相当于在注意力分数上乘以一些注意力常量,模型结构不改变。
【远程衰减特性】
在旋转位置编码(RoPE)中,另一种计算结果是:内积最终表现为所有分量的【cos((m-n)θ i)】加权和,sin项消失的原因源于复数内积的共轭对称性和旋转矩阵的正交性。
【高频分量的剧烈震荡】与【低频分量的平缓衰减】叠加,形成整体震荡衰减趋势,距离越远得到的关注权重越少。
【远程衰减特性】与【θ i的指数衰减设计】直接相关,若θ i固定为1,该衰减特性将完全消失。
【外推能力】
拥有一定的外推能力,不用重新训练,但是推理长度远大于训练长度时,注意力也会崩溃。
旋转后模长不变,为后续的改进提供了基础。
【Rope升级】
-
【llama的Rope】:通过旋转矩阵,加入高效计算的位置差编码,保持框架结构不变
【Attention_originRope(Q,K)】= QR(m-n, θi ) K^T,θi =10000 ^{−2i/d},d是每个注意力头的维度,i∈[0,d/2)
【直接外推】推理长度超出训练长度时,Linfer=Linfer-n*Ltrain -
【qwen的NTK-Rope】:加入([最长]推理长度/最长训练长度)信息,改进旋转角度设置,外推能力强
#假设L_train_max=512,但是L_infer_max=4096,此时需要NTK外推
【Attention_NTKRope(Q,K)】=Q*R(m-n, θi_NTK )*K^T,
θi_NTK = θi s^{-2i/(d-2)}=θi (L_infer_max/L_train_max)^{-2i/(d-2)}
=10000 {−2i/d}*4{-2i/(d-2)} # d-2是因为i取不到d/2,只能取到d/2-1
【线性内插】当i=d/2,θi_NTK =10^{-4*1/4,把[0,4096)映射到[0,512),此为内插 -
【deepseek的XPos(外推优化版Rope)】:加入([当前]推理长度/最长训练长度)信息,加强调控衰减能力,外推能力进一步加强
【Attention_XPos(Q,K)】=γ^{(m-n)/L_train_max}*【Attention_originRope(Q,K)】
=(L_now/L_train_max)^{-k*(m-n)/L_train_max}*【Attention_originRope(Q,K)】
4、归一化与激活
【归一化方法Norm】
-
【BatchNorm】:对【batch维度B】计算均值与方差,做归一化,多用于cv。
均值: μ_B = 1/B* ∑ _{i=1} ^B x_i
方差:(σ_B)^2=1/B* ∑ _{i=1} ^B (x_i-μ_B )^2
y=γ⋅ (x-u_B)/sqrt((σ_B)^2+ϵ)+β -
【LayerNorm】:对【feature维度d】计算均值与方差,做归一化,多用于NLP。
均值: μ_L = 1/d* ∑ _{i=1} ^d x_i
方差:(σ_L)^2=1/d* ∑ _{i=1} ^d (x_i-μ_L )^2
y=γ⋅ (x-u_L)/sqrt((σ_L)^2+ϵ)+β -
【llama2-RMSNorm】:对【feature维度d】计算平方的均值,【省却一次reduce_add计算】,加速 大模型训练15%速度。
平方的均值(保持能量强度):μ_R^2=1/d* ∑ _{i=1} ^d x_i^2
y=γ *x/(sqrt(μ_R^2)+ϵ) -
【deepseek优化-RMSNorm】:比llama2-RMSNorm多了一个动态缩放因子τ在分母
y=γ*x/(τ*sqrt(μ_R^2)+ϵ)
τ:使长文本生成任务中的困惑度降低0.15
【激活函数(非线性能力)】
- 【RELU】
x=0处不可导 - 【GELU】
GELU(x)=x⋅Φ(x),Φ(x)为标准正态分布CDF,平滑可导适合深度训练 - 【GLU】
GLU(x)=(Wa* x)⊙σ(Wb* x),⊙表示逐像素点乘,σ是sigmoid函数
【学习特征】:Wa* x负责学习输入的本质特征(如语义、语法)
【激活决策】:Wb* x负责学习各维度的激活优先级(如哪些词汇对当前任务更重要)
作用:信息解耦,提升对特征的细粒度控制,避免局部最优 - 【SwiGLU】
swish做激活函数的GLU,避免sigmoid的梯度消失,捕捉更复杂的特征
SwiGLU(x)=Swish(W1*x+b1) ⊙(W2*x+b2)=x⋅σ(β*W1*x+b1)⊙(W2*x+b2) - 【GeGLU】
gelu做激活函数的GLU,更适合处理中长尾分布的特征
GeGLU(x)=GELU(W1* x+b1)⊙(W2* x+b2)=(W 1\* x+b1)*Φ(W 1\* x+b1)⊙(W2* x+b2)
5、Deepseek 模型 关键点
【Deepseek部分模型】
1 DeepseekV2Model(
2 (embed_tokens): PPMissingLayer()
3 (layers): ModuleList(
4 (0-15): 16 x PPMissingLayer()
5 (16-23): 8 x DeepseekV2DecoderLayer(
6 (self_attn): DeepseekV2MLAAttention(
7 (q_a_proj): ReplicatedLinear(in_features=7168, output_features=1536, bias=False)
8 (q_a_layernorm): RMSNorm(hidden_size=1536, eps=1e-06)
9 (q_b_proj): ColumnParallelLinear(in_features=1536, output_features=6144, bias=False, tp_size=4, gather_output=False)
10 (kv_a_proj_with_mqa): ReplicatedLinear(in_features=7168, output_features=576, bias=False)
11 (kv_a_layernorm): RMSNorm(hidden_size=512, eps=1e-06)
12 (kv_b_proj): ColumnParallelLinear(in_features=512, output_features=8192, bias=False, tp_size=4, gather_output=False)
13 (o_proj): RowParallelLinear(input_features=4096, output_features=7168, bias=False, tp_size=4, reduce_results=True)
14 (rotary_emb): DeepseekScalingRotaryEmbedding(head_size=64, rotary_dim=64, max_position_embeddings=4096, base=10000, is_neox_style=False)
15 (mla_attn): Attention(head_size=576, num_heads=32, num_kv_heads=1, scale=0.1352337788608801, backend=SUPAFlashMLAImpl)
16 )
17 (mlp): DeepseekV2MoE(
18 (gate): ReplicatedLinear(in_features=7168, output_features=256, bias=False)
19 (experts): FusedMoE(
20 global_num_experts=256, local_num_experts=64, top_k=8, intermediate_size_per_partition=2048, tp_size=1,
21 ep_size=4, reduce_results=False, renormalize=True, use_grouped_topk=True, num_expert_group=8, topk_group=4, scoring_func=‘sigmoid’, activa tion=‘silu’
22 )
23 (shared_experts): DeepseekV2MLP(
24 (gate_up_proj): MergedColumnParallelLinear(in_features=7168, output_features=1024, bias=False, tp_size=4, gather_output=False)
25 (down_proj): RowParallelLinear(input_features=512, output_features=7168, bias=False, tp_size=4, reduce_results=False)
26 (act_fn): SiluAndMul()
27 )
28 )
29 (input_layernorm): RMSNorm(hidden_size=7168, eps=1e-06)
30 (post_attention_layernorm): RMSNorm(hidden_size=7168, eps=1e-06)
31 )
32 (24-60): 37 x PPMissingLayer()
33 )
34 (norm): PPMissingLayer()
35 )
【MLA+解耦ROPE】:
旨在通过【低秩压缩技术】显著【减少推理时的 KV 缓存占用】和【计算冗余】
KV 联合压缩:将 K 和 V 投影到一个共享的低维潜在空间,减少显存占用。
解耦位置编码:分离语义和位置信息,避免低秩压缩对 RoPE(旋转位置编码)的干扰,Qt=[【Q】;【q_rope】],
存储优化:推理时仅需缓存 【compressed_kv】[d=512] 和解耦的 【k_rope】[d=64] ,而非完整的 K + V[d=16384]。
seqlen=4096,d=d_{o_proj}_out=7168,d_{o_proj}_in=8192
rotary_head_size=64,rotary_dim=64,RoPE部分:仅作用于Query和Key的64维,Value无需位置敏感信息
mla_attn_num_heads=64,mla_attn_head_size=576(MLA低秩投影后的潜在空间维度,而非拼接后的实际维度),scale=0.1352337788608801对应1/sqrt(576)
hidden_size[q_a_layernorm]=q_lora_rank=1536,hidden_size[kv_a_layernorm]=kv_lora_rank=512,
-
【Q路径】:
输入hidden_states :[1, 4096, 7168]
乘以【降维权重 W_{q_a_proj}】[7168, 1536]->【compressed_q】[1, 4096, 1536]
归一化:q_a_layernorm[1536]->【compressed_q】[1, 4096, 1536]
乘以【升维权重 W_{q_b_proj}】[1536, 12288]->[1, 4096, 12288]->拆分多头64->[1, 4096, 64, 192],
->其中q_head_dims =8192/64=128,rotary_head_size=64,则 【Q】=[1, 4096, 64, 128],【q_loc】=[1, 4096, 64, 64]
->头数提前【Q】=[1, 64, 4096, 128],【q_loc】=[1, 64, 4096, 64]
位置信息:rotary_emb[64, 64]->【q_rope】=[1, 4096, 64, 64] -
【K与V路径】:
输入hidden_states :[1, 4096, 7168]
乘以【降维权重W_{kv_a_proj_with_mqa}】[7168, 576]->[1, 4096, 576]
->根据 hidden_size[kv_a_layernorm]=512与num_heads=64,拆分为【compressed_kv】[1, 4096, 512] +【k_loc】 [1, 4096, 64]
归一化:kv_a_layernorm[512]->【compressed_kv】[1, 4096, 512]
【k_loc】广播到所有头:[1, 64, 4096, 64]
位置信息:rotary_emb[64, 64]->【k_rope】=[1, 4096, 64, 64]
乘以【升维权重W_{kv_b_proj}】[512, 16384]->[1, 4096, 16384]拆分多头64->[1, 4096, 64, 256]
->拆分K V 128:前128维【K】[1, 4096, 64, 128],后128维【V】[1, 4096, 64, 128]->头数提前【V】[1, 64, 4096, 128] -
【Attention计算】:
Qt=[【Q】;【q_rope】]=[1, 64, 4096, 192],Kt=[【K】;【k_rope】]=[1, 64, 4096, 192]
【Attention_score】 = softmax(【Qt】·【Kt】^T/√d) = softmax([1, 64, 4096, 192]·[1, 64, 192, 4096]/√576) = [1, 64, 4096, 4096]
【Attention】 = 【Attention_score】 · 【V】 = [1, 64, 4096, 4096] · [1, 64, 4096, 128] = [1, 64, 4096, 128] = [1, 4096, 128x64] = [1, 4096, 8192]
权重o_proj[8192, 7168]适配输入->【Attention_out】=[1, 4096, 7168] -
【KVcache存储内容】:
【compressed_kv】:[1,4096,512],由kv_a_proj_with_mqa降维后生成,是KV Cache的核心压缩表示。
【k_rope】:[1,4096,64],RoPE部分独立缓存,广播到所有头。
->总共就是存储[1,4096,576]
compressed_q和q_rope无需缓存,因Query在解码阶段每次重新计算。
缓存参数量:【compressed_kv】+【k_rope】=[1, 4096, 576],而非原始【K】+【V】:2x[1, 64, 4096, 128]=[1, 4096, 16384],显存占用减少约96.5%。
【MLA关键点】
1、【低秩压缩技术】:引入变换矩阵c对输入做变换。增加 降维 与 升维 矩阵,得到【更低维度的矩阵c】替代全量的【K】【V】
2、【解耦ROPE】:Q与KV都在降维后,将数据分为【非rope】与【rope部分】,在【rope部分】添加旋转位置嵌入,不参与后续升维。
【MOE+辅助无损耗负载平衡功能】
- 【MOE的输入】是上面MLA的输出,也是[4096,7168]
乘以【门控权重W_{gate}】[7168, 256]->[4096,256],表示每个token(共4096个token)在256个专家上的得分
【辅助无损耗负载平衡功能】
动态偏置 b:通过训练动态调整并固化到推理阶段,既保障负载均衡又不损害模型性能,
通常以与专家数量相同的维度(如256维)单独存储,作为路由网络的附加参数。
偏置叠加:将动态偏置 b 按元素加到 上述原始亲和度分数s = W_gate * x([4096, 256])上:s_adjusted = s + b=[4096, 256] - 在【FusedMoE】算子中:
==== 参数相关 ====
【专家总数】:global_num_experts=256,
【专家并行】:local_num_experts=global_num_experts/EP,
ep_size=1, 无专家并行;local_num_experts=256, 单设备部署的专家数量为256,
若EP=4,则local_num_experts=256/4=64
【激活专家】:top_k=8,总共激活8个专家; num_expert_group=8,把 global_num_experts个专家分为8组,每组32个;
topk_group=4,取前4组专家;结合top_k=8,每组取2个专家
【模型并行】:intermediate_size_per_partition=1024,每个张量并行分区的中间层维度;
tp_size=2,张量并行分组为2,参数在2张GPU上切分
==== 计算相关 ====
【路由分配】:[4096,256]排序后取前4大组中的前2个最靠前专家,共8个,得到[4096,8],表示每个token选择的8个专家的index,
然后对【MLA输入】进行【token分组】,选择了相同专家的token被放到一起,形成[分组Token, 7168]的输入块,比如:
极端情况1:全部token使用同一个专家——1组[4096, 7168]
极端情况2:平均分配到8个相同专家——8组[512, 7168]
极端情况3:平均分配到所有256个专家——256组[16, 7168]
【专家计算】:通过Group GEMM(分组矩阵乘法)批量处理不同专家的计算,
如上面8组[512, 7168]乘以每个不同的专家权重,专家的FFN计算过程,累加后的结果仍然是[4096, 7168]:
降维:[分组Token, 7168] × W[7168, 1024] → [分组Token, 1024]
激活: (act_fn): SiluAndMul()=x*(1/(1+e^{-x}))*y,即输入x乘以x的sigmoid函数,再乘以常数y
升维:[分组Token, 1024] × [1024, 7168] → [分组Token, 7168]
【输出聚合】:【MLA输入】中,每个token经过8个专家的计算,总共会获得4096x[1,7168]x8的数据,
其中[1,7168]x8会被加权求和=sum(专家输出_i × 路由权重_i),其中i ∈ [1,8],结果仍然是[1,7168],
于是【FusedMoE】最终的输出仍然是[4096,7168],但是它已经【经过了分组分数最高的8个专家的计算并加权求和】 - 【DeepseekV2MLP】:处理通用任务(如基础语言理解),所有Token均会调用,确保模型基础能力,常规FFN
【gate_up_proj】:MergedColumnParallelLinear,tp_size=2,in_features=7168, output_features=2048(分片前size),
ColumnParallel按【列】划分权重tp_size=2,权重为两个[7168, 2048/2]=[7168, 1024],计算得到两个[4096, 1024]
【激活】:同上(act_fn): SiluAndMul()
【down_proj】:RowParallelLinear,tp_size=2,input_features=1024(分片后size), output_features=7168,
RowParallel按【行】划分权重tp_size=2,权重为2x[1024, 7168],
2x[4096, 1024]与2x[1024, 7168]乘加之后仍然得到[4096, 7168]
到此完成了MOE的计算。