从零开始开发开源大语言模型:从预训练到RLHF(PPO/GRPO)
摘要
一位开发者分享了从零开始训练一个70亿参数开源大语言模型的进展,该模型基于DeepSeek架构并针对低显存进行了优化,目标是推动AI开发的民主化,并最终超越大型专有模型。
大家好,我一直在从头开发一个大语言模型(LLM)。它基于DeepSeek架构,并大幅减少了显存占用(使用了GUM+muon优化)。以下是当前用于预训练的JSON schema,应该足够说明当前进展。我拥有两块6000 Pro 600W显卡。正在测试一个含64个专家的70亿参数模型……目前单GPU运行,达到100%吞吐量(最难的部分),训练占用约80GB显存。(减少专家数量会显著降低显存占用——我不过是在挑战极限!)
我的主要目标是:让开源开发远远超越大公司的开发速度。我相信,一定有人能够利用这个项目,从头构建出一个击败所有顶级万亿参数模型的LLM。我的目标是创建一个庞大的已训练模型数据库,供任何人使用。未来,或许可以支持从开源开发者处租用模型作为辅助功能。话不多说,以下是技术报告:
由于我使用的是DOLMA/redpajama数据集,你可以按数据拆分,让模型在数学、文学、物理等领域分别训练,然后作为智能体集成部署(这是待办事项,目前我还没有可对比的单一模型)。本方案也遵循了Chinchilla最优策略!感谢DeepMind!
全部使用bfloat16,可配置为fp16或fp32(如果你来自未来,且拥有一块能以bf16速度运行fp32的GPU)。没错,在此期间我多次崩溃,但总算有了可运行的东西!目前已经进行了15000步。
======================================================================
[事实准确性测试] 第14000步
======================================================================
Prompt: "The capital of France is"
Output: "the city of Nice. France may also refer to: France (surname) France (surname) France (or Republ..." [正确]
Prompt: "The capital of Japan is"
Output: "the capital of the autonomous prefecture of Hokkaido. Etymology The name of Hokkaido is derived fro..." [期望:Tokyo]
Prompt: "def fibonacci(n): """Return the nth Fibonacci ..."
Output: """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""..."
Prompt: "import torch import torch.nn as nn class Transfor..."
Output: "// InverterBlock // s2, s2, s3 // A_1, A_2, A_3, A_4, A_5, A_6 // A1, A2, A3, A4, A5 // A1, A2, A3, ..."
Prompt: "The theory of relativity states that"
Output: "the speed of light varies with the speed of the observer. This is a constant, since the speed of lig..."
Prompt: "In machine learning, gradient descent is used to"
Output: "perform a gradient descent, where the gradient is calculated via a local gradient. The gradient eval..."
Prompt: "Question: What is 2 + 2? Answer:"
Output: "2 + 2 Author: PCR Date Submitted: 2nd April 2013 Pp: 200-201 Exercise: Exercise 2.0 2 + 1 = 2 +..." [期望:4]
Prompt: "Question: Explain the concept of recursion. Answer..."
Output: "In programming, a function or sequence of operations is a function that can transform a variable to ..."
事实准确性:1/3 = 33.3%
----------------------------------------------------------------------
[SMBench] 第14000步 -- 1/5: 多规则推理
. . .
定义架构的JSON结构如下:
"experiment_name": "deepseek_v3_7b_lowvram",
"output_dir": "*******",
"seed": 420,
"model": {
"num_layers": 24,
"vocab_size": 50304,
"norm_type": "rmsnorm",
"norm_eps": 1e-06,
"tie_word_embeddings": false,
"init_method_std": 0.006,
"first_k_dense_replace": 8,
"dense_layer_interval": 1,
"paper_compliant": false,
"mla": {
"d_model": 1408,
"d_latent": 352,
"num_heads": 22,
"num_kv_heads": 2,
"max_context_length": 4096,
"use_flash_mla": false,
. . .
},
"moe": {
"num_experts": 64,
"num_experts_per_token": 4,
"expert_intermediate_size": 1536,
"expert_dim": 1536,
"dropout": 0.0,
"num_shared_experts": 1,
. . . .
}
},
"fusions": {
"use_fused_expert_ffn": true,
"use_te_fused_topk": false,
"use_te_fused_permute": false,
"use_fused_softmax": true,
"fused_softmax_in_fp32": true,
"use_group_limited_topk": true,
. . .
},
"memory_optimization": {
"use_galore": false,
"galore_rank": 256,
"galore_update_proj_gap": 500,
"galore_scale": 1.0,
. . .
},
"training": {
"device": "cuda",
"global_batch_size": 256,
"micro_batch_size": 4,
"gradient_accumulation_steps": 64,
"seq_length": 1024,
"max_batch_seq_multiplier": 1.25,
"tokens_per_parameter_ratio": 40.0,
"total_training_tokens": 280000000000,
"learning_rate": 0.00042,
"min_learning_rate": 4.2e-05,
"lr_preset": "deepseek_v3",
. . .
},
"data": {
"use_multi_source": true,
"sources": [
{
"name": "redpajama",
"type": "dolma",
"subset": "dolma_v1_6_redpajama",
"weight": 0.45,
"description": "RedPajama - CommonCrawl-like diverse web/code/books"
},
{
"name": "stack",
"type": "dolma",
"subset": "dolma_v1_6_stack",
"weight": 0.25,
. . .
}
],
"cache_dir": "*******",
"sanitization": {
"enabled": true,
"target_language": "en",
"min_language_confidence": 0.9,
"min_article_length": 100,
. . .
},
"preprocessing": {
"num_workers": 8,
"shuffle": true,
"shuffle_seed": 42,
. . .
},
"max_articles": null,
"focus_historical": false,
"boost_hiroshima_content": false
},
"distributed": {
"backend": "nccl",
"launcher": "single_gpu",
"tensor_parallel_size": 1,
"pipeline_parallel_size": 1,
"expert_parallel_size": 1,
"data_parallel_size": 1,
"zero_stage": 2,
"zero_offload": true,
"overlap_grad_reduce": true,
"overlap_param_gather": true,
"deepspeed": {
"enabled": false
}
},
"checkpointing": {
"save_interval": 1000,
"save_total_limit": 3,
"resume_from_checkpoint": null,
"checkpoint_format": "pytorch",
"save_optimizer_states": true
},
"logging": {
"log_level": "INFO",
"log_interval": 100,
"tensorboard_dir": "*******",
"wandb": {
"enabled": false
},
"tensorboard": {
"enabled": true
}
},
"validation": {
"enabled": true,
"eval_interval": 1000,
"eval_samples": 500,
"metrics": [
"loss",
"perplexity"
],
"patience": 300,
"early_stopping": false
},
"profiling": {
"trace_nvtx": false
},
"gpu_optimization": {
"cuda_graphs": true,
"torch_compile": true,
"flash_attention": true,
"fused_kernels": true,
"autocast_dtype": "bfloat16"
},
"test_prompts": {
"enabled": true,
. . .
基本上,我研究并尝试了地球上所有能想到的优化方法。甚至尝试自建FlashMLA来适配sm120 Blackwell架构,但惨遭失败——虽然推理能跑通,但反向传播由于分块(tiling)问题无法进行,结果与Aeten torch后端一样甚至更差……不过目前这套方案还能工作,每个步骤约20秒。例如训练进度:
1%|█ | 14609/1000000 [53:18:23<5533:28:53, 23.37s/step, loss=2.1507, mtp=1.9643, ent=4.12, util=100.0%, imbal=0.26, lr=4.20e-04, tok=2.23B]
所以,结论是:我很害怕将这个项目开源,直到它100%正常工作为止,以尽量减少社区可能会给我的负面反馈。我唯一的顾虑是:我希望所有使用本代码训练出的模型都必须是公开的,我不希望任何人将其私有化并用于盈利而不开源。因此我需要征求大家的意见,寻找合适的方法来解决这个问题。因为我相信,总有一天会有人找到正确的配置,训练出超过顶级性能的模型。这正是我这样做的原因——我知道自己无法创造那个“终极模型”,但我确信一定有某个天才能够利用这个工具训练出SOTA模型。
在我将代码公开前,还有许多清理工作需要完成,因为我害怕那些我独自一人肯定无法解决的bug和反馈。如果你感兴趣,可以定期查看我的账户,我会在决定公开此仓库时发布消息。
我不知道……我欢迎大家给出反馈,关于如何正确地公开此项目,并制定严格的规则:使用此代码训练出的所有safetensors或checkpoints都必须开源。我知道,只要给予合适的工具,一定有人能够构建一个包含100亿到500亿参数的模型集成,达到接近SOTA水平的性能!正如他们常说的:分而治之。
这篇已经写得太长了,我已经吐了。
相似文章
DeepSeek LLM:以长期主义扩展开源语言模型
DeepSeek LLM是一个开源语言模型项目,它开发了一个大规模数据集,并采用SFT和DPO,在各种基准测试和开放式评估中实现了超越LLaMA-2 70B和GPT-3.5的性能。
@heygurisingh: 过去训练参数量达数十亿的LLM需要花费1000万美元以上。有人开源了一个仓库,现在可以在单张GPU上完成。
一个名为train-llm-from-scratch的开源仓库使得在单张GPU上训练十亿级参数的LLM成为可能,它提供了一个从原始文本到推理的可配置流水线,包括数据集流式加载和检查点保存,采用MIT许可证。
@oliviscusAI:OpenAI 联合创始人刚刚发布了他的个人指南,教你从头训练大语言模型。它叫 llm.c。无需繁琐设置。只…
OpenAI 联合创始人 Andrej Karpathy 发布了 llm.c,这是一份开源指南,教你如何从头训练大语言模型。代码简洁,可在任何硬件上运行,包括 CPU 和 MacBook,并且比标准方法快 7%。
@neural_avb: 如果你仔细想想,2026年的LLM训练其实是一个三步循环:- 用一些数据训练 - 内部测试/运行分类评估…
这条推文概述了2026年LLM训练的三步循环:用数据训练、运行评估、为表现不佳的任务添加合成数据。它强调了通过开源模型和廉价API进行合法蒸馏的易得性,并指出仅凭推理轨迹训练就能获得高分。
从零构建一个复古风格的LLM
作者记录了从零构建一个340M参数LLM的过程,该模型仅使用1900年以前的文本进行训练,包括自定义数据集、训练脚本,并开源了模型和代码。