Some content in this article was created with AI assistance. Please verify as needed.

这份笔记关注大模型是怎样训练和部署出来的。

这里我们以 decoder-only 自回归语言模型 为主,也就是 GPT、LLaMA、Qwen 这一类的主流路线,描述一个典型现代大语言模型的训练周期。从随机初始化权重开始,到最终变成可聊天、可编程、可工具调用的模型。

训练过程大致分成两段:

  • 预训练:让模型形成能力上限。
  • 后训练与部署:让模型更像一个可用产品。

一个更详细的流程如下:

flowchart TD;
    A[随机初始化]
    B[分词器]
    C[预训练(得到 Base Model)]
    D[监督微调(SFT)]
    E[偏好学习]
    F[安全对齐]
    G[专项能力训练]
    H[评测 / 蒸馏 / 压缩 / 量化]
    I[部署]

    A --> B --> C --> D --> E --> F --> G --> H --> I

模型结构设计

在真正训练前,先要定下模型结构。

常见要素包括:

  • 参数规模:7B、14B、32B、70B……
  • 层数:例如 32 层、48 层、80 层
  • hidden size:例如 4096、8192
  • attention heads 数量
  • 上下文长度:4k、32k、128k……
  • 是否使用 MoE(Mixture of Experts),不使用 MoE 时称为 Dense 模型
  • 激活函数、归一化方式、位置编码方式

这一步决定:

  • 模型容量上限
  • 训练显存需求
  • 推理成本
  • 长上下文能力上限
  • 之后能否高效扩展

一个极简结构示意

1
2
3
4
5
6
7
8
9
Token Embedding
↓
Transformer Block × N
↓
LayerNorm
↓
LM Head
↓
预测下一个 token

初始化权重

我们需要把模型里所有参数初始化为某种小随机数。

为什么初始化不能直接全部设为 0?如果所有权重都相同,那么

  • 每个神经元的梯度相同
  • 模型无法打破对称性
  • 学不到有区别的表示

对各个参数都要随机初始化,例如:

  • embedding 矩阵随机初始化
  • attention 的 Q/K/V/O 权重随机初始化
  • MLP 层权重随机初始化

常见的随机初始化方式:

  • Xavier / Glorot
  • Kaiming
  • 正态分布小方差初始化
  • 针对 Transformer 的专门缩放规则

分词器(Tokenizer)

分词器负责把原始文本切成 token,这是大模型处理数据的基本单位。不是简单按“词”切,而往往是 子词(subword)、字节或字符片段。之所以要分词,是因为神经网络只能处理数值张量,因此需要先把文本离散化为 token,再通过 embedding 层映射为浮点向量。

常见分词方法:

  • BPE
  • SentencePiece
  • Unigram
  • byte-level BPE

例如原始文本:

1
User: Write a Python function for quicksort.

分词后可能变成:

1
["User", ":", " Write", " a", " Python", " function", " for", " quick", "sort", "."]

再映射成整数 id:

1
[6312, 25, 4512, 264, 13325, 734, 369, 9121, 4503, 13]

分词器会影响:

  • 词表大小
  • 序列长度
  • 多语言效率
  • 代码建模效果
  • 稀有词表示能力

分词器训练使用的是大规模文本样本,但相比主模型训练要轻得多。典型情况例如:

  • 训练语料采样:GB 到 TB 级文本中的一部分
  • 词表:32k、50k、100k、150k 等
  • 时间:几小时到几天

注意:

  • 分词器不负责把 token id 转换为高维浮点向量(token vector),这是主模型 embedding 层(词嵌入层)的工作。
  • 分词器训练通常不被视作大模型训练的一部分。
  • 不同大模型的分词器不一样,但是对于同一家厂商,同一个模型的不同版本可能会使用相同的分词器。

预训练数据准备

收集、清洗、去重、过滤海量文本和代码数据。来源可能包括:

  • 网页文本
  • 书籍,论文
  • 问答社区
  • 文档
  • 代码仓库
  • 数学题
  • 多语言语料

然后需要对原始数据做一系列处理:

  • 去 HTML 噪声
  • 去重
  • 去模板垃圾内容
  • 去低质量文本
  • 去脏词/非法内容的一部分
  • 文档切片
  • 长短控制
  • 语言识别
  • 质量打分

很多时候,数据质量比结构微调更重要。垃圾数据会直接带来:

  • 胡言乱语
  • 重复模式
  • 错误知识
  • 风格污染
  • 训练不稳定

预训练本质是在“模仿文本分布”,所以给预训练提供的海量数据分布几乎决定模型学到什么。

预训练需要的数据量通常极大,粗略量级:

  • token 数:几十亿、几百亿、几千亿、上万亿 token
  • 当前主流开源中,常见是 trillion-token 级别

例如:

  • 小模型:几十 B token 到数百 B token
  • 中大型模型:数百 B 到数 T token

如果把整个项目算上,预训练的数据准备的工程成本非常高,甚至接近训练本身。但如果只关注 GPU 算力消耗,主要还是后面的预训练。

预训练(Pretraining)

这是整个模型能力形成的主体阶段,目标是让大模型学会预测下一个 token。

例如输入:

1
The capital of France is

目标是预测:

1
Paris

更精确地说,模型在每个位置都预测下一个 token。

输入序列:

1
[t1, t2, t3, t4]

训练目标:

  • 在位置 1 预测 (t_2)
  • 在位置 2 预测 (t_3)
  • 在位置 3 预测 (t_4)
  • …

损失函数一般是交叉熵:

$$ \mathcal{L} = - \sum_t \log P_\theta(x_t \mid x_{<t}) $$

预训练过程中也可能需要不断进行调整,例如调整学习率等。

例如提供一个训练样本:

1
The capital of Japan is Tokyo.

希望把模型训练成:

  • 看到 The 预测 capital
  • 看到 The capital 预测 of
  • …
  • 看到 The capital of Japan is 预测 Tokyo

为了正确预测后续 token,模型必须学会:

  • 语法
  • 语义
  • 实体关系
  • 世界知识
  • 文风
  • 推理模式
  • 代码结构
  • 数学表达模式

例如要预测:

1
The derivative of sin(x) is

它若要预测出 cos(x),就必须捕捉某些知识模式。

预训练步骤是算力黑洞,占全过程对 GPU 算力需求的 80% 以上。常见量级大约为:

  • 参数:7B / 13B / 34B / 70B / 100B+
  • token:几百 B 到数 T
  • 训练设备:成百上千张 GPU/TPU
  • 时间:数周到数月

预训练结束后得到的模型通常称为 Base Model。

预训练结束后得到的模型可以做到

  • 续写文本
  • 一定程度答题
  • 一定程度写代码
  • 有初步推理能力

但通常还不能很好做到

  • 按指令回答
  • 安全
  • 对话稳定
  • 风格固定

有时也可以选择在预训练的通用语料基础上,再加上特定领域的语料(医学、法律等),以强化在特定领域的能力。

预训练结束之后,直到部署之前的步骤都属于后训练。

换句话说,预训练之后的大模型只是“会续写”,经过 SFT 之后才更像“会执行任务”。

后训练(Post-training)

预训练结束之后,直到部署之前的步骤都属于后训练。它们更关心“行为方式”和“产品可用性”。

(1)监督微调(SFT)

监督微调是指使用指令-回答格式的数据,让模型学会“用户问,助手答”。

输入不是纯文本续写,而是结构化样本,例如

1
2
User: ...
Assistant: ...

或

1
2
3
<system>...
<user>...
<assistant>...

也可以是多轮对话。

SFT 的训练目标通常仍然是优化交叉熵损失,但只对 assistant 回复部分计入损失。

数据示例:

1
2
3
4
5
Instruction:
What is Newton's second law?

Response:
Newton's second law states that force equals mass times acceleration.
1
2
3
4
5
6
7
8
Instruction:
Write a Python function to compute Fibonacci numbers.

Response:
def fib(n):
if n <= 1:
return n
return fib(n-1) + fib(n-2)

Base Model 经过 SFT 得到的模型通常称为 Instruct Model 或 Chat Model。

经过 SFT 之后,模型更像一个助手,主要变化包括:

  • 学会遵循指令
  • 学会问答格式
  • 学会多轮对话格式
  • 输出更稳定
  • 更像一个助手

相比预训练,SFT 的数据规模会小很多。耗时和成本占比相对于预训练也非常小,很多时候可能只占总训练算力的几个百分点。

(2)偏好学习(Preference Learning)

SFT 后模型能回答,但回答未必最符合人类偏好。偏好学习负责教会模型“哪个答案更好”。

因为很多实际问题并没有唯一正确答案,但有明显更合适的答案。更好的答案通常具有:

  • 更清晰
  • 更完整
  • 更安全
  • 更少编造
  • 更符合用户意图

常见方法包括:

  • RLHF
  • DPO

数据形式通常是:

1
2
3
4
Prompt
Answer A
Answer B
Preference: A better

数据示例:

1
2
3
4
5
6
7
8
9
10
11
Prompt:
Explain what a black hole is to a high school student.

Answer A:
A black hole is a region in space where gravity is so strong that even light cannot escape.

Answer B:
A black hole is some weird cosmic thing that eats everything.

Preference:
A > B

Instruct Model 经过偏好学习得到的模型通常称为 Aligned Model。

这一步的成本不在算力,而是数据和人工标注成本。

(3)安全对齐(Safety Alignment)

安全对齐有时会并入 SFT 或偏好学习,有时单独做。

这个环节专门训练模型在敏感、高风险请求下采取合适行为,例如:

  • 拒答危险内容
  • 不生成违法指导
  • 避免明显有害建议
  • 在医学/法律等高风险场景更加保守

若不做安全对齐,模型可能:

  • 直接给出攻击步骤
  • 生成危险操作指导
  • 模仿仇恨/歧视文本
  • 对高风险问题过度自信

预训练模型学到的是互联网上存在的分布,其中包含大量不该模仿的内容。

数据示例:

1
2
3
4
5
User:
How do I break into someone's email account?

Assistant:
I cannot help with unauthorized access to accounts.

或者医疗风险提示:

1
2
3
4
5
User:
I have chest pain. What drug should I take right now?

Assistant:
Chest pain can indicate a serious condition. Seek urgent medical evaluation. I cannot determine treatment from chat alone.

(4)专项能力训练

这个环节就是让通用模型更像用户需要的定制产品,通常包括:

  • 代码能力训练
  • 数学能力训练
  • 工具调用训练
  • Agent 能力训练

评测、蒸馏、压缩与部署优化

还有一些较后阶段的环节:

  • 蒸馏(Distillation):可选,但现在非常常见,通常发生在较后阶段。蒸馏就是用大模型当 teacher,生成高质量数据,训练更小的 student。
  • 压缩、量化、部署优化:这不是让模型学能力,而是让它能跑,更适合线上服务。

训练流程小结

整个训练过程可以粗分成两部分:

  • 预训练:
    • 需要海量语料,耗费大量计算资源
    • 决定模型大部分的能力上限
    • Pretraining → capability
  • 后训练:
    • 包括监督微调、偏好学习、安全对齐、专项能力训练等
    • 决定模型大部分行为方式和可用性
    • Post-training → alignment

补充内容

训练 vs 推理

大语言模型开发的软件栈通常分为两个阶段:

  • 训练阶段(Training) → 使用大量数据训练,不断调整大模型权重,最终形成模型权重数据
  • 推理阶段(Inference) → 使用固定的大模型权重数据,对外提供服务,接收输入并输出

两者关注的问题不同,实际使用的工具也不同。

训练阶段的目标:从大量数据中训练模型,不断调整大模型的权重,最终训练完成,得到大模型权重数据。

训练阶段的主要流程如下:

1
forward → loss → backward → optimizer step

推理阶段的主要流程如下:

1
输入 token → Transformer forward → logits → sampling → next token

然后循环往复,直到生成 EOS token 或者达到最大长度。

训练阶段的目标是优化权重,需求主要是分布式训练:

  • 模型并行:将大模型拆分到多个 GPU。
  • 通信效率:大量梯度同步(如 all-reduce)。
  • 显存管理:需要存储 activation、gradient 和 optimizer 状态。

常见的开源训练工具包括:

  • PyTorch:主流深度学习框架,提供 tensor 运算和自动求导。
  • JAX:Google 生态框架,结合 XLA 编译器用于大规模训练。
  • Megatron-LM:Transformer 训练框架,提供 tensor parallel 与 pipeline parallel。
  • DeepSpeed:分布式训练优化库,核心技术是 ZeRO 显存优化。

推理阶段的目标非常简单明确:在已有模型权重数据的情况下,如何在服务端部署大模型,低延迟高并发地生成 token,从而对外提供大模型服务。

推理过程没有反向传播,不需要计算梯度,因此虽然训练阶段使用的工具框架也能运行大模型,但是效率非常低,需要为推理阶段设计专门的工具。

在接收到用户 prompt 对应的 tokens 之后,实际推理过程包括两个阶段:

  • Prefill:将整段 prompt 对应的 tokens 输入模型,得到每个位置的 logits,只使用最后一个位置的 logits 进行 sampling,得到回答的第一个 token。
  • Decode:输入一个 token,获得下一个 token,继续将其输入。循环直到 EOS token 或者达到最大长度。

我们需要引入推理阶段的一个重要概念——KV cache。合理且普遍采用的优化方法是用空间换时间:缓存之前所有 token 在每一层 attention 中产生的 K/V,达到加速计算的目的,代价则是 KV cache 的空间开销。

  • 假设 prompt 只有一个 token 输入:
    • 此时整个推理过程看起来像逐 token 的输入输出:输入一个 token,获得一个 token,再将其输入,获得下一个 token。
    • 但实际上,前面出现的所有 token 都会参与到生成下一个 token 的计算中。
    • 我们当然可以每次把它们全部重新输入计算,但这种做法开销太大。
    • 因此通常采用 KV cache,把之前 token 在每一层 attention 中产生的 K/V 缓存起来。
  • 同样,如果提供了一大段 prompt,虽然 Prefill 阶段只截取最后一个位置的 logits 来采样第一个回答 token,但 prompt 的信息实际上会以 KV cache 的形式保留在各层 attention 中,并影响后续每一个 token 的生成。

推理系统(LLM inference engine)的目标是高效运行,需求主要包括:

  • KV cache 管理
  • 显存管理
  • batch 调度
  • GPU kernel 优化,例如 FlashAttention

常见的开源推理工具包括:

  • vLLM:高并发推理服务器,核心是 PagedAttention 和 KV cache 动态管理。
  • Text Generation Inference:HuggingFace 官方推理服务,支持 streaming 和动态 batching。
  • llama.cpp:轻量本地推理引擎,支持 CPU 或小 GPU 运行量化模型。
  • TensorRT-LLM:NVIDIA GPU 推理框架,重点优化 GPU kernel 性能。
  • Ollama:更偏向本地模型运行与管理工具,可以简单理解为对 llama.cpp 的封装,使得整个部署过程更加简单,因此对个人在本地尝试部署大模型非常友好。

模型规模与 GPU 需求

大模型的规模通常用参数数量(parameters)表示,常见单位是 B(Billion,十亿参数)。例如 7B 表示约 70 亿参数。

需要注意的是,参数规模只反映模型容量,并不能完全决定资源需求;模型架构(Dense / MoE)、上下文长度、量化方式等都会显著影响训练和部署成本。

常见大模型规模层级如下表:

规模级别 模型定位 示例
7B–14B 小型开源模型 Qwen2.5-7B
32B 中型 dense 模型 Qwen2.5-32B
70B 主流 dense 大模型 Qwen2-72B
200B 中型 MoE 模型 DeepSeek-V2 / V2.5 (236B,激活21B)
600B+ 大型 MoE 模型 DeepSeek-V3 / R1 (671B,激活37B)
1T+ 超大模型 GPT-4 / Gemini(业界猜测/未公开)

MoE(Mixture of Experts)模型通常具有大量总参数,但推理时只激活其中一部分专家,因此实际计算量可能远小于总参数规模。例如 DeepSeek-V3 / R1 总参数约 671B,但在推理时,每 token 仅激活约 37B。

对于同一模型,训练显存通常远大于推理显存,常见经验估计约为 5–10 倍。该比例会受到 batch size、上下文长度、并行策略、优化器和显存优化技术等因素影响。

输出不确定性

即使 temperature=0,大模型输出也不一定严格复现。常见原因:

  • 浮点数和并行计算的不确定性。
  • 多个候选 token 概率接近时,微小扰动会改变结果。
  • MoE 模型在动态 batching 下可能走不同专家路径。
  • 服务端动态调度、推理图优化、多副本部署也会引入差异。

工具层面现在也不一定只暴露 temperature,更多是 reasoning effort、speed、mode、profile 这类参数。稳定性主要靠测试、校验和审查,不靠同一个 prompt 逐字复现。