☰
从零构建大语言模型:数据、训练到推理能力全解析
2026/9/30 17:55:18 网站建设 项目流程

这篇博客要写的内容我心里有数,先跟你聊两句背景再切入正题。

这两年 AI 圈的画风变化特别快。前几年大家还在比谁家的 API 调用封装得漂亮、谁的 prompt 写得更花哨;到了最近,风向突然转向了“从零开始”。无论是《Build a Large Language Model from Scratch》这类书籍被疯狂传阅,还是社区里越来越多“build a reasoning model from scratch”的实战分享,都在传递同一个信号:光会用模型已经不够了,越来越多工程师想自己把模型造出来。这篇文章就是围绕“ai-engineering-from-scratch”这个主题,把我从零搭建、训练、微调一个可用的 AI 模型过程中的思考、步骤、踩坑记录全部摊开讲清楚。内容会覆盖数据准备、tokenizer 实现、模型结构、训练循环,以及最近特别火的推理能力构建(CoT + 强化学习路线),适合已经用过 AI API 但想深入底层、有 Python 基础想动手实践的读者,也适合准备系统学习大模型原理的入门者。

1. 内容整体设计与思路拆解

1.1 为什么“从零”成了新趋势

先明确一个概念:AI engineering from scratch,不等于从零发明神经网络。你不需要重新推导数学公式,也不需要复现 GPT-4 那么庞大的架构。这里说的是“从零构建一条自己的 AI 系统链路”——从哪里弄数据、怎么清洗、怎么切词、怎么设计模型结构、怎么让它学会推理,整个过程自己掌控,而不是打开一个 API 接口传参就完事。

我看到很多人在讨论中把“from scratch”误解成“必须完全自己手写所有代码”。实际推敲下来,真正合理的理解是:在关键链路上不做黑盒依赖。比如你可以用 PyTorch 做张量运算,但模型结构要自己搭;你可以用 HuggingFace 的数据集加载工具,但数据筛选策略得自己定。说白了,框架可以用现成的,认知链路必须是自己的。

这也是为什么我特别推荐拿 Sebastian Raschka 那本Build a Large Language Model from Scratch当路线图参考。它没有停在概念讲解层面,而是真的从一段文本开始,一步步构建 tokenizer、实现 GPT 架构、训练出能生成文本的模型。很多人误解这本书是“玩具项目”,实际动手跑完才会明白,它把从零到一的工程链路讲透了:数据处理、模型初始化、训练循环、评估、微调,每一步都在教你“怎么选”而不是只告诉你“怎么做”。

1.2 从零构建能解决什么实际问题

我自己过去有段时间陷入一个怪圈:调用大模型 API 做应用,调不好就怪 prompt 写得不够好,再调不好就怪模型版本太老。表面看是工程问题,本质是对模型能力边界没有感知。当你亲手训练过一个模型,你就会知道 loss 下降的曲线长什么样、数据质量对结果的影响有多大、同一个学习率在不同 batch size 下表现差异有多大。这些感知用熟了之后,你再回去做应用层开发,判断力完全不一样。

从零构建还有实际的经济价值。做实验的时候,你在自己的机器上跑一个小模型,几十块钱的电费就能跑完几轮实验;而如果用 API 反复迭代,光试错成本就可能到几百上千块。训练规模再大一点,自己做数据处理和分布式训练,省下来的费用就更可观。对我这种经常要拿数据测试思路的人,这条路径不仅是“学习成本”,也是“研发成本”的控制手段。

更适合初学者的一点是,从零构建能让你真正看懂“推理模型”的组成。最近社区里“build a reasoning model from scratch”之所以火,是因为 DeepSeek-R1 这类模型展示了一个事实:推理能力不是被神秘地“涌现”出来的,而是一条可复制的工程路径——高质量思维链数据做 SFT 冷启动,再用规则奖励驱动的强化学习(比如 GRPO)让模型在探索中自发提升推理长度和准确率。这条路径你在小模型上完全可以复现。

1.3 适合谁学、需要什么前置知识

我的判断是,不需要数学博士背景,但需要动手的意愿。上手前最好具备:

  • Python 基础到中等水平:能读懂类、函数、循环,会调试报错。
  • PyTorch 基础:知道张量是什么,能跑最简单的训练脚本。不会也别慌,照着官方教程过一遍 basic 章节就够了。
  • 一点线性代数和概率的直觉:知道矩阵乘法是啥,明白交叉熵是衡量什么的就行。复杂的推导可以边做边补,不用一开始全学会。
  • 耐心:这是最重要的前置条件。第一次训练模型,loss 不降、显存爆炸、生成了乱码,太正常了,没有耐心的人第一周就会放弃。

我自己就是从“只会调库、不懂原理”的状态走过来的。下面我把整条实践路线拆开,包括我踩过的坑、反复试出来的参数、以及为什么选那些方案,希望你能少走弯路。

2. 核心细节解析与实操要点

2.1 数据预处理:Tokenization 与 BPE 的取舍

很多人从零做模型,第一反应是去搞模型架构,实际上第一个拦路虎是数据怎么变成数字。文本不能直接喂进神经网络,得先拆成最小单位(token),再映射成整数索引。这里我首选 BPE(Byte Pair Encoding,字节对编码),原因很简单:它既能高效压缩常见词,又能处理生僻词和未知词。

BPE 的核心逻辑听起来挺直白:先把文本拆成字节,然后反复统计相邻字符对的出现频率,把最高频的字符对合并成一个新 token,直到达到预设的词汇表大小。实际操作里有两个细节特别容易踩坑:

  1. 训练 tokenizer 的语料要与最终训练语料同源。我先用小规模中文语料训了一个 mini tokenizer,然后拿去做英文语料训练,结果生成的文本全是乱码。原因是同一套 BPE 规则在不同语言上的分词结果完全不同。后来我统一用混合中英文语料来做,问题就消失了。
  2. 词汇表大小要权衡。词汇表太小(比如 512),每个 token 表达的信息太碎,序列会特别长、训练变慢;词汇表太大(比如 64K),模型要学的 embedding 参数大量增加。我做实验时常用 4K~8K,学习效果和训练速度比较平衡。

一个实用的数据清洗流程可以这么设计:

def clean_text(text: str) -> str: # 去除 HTML 标签和不可见字符 text = re.sub(r"<[^>]+>", " ", text) text = re.sub(r"[\x00-\x08\x0b\x0c\x0e-\x1f]", "", text) # 统一换行符 text = text.replace("\r\n", "\n").replace("\r", "\n") # 压缩连续空白 text = re.sub(r"[ \t]+", " ", text) # 过滤过长段落(通常是抓取的异常页面) if len(text.split(" ")) > 2000: return "" return text.strip()

这套流程看着简单,实际效果立竿见影。我一开始偷懒不清洗,直接拿爬来的语料训练,结果 loss 下降极慢,生成内容里夹杂大量乱码符号,后来才发现是清洗不够导致的。

2.2 模型骨架:从 Embedding 到 Transformer Block

网上关于 Transformer 原理的文章多到看不完,但你自己动手实现时,真正需要写出来的核心模块就那几个。我建议用“组装乐高”的心态来理解,不要被注意力机制的公式吓到。

Embedding 层负责把 token 索引变成向量。这里有个小细节:位置编码必须加,否则模型分不清“我打你”和“你打我”的区别。我现在常用 RoPE(旋转位置编码),它在长文本上的外推能力好于最早的绝对位置编码,而且实现起来就是一个旋转矩阵操作,不算复杂。

多头注意力机制是整个模型的灵魂。我自己的理解方式是把它想象成一个“自助图书馆检索系统”:每个 token 先拿自己的查询向量(Query)去跟所有 token 的键向量(Key)比对,算出相关性分数,再按分数加权取出对应的值向量(Value)。在这个机制里,你要特别注意因果掩码(causal mask)——生成任务中当前位置不能看到未来内容,所以注意力矩阵的上三角部分必须置成负无穷,否则模型会作弊。

一个极简的注意力实现大概长这样:

def causal_attention(q, k, v, mask=None): # q, k, v: [batch, seq_len, heads, head_dim] scores = torch.einsum("bhid,bhjd->bhij", q, k) scores = scores / math.sqrt(q.shape[-1]) if mask is not None: scores = scores.masked_fill(mask == 0, float("-inf")) weights = torch.softmax(scores, dim=-1) return torch.einsum("bhij,bhjd->bhid", weights, v)

看到这个代码,我要提醒一点:千万不要直接用这个版本去训练稍大一点的模型,因为复杂度是序列长度的平方。拿它理解原理没问题,工程上要用的还是 Flash Attention 这类高效实现。我在从零写模型的时候,先用自己的 naive 实现跑通逻辑,然后再切到官方优化版,这样才能既理解原理又不浪费算力。

前馈网络(MLP)的细节更简单,每个 token 的向量经过两三次线性变换加激活函数就行,但它的参数量占了整个模型的近三分之二。实际挑参时,我发现把隐藏层维度设为 embedding 维度的 4 倍是经济的选择:参数量合理,效果也不会明显退化。

最后把 embedding、注意力、前馈网络组合成一个 Transformer Block,再把多个 Block 堆叠起来,配上最后的 layer norm 和输出投影层,模型主体就完成了。LayerNorm 的位置值得注意,现在主流做法是放在注意力计算之前(Pre-Norm),比放在后面(Post-Norm)更容易训练稳定。我自己在同样参数下对比过,Pre-Norm 的首轮 loss 下降确实更平滑。

2.3 损失函数与训练循环:模型到底在“学”什么

有了模型结构,接下来要回答的问题是“模型怎么知道自己说得对不对”。答案就是交叉熵损失:给定前面的文本,模型预测下一个 token 的概率分布,与真实下一个 token 做比较,越接近则损失越小。

写训练循环的时候,有三个细节不能省:

  1. 打乱与批次策略。我一开始把整个语料拼成一个超长序列,然后连续切块进模型。这样做会在批次内保留顺序,对各次训练不太差,但最终效果不如随机采样。随机采样的意思是每个 batch 从语料的不同位置抽取,这样模型每次看到的上下文更多样,泛化效果更好。缺点是会打断文档的连续性,需要张量拼接。

  2. 梯度累积。显存有限的小机器上,这是一个救命技巧。假设你需要有效 batch size 为 16,但单次只能放 4 条序列,那就跑 4 次前向和反向,把梯度累积起来再做一次优化器更新。注意 PyTorch 里要手动把loss除以累积步数,否则梯度会按 4 倍算大,学习率直接失效。

  3. 学习率预热(warmup)。训练刚开始时,模型参数是随机状态,直接大步更新很容易把参数冲到不稳定的区域。业界惯用的做法是先用 500~2000 步把学习率从接近 0 线性升到目标值,之后再根据轮次衰减。我试过从第一步就用固定学习率,效果明显更差——特别是用 AdamW 优化器时,没热身状态下的方差动辄偏大。

这里附一个极简的训练循环骨架,方便你看到整体流程:

optimizer = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.1) scheduler = CosineWarmupScheduler(optimizer, warmup_steps=1000, total_steps=20000) for step, batch in enumerate(train_loader): logits = model(batch["input_ids"]) loss = cross_entropy(logits, batch["target_ids"]) # 梯度累积 loss = loss / grad_accum_steps loss.backward() if (step + 1) % grad_accum_steps == 0: torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) optimizer.step() scheduler.step() optimizer.zero_grad()

2.4 训练策略选型:预训练 → SFT → RL

模型结构是骨架,数据训练是血肉。从零开始构建一个有用模型的完整路线,我总结为三步:

第一步:预训练(Pre-training)。目标是让模型学会语言本身。用大规模无标注语料,做标准的下一个 token 预测。这一步的产物是一个“会说但不会干活”的模型——它能接出流利的句子,但不一定听话,也不一定正确。

第二步:监督微调(SFT)。准备一批“问题-优质回答”对,让模型学会按指令回答。重点在于数据质量远大于数量。几百条高质量问答,有时候效果能明显好过几万条噪声数据。这里的窍门是把指令、输入、回答用专门的特殊 token(比如<|im_start|>和<|im_end|>)分隔,让模型学到格式边界。

第三步:对齐与推理增强(RL / RLHF 类方法)。这一层做的是“告诉模型什么答案好”。对推理类任务来说,我特别推荐用规则奖励而不是人工偏好模型。比如做数学题,直接核对最终答案是否正确;做事实验证,直接调用知识库比对。奖励明确,信噪比高,工程上实现也简单。用 GRPO 这类策略优化算法,让模型在探索多个答案时,从奖励差异中学习,这就是近期“build a reasoning model from scratch”的核心思路。

这条路线是一个连续递进的过程,不是分开的孤立任务。我之前犯过的错误是跳过 SFT 直接做强化学习,结果 RL 阶段模型生成的答案乱写,奖励信号完全没法引导,白白浪费了好几天计算资源和调整时间。

3. 实操过程与核心环节实现

3.1 环境准备与数据准备

我所有的实验都是在单张 24GB 显存的消费级显卡上完成的(RTX 3090 跑起来完全够)。如果你显存只有 12GB,也不是没法做,把模型缩到 1 亿参数以下、序列长度缩短到 512 以内就行。所以给你一份环境清单:

torch>=2.0 transformers==4.40 datasets==2.19 numpy tiktoken # 或者自己实现的 BPE

数据方面给个示例流程。我用的是开源中文语料,大概 2GB 纯文本。首先按段落切分,过滤掉过短和过长的片段,然后做语言过滤(去除非中英文字符占比过高的行),最后把数据切成固定长度块(比如 1024 token),存成二进制文件。一个重要的经验是:把数据缓存在磁盘,训练时按索引读取,不要每次重启都重新清洗一遍。我一开始没缓存,每次调试都要等 20 分钟数据预处理,烦得想砸键盘。

切块代码很简单:

# 将 token ids 拼接并切成固定长度 def make_chunks(token_ids, block_size=1024): chunks = [] for i in range(0, len(token_ids) - block_size, block_size): chunks.append(token_ids[i : i + block_size]) return chunks

注意这里有个隐藏问题:切块从 0 开始的偏移量是固定的,如果语料长度不是 block_size 的整数倍,就会丢弃尾部数据。简单做法是头部留出 overlap,或者直接用 sliding window 做重叠采样。我后来直接保留 128 token 的重叠量,有效地利用了数据。

3.2 手写 tokenizer、模型与训练代码

我不想给你贴一个超大代码块然后就走人,这里把最核心的三段代码块拆开讲:tokenizer 训练、Transformer 模型主类、训练入口。

Tokenzier 训练:如果不想手写 BPE 那套合并逻辑,可以直接用tiktoken训练,但“从零”路线我还是建议自己写一遍 BPE。核心就三步:初始化字节词汇表,统计相邻对频率,迭代合并最高频对直到词汇数量达标。写完之后在语料上跑一遍分词,打印几个样例检查切分是否合理。我发现中文语料中,BPE 会倾向于合并常见词组,比如“人工智能”会成为一个 token,这个行为正常,不用特意去分词成单字。

模型实现:GPT 风格的模型结构并不复杂,一个高水平的精简实现大概是:nn.Embedding做 token embedding,一个可学习的或者位置编码模块,然后堆叠 N 个 TransformerBlock,每个 Block 里包含因果多头注意力和 MLP,注意残差连接和 layer norm 的顺序。有一个容易出错的地方是初始化:残差层最后的投影层通常初始化为零或者很小权重,这能保证初始时整个 Block 近似恒等映射,深层堆叠时才不会出现数值爆炸。我前期没注意初始化,用默认分布去初始化深层模型,跑了几个 step 之后 loss 直接变成 NaN。

训练入口:使用torch.utils.data.DataLoader从预处理好的二进制文件取 batch,每个 iteration 里取两个连续的 block,第二个 block 作为第一个的标签(也就是把数据右移一位)。我通常把 batch_size 设为 8、序列长度 1024,正好吃满 24GB 显存。如果内存不够,batch_size 减半然后用梯度累积找平即可。

最后贴一下训练时的观察项。我不光盯 step loss,还会持续记录:

  • 训练集 loss 与验证集 loss 的差值(判断过拟合)
  • 生成的样例文本(每 500 步生成一小段,直观感受模型状态)
  • 学习率当前值(确认调度器在正常变化)
  • 梯度范数(如果超过 5,说明优化器步长太大或数据有异常)

3.3 构建推理能力:从 CoT 数据到强化学习

这是 2025 年之后整个 AI 工程圈最热门的话题,也是我花时间最多的地方。从零构建推理能力,我认为路径分三段走:

第一段,收集思维链(Chain-of-Thought)数据。单纯让模型直接给答案,它不会“思考”;要让模型学会思考,你得先给它看“思考过程”。数据格式大概是:问题,然后是一长段中间推理过程(可以自言自语式),最后是答案。公开的数学推理数据(比如 GSM8K 训练集)可以直接用,但如果你有自己的垂直领域任务,就需要自己构造数据。我的经验是,先做 1000~5000 条高质量 CoT 数据做 SFT 冷启动,比上来就跑 RL 更稳。冷启动模型至少要能把思考格式写出来,否则 RL 阶段根本探索不到高奖励的回答。

第二段,用规则奖励做强化的启动。对推理任务,奖励信号不需要“人类打分”,直接用规则判断:答案正确得 1 分,错误得 0 分,如果格式不合法(比如没有输出答案:标签)甚至可以直接扣分。我还加了一个长度奖励项的变体,鼓励模型写出更长的推理步骤,但注意权重不要太大,不然模型会学成“废话制造机”,绕了一大圈最后答案还是错的。

第三段,用 GRPO 替代 PPO 做迭代更新。我强烈建议直接尝试 GRPO(Group Relative Policy Optimization),它是 PPO 的一个简化变体,取消了对价值网络的依赖,只用同一个 prompt 采样出一组答案,通过组内相对奖励计算优势。实现起来少了一个庞大的 critic 模型,显存占用和实现复杂度都大幅下降。这也是 DeepSeek-R1 等模型公开的技术路线中用得比较顺的策略。

下面这个伪代码展示 GRPO 部分逻辑的尺度,帮助你建立直观印象:

# 对同一个 prompt 采样 group_size 个回答 responses = policy.sample(prompt, n=group_size) rewards = [rule_reward(r) for r in responses] baseline = mean(rewards) advantages = [(r - baseline) for r in rewards] # 再用这些 advantage 做 PPO 风格的策略更新(截断)

3.4 评估与验证:训练完怎么知道“行不行”

训练完模型,最怕的是自我感觉良好但拿不出评估数据。我建了一套三层次评估法:

  • 自动评估:跑一个固定题集(比如 200 道数学题),统计准确率。训练前测一次,训练后测一次,看提升幅度。
  • 对抗评估:故意把问题改写成带噪声的版本(错别字、语序打乱、冗余信息),看模型推理是否稳健。
  • 人工盲测:把模型输出和参考答案混在一起,让评测者打分。这个对于主观性强的任务特别重要。

我观察到的一个真实规律是:训练集准确率接近 100%,但测试集却只到 70% 左右,几乎一定是过拟合了。解决办法不是盲目加数据,而是先看验证集上错误的类型。比如,如果你的模型只在“计算最后一步”上出错,那就去增强最后一步算术的专项数据;如果模型容易漏掉问题条件,那就去改 prompt 格式,让条件更显眼。

4. 常见问题与排查技巧实录

4.1 训练不收敛或者 loss 是 NaN

这是新手最常碰到的“劝退问题”。我总结下来主要有三个原因:学习率过高、数据里有异常值、模型初始化不当。

学习率过高很好判断:loss 前期震荡特别剧烈,然后一飞冲天变成 NaN。应对方法首先把目标学习率降到一半,再观察几轮。如果仍然不行,把 warmup 步数加长,例如从 1000 步加到 3000 步,让参数逐渐被“带入正轨”。

数据异常会直接表现为某个 batch 的 loss 突然从正常值跳到 NaN。排查办法是用一个很小的 batch(比如 2 条样本)逐条前向计算 loss,找出那一条导致异常的数据。我遇到过一种情况:数据里混入了超长数字,tokenizer 输出的 token 数量超过了模型的最大长度,结果位置编码越界。这类问题在数据清洗阶段就应该把它过滤掉。

初始化不当的问题在 2.3 节提过,核心是残差层的输出全部初始化为接近 0 的权重(或者使用小的标准差),这样深层网络的初始状态是稳定的,训练从一开步就在一个合理的地基上。

4.2 显存不够怎么办

不要一上来就换大机器。我给你一套由快到慢的排查顺序:

  1. 降低 batch size,保持有效 batch 用梯度累积补回来。显存主要被 batch 里的激活值占掉,这个方法效果最明显。
  2. 减少序列长度。从 1024 降到 512,显存几乎立刻省一半。对很多任务来说,512 长度的上下文已经够用。
  3. 打开混合精度训练(AMP)。PyTorch 里一行torch.cuda.amp就能做到前向半精度,反向全精度,显存直接减少不少,速度还能提升。
  4. 使用梯度检查点。前向时丢弃中间激活,反向时再重新计算。注意这会降低约 30% 的运算速度,但在杯水车薪的显存压力下,是值得的。

还有一个容易被忽略的点:优化器状态占的显存不比模型小。用 AdamW 的话,每个参数要存两份动量,模型 10 亿参数,optimizer 状态会额外占 8GB。如果显存紧张,可以考虑把部分参数冻结(比如只训练最后几层),或者换用更省内存的优化器如 Adafactor,但收敛效果通常不如 AdamW,你自己权衡。

4.3 生成内容重复、逻辑断裂

这种现象的根源通常是采样策略和训练数据两方面的问题。训练数据里如果有大量重复文本(比如新闻网站的泛页),模型会把“复读”当作合理生成。清理数据时,可以用 n-gram 去重:统计 8-gram 级别的重复片段,把重复率超标的文档直接扔掉。

生成阶段的重复则是采样问题。温度参数调低(比如 0.7)可以降低随机性,但过低会陷入贪心循环;top-k 和 top-p 过滤掉概率极低的 token,能有效减少从长尾里选到无关词。我的经验值组合是:温度 0.8、top-k 40、top-p 0.9,先跑一遍看效果再微调。要注意的是,这些参数不是越大越好,需要结合任务来调。开放创作类内容可以稍高一点,数学题则大概率降低温度更合适。

逻辑断裂问题则基本指向模型本身的容量不够或者 CoT 数据太少。小模型想推理长链条本身就不现实,我一般会把任务拆成多步提示,让模型每步只做少量推理,然后汇总全部结果,这比指望一次性输出长链条可靠得多。

4.4 数据配比与过拟合的纠偏

训练混合数据时,你不能简单把不同来源的数据等比拼接。比如你拿了 1GB 维基百科风格文本再加 1GB 代码,那么模型的语言能力可能偏“书面化”,代码能力却会因为格式学习不到位而表现较差。一个合理的方法是按 token 数量设定采样权重,让每种来源的数据在每轮训练中都能得到大致充分的曝光。我在混入推理数据时,通常让数学题数据占总 token 的 10%~20%,其余留给通用语料,这样推理能力不会以牺牲通用能力为代价。

过拟合的另一种纠正方向是正则化与早停。小模型在几万条文本上训练多轮,很容易把训练集的边角料都背下来。我在训练第 2 轮后验证集 loss 基本不再下降时就会停手,省下来的时间去调数据和策略,收益高得多。我还试过对 attention 权重做 dropout,从 0.0 调到 0.1,验证集 loss 确实平稳了一些,代价是训练时间稍微变长,这个度你自己把握。

5. 一些动手实践中才有的心得体会

这节内容不是教科书上的,是我踩过几次坑之后总结的,按重要程度排给你。

第一,“从零”最大的收获不是造出了模型,而是你对 AI 系统的“失控感”消失了。以前我遇到模型输出不对劲,只能靠叠 buff 式的 prompt,再不行就怀疑模型“笨”。现在我会下意识推断问题是出在数据分布、训练阶段、还是采样策略——这种判断力,只有亲手把每个环节都捏过一遍之后才会长出来。

第二,能跑通和能好用之间,差距全在数据和评测上。很多人止步于“loss 降了、能生成文本了”,但一个能用的模型要过得了标准题集、扛得住对抗改写、经得起人工盲测。把这些评测工具早早在工程链路里布好,比事后补救省力太多。

第三,想构建推理能力,别直接冲 RL。社区里不少“quick start 教程”会直接甩给你一个 GRPO 的训练脚本,我劝你别照着跑完就以为自己会了。先老老实实做几百条 CoT 数据,把模型冷启动到能按格式思考,再用 RL 增强,这条路径的稳定性和可解释性都远高于直接硬碰强化学习。

第四,硬件不够不是放弃的理由,而是限制设计的纪律。我见过有人在单卡上硬跑一个几十亿参数的模型,结果只能在日志里看 loss 数字,连一次生成样例都等不到。与其这样,不如把模型缩小到能实时调试的规模,把实验迭代的周期压缩到分钟级。可以这样理解,训练一次 3 天的模型,你想试一个参数都要等 3 天;模型缩小 10 倍,迭代周期变成几小时,反而让你更可能找到正确的方向,整体进展更快。

如果想在这个路线图上继续延伸,我个人的建议方向包括:把 SFT 数据构造流程写成一个自动化 pipeline,接入自己的业务数据做垂直领域指令微调;或者在评估环节引入更严格的对抗测试集,专门攻击模型的推理漏洞;再进一步,也可以读一读 R1 的技术报告,看它是如何在强化学习阶段让模型自发涌现出“重新检查”和“反思”行为的,并尝试在更小的模型上复现出部分现象。这条路我还在走,希望你看了这篇笔记之后,能比我少走几个弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询