中文大模型预训练实战:1.4B参数从零开始

2026-06-22阅读 0热度 0
ai 人工智能

这篇文章详细记录了从零起步完整复现1.4B参数中文大语言模型的全流程。基座模型采用QWEN系列,训练数据总量约8B token,算力配置为两张A100 80G显卡,累计训练时长约100小时。虽然规模远不及数百亿甚至千亿参数的大模型,但最终效果基本达到预期。整个复现过程中踩了不少坑,也沉淀了一些可直接复用的实战经验,整理出来供有类似需求的团队参考。

项目代码仓库地址:https://github.com/jiahe7ay/MINI_LLM ——名字实在没想好,索性就叫miniLLM了。

动机

决定做这件事主要基于三个考量。

第一,Allen实验室发布的OLMO技术报告让人印象深刻。他们不仅细致公开了训练细节,还把从数据处理、模型训练到评估的完整代码全部开源。这种透明度值得学习,也希望能把自己踩过的坑和积累的方法分享出来。

第二,说实话,一直想亲自预训练一个大模型,但又总是犹豫——既担心能力不足,也怕算力不够。直到在GitHub上发现两个项目:baby-llama2-chinesePhi2-mini-Chinese。深入研究后发现,个人复现大模型并没有想象中那么遥不可及。于是决定参考这两个项目的成功经验,换用自选的模型架构和训练数据集,尝试跑通一套自己的“大模型”。过程虽然折腾,但相比只看论文,这种动手实践对理解预训练机制带来的收获要大得多。

第三,一个明显的行业趋势是:越来越多的厂商开始关注小参数模型,比如Qwen-0.5B、Phi-2B。这说明小参数模型在大模型生态中逐渐找到了自己的位置。相比参数量庞大的模型,小模型计算需求低、训练速度快、资源占用少,更多个人和团队有能力参与进来。而且这类模型在不少具体任务上表现也不差,实际应用价值正在被验证。从长远角度看,小参数模型这条路线值得持续投入。

细节

模型基座的选择

项目选用QWEN作为基座,通过调整注意力头数和层数将参数量扩展到1.4B。具体配置改动在项目代码的config文件中均可查见,这里不赘述。选QWEN的主要原因是它在中文开源大模型中成熟度和稳定性都较高。另外也注意到,不少个人复现项目会自训练tokenizer,但这一步确实耗时费力。权衡后决定直接复用现成的开源tokenizer。对比了几个主流tokenizer的压缩率和训练规模后,QWEN的tokenizer表现突出,于是连整个模型架构也一并采用QWEN。毕竟核心目标是复现实践,而非从零创造全新模型。

训练数据的选择

本次训练主要使用了以下数据:

  • wikipedia-cn-20230720-filtered:基于2023年7月20日的中文维基dump,只保留了质量较高的约25万条条目。
  • 中文BaiduBaike数据
  • 天工150B中文预训练数据集:受限于算力,仅下载了前20个文件。
  • Bell数据集:分别使用了其中的2M、0.5M和1M子集作为SFT训练数据。

训练集构造

数据预处理遵循QWEN的通用办法:每篇文章末尾添加专用的结束符 <|im_end|>,清晰界定单篇边界,确保模型训练时能准确区分不同样本。对于超出输入序列长度限制的文章,直接截断到规定长度,截断部分作为下一个独立样本。这样既保证了输入合规性,又避免浪费原始数据。

环境

如果能装上flash-attn,训练速度大概可提升20%。但实话讲,这组件现在越来越难装了。具体依赖版本如下:

datasets
transformers==4.36.0
torch==2.2.0
accelerate==0.27.2
einops==0.7.0
flash-attn==2.5.5
tiktoken
einops

训练参数

预训练参数配置如下:

per_device_train_batch_size=24,
per_device_eval_batch_size=4,
gradient_accumulation_steps=10,
num_train_epochs=1,
weight_decay=0.1,
ddp_find_unused_parameters=False,
warmup_steps=0,
learning_rate=1e-4,
evaluation_strategy='steps',
eval_steps=100,
sa ve_steps=50,
sa ve_strategy='steps',
sa ve_total_limit=4,
report_to='tensorboard',
optim="adamw_torch",
lr_scheduler_type='cosine',
bf16=True,
logging_steps=20,
log_level='info',
logging_first_step=True,

SFT阶段的训练参数:

per_device_train_batch_size=32,
gradient_accumulation_steps=2,
num_train_epochs=3,
weight_decay=0.1,
warmup_steps=0,
learning_rate=6e-5,
ddp_find_unused_parameters=False,
evaluation_strategy='steps',
eval_steps=500,
sa ve_steps=500,
sa ve_total_limit=3,
report_to='tensorboard',
optim="adamw_torch",
remove_unused_columns=False,
lr_scheduler_type='cosine',
bf16=True,
logging_steps=10,
log_level='info',
logging_first_step=True,

两个关键注意点:

  • 多卡训练时建议将 ddp_find_unused_parameters 设为 False,能明显提升训练速度。
  • 尽量调大单卡的batch size。尝试过用较小的单卡bs搭配较大的梯度累积步数凑总bs,但收敛速度明显不如直接放大单卡bs。推测与学习率调度机制有关。

训练加速

使用accelerate库配合deepspeed实现多卡加速,启动命令是 accelerate launch --multi_gpu --config_file accelerate_multi_gpu.yaml xx.py。deepspeed配置文件如下:

compute_environment: LOCAL_MACHINE
debug: false
deepspeed_config:
  gradient_accumulation_steps: 10
  gradient_clipping: 1.0
  offload_optimizer_device: cpu
  offload_param_device: cpu
  zero3_init_flag: false
  zero3_sa ve_16bit_model: false
  zero_stage: 2
distributed_type: DEEPSPEED
downcast_bf16: 'no'
machine_rank: 0
main_training_function: main
mixed_precision: bf16
num_machines: 1
num_processes: 2
rdzv_backend: static
same_network: true
tpu_env: []
tpu_use_cluster: false
tpu_use_sudo: false
use_cpu: false

启动训练

(此部分原文无具体解释性内容,保留标题。)

训练结果

预训练loss

先用维基百科加百度百科的数据进行第一轮预训练,保存好checkpoint权重,再基于该权重继续训练。

SFT训练loss

(此部分原文无具体描述。)

从上面这几张Loss图可以清楚看出,大模型训练确实遵循scaling law——曲线走势基本一致。这次亲手实践后,对scaling law的理解又加深了一层。

模型效果

1. 简单的问好

(此部分原文内容为空。)

2. 一些通识类的问题

比如关于乔布斯的问题,基本能答对80%。但存在典型幻觉:模型说乔布斯是在攻读博士期间开始创业的,这明显不符合事实。苹果公司相关问题回答基本正确。不过介绍广州时出现了重复回答,同一个句子中“广州塔”出现了两次。

3. 模型有分辨问题并进行准确回答的能力

测试了四个问题,全部回答正确。

4. 尝试使用它来写一下代码

先让它写一个排序算法,它用文字给出了思路。乍一看是冒泡排序,但仔细看第2步描述——“继续比较下一个值和最后一个值”——这个“最后一个值”明显多余,差一点才能完全正确。然后让它用Python写排序算法,结果直接变成了调包侠。不过注释部分仍存在问题:第一条注释说“将排序后的结果储存在新的列表中”,但代码里并未这样做;第二条注释中的列表名也写错了。

5. 尝试写一下文案

这部分表现倒是有模有样,基本符合预期。

总结

这次实践从准备到完成大约花了一个月时间。整个项目代码量不大,但过程确实充满折腾。作为一个独立项目,各种报错和问题层出不穷,只能逐一排查、解决。其中的艰辛,只有真正动手做过的人才能体会。

不过,正是这些挑战让做模型的乐趣变得格外真实。每解决一个bug、每看到模型性能往上跳一点,那种成就感跟通关一个好游戏差不多。这种乐趣不仅来自技术本身的挑战,更来自对知识探索和实际应用的满足感。

后续还会继续尝试训练更多的模型和数据,希望能为中文大模型的开源社区多贡献一点力量。

最后,感谢所有能看到这里的朋友。

QA

Q:为什么没有使用强化学习?
A:其实试过DPO来做强化学习,但效果不太理想,知识遗忘得比较厉害。不确定是训练数据的问题还是方法本身的问题,后续会继续尝试用强化学习来优化模型。

Q:项目的后续计划是什么?
A:有可能会继续增加数据规模接着训练,或者转向尝试训练一个MoE(混合专家)模型。

Q:为什么没有用C-EVAL做评测?
A:坦白说,目前这个模型能力还比较弱,等后续能力提升之后再去做更有挑战性的评测。

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

相关阅读

更多
欢迎回来 登录或注册后,可保存提示词和历史记录
登录后可同步收藏、历史记录和常用模板
注册即表示同意服务条款与隐私政策