零基础到精通:完整教程与代码,教你如何预训练自己的大模型!

大语言模型(Large Language Model,简称LLM),指使用大量文本数据训练的深度学习模型,可以生成自然语言文本或理解语言文本的含义。

虽然网上有大量关于transformer理论、大语言模型微调的教程。但是少有关于预训练的解释。本文则从如何自己实战预训练一个大语言模型的角度,使用wiki数据集进行一个简单的从零预训练工作,并附上使用swanlab launch白嫖显卡的方法

安装环境

首先,项目推荐使用python3.10。需要安装的python包如下:

swanlabtransformersdatasetsaccelerate

使用如下命令一键安装:

pip install swanlab transformers datasets accelerate modelscope

下载数据集

本教程使用的是中文wiki数据,理论上预训练数据集种类越丰富、数据量越大越好,后续会增加别的数据集。

huggingface链接:https://link.zhihu.com/?target=https%3A//huggingface.co/datasets/fjcanyue/wikipedia-zh-cn

百度网盘下载地址:https://link.zhihu.com/?target=https%3A//pan.baidu.com/s/1p5F52bRlnpSY7F78q0hz7A%3Fpwd%3Dj8ee(提取码:j8ee)

下载wikipedia-zh-cn-20240820.json文件后放到项目目录下./data/文件夹中

该数据集文件约1.99G大,共有1.44M条数据。虽然数据集中包含文章标题,但是实际上在预训练阶段用不上。正文片段参考:

数学是研究数量、结构以及空间等概念及其变化的一门学科,属于形式科学的一种。数学利用抽象化和逻辑推理,从计数、计算、量度、对物体形状及运动的观察发展而成。数学家们拓展这些概念...

使用 Huggingface Datasets加载数据集的代码如下:

from datasets import load_dataset
ds = load_dataset("fjcanyue/wikipedia-zh-cn")

如果使用百度网盘下载的json文件,可以通过如下代码加载​​​​​​​

raw_datasets = datasets.load_dataset(    "json", data_files="data/wikipedia-zh-cn-20240820.json")
raw_datasets = raw_datasets["train"].train_test_split(test_size=0.1, seed=2333)print("dataset info")print(raw_datasets)
构建自己的大语言模型

本教程使用 huggingface transformers构建自己的大模型。

因为目标是训练一个中文大模型。因此我们参考通义千问2的tokenize和模型架构,仅仅做一些简单的更改让模型更小更好训练。

因为国内无法直接访问到huggingface,推荐使用modelscope先把模型配置文件和checkpoint下载到本地,运行如下代码​​​​​​​

import modelscope
modelscope.AutoConfig.from_pretrained("Qwen/Qwen2-0.5B").save_pretrained(    "Qwen2-0.5B")modelscope.AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B").save_pretrained(    "Qwen2-0.5B")

配置参数,并修改模型注意力头数量、模型层数和中间层大小,把模型控制到大概120M参数左右(跟GPT2接近)。​​​​​​​

import transformers
tokenizer = transformers.AutoTokenizer.from_pretrained("./Qwen2-0.5B")   # 这里使用qwen2的tokenzierconfig = transformers.AutoConfig.from_pretrained(        "./Qwen2-0.5B",        vocab_size=len(tokenizer),        hidden_size=512,        intermediate_size=2048,        num_attention_heads=8,        num_hidden_layers=12,        n_ctx=context_length,        bos_token_id=tokenizer.bos_token_id,        eos_token_id=tokenizer.eos_token_id,    )print("Model Config:")print(config)

使用transformers库初始化模型​​​​​​​

model = transformers.Qwen2ForCausalLM(config)model_size = sum(t.numel() for t in model.parameters())print(f"Model Size: {model_size/1000**2:.1f}M parameters")

设置训练参数

设置预训练超参数:​​​​​​​

args = transformers.TrainingArguments(    output_dir="checkpoints",    per_device_train_batch_size=24,  # 每个GPU的训练batch数    per_device_eval_batch_size=24,  # 每个GPU的测试batch数    eval_strategy="steps",    eval_steps=5_000,    logging_steps=500,    gradient_accumulation_steps=12,  # 梯度累计总数    num_train_epochs=2, # 训练epoch数    weight_decay=0.1,    warmup_steps=1_000,    optim="adamw_torch",  # 优化器使用adamw    lr_scheduler_type="cosine",  # 学习率衰减策略    learning_rate=5e-4,  # 基础学习率,    save_steps=5_000,    save_total_limit=10,    bf16=True,  # 开启bf16训练, 对于Amper架构以下的显卡建议替换为fp16=True)print("Train Args:")print(args)

初始化训练+使用swanlab进行记录

使用transformers自带的train开始训练,并且引入swanlab作为可视化日志记录​​​​​​​

from swanlab.integration.huggingface import SwanLabCallbacktrainer = transformers.Trainer(    model=model,    tokenizer=tokenizer,    args=args,    data_collator=data_collator,    train_dataset=tokenized_datasets["train"],    eval_dataset=tokenized_datasets["test"],    callbacks=[SwanLabCallback()],)trainer.train()

如果是第一次使用SwanLab,需要登陆SwanLab官网https://swanlab.cn/,注册,并且在如下位置找到和复制自己的key。

接下来在命令行中输入

swanlab login

会看到提示输入key

按照提示将key粘贴进去(注意key是不会显示到终端当中的)就可以完成配置,完成效果如下:

完整代码

项目目录结构:​​​​​​​

|---data\|------wikipedia-zh-cn-20240820.json    # 数据集放在data文件夹中|--- pretrain.py

pretrain.py代码如下:​​​​​​​

import datasetsimport transformersimport swanlabfrom swanlab.integration.huggingface import SwanLabCallbackimport modelscope
def main():    # using swanlab to save log    swanlab.init("WikiLLM")
    # load dataset    raw_datasets = datasets.load_dataset(        "json", data_files="/data/WIKI_CN/wikipedia-zh-cn-20240820.json"    )
    raw_datasets = raw_datasets["train"].train_test_split(test_size=0.1, seed=2333)    print("dataset info")    print(raw_datasets)
    # load tokenizers    # 因为国内无法直接访问HuggingFace,因此使用魔搭将模型的配置文件和Tokenizer下载下来    modelscope.AutoConfig.from_pretrained("Qwen/Qwen2-0.5B").save_pretrained(        "Qwen2-0.5B"    )    modelscope.AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B").save_pretrained(        "Qwen2-0.5B"    )    context_length = 512  # use a small context length    # tokenizer = transformers.AutoTokenizer.from_pretrained("Qwen/Qwen2-0.5B")    tokenizer = transformers.AutoTokenizer.from_pretrained(        "./Qwen2-0.5B"    )  # download from local
    # preprocess dataset    def tokenize(element):        outputs = tokenizer(            element["text"],            truncation=True,            max_length=context_length,            return_overflowing_tokens=True,            return_length=True,        )        input_batch = []        for length, input_ids in zip(outputs["length"], outputs["input_ids"]):            if length == context_length:                input_batch.append(input_ids)        return {"input_ids": input_batch}
    tokenized_datasets = raw_datasets.map(        tokenize, batched=True, remove_columns=raw_datasets["train"].column_names    )    print("tokenize dataset info")    print(tokenized_datasets)    tokenizer.pad_token = tokenizer.eos_token    data_collator = transformers.DataCollatorForLanguageModeling(tokenizer, mlm=False)
    # prepare a model from scratch    config = transformers.AutoConfig.from_pretrained(        "./Qwen2-0.5B",        vocab_size=len(tokenizer),        hidden_size=512,        intermediate_size=2048,        num_attention_heads=8,        num_hidden_layers=12,        n_ctx=context_length,        bos_token_id=tokenizer.bos_token_id,        eos_token_id=tokenizer.eos_token_id,    )    model = transformers.Qwen2ForCausalLM(config)    model_size = sum(t.numel() for t in model.parameters())    print("Model Config:")    print(config)    print(f"Model Size: {model_size/1000**2:.1f}M parameters")
    # train    args = transformers.TrainingArguments(        output_dir="WikiLLM",        per_device_train_batch_size=32,  # 每个GPU的训练batch数        per_device_eval_batch_size=32,  # 每个GPU的测试batch数        eval_strategy="steps",        eval_steps=5_00,        logging_steps=50,        gradient_accumulation_steps=8,  # 梯度累计总数        num_train_epochs=2,  # 训练epoch数        weight_decay=0.1,        warmup_steps=2_00,        optim="adamw_torch",  # 优化器使用adamw        lr_scheduler_type="cosine",  # 学习率衰减策略        learning_rate=5e-4,  # 基础学习率,        save_steps=5_00,        save_total_limit=10,        bf16=True,  # 开启bf16训练, 对于Amper架构以下的显卡建议替换为fp16=True    )    print("Train Args:")    print(args)    # enjoy training    trainer = transformers.Trainer(        model=model,        tokenizer=tokenizer,        args=args,        data_collator=data_collator,        train_dataset=tokenized_datasets["train"],        eval_dataset=tokenized_datasets["test"],        callbacks=[SwanLabCallback()],    )    trainer.train()
    # save model    model.save_pretrained("./WikiLLM/Weight")  # 保存模型的路径
    # generate    pipe = transformers.pipeline("text-generation", model=model, tokenizer=tokenizer)    print("GENERATE:", pipe("人工智能", num_return_sequences=1)[0]["generated_text"])    prompts = ["牛顿", "北京市", "亚洲历史"]    examples = []    for i in range(3):        # 根据提示词生成数据        text = pipe(prompts[i], num_return_sequences=1)[0]["generated_text"]        text = swanlab.Text(text)        examples.append(text)    swanlab.log({"Generate": examples})

if __name__ == "__main__":    main()

训练结果演示

运行如下命令

python pretrain.py

可以看到如下训练日志。由于训练时间较长,推荐使用tmux将训练任务hold住

可以在SwanLab中查看最终的训练结果:

使用训练好的模型进行推理

以“人工智能”为开头生成内容的代码如下:​​​​​​​

pipe = transformers.pipeline("text-generation", model=model, tokenizer=tokenizer)print("GENERATE:", pipe("人工智能", num_return_sequences=1)[0]["generated_text"])

推理效果如下:

(模型训练ing,可以在https://link.zhihu.com/?target=https%3A//swanlab.cn/%40ShaohonChen/WikiLLM/overview实时查看训练进展和推理效果)

如何学习AI大模型?

​​​​​​​

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。


👉学会后的收获:👈
• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。


1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值