**MLA 多头潜在注意力,利用低秩压缩技术,将模型参数压缩到极致
MOE 混合专家机制,ff前馈连接层整体分为N个专家主导,利用linear层加权求和的方式算出专家的得分logits,利用softmax算出专家的权重比例,topk选择排名靠前的专家进行激活计算,抓重点,专业的事交给专业的部分搞定,大幅节省算力(激活率 5.5%)
FP8 采用FP8精度,量化压缩50%
RLAIF AI强化学习,节省人工标注成本,让模型更懂人性,听人话
AI标注>>有监督微调>>排序实现奖励模型>>PPO强化学习>>反向促进模型成长
Deepseek Sparse Attention 稀疏注意力机制,抓重点部分做计算,节省半数算力
DSA是通过linear层不断更新参数,不断学习如何筛选更优质的注意力部分**
**混合专家机制MOE专项理解:
混合专家模式MOE的意义从来不是像MLA或者DSA这样直接的节省参数计算量,反而分配多个专家会导致算力消耗翻倍,但是收益确实指数级增长的,利用低算力的成本,敲动高算力成果
处理层级是ff前馈连接层,假定100个专家,我们给这100个专家均配备标准的ff层用以反向梯度更新参数,重点是我们提前对输入维度经过linear层输出到100个logits(对应100个专家),经过softmax(logtis)得到相应的专家权重分布比例,经过topv可以得到权重靠前的5个专家,我们通过激活靠前的5个专家来更新他们的参数,从而达到用5倍算力撬动100倍算力的杠杆效果,激活率5%
激活专家的方式是通过将专家权重矩阵中不需要计算的专家权重置为0,来规避他们的更新,同时我们引入惩罚系数,强制模型雨露均沾,避免一些专家饿死,让他们都能得到参数的更新,这就是deepseek的负载均衡机制(惩罚系数)**
# 共享+路由专家模型 import torch import torch.nn as nn import torch.nn.functional as F # ===================== 专家网络定义 ===================== class Expert(nn.Module): def __init__(self, input_dim, hidden_dim, output_dim): super().__init__() # 第一层全连接层,将输入维度映射到隐藏层维度 self.fc1 = nn.Linear(input_dim, hidden_dim) # 第二层全连接层,将隐藏层映射到输出维度 self.fc2 = nn.Linear(hidden_dim, output_dim) def forward(self, x): # 先经过第一层并激活 x = F.relu(self.fc1(x)) # 再经过第二层输出 return self.fc2(x) # ===================== 路由门控网络定义 ===================== class RoutingGate(nn.Module): def __init__(self, input_dim, num_routed_experts, k=2): super().__init__() # 全连接层输出每个专家的分数 self.fc = nn.Linear(input_dim, num_routed_experts) self.k = k # Top-k,表示每个输入只选择k个专家 def forward(self, x): # logits: [batch, num_routed_experts],每个专家的分数 logits = self.fc(x) # 取Top-k分数及其索引 topk_val, topk_idx = torch.topk(logits, self.k, dim=-1) # 对Top-k分数做softmax,得到归一化权重 weights = F.softmax(topk_val, dim=-1) print("weights:", weights) # 构造与logits同形状的全零权重 routed_weights = torch.zeros_like(logits) # 将Top-k权重填入对应位置,其余为0 routed_weights.scatter_(-1, topk_idx, weights) print("Routed weights:", routed_weights) return routed_weights # [batch, num_routed_experts] # ===================== MoE主结构:包含路由专家和共享专家 ===================== class MoEWithRouting(nn.Module): def __init__( self, input_dim, hidden_dim, output_dim, num_routed_experts, num_shared_experts, k=2, ): super().__init__() # 路由专家列表,每个专家是一个Expert实例 self.routed_experts = nn.ModuleList( [ Expert(input_dim, hidden_dim, output_dim) for _ in range(num_routed_experts) ] ) # 共享专家列表 self.shared_experts = nn.ModuleList( [ Expert(input_dim, hidden_dim, output_dim) for _ in range(num_shared_experts) ] ) # 路由门控网络 self.routing_gate = RoutingGate(input_dim, num_routed_experts, k) # 共享专家的权重参数(可学习),初始均分 self.shared_weights = nn.Parameter( torch.ones(num_shared_experts) / num_shared_experts, requires_grad=True ) def forward(self, x): # ========== 路由专家部分 ========== # 计算每个输入分配到各个路由专家的权重 [batch, num_routed_experts] routed_weights = self.routing_gate(x) print("routed_weights:", routed_weights) # 计算所有路由专家的输出,堆叠成 [batch, output_dim, num_routed_experts] routed_outputs = torch.stack( [expert(x) for expert in self.routed_experts], dim=2 ) print("routed_outputs:", routed_outputs) # 按权重加权求和,得到路由专家的最终输出 [batch, output_dim] routed_result = torch.sum(routed_weights.unsqueeze(1) * routed_outputs, dim=2) print("routed_result:", routed_result) # ========== 共享专家部分 ========== # 计算所有共享专家的输出,堆叠成 [batch, output_dim, num_shared_experts] shared_outputs = torch.stack( [expert(x) for expert in self.shared_experts], dim=2 ) # 对共享专家权重做softmax归一化 [num_shared_experts] shared_weights = F.softmax(self.shared_weights, dim=0) # 按权重加权求和,得到共享专家的最终输出 [batch, output_dim] shared_result = torch.sum( shared_weights.unsqueeze(0).unsqueeze(1) * shared_outputs, dim=2 ) # ========== 融合输出 ========== # 路由专家输出与共享专家输出相加,作为最终输出 output = routed_result + shared_result return output # ===================== 测试代码 ===================== # 定义各参数 input_dim = 10 # 输入特征维度 hidden_dim = 20 # 专家网络隐藏层维度 output_dim = 5 # 输出特征维度 num_routed_experts = 4 # 路由专家数量 num_shared_experts = 2 # 共享专家数量 k = 2 # Top-k,路由门控每次选择的专家数 seq_len = 8 # 输入序列长度(batch size) # 实例化模型 model = MoEWithRouting( input_dim, hidden_dim, output_dim, num_routed_experts, num_shared_experts, k ) # 构造随机输入 x = torch.randn(seq_len, input_dim) # 前向传播 output = model(x) # 打印输出形状和内容 print("Output shape:", output.shape, output) # [seq_len, output_dim]
""" ═══════════════════════════════════════════════════════════════════ 输入数据 x 形状: [8, 10] (batch=8, dim=10) ═══════════════════════════════════════════════════════════════════ │ ┌─────────────────┼─────────────────┐ │ │ │ ▼ ▼ ▼ ┌────────┐ ┌────────┐ ┌────────┐ │门控网络│ │路由专家│ │共享专家│ │ │ │ (4个) │ │ (2个) │ └────────┘ └────────┘ └────────┘ │ │ │ ▼ ▼ ▼ ┌────────┐ ┌────────────────────────────┐ │[8,4] │ │ 每个专家内部: │ │(权重) │ │ ┌────────────────────────┐ │ └────────┘ │ │ 输入: [8,10] │ │ │ │ │ ↓ │ │ │ │ │ fc1: Linear(10→20) │ │ │ │ │ ↓ │ │ │ │ │ ReLU │ │ │ │ │ ↓ │ │ │ │ │ fc2: Linear(20→5) │ │ │ │ │ ↓ │ │ │ │ │ 输出: [8,5] │ │ │ │ └────────────────────────┘ │ │ │ │ │ │ 4个专家各自输出: │ │ │ E0: [8,5] │ │ │ E1: [8,5] │ │ │ E2: [8,5] │ │ │ E3: [8,5] │ │ │ ↓ │ │ │ stack(dim=2) │ │ │ ↓ │ │ │ [8,5,4] ←────────────┐ │ │ │ │ │ │ └───────────────────────┼────┘ │ │ ▼ ▼ ┌─────────────────────────────────────────────────┐ │ 路由加权求和: [8,1,4] × [8,5,4] = [8,5,4] │ │ sum(dim=2) → [8,5] │ └─────────────────────────────────────────────────┘ │ ▼ routed_result: [8,5] │ │ ┌────────────────────────────┐ │ │ 共享专家 (2个): │ │ │ 每个专家内部: │ │ │ 输入: [8,10] │ │ │ ↓ │ │ │ fc1: Linear(10→20) │ │ │ ↓ │ │ │ ReLU │ │ │ ↓ │ │ │ fc2: Linear(20→5) │ │ │ ↓ │ │ │ 输出: [8,5] │ │ │ │ │ │ S0: [8,5] │ │ │ S1: [8,5] │ │ │ ↓ │ │ │ stack(dim=2) │ │ │ ↓ │ │ │ [8,5,2] │ │ └────────────────────────────┘ │ │ │ ▼ │ shared_weights: [2] │ │ │ ▼ │ ┌─────────────────────────────┐ │ │ 共享加权求和: │ │ │ [1,1,2] × [8,5,2] = [8,5,2] │ │ │ sum(dim=2) → [8,5] │ │ └─────────────────────────────┘ │ │ │ ▼ │ shared_result: [8,5] │ │ └──────┬───────┘ ▼ ┌─────────────────────────┐ │ 最终输出 = routed + shared │ │ [8,5] + [8,5] = [8,5] │ └─────────────────────────┘ │ ▼ ════════════════════════════ 最终输出: [8, 5] ════════════════════════════ """