LLM基础知识备忘录

预训练相关

LearningRate和BatchSize之间的关系

假设batch_size足够小,等于1,如果lr设的比较大则容易导致loss发散;假设batch_size足够大,等于全量的数据,如果这个时候lr设的小则收敛会很慢。所以理论上来说,batch_size和模型参数增大,较小的lr并不是说不收敛,而是可能需要更多的steps才能收敛,因此需要适当增大lr。

关于位置编码

  • sinusoidal位置编码

考虑两个位置 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i 和 <math xmlns="http://www.w3.org/1998/Math/MathML"> j j </math>j,由于正弦和余弦函数的性质,位置编码的差值 <math xmlns="http://www.w3.org/1998/Math/MathML"> PE ( i ) − PE ( j ) \text{PE}(i) - \text{PE}(j) </math>PE(i)−PE(j)将与 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i和 <math xmlns="http://www.w3.org/1998/Math/MathML"> j j </math>j之间的差值有关。这意味着通过比较不同位置编码之间的差值,模型可以推断出它们之间的相对位置。

  • ROPE相对位置编码

  • ALiBi位置编码

Pre-Norm和Post-Norm的差异和优劣

DeepSeek要点

  • 学习率细节 :2000个warmup steps之后达到最大值,在80%的tokens之后学习率下降到最大值的31.6%,90%的tokens之后下降到最大值的10%。 最终模型表现上,multi-step schedulercosine scheduler基本保持一致;而multi-step的优势是,在保持模型大小固定调整训练规模时,可以重用第一阶段训练的结果,这比较方便后续的 继续训练

  • 梯度的grad clip设为1.0

  • 分布式策略

    • 数据并行、张量并行、序列并行、1F1B的流水线并行
    • flash attention
    • ZeRO-1用于根据数据并行排列划分优化器状态
    • 模型参数的精度为bf16,梯度的精度为fp32
  • 模型权重和优化器状态每5分钟同步,并且逐步清除之前保存的ckpt

  • Scaling Law

    • 数据质量越高,越可以将更多的计算预算分配给模型规模
    • 随着模型计算量的增大(即模型规模增大),最优的batch_size也在增大,最优的learning_rate呈现减小的趋势
  • Alignment:收集了150w中英文instruction数据,其中helpful数据有120w,31.2%是通用语言任务,46.6%是数学问题,22.2%是代码问题;安全数据有300K条,包含不同的敏感话题

    • 有监督微调SFT
      • 7B模型微调了4个epoch,67B模型只微调2个epoch,学习率分别是1e-55e-6
      • 微调过程中,除了观察benchmark的准确率,还会评估chat模型的重复率,收集了3868条中英文prompts,观测生成回复没有终止或者无休止重复一段文本的比例。发现随着数学SFT数据的增多 ,重复的概率也倾向于增大;主要原因应该是数学SFT数据较少包含相似的推理模式,弱模型较难获取这样的推理模式,导致重复的回复,为此设计了两阶段微调和DPO,保持benchmark恩叔的同时大大降低重复repetition
    • DPO :就helpfulness和harmlessness两方面构建训练DPO的偏好数据。对于helpfulness数据,收集多语言prompts,包含创新写作、问答、指令跟随等,使用DeepSeek Chat模型生成回复候选;对于harmlessness数据也进行相似的操作。
      • 训练1个epoch、learning_rate=5e-6batch_size=512,使用learning rate warmup和cosine learning rate scheduler
      • 我们发现DPO能够强化模型开发侧生成技能,而在标准benchmark的表现一般
  • 一些发现

    • Staged Fine-Tuning :在数学和代码数据集上,下模型需要更长微调时间,但是会损害模型对话的能力(比如增加重复的概率)。因此本文采用了分阶段微调:
      • 第一阶段采用全量数据未提哦啊
      • 第二阶段主要关注在对话数据上微调
    • 多项选择问题 :对齐阶段加入多项选择数据,能够改善在多项选择评估任务上的效果,但是对于其他生成式任务没有明显改善(也没有下降)。因此在预训练和微调阶段,我们移除了MC数据,因为这些数据容易导致模型过拟合,却不会强化模型的智能性
    • 预训练中加入指令数据:在预训练最后10%过程加入500w条多项选择的指令数据,表明确实能强化base模型在benchmark上的效果。但是实验发现,其实在SFT阶段加入同样的数据结果是一致的。因此,我们认为==模型整体的潜力并不会因为在预训练过程加入指令数据而得到强化==。不过,如果指令数据规模够大,确实可以考虑在预训练过程中加入。而本文选择预训练过程不加入指令数据。
    • System Prompt :精心设计的system prompt能够有效指导模型生成helpful和respectful的结果。
      • 当引入system prompt时,7B LLM性能有一点下降,而67B的LLM性能有比较显著提升。我们认为更大的模型能够更好地理解system prompt的意图,从而更好地遵循指令、得到更好的回复。小模型很难充分掌握system prompt,同时训练和测试的不一致对性能产生了负面影响。
  • 核心贡献

    • 矫正了之前工作中scaling laws的问题,提供新的最优的模型-数据规模分配策略
    • 提出了一种新的方法,基于给定的预算budget来预测接近最优的batch sizelearning rate
    • 总结了scaling laws和数据质量的关系

关于MoE

Mixtral要点

  • Mixtral的每一层包含8个FFN块。对于每一层的每一个token,router网络选择两个experts处理当前状态,并将他们的输出进行组合。尽管每个token只使用了两个experts,但是每一个timestamp选择的expert是不同的,因此每一个token可以访问47B的参数,但是推理时只使用13B激活的参数。

  • 对于给定的输入 <math xmlns="http://www.w3.org/1998/Math/MathML"> x x </math>x,MoE模块的输出是expert网络输出的加权和,这里的权重是由门网络输出,假设有 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n个expert网路 <math xmlns="http://www.w3.org/1998/Math/MathML"> { E 0 , E i , ⋯   , E n − 1 } \{E_0, E_i, \cdots, E_{n-1}\} </math>{E0,Ei,⋯,En−1},专家层的输出为:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> ∑ i = 0 n − 1 G ( x ) i ⋅ E i ( x ) \sum_{i=0}^{n-1} G(x)_i \cdot E_i(x) </math>i=0∑n−1G(x)i⋅Ei(x)

这里门网络 <math xmlns="http://www.w3.org/1998/Math/MathML"> G ( x ) G(x) </math>G(x)有多种实现方式,一种简单且有效的方式就是记忆线性输出的Top-K的logits进行softmax
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> G ( x ) : = Softmax ( TopK ( x ⋅ W g ) ) G(x) := \text{Softmax}(\text{TopK}(x \cdot W_g)) </math>G(x):=Softmax(TopK(x⋅Wg))

这里,如果 <math xmlns="http://www.w3.org/1998/Math/MathML"> l i l_i </math>li存在于logits的topK位置,则 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( TopK ( l ) ) i : = l i (\text{TopK}(l))_i := l_i </math>(TopK(l))i:=li,否则 <math xmlns="http://www.w3.org/1998/Math/MathML"> ( TopK ( l ) ) i = − ∞ (\text{TopK}(l))_i = - \infty </math>(TopK(l))i=−∞。这里的 <math xmlns="http://www.w3.org/1998/Math/MathML"> K K </math>K表示每个token使用的experts的数量,是一个可以自定义的超参数。

  • 如果增加专家的数量 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n同时保持 <math xmlns="http://www.w3.org/1998/Math/MathML"> K K </math>K固定,则可以在增加模型参数的同时保持计算开销固定。模型的参数随着专家数 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n的增加而增加,处理一个单独token的参数数量随着 <math xmlns="http://www.w3.org/1998/Math/MathML"> K K </math>K的增加而增加,最大为 <math xmlns="http://www.w3.org/1998/Math/MathML"> n n </math>n

  • MoE层在硬件上的前向:

    • 可以通过高性能专门的内核,在单个GPU上有效运行,如Megablocks
    • 也可以通过Expert Parallelism(EP)策略分配到多个GPU上。当MoE层执行时,tokens通过一个路由到对应GPU的专家进行处理,然后专家的输出返回到原始的token位置。

在Transformer模型中,MoE层在每一个token上单独应用,替换transformer block中的FFN子块。对于Mixtral我们使用相同的SwiGLU结构,对应专家函数为 <math xmlns="http://www.w3.org/1998/Math/MathML"> E i ( x ) E_i(x) </math>Ei(x)并设置 <math xmlns="http://www.w3.org/1998/Math/MathML"> K = 2 K=2 </math>K=2。这意味着每一个token路由到2个不同权重集合的SwiGLU子块,因此对于输入token <math xmlns="http://www.w3.org/1998/Math/MathML"> x x </math>x的输出 <math xmlns="http://www.w3.org/1998/Math/MathML"> y y </math>y为:
<math xmlns="http://www.w3.org/1998/Math/MathML" display="block"> y = ∑ i = 0 n − 1 Softmax ( Top2 ( x ⋅ W g ) ) i ⋅ SwiGLU ( x ) y = \sum_{i=0}^{n-1} \text{Softmax}(\text{Top2}(x \cdot W_g))_i \cdot \text{SwiGLU}(x) </math>y=i=0∑n−1Softmax(Top2(x⋅Wg))i⋅SwiGLU(x)

这个公式和GShard结构比较相似,只不过我们通过MoE层替换了所有FFN子块,而GShard替换了其他块,而且GShard对于每一个token的第二个专家采用了更加复杂的门控策略。

DeepSeekMoE要点

  • 两个核心原则:

    • Fine-grained Expert Segmentation:细地将专家划分为 <math xmlns="http://www.w3.org/1998/Math/MathML"> m N mN </math>mN个,激活其中的 <math xmlns="http://www.w3.org/1998/Math/MathML"> m K mK </math>mK个,实现激活的专家更灵活的组合
    • Shared Expert Isolation:将 <math xmlns="http://www.w3.org/1998/Math/MathML"> K s K_s </math>Ks单独看做共享专家,用于捕获常识以及缓解路由专家中的冗余知识
  • 经典的将FFN替换为MoE层的方式如下:

    • <math xmlns="http://www.w3.org/1998/Math/MathML"> N N </math>N表示专家的数量
    • <math xmlns="http://www.w3.org/1998/Math/MathML"> FFN i ( ⋅ ) \text{FFN}_i(\cdot) </math>FFNi(⋅) 表示第 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i个专家FFN
    • <math xmlns="http://www.w3.org/1998/Math/MathML"> g i , t g_{i, t} </math>gi,t表示第 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i个专家的gate value, <math xmlns="http://www.w3.org/1998/Math/MathML"> s i , t s_{i, t} </math>si,t表示token-to-expert亲近度
    • <math xmlns="http://www.w3.org/1998/Math/MathML"> Topk ( ⋅ , K ) \text{Topk}(\cdot, K) </math>Topk(⋅,K)表示第 <math xmlns="http://www.w3.org/1998/Math/MathML"> t t </math>t个token和所有 <math xmlns="http://www.w3.org/1998/Math/MathML"> N N </math>N个专家计算得到的 <math xmlns="http://www.w3.org/1998/Math/MathML"> K K </math>K个最高的亲近度分数
    • <math xmlns="http://www.w3.org/1998/Math/MathML"> e i l \mathbf{e}_i^l </math>eil表示第 <math xmlns="http://www.w3.org/1998/Math/MathML"> l l </math>l层的第 <math xmlns="http://www.w3.org/1998/Math/MathML"> i i </math>i个专家中心centroid
  • DeepSeekMoE的结构
    • 对于传统MoE中每一个专家FFN,将FFN中间隐层维度降低到原大小的 <math xmlns="http://www.w3.org/1998/Math/MathML"> 1 m \frac{1}{m} </math>m1,将一个专家划分成 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m个更小的专家
    • 由于每一个专家变得更小了,相应地我们将激活的专家的数量增大到 <math xmlns="http://www.w3.org/1998/Math/MathML"> m m </math>m倍来保持相同的计算开销
    • 将专家 <math xmlns="http://www.w3.org/1998/Math/MathML"> K s K_s </math>Ks看做共享专家独立看待,无论路由模块如何,每一个token会确定性地分配到这些共享的专家上。为了保持计算开销一致,其他路由专家的激活数量需要减去 <math xmlns="http://www.w3.org/1998/Math/MathML"> K s K_s </math>Ks。

  • Load Balance Consideration:训练时如果模型总是选择部分experts,其他experts就无法得到充分训练;如果专家分布在不同的devices上,负载不均衡就会成为计算瓶颈
    • Expert-Level Balance Loss:为了缓解路由崩塌的风险,我们采用了expert-level balance loss
    • Device-Level Balance Loss:我们的珠海要目标是保证不同设备均衡计算,如果我们将所有的路由专家分成 <math xmlns="http://www.w3.org/1998/Math/MathML"> D D </math>D组 <math xmlns="http://www.w3.org/1998/Math/MathML"> { E 1 , E 2 , ⋯   , E D } \{ \mathcal{E}_1, \mathcal{E}_2, \cdots, \mathcal{E}_D \} </math>{E1,E2,⋯,ED},将每一组部署到一个单独的device,那么device-level的均衡损失为:
  • 实验设置
    • 9层Transformer层,hidden_dim=1280, num_heads=10, head_dim=128。将所有FFN层替换为MoE层,保证专家参数总数等于标准FFN的16倍
    • 保证激活的专家参数,包括共享专家参数和激活的路由专家参数,是标准FFN的2倍
    • 这样每个MoE模型总参数量为2B,激活的参数约为0.3B

对齐

Reward模型的损失函数

python 复制代码
logits = 1 + torch.exp(rejected_reward - chosen_reward)

loss = torch.log(logits).mean()

Reward模型的输入和输出

python 复制代码
# <s> prompt response </s>

分布式相关

DeepSpeed和Megatron之间的差异


部署相关

常用的部署方式有哪些

vLLM

github.com/vllm-projec...

shell 复制代码
python -m vllm.entrypoints.openai.api_server --served-model-name Qwen1.5-7B-Chat --model Qwen/Qwen1.5-7B-Chat 
shell 复制代码
curl http://localhost:8000/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "Qwen1.5-7B-Chat",
"messages": [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Tell me something about large language models."}
]
}'
python 复制代码
from openai import OpenAI
# Set OpenAI's API key and API base to use vLLM's API server.
openai_api_key = "EMPTY"
openai_api_base = "http://localhost:8000/v1"

client = OpenAI(
api_key=openai_api_key,
base_url=openai_api_base,
)

chat_response = client.chat.completions.create(
model="Qwen1.5-7B-Chat",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Tell me something about large language models."},
]
)
print("Chat response:", chat_response)

SGLang

github.com/sgl-project...

shell 复制代码
python -m sglang.launch_server --model-path Qwen/Qwen1.5-7B-Chat --port 30000
python 复制代码
from sglang import function, system, user, assistant, gen, set_default_backend, RuntimeEndpoint

@function
def multi_turn_question(s, question_1, question_2):
s += system("You are a helpful assistant.")
s += user(question_1)
s += assistant(gen("answer_1", max_tokens=256))
s += user(question_2)
s += assistant(gen("answer_2", max_tokens=256))

set_default_backend(RuntimeEndpoint("http://localhost:30000"))

state = multi_turn_question.run(
question_1="What is the capital of China?",
question_2="List two local attractions.",
)

for m in state.messages():
print(m["role"], ":", m["content"])

print(state["answer_1"])

FastChat

github.com/lm-sys/Fast...

shell 复制代码
# For Chinese users, you can use models from www.modelscope.cn via specify the following environment variables.
# export FASTCHAT_USE_MODELSCOPE=True
python3 -m fastchat.serve.model_worker --model-path lmsys/vicuna-7b-v1.5

参考

相关推荐
字节跳动开源2 天前
最高提升20倍吞吐量!豆包大模型团队发布全新 RLHF 框架,现已开源!
开源·llm·强化学习
kida_yuan2 天前
【从零开始】6. RAG 应用性能压测工具(番外篇)
后端·llm·测试
真忒修斯之船2 天前
大模型分布式训练并行技术(四)张量并行
面试·llm·aigc
Code_Artist2 天前
Spring AI: Make Spring Great Again!设计并实现一款智能Chat Bot!
后端·llm·openai
知来者逆3 天前
Gen-RecSys——一个通过生成和大规模语言模型发展起来的推荐系统
人工智能·gpt·语言模型·自然语言处理·llm·推荐算法·多模态
暮暮七3 天前
小语言模型介绍与LLM的比较
人工智能·语言模型·自然语言处理·llm·aigc·slm
真忒修斯之船4 天前
大模型分布式训练并行技术(三)流水线并行
面试·llm·aigc
SpikeKing5 天前
LLM - 使用 LLaMA-Factory 微调大模型 环境配置与训练推理 教程 (1)
人工智能·llm·大语言模型·llama·环境配置·llamafactory·训练框架
数据智能老司机5 天前
LLM工程师手册——监督微调
深度学习·架构·llm
AI_小站6 天前
LLM——10个大型语言模型(LLM)常见面试题以及答案解析
人工智能·程序人生·语言模型·自然语言处理·大模型·llm·大模型面试