nanoGPT:古诗集为例,训练一个自己的gpt模型

使用nanoGPT,手把手带你训练一个属于自己的GPT模型,基于gpt2,优点是cpu也可以跑,简单,快速(LLaMa的模型训练太耗费gpu,很多人也跑不了,所以暂时选择这个)

最终实现:以古诗集为例,训练一个可以续写诗词的gpt模型

开源地址

github.com/karpathy/nanoGPT
github.com/chinese-poetry/chinese-poetry

环境准备

以下可以做一个保存,模型训练这些环境都是必须的,这是小编整理的最简单的基础环境搭建流程,收藏不迷路

1 conda(python环境)

#网址:https://conda.io/en/latest/miniconda.html
wget https://repo.anaconda.com/miniconda/Miniconda3-py310_23.1.0-1-Linux-x86_64.sh #下载脚本
sh Miniconda3-py39_4.12.0-Linux-x86_64.sh # 执行
~/miniconda3/bin/conda init #初始化Shell,以便直接运行conda
conda create --name nanogpt python=3.9  #关启shell,创建虚拟环境
conda activate nanogpt #激活 

2 下载代码

wget https://github.com/karpathy/nanoGPT/archive/refs/heads/master.zip

3 安装依赖:

pip install transformers tiktoken tqdm

4 torch安装

https://pytorch.org/get-started/locally/
安装:pip3 install torch torchvision torchaudio

图片

测试:

图片

将例子demo跑起来

环境准备好了之后,切换到项目目录下,直接执行:

python data/shakespeare_char/prepare.py #数据结构处理
python train.py config/train_shakespeare_char.py  #训练,有GPU

无GPU
python train.py config/train_shakespeare_char.py --device=cpu --compile=False --eval_iters=20 --log_interval=1 --block_size=64 --batch_size=12 --n_layer=4 --n_head=4 --n_embd=128 --max_iters=2000 --lr_decay_iters=2000 --dropout=0.0

报错解决:
1 error:
RuntimeError: Current CUDA Device does not support bfloat16. Please switch dtype to float16.

图片

AttributeError: module 'torch' has no attribute 'compile'

图片

2 解决以上两个问题:
打开train.py文件,修改如下参数(73行附近)
dtype = 'float16'
compile = False

图片

结束标志:

best validation loss is 1.4697;默认250轮会保存一次模型;在训练差不多可以直接ctrl+c停掉

图片

模型保存路径:

图片

运行demo模型(sampling / inference)

python sample.py --out_dir=out-shakespeare-char
python sample.py --out_dir=out-shakespeare-char --device=cpu ## 无gpu

成功标志:

图片

训练自己的数据集

以下以古诗集为例,训练一个可以续写诗词的gpt模型

以下数据集,下载到根目录 (/nanoGPT-master/XX)

github.com/chinese-poetry/chinese-poetry
最全中华古诗词数据库, 唐宋两朝近一万四千古诗人, 接近5.5万首唐诗加26万宋诗. 两宋时期1564位词人,21050首词

图片

下载的诗词合集太多所以这里以唐诗为示例,所以第一是处理数据,收集所有唐诗相关数据(nanoGPT-master\chinese-poetry-master\全唐诗)并过滤

1 数据预处理

提取相关的唐诗数据

# -*- coding: utf-8 -*-
"""
目标:获取数据集中全唐诗,并提取五言诗词,两句的数据
 示例:
{
        "author": "郭向",
        "paragraphs": [
            "抱玉三朝楚,懷書十上秦。",
            "年年洛陽陌,花鳥弄歸人。"
        ],
        "title": "途中口號",
        "id": "32898701-8d9c-4b4d-b192-510564f63b2f"
    },
"""

import glob
import json
import os
datas_json=glob.glob("../../chinese-poetry-master/全唐诗/poet*.json") #1匹配所有唐诗json文件
# print(datas_json,"\n",len(datas_json))

if os.path.exists("tang_poet.txt"):
    os.remove("tang_poet.txt")
    print("已经删除原数据-tang_poet.txt")

print("总共处理文件个数:", len(datas_json))
print("预处理中,请稍后。。")
for data_json in datas_json[:]: #2处理匹配的每一个文件

    with open(data_json,"r",encoding="utf-8") as f:
        ts_data =json.load(f)
        for each_ts in ts_data[:]: #3处理文件中每段数据,只要五言诗和2句的
            paragraphs_list =each_ts["paragraphs"]
            if len(paragraphs_list) == 2 and len(paragraphs_list[0])==12 and len(paragraphs_list[1]) == 12:
                with open("tang_poet.txt","a",encoding="utf-8") as f2:
                    f2.write("".join(paragraphs_list))
                    f2.write("\n")

f =open("tang_poet.txt","r",encoding="utf-8")
print(len(f.readlines()))
print("success")
图片

2 生成网络数据

修改prepare.py:

图片

新建config/gu_char.py;内容复制train_shakespeare_char.py,就可以了

修改:out_dir = 'out-gu-char'
dataset = 'gu_poems'

图片

3 训练
python data/gu_poems/prepare.py

图片

python train.py config/gu_char.py

图片

查看train和val的loss 评估模型是否有问题;如果开始val收敛不好,可能数据太少

图片

4 推理

开始续写古诗。。
python sample.py --out_dir=out-gu-char

图片
THE END