news 2026/5/20 11:36:26

从零到精通:手把手教你构建自己的大语言模型(LLM)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
从零到精通:手把手教你构建自己的大语言模型(LLM)

本文深入浅出地介绍了大语言模型(LLM)的原理、构建方法和实际应用。文章首先解释了LLM的基本概念和核心训练任务,即通过海量文本数据学习生成通顺的文本内容。接着,详细阐述了构建LLM的步骤,包括预训练和微调,并介绍了Transformer架构和注意力机制等关键技术。文章还提供了具体的代码实现和实验结果,展示了如何使用Python和PyTorch在普通电脑上构建和训练LLM。最后,总结了从零构建LLM的完整流程,强调了理解LLM工作原理的重要性。


这篇文章将让你对神秘莫测的大语言模型(LLM),从"这玩意儿到底怎么工作的?"到"哦,原来我也能造一个!"的奇妙转变。

咱们一起轻松愉快的发车吧!


第1章:大语言模型是什么鬼?

1.1 LLM 到底是啥?

LLM(Large Language Model),翻译成人话就是:一个特别大的神经网络,吃了海量的文本数据,然后学会了说人话。

但你千万别被骗了——所谓的"理解",其实是模型能生成看起来通顺、上下文相关的内容,它并没有人类的意识。就像鹦鹉会说"你好",但它并不真的想跟你打招呼。

LLM 的核心训练任务特别简单:预测下一个词。给你一句话的前半段,猜后半段。比如:

输入:“我今天中午吃了——”

输出:“饭”

就这么朴素的逻辑,居然能训练出 ChatGPT 这种怪物。这就像你教孩子就教了"1+1=2",结果他自己学会了微积分——研究者自己都觉得很惊讶。

1.2 LLM 能干啥?

翻译、写小说、写代码、做客服、总结文档、回答法律问题……基本上跟文字沾边的事它都能干。现在的 LLM 不仅仅是聊天机器人,它正在重新定义我们和技术的交互方式。

1.3 构建 LLM 的两步走

预训练(Pretraining)

用海量无标注文本训练模型做"填空",得到一个"基础模型"(foundation model)。这一步极其烧钱——GPT-3 的预训练花掉了460 万美元的云计算费用。

微调(Fine-tuning)

用少量标注数据进一步训练,让它变成某个领域的专家。又分两种:

自定义的小模型能在特定领域干翻通用大模型,而且还省钱、保护隐私、能部署在手机上。苹果公司就在搞这个。

1.4 Transformer 架构:LLM 的"祖宗"

2017 年的神论文《Attention Is All You Need》提出了 Transformer 架构,它有两个子模块:

编码器(Encoder):读入输入文本,编码成向量

解码器(Decoder):拿编码器的输出,生成目标文本

原始 Transformer 是用于翻译的,编码器读英文,解码器吐中文。后来的 BERT 用了编码器部分(擅长分类),GPT 用了解码器部分(擅长生成)。本书只做 GPT,也就是只用解码器。

1.5 海量数据集

GPT-3 的训练数据包括:

CommonCrawl(网络爬虫):4100 亿 token,占 60%

WebText2:190 亿 token

Books1 + Books2:670 亿 token

Wikipedia:30 亿 token

总共训练了 3000 亿 token。什么概念?如果一个人每秒读一个字,不吃不睡要读9.5 万年。

1.6 GPT 架构的精髓

GPT 本质上就是 Transformer 的解码器部分,它通过自回归的方式生成文本——每次预测一个词,然后把这个词拼回输入,再预测下一个词。

GPT-3 有96 层 Transformer、1750 亿参数。这些模型还展现出涌现能力(emergent behavior)——没专门学过翻译,但能翻译;没专门学过写诗,但能写。就像你本来想养条看门狗,结果它自己学会了弹钢琴。

1.7 三阶段构建计划

本书把构建 LLM 分为三个阶段:

阶段内容章节
Stage 1数据准备 + 注意力机制第2-3章
Stage 2构建 LLM + 预训练第4-5章
Stage 3微调(分类 + 指令)第6-7章

(图片来自gpt,image_prompt: A three-stage pipeline diagram showing Stage 1 (Data Preparation & Attention Mechanism), Stage 2 (GPT Architecture & Pretraining), and Stage 3 (Fine-tuning for Classification & Instruction Following), with arrows connecting each stage, colorful modern flat design style)


第2章:跟文本数据打交道——把"人话"变成机器能啃的饲料

2.1 词嵌入:给每个词发张"身份证"

神经网络不认识文字,只认识数字。所以我们需要嵌入(embedding)——把每个词映射成一串浮点数。

比如"猫"可能被映射成 [0.43, 0.15, 0.89],"狗"映射成 [0.41, 0.18, 0.85]。相似的词向量距离近,不相似的离得远。

GPT-2 Small 的嵌入维度是768,GPT-3 最大版是12,288。维度越高能捕捉的关系越细腻,但计算量也越大。这就好比用 4K 电视看《猫和老鼠》——画质再好,内容还是那只猫追那只老鼠。

2.2 分词:把句子大卸八块

分词(tokenization)就是把一段话切成小碎片。作者用了一篇叫《The Verdict》的短篇小说(20,479 个字符)做示例。

先用 Python 正则表达式手动实现分词器,处理了单词、空格、逗号、句号、问号、引号、双破折号等特殊情况。最终把这篇小说切成了4,690 个 token。

2.3 Token → Token ID:编号发牌

每个唯一 token 分配一个唯一整数 ID。作者实现了 SimpleTokenizerV1 类,有 encode(文本→ID列表)和 decode(ID列表→文本)两个方法。

但有个大问题:遇到没见过的词(比如"Hello"),直接报 KeyError。

2.4 特殊 Token:给 LLM 加点暗号

为了解决这个问题,引入两个特殊 token:

<|unk|>:表示"我不认识这个词"

<|endoftext|>:分隔不相关的文本片段

GPT 系列只用 <|endoftext|> 就够了,其他模型还会用 [BOS](开始)、[EOS](结束)、[PAD](填充)。

2.5 Byte Pair Encoding(BPE):GPT 的秘密武器

SimpleTokenizer 遇到未知词就变成 <|unk|>,太粗暴了。GPT 用的是BPE 分词器(来自 OpenAI 的 tiktoken 库)。

BPE 的牛X之处:不认识整个词?没关系,拆成子词甚至单个字符。所以 BPE永远不会遇到 unknown token——它总能把输入拆成它能处理的碎片。

GPT-2 的 BPE 词汇表有50,257 个 token。

2.6 滑动窗口采样:制造训练数据

LLM 的训练是预测下一个词,所以需要构造"输入-输出"对。

用滑动窗口在文本上移动:max_length 控制输入长度,stride 控制步长。比如 stride=1,输入是 [1,2,3],输出就是 [2,3,4]——每次往后挪一位。

从一篇短篇小说就能造出海量的训练样本。

2.7-2.8 Token 嵌入 + 位置编码

Token ID 经过 nn.Embedding 层变成向量(一个大查询表)。但嵌入层有个致命缺陷:不管词在句子的哪个位置,向量都一样。

解决方案是位置编码。GPT 用可训练的位置嵌入——每个位置有自己的向量,直接加到 token 嵌入上。位置 1 加位置 1 的向量,位置 2 加位置 2 的。简单粗暴但有效。

(图片来自gpt,image_prompt: A flowchart showing text processing pipeline: raw text → tokenization → token IDs → embedding layer → embedding vectors + positional encoding → final input vectors, modern flat design with bright colors)


第3章:注意力机制——让 LLM 学会"察言观色"

3.1 RNN 的"记忆缺陷"

在 Transformer 出来之前,RNN 是处理序列数据的主流。它的工作方式是把输入压缩成一个"记忆状态",然后基于这个状态做生成。

但 RNN记不住太长的东西。就像让你传话,传了十个人之后,原话早就走样了。

3.2 注意力的诞生

2017 年的 Transformer 论文提出自注意力(Self-Attention)机制——模型在生成每个词时,可以"回头看"输入序列中的所有位置,决定哪些地方更重要。

3.3 丐版自注意力

先看不带可训练权重的简化版本:

对于句子中每个词,计算它跟所有词的相关性(用点积衡量),然后 softmax 归一化成概率,再用这些概率加权求和所有词的向量——得到上下文向量。

这个上下文向量融合了整个句子的信息,解决了 RNN 的"健忘"问题。

3.4 完全体:缩放点积注意力

真正的 LLM 用的是带三个可训练权重矩阵的自注意力:

Wq(Query)

你在问"这段话里谁跟我有关系?"

Wk(Key)

每个词在说"我的特征是这些"

Wv(Value)

“如果觉得我重要,就拿走这个信息”

计算步骤:

输入分别乘 Wq、Wk、Wv 得到 Q、K、V

attn_scores = Q @ K.T

算相关性

除以 √d_k

(缩放),防止高维度下点积过大导致梯度消失

softmax 归一化

output = attention_weights @ V

得到上下文向量

3.5 因果注意力:不许"开天眼"

训练时,模型不能看到未来的词。比如预测 “I love you” 中的 “you” 时,只能看到 “I love”,不能偷看答案。

实现方式:在注意力权重矩阵的右上角加一个上三角掩码,把未来位置的权重全变成 0。方法是在 softmax 之前把右上角全设为 -inf,这样 softmax 后自然就是 0。

还引入了Dropout,随机丢弃一部分注意力权重(训练时用 0.1-0.2),防止过拟合。

3.6 多头注意力:一个脑袋不够用

多头注意力就是并行运行多个因果注意力机制。不同头关注不同信息——一个可能关注语法关系,另一个关注语义相似性。

GPT-2 Small(1.24 亿参数)有12 个头,嵌入维度 768,每个头处理 64 维。

高效实现方式:先做一次大 QKV 投影,然后拆分成多个头,用批量矩阵乘法并行计算所有头。


第4章:搭积木——实现 GPT 模型架构

4.1 GPT-2 的"身份证"

GPT-2 Small(1.24 亿参数)的配置:

参数
词汇量50,257
上下文长度1,024
嵌入维度768
注意力头数12
Transformer 层数12
Dropout0.1

为什么用 GPT-2 不是 GPT-3?因为 GPT-3 的 1750 亿参数在单张 V100 上要训355 年。等你训完,世界末日可能都过去好几轮了。

4.2 Layer Normalization:情绪稳定剂

深度神经网络的梯度容易消失或爆炸。层归一化把每一层的输出拉成均值为 0、方差为 1 的标准分布。

LayerNorm 不依赖 batch size(不像 BatchNorm),所以特别适合 LLM 训练。

而且它还有可训练的 scale 和 shift 参数——如果模型觉得标准化后不好用,它能自己调回去。就像你妈让你把房间收拾整齐,但你之后可以把枕头摆歪一点——舒服就行。

4.3 GELU:比 ReLU 更"温柔"

ReLU 简单粗暴:正数留着,负数变零。

GELU 就温柔多了:负数区域也保留非零梯度,只是很小。ReLU 像"不及格就滚",GELU 像"不及格还可以补考"。

前馈网络(FeedForward)结构:Linear(768 → 3072) → GELU → Linear(3072 → 768)。先扩大 4 倍再缩小,维度没变但内涵丰富了。

4.4 Shortcut Connections:高速通道

随着网络加深,梯度在反向传播时会越来越小。**Shortcut(残差连接)**就是把输入直接加到输出上,给梯度修了一条"高速公路"。

没有 shortcut 时第一层比第五层梯度小 25 倍;加了 shortcut,各层梯度大小基本一致。

4.5 Transformer Block:组装成型

每个 Transformer Block 的结构:

LayerNorm → Multi-Head Attention → Dropout → Shortcut

LayerNorm → FeedForward → Dropout → Shortcut

注意这里用的是Pre-LayerNorm(先归一化再进子层),比 Post-LayerNorm 训练更稳定。

关键是:输入输出形状完全一样!所以你可以像叠罗汉一样叠 12 层。

4.6 GPTModel:终极合体

GPTModel = Token Embedding + Positional Embedding + 12× TransformerBlock + Final LayerNorm + Output Head(映射到 50,257 维词汇表)

1.63 亿参数,float32 存储需要 621 MB。跟今天 Llama 3 70B(存权重就要 140GB)比,简直是小巫见大巫。

4.7 文本生成

用 generate_text_simple 做自回归生成:输入 “Hello, I am”,输出 “Featureiman Byeswickattribute argue”。

这是啥玩意儿?别急——模型还没训练,权重是随机的,跟刚出生的婴儿一样,话都不会说。


第5章:预训练——从"胡言乱语"到"能说会道"

5.1 评估文本质量:怎么量化"说得好不好"?

交叉熵损失(Cross-Entropy Loss):模型预测的概率分布跟实际情况差多远。值越小越好。

困惑度(Perplexity)= exp(loss)。初始值 48,725,相当于模型在 50,257 个词里完全随机乱猜。理想目标:接近 1。

训练数据集:《The Verdict》(只有 5,145 个 token),90% 训练 / 10% 验证。

5.2 训练过程:见证 AI 的成长

用 AdamW 优化器,训练 10 个 epoch(约 5 分钟):

EpochLoss生成文本
19.78Every effort moves you, (变逗号复读机)
26.66Every effort moves you, and, and, and, … ("and"复读机)
90.54开始输出语法正确的句子
100.39能写出通顺的英文句子

从逗号复读机到能写出完整句子——这 5 分钟的学习曲线比某些大学生四年的进步还明显。

但验证 loss 在第 2 个 epoch 后就停滞在 6.45 了,而训练 loss 降到了 0.39——过拟合了。解决办法:用更大的数据集。

5.3 解码策略:让模型有创意而不是背答案

贪心解码(Greedy Decoding):每次选概率最高的 token。安全但无聊,像每次都点同一道菜。

Temperature 缩放:控制随机性。

temperature = 0.1:几乎确定,像严谨的科学家

temperature = 1:正常发挥

temperature = 5:放飞自我,有 4% 概率生成 “Every effort moves you pizza”

Top-k 采样:只保留概率最高的 k 个 token 再采样。k=3 时,“forward、toward、closer” 竞争,“pizza” 直接出局。

把两者结合:先用 top-k 筛选候选池,再用 temperature 调整概率分布后再采样。

5.4 保存和加载模型

保存

torch.save(model.state_dict(), "model.pth")

加载

model.load_state_dict(torch.load("model.pth"))

如果要继续训练,记得连 optimizer 状态一起保存——AdamW 记住了每个参数的历史学习率,丢了就失忆了。

5.5 白嫖 OpenAI 的预训练权重

自己训太贵?直接用 OpenAI 的 GPT-2 权重!下载 498MB 的权重文件,需要做一个"翻译"工作——OpenAI 的变量命名和我们不一样,得手动映射。

加载成功的标志:输入 “Every effort moves you”,不再输出乱码,而是输出 “toward finding an ideal new way to practice something!”——这才是正常人该说的话。

(图片来自gpt,image_prompt: Illustration showing pretraining process: unlabeled text data flowing into a GPT model, the model predicting next tokens, loss curve decreasing from high to low over epochs, and the output changing from gibberish to coherent sentences, colorful educational style)


第6章:分类微调——让 LLM 当"专才"

6.1 微调的两种路子

分类微调

让模型变成"偏科生",只会做一件事(比如判断垃圾邮件)

指令微调

培养"全才",能听懂各种指令

全才比偏科生难训练得多。作者说得很直白:全才难做,偏科容易。

6.2 准备垃圾邮件数据集

用SMS Spam Collection数据集(5,572 条短信)。原始数据不平衡(垃圾 747 vs 正常 4,825),用欠采样平衡到 747 vs 747。

数据集按 70% 训练、10% 验证、20% 测试拆分。

6.3 创建数据加载器

短信长短不一,用 <|endoftext|> token 填充到一样长。每个 batch 内所有序列统一长度。

6.4 加载预训练权重

加载 GPT-2 预训练权重。试一下未经微调的模型:你问它"这是垃圾邮件吗?",它不回答,只会继续补全文本——光预训练不微调,模型就是个复读机。

6.5 加装分类头

把原来的输出层(映射到 50,257 个 token)换成新的(映射到 2 个类别:spam / not spam)。

技巧:

冻结大部分参数

(设置 requires_grad = False),只训练输出层 + 最后一个 Transformer block + 最后的 LayerNorm

只用最后一个 token 的输出做分类

——因为因果注意力掩码让最后一个 token 能看到前面所有信息

6.6 训练结果

超参数:AdamW,学习率 5e-5,weight_decay 0.1,5 个 epoch。

在 M3 MacBook Air 上跑约5.65 分钟:

指标数值
训练集准确率97.21%
验证集准确率97.32%
测试集准确率95.67%

测试集 95.67%,相当能打。而且训练和验证曲线贴得很近——没有过拟合,nice。

6.7 保存模型

torch.save(model.state_dict(), "classifier.pth")

第7章:指令微调——让 LLM 当"通才"

7.1 目标

把 GPT-2 medium(3.55 亿参数)训练成一个能听懂人话指令的模型。“把这句话改成被动语态”、“伦敦的首都是哪里”——这些活儿它都得会干。

跟分类微调不同,指令微调不限制输出——输出空间大得没边,难度高得多。

7.2 准备指令数据集

1,100 条指令-回答对(JSON 格式),每条包含 instruction、input、output 三个字段。

使用Alpaca 格式组织 prompt:

Instruction: 把下句改成被动语态

Input: The chef cooks the meal.

Response: The meal is cooked by the chef.

数据集划分:85% 训练(935 条)、10% 测试(110 条)、5% 验证(55 条)。

7.3 自定义 Collate 函数

指令长度不一,需要每个 batch 各自填充到当前 batch 的最长长度,而不是整个数据集的最长长度。这样节省大量计算和内存。

关键技巧:把 padding token 在 target 中对应的位置设为-100。PyTorch 的交叉熵损失默认忽略 -100,这样 padding 部分就不会参与损失计算。不然模型会去学预测那些无聊的填充 token。

7.4 加载 GPT-2 medium(355M)

为什么用 3.55 亿参数而不是 1.24 亿?因为指令微调任务复杂,小模型撑不住。

没微调的模型试一下:让它把主动句改被动句——它直接复读原句,还顺带重抄了一遍指令。就像学生考试时把题目抄了一遍当答案。

7.5 正式微调

超参数:AdamW,学习率 5e-5,只跑 2 个 epoch(数据集小,再多就过拟合了)。

在 A100 GPU 上只需52 秒。训练 loss 从 2.637 降到 0.300。

第 1 个 epoch 结束:已经能把 “The chef cooks the meal every day.” 改成 “The meal is prepared every day by the chef.”——虽然用了 “prepared” 而不是标准答案的 “cooked”,但语法和语义完全正确。

第 2 个 epoch 结束:变成正确的 “The meal is cooked every day by the chef.”

7.6 评估

人工评估 110 条回复太累?用另一个 LLM(Llama 3 8B)来打分!

评分 prompt 里包含:指令 + 标准答案 + 模型回答,让 Llama 3 从 0-100 打分。

测试样例:

“快如子弹”(标准答案是"快如闪电")→85 分(没毛病但不够精确)

“积云”(标准答案是"积雨云")→40 分(方向对了但答错了)

“简·奥斯汀” →95 分(接近完美,但稍微啰嗦了点)

110 条测试集平均分:50.32 分。可以用来做基准对比。

假如你从2026年开始学大模型,按这个步骤走准能稳步进阶。

接下来告诉你一条最快的邪修路线,

3个月即可成为模型大师,薪资直接起飞。

阶段1:大模型基础

阶段2:RAG应用开发工程

阶段3:大模型Agent应用架构

阶段4:大模型微调与私有化部署

配套文档资源+全套AI 大模型 学习资料,朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】👇👇


配套文档资源+全套AI 大模型 学习资料,朋友们如果需要可以微信扫描下方二维码免费领取【保证100%免费】👇👇

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 11:35:23

在持续集成环境中集成 Taotoken API 进行自动化测试的实践分享

&#x1f680; 告别海外账号与网络限制&#xff01;稳定直连全球优质大模型&#xff0c;限时半价接入中。 &#x1f449; 点击领取海量免费额度 在持续集成环境中集成 Taotoken API 进行自动化测试的实践分享 将大模型能力集成到产品中&#xff0c;意味着我们需要确保其交互的…

作者头像 李华
网站建设 2026/5/20 11:33:27

RT-Thread串口驱动阻塞超时机制实现与优化指南

1. 项目概述&#xff1a;从“永久阻塞”到“优雅超时”的串口驱动进化在嵌入式开发&#xff0c;特别是基于RT-Thread这类实时操作系统的项目中&#xff0c;串口通信是连接设备与外界、进行调试、数据交换的“大动脉”。然而&#xff0c;这条动脉的“通畅度”往往决定了整个系统…

作者头像 李华
网站建设 2026/5/20 11:33:27

3分钟从零到一:用Pixelle-Video制作你的第一个AI短视频终极指南

3分钟从零到一&#xff1a;用Pixelle-Video制作你的第一个AI短视频终极指南 【免费下载链接】Pixelle-Video &#x1f680; AI 全自动短视频引擎 | AI Fully Automated Short Video Engine 项目地址: https://gitcode.com/GitHub_Trending/pi/Pixelle-Video 还在为视频制…

作者头像 李华
网站建设 2026/5/20 11:32:14

别再死记硬背了!用Python+NumPy可视化理解卡方、t、F三大分布(附代码)

用PythonNumPy可视化三大统计分布&#xff1a;从数学公式到动态图表 统计学中的卡方分布、t分布和F分布是数据分析、假设检验和机器学习的基石。但翻开教材&#xff0c;满屏的希腊字母和积分符号总让人望而生畏。作为曾经被这些概念折磨过的数据科学从业者&#xff0c;我找到了…

作者头像 李华