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
