当前位置: 首页 > news >正文

大模型设计

目录

  • 1. pre-norm还是post-norm
  • 2. LayerNorm还是RMSNorm
  • 3. SwiGLU
    • 4. RoPE
  • 4. FFN层放大倍数
    • 5. 网络层数和宽度设置
  • 6. 词表大小
  • 7. 正则化
  • 8. softcap与训练稳定性问题
  • 9. 注意力的变种
  • 10. 超长上下文
  • 11. MOE (mixture of experts)
  • 12. DeepSeek 的MOE
  • 13. Expert的选择不均匀怎么办
    • 13.1 MoE初始化
  • 14. 数据处理
    • 14.1 去重
    • 14.2 数据过滤
  • 15 Post-training
    • 14.1 FLAN数据集
    • 14.2 Alpaca
    • 14.3 OpenAssistant
  • 15. 模型幻觉

1. pre-norm还是post-norm

一般我们把norm操作放到支路里, 让模型能够有shortcut从第一层直达最后一层, 这样能保持训练的稳定性。
在这里插入图片描述
在这里插入图片描述

发现doublenorm效果更好
在这里插入图片描述

2. LayerNorm还是RMSNorm

实验发现减去均值没必要, 因此只需要除以方差, 然后用γ\gammaγ缩放即可:
在这里插入图片描述
减均值虽然计算量不大, 但是对时间影响大。因为GPU很大一部分时间是消耗在数据从HBM运送到DRAM计算里面, 因此去掉均值部分能够优化时间:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
现代的Transformer基本都去掉了bias, 主要是内存, 时间效率和训练稳定性:
在这里插入图片描述
在这里插入图片描述

3. SwiGLU

在这里插入图片描述
在这里插入图片描述

4. RoPE

我们希望不同的位置有相对位置不变性:
在这里插入图片描述
在这里插入图片描述
内积运算不受相对位置影响, 仅与位置间距有关。

二维空间的旋转非常直观, 但是高维空间怎么旋转?

最简单有效的办法就是将高维向量ddd切分成若干个2维的, 每2个维度都以角度θ\thetaθ进行旋转。然后某些二维pair旋转更快, 另外一些维度旋转更慢。这样既能获取高频信息, 也能获取邻近信息, 以及遥远的低频信息。
在这里插入图片描述
这里的旋转位置编码是不可学习的, 是固定值。θ\thetaθ不同, 捕捉的频率也不同。实际运算时, 用旋转位置编码乘以key和query即可。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
然后我们计算attention的时候:
Q′@K′T=Q@Rq@(K@Rk)T=Q@(Rq@RkT)@KT=Q@Rm−n@TQ'@K'^T = Q@R_q @ (K@R_k)^T = Q@(R_q@R_k^T)@K^T=Q@R_{m-n}@T Q@KT=Q@Rq@(K@Rk)T=Q@(Rq@RkT)@KT=Q@Rmn@T

这里的θ\thetaθ不决定旋转角度, 只是用于不同的频率(frequency)范围。

RoPE支持上下文窗口的扩展, 效果好, 成为标配。

def precompute_freqs_cis(dim: int, end: int, theta: float = 10000.0):""" Precomputing the frequency tensor with complex exponentials for the given sequence length and dimensions"""freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim))t = torch.arange(end, device=freqs.device, dtype=torch.float32)freqs = torch.outer(t, freqs).float() freqs_cos = torch.cos(freqs)freqs_sin = torch.sin(freqs)return freqs_cos, freqs_sindef reshape_for_broadcast(freqs_cis: torch.Tensor, x: torch.Tensor):ndim = x.ndimassert 0 <= 1 < ndimassert freqs_cis.shape == (x.shape[1], x.shape[-1])shape = [d if i == 1 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)]return freqs_cis.view(shape)def apply_rotary_emb(xq: torch.Tensor,xk: torch.Tensor,freqs_cos: torch.Tensor,freqs_sin: torch.Tensor
) -> Tuple[torch.Tensor, torch.Tensor]:""" Applying rotary position embeddings to input tensors using the given frequency tensor"""# reshape xq and xk to match the complex representationxq_r, xq_i = xq.float().reshape(xq.shape[:-1] + (-1, 2)).unbind(-1)xk_r, xk_i = xk.float().reshape(xk.shape[:-1] + (-1, 2)).unbind(-1)# reshape freqs_cos and freqs_sin for broadcastingfreqs_cos = reshape_for_broadcast(freqs_cos, xq_r)freqs_sin = reshape_for_broadcast(freqs_sin, xq_r)# apply rotation using real numbersxq_out_r = xq_r * freqs_cos - xq_i * freqs_sinxq_out_i = xq_r * freqs_sin + xq_i * freqs_cosxk_out_r = xk_r * freqs_cos - xk_i * freqs_sinxk_out_i = xk_r * freqs_sin + xk_i * freqs_cos# flatten last two dimensionsxq_out = torch.stack([xq_out_r, xq_out_i], dim=-1).flatten(3)xk_out = torch.stack([xk_out_r, xk_out_i], dim=-1).flatten(3)return xq_out.type_as(xq), xk_out.type_as(xk)freqs_cos, freqs_sin = precompute_freqs_cis(params.dim // params.n_heads, params.max_seq_len, params.rope_theta)
self.register_buffer("freqs_cos", freqs_cos, persistent=False)
self.register_buffer("freqs_sin", freqs_sin, persistent=False)freqs_cos = self.freqs_cos[:seqlen]
freqs_sin = self.freqs_sin[:seqlen]xq, xk = apply_rotary_emb(xq, xk, freqs_cos, freqs_sin)

4. FFN层放大倍数

在这里插入图片描述
采用GLU可以设置为2.66

5. 网络层数和宽度设置

在这里插入图片描述
在这里插入图片描述

6. 词表大小

大的词表处理能力更强, 例如支持多语言。
在这里插入图片描述

7. 正则化

预训练不需要正则化。因为训练数据远远大于参数量, 不会过拟合。
预训练只会走1个epoch, 因为数据量太大。
在这里插入图片描述

Dropout不太用了, 但是weight_decay (L2) 仍然在用。但是weight_decay不是在避免过拟合了, 而是通过优化训练损失来提升性能。在cosine_schedule的时候对learning_rate有影响。
在这里插入图片描述

8. softcap与训练稳定性问题

Softmax里面因为有指数操作, 会导致训练不稳定的问题, 需要特别注意。
trick:
在这里插入图片描述
在这里插入图片描述

9. 注意力的变种

MQA和GQA等, 对训练阶段影像不大, 但是对推理阶段模型的cost和behavior影响很大。
在这里插入图片描述
在这里插入图片描述
多个head之间共享key, value, 减少访存。

GQA在两者实现折中:
在这里插入图片描述

10. 超长上下文

采用sliding window:
在这里插入图片描述

11. MOE (mixture of experts)

更多的参数, 但是不增加FLOPs在这里插入图片描述
FLOPs相同的时候, 参数越多效果越好。
MOE训练起来更快:

在这里插入图片描述

MOE中好的routing是关键。MOE让基础设置变得非常复杂。而且如果学习routing策略非常困难。早期的文章发现性价比不高。

routing策略不可导。早起用强化学习来决定routing策略, 但是计算量太高, 训练太不稳定。
在这里插入图片描述
在这里插入图片描述

12. DeepSeek 的MOE

维度小一点, 但是MoE数量多一点更好。
在这里插入图片描述
DeepSeek进一步添加了一个shared Expert.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
添加噪声扰动:
在这里插入图片描述
噪声扰动: 没有针对性, 效率低下。效果不好:
在这里插入图片描述

13. Expert的选择不均匀怎么办

在这里插入图片描述
其实就是对每个expertiexpert_iexperti, 实际的token分配到的比例fif_ifi, 乘以总的概率PiP_iPi, 其中fif_ifi是离散得到的。

例如有5个token, 3个experts, 分配为:
token1 → [0.7, 0.2, 0.1]
token2 → [0.8, 0.1, 0.1]
token3 → [0.2, 0.6, 0.2]
token4 → [0.3, 0.3, 0.4]
token5 → [0.9, 0.05, 0.05]

loss1=35×2.95loss_1=\frac{3}{5} \times \frac{2.9}{5}loss1=53×52.9
loss2=15×1.255loss_2=\frac{1}{5} \times \frac{1.25}{5}loss2=51×51.25
loss3=15×0.855loss_3=\frac{1}{5} \times \frac{0.85}{5}loss3=51×50.85

loss=0.432loss=0.432loss=0.432

加入都分配给1个expert:
token1 → [1.0, 0.0, 0.0]
token2 → [1.0, 0.0, 0.0]
token3 → [1.0, 0.0, 0.0]
token4 → [1.0, 0.0, 0.0]
token5 → [1.0, 0.0, 0.0]

loss=55=1loss=\frac{5}{5}=1loss=55=1, 因此分配越均匀, loss越小。
这种loss就会压制expert1的概率:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
就是more frequently used, stronger down-weighting.

DeepSeek进一步改进, 让不同在这里插入图片描述
devices之间更加均衡:

另外MoE也能增加GPT模型的随机性, 让模型多样性更强。
在这里插入图片描述

13.1 MoE初始化

用预训练好的Dense FFN+随机噪声初始化MoE
在这里插入图片描述

14. 数据处理

14.1 去重

去重更多的是在pretraining阶段, 例如使用Bloom或者minihash算法去重。

但是在post-training阶段, 对于一些高质量得数据, 尽管出现多次, 但是我们仍然想要多次使用。因此这种去重在post-training阶段不一定合理。

14.2 数据过滤

一般用N-gram, 然后训练分类器, 过滤掉低质量数据。

15 Post-training

GPT-3经过海量的互联网数据, 通过next token prediction训练之后, 其实没什么用。因为它无法遵循特定指令。因此后训练才是使得模型变得能遵循指令的有用系统的关键。

后训练是数据尤其重要的一环。因为你希望使用少量数据获得你希望的指令模型。如果有嘈杂的指令微调数据, 模型就会产生奇怪的行为。

后训练阶段, 我们需要去收集各种行为的数据。
在这里插入图片描述

14.1 FLAN数据集

在这里插入图片描述

14.2 Alpaca

在这里插入图片描述

14.3 OpenAssistant

在这里插入图片描述
在这里插入图片描述

15. 模型幻觉

后训练阶段的数据如果超出了模型pre-training阶段达到的能力, 可能会让模型去做一些它根本做不到的事情。如果模型在预训练阶段没有接触到相关数据, 那模型可能就会迫使模型"一本正经的胡说八道"。

http://www.dtcms.com/a/313623.html

相关文章:

  • 学习方法论
  • 智能化设备维护:开启高效运维新时代
  • 前端异步任务处理总结
  • Maven - 依赖的生命周期详解
  • 服务端技术栈分类总结
  • 模型预估打分对运筹跟踪的影响
  • 数据结构:单向链表的函数创建
  • [硬件电路-141]:模拟电路 - 源电路,信号源与电源,能自己产生确定性波形的电路。
  • 高质量数据集|大模型技术正从根本上改变传统数据工程的工作模式
  • RapidIO/SRIO 入门之什么是SRIO
  • 环绕字符串中的唯一子字符串-动态规划
  • [2025ICCV-目标检测方向]DuET:通过无示例任务算术进行双增量对象检测
  • 1.内核模块
  • C语言基础03——数组——习题
  • 工作笔记-----IAP的相关内容
  • 8大图床高速稳定网站,值得长期选用
  • 【最长公共前缀】
  • DMDRS产品概述和安装部署
  • Kaggle 竞赛入门指南
  • Pygame如何制作小游戏
  • vllm0.8.5:自定义聊天模板qwen_nonthinking.jinja,从根本上避免模型输出<think>标签
  • Docker环境离线安装指南
  • C++与Go的匿名函数编程区别对比
  • SPI入门(基于ESP-IDF-v5.4.1)
  • accept4系统调用及示例
  • ELECTRICAL靶场
  • 检索召回率优化探究三:基于LangChain0.3集成Milvu2.5向量数据库构建的智能问答系统
  • 思途JSP学习 0802(项目完整流程)
  • Fay数字人如何使用GPT-SOVITS进行TTS转换以及遇到的一些问题
  • 写作路上的迷茫与突破