• 仅用61行代码,你也能从零训练大模型


    本文并非基于微调训练模型,而是从头开始训练出一个全新的大语言模型的硬核教程。看完本篇,你将了解训练出一个大模型的环境准备、数据准备,生成分词,模型训练、测试模型等环节分别需要做什么。AI 小白友好~文中代码可以直接实操运行。

    通过这篇文章,你可以预训练一个全新大语言模型。注意是全新的模型,不是微调。

    全新训练的好处是训练的数据、训练的参数都是可修改的,通过调试运行我们可以更好的理解大模型训练过程。我们可以用特定类型数据的训练,来完成特定类型数据的输出。

    技术交流

    技术要学会分享、交流,不建议闭门造车。一个人可以走的很快、一堆人可以走的更远。

    相关资料、数据、技术交流提升,均可加我们的交流群获取,群友已超过2000人,添加时最好的备注方式为:来源+兴趣方向,方便找到志同道合的朋友。

    方式①、添加微信号:mlc2060,备注:来自CSDN + 技术交流
    方式②、微信搜索公众号:机器学习社区,后台回复:加群

    关于大模型已经有很多文章,微调模型的文章比较多,全新预训练全新模型的文章很少。个人觉得有的也讲的很复杂,代码也很难跑通。本文不会讲的很复杂,代码也很容易运行。仅用61行代码,就能训练出一个全新大语言模型。

    图片

    本文以代码为主,运行代码需要 Python 环境。

    01 准备训练环境

    我的训练环境基于腾讯云的 GPU 机器。

    地址:https://cloud.tencent.com/product/gpu

    • GPU类型:GN7.2XLARGE32 T4 显卡:1颗 显存:16GB;
    • python 3.11;
    • requirements.txt:
    tokenizers==0.13.3
    torch==2.0.1
    transformers==4.30.
    
    • 1
    • 2
    • 3

    02 准备训练数据

    首先我们要为训练准备数据,比如我就想基于《三国演义》训练一个模型。三国演义下载地址:

    https://raw.githubusercontent.com/xinzhanguo/hellollm/main/text/sanguoyanyi.txt

    图片

    03 训练分词器

    分词(tokenization)是把输入文本切分成有意义的子单元(tokens)。通过以下代码,根据我们的数据生成一个新的分词器:

    from tokenizers import Tokenizer
    from tokenizers.models import BPE
    from tokenizers.trainers import BpeTrainer
    from tokenizers.normalizers import NFKC, Sequence
    from tokenizers.pre_tokenizers import ByteLevel
    from tokenizers.decoders import ByteLevel as ByteLevelDecoder
    from transformers import GPT2TokenizerFast
    
    # 构建分词器 GPT2 基于 BPE 算法实现
    tokenizer = Tokenizer(BPE(unk_token=""))
    tokenizer.normalizer = Sequence([NFKC()])
    tokenizer.pre_tokenizer = ByteLevel()
    tokenizer.decoder = ByteLevelDecoder()
    
    special_tokens = ["","","","",""]
    trainer = BpeTrainer(vocab_size=50000, show_progress=True, inital_alphabet=ByteLevel.alphabet(), special_tokens=special_tokens)
    # 创建 text 文件夹,并把 sanguoyanyi.txt 下载,放到目录里
    files = ["text/sanguoyanyi.txt"]
    # 开始训练了
    tokenizer.train(files, trainer)
    # 把训练的分词通过GPT2保存起来,以方便后续使用
    newtokenizer = GPT2TokenizerFast(tokenizer_object=tokenizer)
    newtokenizer.save_pretrained("./sanguo")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    运行时显示如下图:

    图片

    成功运行代码后,我们在 sanguo 目录生成如下文件:

    merges.txt
    special_tokens_map.json
    tokenizer.json
    tokenizer_config.json
    vocab.json
    
    • 1
    • 2
    • 3
    • 4
    • 5

    现在我们已经成功训练了一个大语言模型的分词器。

    04 训练模型

    利用下面代码进行模型训练:

    from transformers import GPT2Config, GPT2LMHeadModel, GPT2Tokenizer
    # 加载分词器
    tokenizer = GPT2Tokenizer.from_pretrained("./sanguo")
    tokenizer.add_special_tokens({
      "eos_token": "",
      "bos_token": "",
      "unk_token": "",
      "pad_token": "",
      "mask_token": ""
    })
    # 配置GPT2模型参数
    config = GPT2Config(
      vocab_size=tokenizer.vocab_size,
      bos_token_id=tokenizer.bos_token_id,
      eos_token_id=tokenizer.eos_token_id
    )
    # 创建模型
    model = GPT2LMHeadModel(config)
    # 训练数据我们用按行分割
    from transformers import LineByLineTextDataset
    dataset = LineByLineTextDataset(
        tokenizer=tokenizer,
        file_path="./text/sanguoyanyi.txt",
        block_size=32,
      # 如果训练时你的显存不够
      # 可以适当调小 block_size
    )
    from transformers import DataCollatorForLanguageModeling
    data_collator = DataCollatorForLanguageModeling(
        tokenizer=tokenizer, mlm=False, mlm_probability=0.15
    )
    
    from transformers import Trainer, TrainingArguments
    # 配置训练参数
    training_args = TrainingArguments(
        output_dir="./output",
        overwrite_output_dir=True,
        num_train_epochs=20,
        per_gpu_train_batch_size=16,
        save_steps=2000,
        save_total_limit=2,
    )
    trainer = Trainer(
        model=model,
        args=training_args,
        data_collator=data_collator,
        train_dataset=dataset,
    )
    trainer.train()
    # 保存模型
    model.save_pretrained('./sanguo')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    运行比较耗时,显示训练数据如下图:

    图片

    成功运行代码,我们发现 sanguo 目录下面多了三个文件:

    config.json
    generation_config.json
    pytorch_model.bin
    
    • 1
    • 2
    • 3

    现在我们就成功生成训练出基于《三国演义》的一个大语言模型。

    05 测试模型

    我们用文本生成,对模型进行测试代码如下:

    from transformers import pipeline, set_seed
    generator = pipeline('text-generation', model='./sanguo')
    set_seed(42)
    txt = generator("吕布", max_length=10)
    print(txt)
    
    • 1
    • 2
    • 3
    • 4
    • 5

    运行显示模型输出了三国相关的文本:“吕布十二回 张翼德 张翼德时曹操 武侯计计计”

    图片

    再测试一条:

    txt = generator("接着奏乐", max_length=10)
    print(txt)
    
    • 1
    • 2

    “接着奏乐\u3000却说曹操引军因二人”

    图片

    这内容不忍直视,如果想优化,我们也可以基于全新的模型进行微调训练;我们也可以适当地调整下训练参数,以达到较好的效果。

    06 完整代码

    以下是完整代码,代码地址:

    https://github.com/xinzhanguo/hellollm/blob/main/sanguo.py

    linux 中运行方法:

    # 创建环境
    python3 -m venv ~/.env
    # 加载环境
    source ~/.env/bin/activate
    # 下载代码
    git clone git@github.com:xinzhanguo/hellollm.git
    cd hellollm
    # 安装依赖
    pip install -r requirements.txt
    # 运行代码
    python sanguo.py
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    以上我们就完成一个全新的模型训练。代码去除注释空行总共61行。

    本文代码模型是基于 GPT2 的,当然你也可以基于 LLama 或者 Bert 等模型去实现全新的大语言模型。

    代码虽然不是很多,但是如果初次尝试运行的话你也许会遇到很多问题,比如环境搭建。为了避免其他烦恼,我建议用 docker 方式运行代码:

    # 下载代码
    git clone git@github.com:xinzhanguo/hellollm.git
    cd hellollm
    # 编译镜像
    docker build -t hellollm:beta .
    # 可以选择以GPU方式运行
    # docker run -it --gpus all hellollm:beta sh
    docker run -it hellollm:beta sh
    python sanguo.py
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    更多代码可以参考:Hello LLM!

    https://github.com/xinzhanguo/hellollm

    以上就是本篇文章的全部内容,欢迎转发分享。

  • 相关阅读:
    Eureka
    Mybatis、MybatisPlus自定义返回单个Map集合
    java面试题
    C# 通过winmm枚举音频设备
    XML简介
    【老生谈算法】matlab实现低阶函数的二维图像获取——二维图像获取
    linux 文件管理
    Java异常机制
    全球名校AI课程库(4)| Stanford斯坦福 · 机器学习课程『Machine Learning』
    Docker数据集与自定义镜像:构建高效容器的关键要素
  • 原文地址:https://blog.csdn.net/2301_78285120/article/details/133721239