update readme

This commit is contained in:
anrongqiao 2024-04-29 19:37:04 +08:00
parent 56a831ec8d
commit c6a5a5c243
2 changed files with 118 additions and 28 deletions

View File

@ -1,9 +1,14 @@
# 九格大模型使用文档 # 九格大模型使用文档
模型的训练、推理环境及其硬件的信息: ## 环境配置:
[环境配置、硬件信息](https://www.osredm.com/jiuyuan/CPM-9G-8B/tree/master/quick_start_clean/readmes/README_ENV.md)
[百亿SFT开源模型](https://qy-obs-6d58.obs.cn-north-4.myhuaweicloud.com/checkpoints-epoch-1.tar.gz)
[环境配置、硬件信息](https://www.osredm.com/jiuyuan/CPM-9G-8B/tree/master/quick_start_clean/readmes/README_ENV.md)
## 开源模型
1 目前启元开源了80B的百亿SFT模型模型的路径[百亿SFT开源模型](https://qy-obs-6d58.obs.cn-north-4.myhuaweicloud.com/checkpoints-epoch-1.tar.gz)
## 使用教程
为了帮助您快速了解CPM-9G的使用我们准备了一个快速入门教程目标是基于CPM-9G基座模型通过指令微调的方式构建一个Chat模型。 为了帮助您快速了解CPM-9G的使用我们准备了一个快速入门教程目标是基于CPM-9G基座模型通过指令微调的方式构建一个Chat模型。
@ -15,7 +20,7 @@
#### 1. 准备jsonl文件 #### 1. 准备jsonl文件
首先需要将原始数据处理位jsonl形式每一行一个json每行包含两个字段分别是input和output以下是一个例子 首先需要将原始数据处理位jsonl形式每一行一个json每行包含两个字段分别是input和output以下是一个例子
{"input":"", "output": "我爱北京。"}实际预训练时数据多为txt格式可以参照以下过程将txt格式的文件转换为jsonl格式 {"input":"", "output": "我爱北京。"}实际预训练时数据多为txt格式可以参照以下过程将txt格式的文件转换为jsonl格式
```js ``` python
# convert_txt2jsonl.py # convert_txt2jsonl.py
import json import json
import sys import sys
@ -31,10 +36,9 @@ for line in sys.stdin:
cat pretrain.txt | python convert_txt2jsonl.py > pretrain.jsonl cat pretrain.txt | python convert_txt2jsonl.py > pretrain.jsonl
``` ```
在本Quick Start教程中已准备好jsonl数据,路径为raw_data/alpaca_zh.jsonl示例如下 在本Quick Start教程中已准备好jsonl数据,路径为raw_data/alpaca_zh.jsonl示例如下
```js ```json
{"input": "<用户>保持健康的三个提示。<AI>", "output": "以下是保持健康的三个提示:\n\n1. 保持身体活动。每天做适当的身体运动,如散步、跑步或游泳,能促进心血管健康,增强肌肉力量,并有助于减少体重。\n\n2. 均衡饮食。每天食用新鲜的蔬菜、水果、全谷物和脂肪含量低的蛋白质食物,避免高糖、高脂肪和加工食品,以保持健康的饮食习惯。\n\n3. 睡眠充足。睡眠对人体健康至关重要,成年人每天应保证 7-8 小时的睡眠。良好的睡眠有助于减轻压力,促进身体恢复,并提高注意力和记忆力。"} {"input": "<用户>保持健康的三个提示。<AI>", "output": "以下是保持健康的三个提示:\n\n1. 保持身体活动。每天做适当的身体运动,如散步、跑步或游泳,能促进心血管健康,增强肌肉力量,并有助于减少体重。\n\n2. 均衡饮食。每天食用新鲜的蔬菜、水果、全谷物和脂肪含量低的蛋白质食物,避免高糖、高脂肪和加工食品,以保持健康的饮食习惯。\n\n3. 睡眠充足。睡眠对人体健康至关重要,成年人每天应保证 7-8 小时的睡眠。良好的睡眠有助于减轻压力,促进身体恢复,并提高注意力和记忆力。"}
{"input": "<用户>三原色是什么?<AI>", "output": "三原色通常指的是红色、绿色和蓝色RGB。它们是通过加色混合原理创建色彩的三种基础颜色。在以发光为基础的显示设备中如电视、计算机显示器、智能手机和平板电脑显示屏, 三原色可混合产生大量色彩。其中红色和绿色可以混合生成黄色,红色和蓝色可以混合生成品红色,蓝色和绿色可以混合生成青色。当红色、绿色和蓝色按相等比例混合时,可以产生白色或灰色。\n\n此外在印刷和绘画中三原色指的是以颜料为基础的红、黄和蓝颜色RYB。这三种颜色用以通过减色混合原理来创建色彩。不过三原色的具体定义并不唯一不同的颜色系统可能会采用不同的三原色。"} {"input": "<用户>三原色是什么?<AI>", "output": "三原色通常指的是红色、绿色和蓝色RGB。它们是通过加色混合原理创建色彩的三种基础颜色。在以发光为基础的显示设备中如电视、计算机显示器、智能手机和平板电脑显示屏, 三原色可混合产生大量色彩。其中红色和绿色可以混合生成黄色,红色和蓝色可以混合生成品红色,蓝色和绿色可以混合生成青色。当红色、绿色和蓝色按相等比例混合时,可以产生白色或灰色。\n\n此外在印刷和绘画中三原色指的是以颜料为基础的红、黄和蓝颜色RYB。这三种颜色用以通过减色混合原理来创建色彩。不过三原色的具体定义并不唯一不同的颜色系统可能会采用不同的三原色。"}
{"input": "<用户>描述原子的结构。<AI>", "output": "原子是物质的基本单位,它由三种基本粒子组成:质子、中子和电子。质子和中子形成原子核,位于原子中心,核外的电子围绕着原子核运动。\n\n原子结构具有层次性。原子核中质子带正电中子不带电中性。原子核非常小且致密占据了原子总质量的绝大部分。电子带负电通常围绕核运动形成若干层次称为壳层或电子层。电子数量与质子数量相等使原子呈电中性。\n\n电子在每个壳层中都呈规律分布并且不同壳层所能容纳的电子数也不同。在最里面的壳层一般只能容纳2个电子其次一层最多可容纳8个电子再往外的壳层可容纳的电子数逐层递增。\n\n原子核主要受到两种相互作用力的影响强力和电磁力。强力的作用范围非常小主要限制在原子核内具有极强的吸引作用使核子质子和中子紧密结合在一起。电磁力的作用范围较大主要通过核外的电子与原子核相互作用发挥作用。\n\n这就是原子的基本结构。原子内部结构复杂多样不同元素的原子核中质子、中子数量不同核外电子排布分布也不同形成了丰富多彩的化学世界。"}
``` ```
#### 2. 数据二进制化 #### 2. 数据二进制化
@ -55,12 +59,12 @@ python data_binarize.py --input [PATH to raw_data] --data_type json --output_pat
例如用32卡训练时需满足block_end>32如果文件较小可以在二进制化之前对多个小文件进行拼接以满足大规模训练的需求。 例如用32卡训练时需满足block_end>32如果文件较小可以在二进制化之前对多个小文件进行拼接以满足大规模训练的需求。
在本Quick Start中我们为jsonl数据到二进制数据的转换过程准备了脚本 在本Quick Start中我们为jsonl数据到二进制数据的转换过程准备了脚本
```js ``` python
for i in {1..10};do for i in {1..10};do
cat raw_data/alpaca_zh.jsonl >> raw_data/alpaca_zh_repeat.jsonl cat raw_data/alpaca_zh.jsonl >> raw_data/alpaca_zh_repeat.jsonl
done done
``` ```
```js ``` shell
mkdir raw_data_repeat mkdir raw_data_repeat
mv raw_data/alpaca_zh_repeat.jsonl raw_data_repeat/data.jsonl mv raw_data/alpaca_zh_repeat.jsonl raw_data_repeat/data.jsonl
@ -72,11 +76,9 @@ python data_binarize.py --input raw_data_repeat --data_type json --output_path b
# transform_script.py # transform_script.py
import random import random
def rand(n: int, r: random.Random): def rand(n: int, r: random.Random):
return int(r.random() * n) return int(r.random() * n)
def transform(data, num_sample: int, r: random.Random): def transform(data, num_sample: int, r: random.Random):
return {"input": data["input"], "output": data["output"]}我们还支持多个数据集的混合读入并设置不同数据集的比例。为此需要准备一个数据混合的json文件来指导训练过程中的数据读取策略示例如下 return {"input": data["input"], "output": data["output"]}我们还支持多个数据集的混合读入并设置不同数据集的比例。为此需要准备一个数据混合的json文件来指导训练过程中的数据读取策略示例如下
[ [
@ -106,13 +108,13 @@ def transform(data, num_sample: int, r: random.Random):
模型训练代码的位置9G-Train/apps/cpm9g/pretrain_cpm9g.py 模型训练代码的位置9G-Train/apps/cpm9g/pretrain_cpm9g.py
需要将代码中环境变量设置为您的代码路径: 需要将代码中环境变量设置为您的代码路径:
```js ``` python
#CPM-9G/apps/cpm9g/pretrain_cpm9g.py:17 #9G-Train/apps/cpm9g/pretrain_cpm9g.py:17
sys.path.insert(0, "/data/public/CPM-9G/9G-Train") sys.path.insert(0, "/data/public/CPM-9G/9G-Train")
``` ```
1 训练脚本: ### pretrain shell脚本:
```js ```shell
#! /bin/bash #! /bin/bash
# use 8 GPU for example, pretrain may need 32 GPU # use 8 GPU for example, pretrain may need 32 GPU
@ -122,11 +124,11 @@ export MASTER_PORT=12345
EXP_PATH=. # 修改为您的实验路径,用于存储训练日志和模型 EXP_PATH=. # 修改为您的实验路径,用于存储训练日志和模型
CODE_PATH=/data/public/CPM-9G/9G-Train # 修改为您的代码路径 CODE_PATH=/data/public/CPM-9G/9G-Train # 修改为您的代码路径
DATA_PATH=/data/public/CPM-9G/quick_start/datasets.json # 修改为您的datasets.json路径 DATA_PATH=/data/public/CPM-9G/quick_start/datasets.json # 修改为您的datasets.json路径
CHECKPOINT=/data/public/CPM-9G/models/7b-base/7b.pt # 修改为您的基座模型路径 CHECKPOINT=/data/public/CPM-9G/models/model.pt # 修改为您的基座模型路径
mkdir -p ${EXP_PATH}/logs/debug mkdir -p ${EXP_PATH}/logs/debug
mkdir -p ${EXP_PATH}/logs/tensorboard/cpm9g/ mkdir -p ${EXP_PATH}/logs/tensorboard/cpm9g/
CONFIG_NAME="${CODE_PATH}/apps/cpm9g/config/7b" CONFIG_NAME="${CODE_PATH}/apps/cpm9g/config/"
# --------------- 运行参数 --------------- # --------------- 运行参数 ---------------
OPTS="" OPTS=""
OPTS+=" --model-config ${CONFIG_NAME}/config.json" OPTS+=" --model-config ${CONFIG_NAME}/config.json"
@ -146,14 +148,11 @@ OPTS+=" --loss-scale 1048576" # 和训练稳定性相关,一般情况下不需
OPTS+=" --loss-scale-steps 32" # 和训练稳定性相关,一般情况下不需修改 OPTS+=" --loss-scale-steps 32" # 和训练稳定性相关,一般情况下不需修改
OPTS+=" --offload" # 使用cpu offload将优化器参数转移到cpu一般情况下无需修改 OPTS+=" --offload" # 使用cpu offload将优化器参数转移到cpu一般情况下无需修改
OPTS+=" --flash cuda" OPTS+=" --flash cuda"
# OPTS+=" --load-grad"
# --------------- 写文件路径 --------------- # --------------- 写文件路径 ---------------
## checkpoint
OPTS+=" --save ${EXP_PATH}/checkpoints/cpm9g/" OPTS+=" --save ${EXP_PATH}/checkpoints/cpm9g/"
OPTS+=" --save-model ${EXP_PATH}/models/cpm9g/" OPTS+=" --save-model ${EXP_PATH}/models/cpm9g/"
## logs/local/logs 等价于 /data/logs软链
OPTS+=" --log-dir ${EXP_PATH}/logs/train/" OPTS+=" --log-dir ${EXP_PATH}/logs/train/"
OPTS+=" --tensorboard ${EXP_PATH}/tensorboard/cpm9g/"`date +"%Y%m%d%H%M%S"` OPTS+=" --tensorboard ${EXP_PATH}/tensorboard/cpm9g/"`date +"%Y%m%d%H%M%S"`
@ -166,15 +165,64 @@ OPTS+=" --start-step 1"
OPTS+=" $@" OPTS+=" $@"
# --------------- 最终指令 --------------- # --------------- 最终指令 ---------------
CMD="torchrun --nnodes=1 --nproc_per_node=8 --rdzv_id=1 --rdzv_backend=c10d --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} ${CODE_PATH}/apps/cpm9g/pretrain_cpm9g.py ${OPTS}" CMD="torchrun --nnodes=1 --nproc_per_node=8 --rdzv_id=1 --rdzv_backend=c10d --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} ${CODE_PATH}/apps/cpm9g/pretrain_cpm9g.py ${OPTS}"
echo "${CMD}" echo "${CMD}"
$CMD $CMD
``` ```
### sft 训练shell 脚本
``` shell
export MASTER_ADDR=`hostname`
export MASTER_PORT=12345
CPM_PATH="/data/groups/QY_LLM_Core/arq_project/code/9G-Train"
CKPT_NAME="/data/public/anrongqiao/models/"
EXP_PATH=./exp/8b/
mkdir -p $EXP_PATH
MODEL_NAME="cpm9g-8b-sft"
OPTS=""
OPTS+=" --model-config ${CKPT_NAME}/config.json"
OPTS+=" --vocab ${CKPT_NAME}/vocab.txt"
OPTS+=" --train-iters 10000" # 训练步数,达到此步数后,学习率降到最小值
OPTS+=" --inspect-iters 200" # 存储步数,每隔此步数,存储一个模型文件
OPTS+=" --warmup-iters 20" # 热启动步数
OPTS+=" --lr-decay-style cosine" # 学习率变化策略
OPTS+=" --weight-decay 0.1" # 正则化参数
OPTS+=" --clip-grad 1.0" # 正则化参数
OPTS+=" --loss-scale 1048576" # 和训练稳定性相关,一般情况下不需修改
OPTS+=" --max-loss-scale 33554432" #和训练稳定性相关,一般情况下不需修改
OPTS+=" --min-loss-scale 1" #和训练稳定性相关,一般情况下不需修改
OPTS+=" --loss-scale-steps 32" # 和训练稳定性相关,一般情况下不需修改
OPTS+=" --offload" # 使用cpu offload将优化器参数转移到cpu一般情况下无需修改
OPTS+=" --batch-size 1"
OPTS+=" --max-length 4096" #上下文长度
OPTS+=" --lr 1e-5" #学习率
OPTS+=" --start-step 0" #初始steps
OPTS+=" --epoch 1" # 训练多少个epoch
OPTS+=" --load ${CKPT_NAME}/model.pt" # 修改成自己的预训练模型
OPTS+=" --dataset ../dataset/qy_sft_20230129_bin/" # 和pretrain脚本不同sft数据量少直接输入bin文件即可
OPTS+=" --save ${EXP_PATH}/checkpoints" # 模型存储
OPTS+=" --save-name ${MODEL_NAME}" #待存储模型的前缀
OPTS+=" --tensorboard /data/logs/tensorboard/${MODEL_NAME}/${CUR_DATE}/" #
OPTS+=" --gradient-accumulation-steps 4" # 梯度累积更新步数
OPTS+=" $@"
#运行指令
CMD="torchrun --nnodes=1 --nproc_per_node=8 --rdzv_id=1 --rdzv_backend=c10d --rdzv_endpoint=${MASTER_ADDR}:${MASTER_PORT} ${CPM_PATH}/apps/cpm9g/sft_cpm9g.py ${OPTS}"
echo "${CMD}"
$CMD
```
## 模型推理 ## 模型推理
1 模型推理代码 ```python
```js
import os import os
from libcpm import CPM9G from libcpm import CPM9G
@ -207,13 +255,53 @@ def main():
'''<用户>我要参加一个高性能会议,请帮我写一个致辞。<AI>''', '''<用户>我要参加一个高性能会议,请帮我写一个致辞。<AI>''',
] ]
# print(model.inference(datas, max_length=30)) # inference batch
for data in datas: for data in datas:
res = model.inference(data, max_length=4096) res = model.inference(data, max_length=4096)
print(res['result']) print(res['result'])
# print(model.random_search(data))
if __name__ == "__main__": if __name__ == "__main__":
main() main()
``` ```
## FAQs
常见问题汇总持续补充ing
### 训练相关
1 推荐大家使用docker避免大家在conda 环境安装时候遇到的问题
2 pretrain训练的脚本和sft训练的脚本基本类似在apps/cpm_9g目录下
3 尽量避免在window机器下修改脚本window中的编码和格式linux是有差别的容易在脚本执行中报错
4 微调训练中train_iters如何计算
```
回答因为模型上下文是4096的token数目通常情况存在训练数据不足4096的长度所以会对多条数据进行merge送入模型的数据量会少于1000条
```
5 打印出来的Iter信息有缺失
```
回答debug下看看是否是出现drop_last的情况
```
6 现有代码是否需要验证集合?
```
回答不需要参数中出现的val_datasets忽略即可
```
7 SFT如何调参训练
```
回答如果数据量少于10w条多训练几个epoch把学习率调低一些比如说5e-6等
数据量很多呢训练最多2个epoch足够注意过拟合的问题
```
8 Lora 推理需要进行merge 模型后预测五一后release该代码
9 加载模型遇到invalid header or archive is carrupted这种一般是模型没有下载完导致的目前红山上的模型确定是完整的首先自查自己的模型是否下载成功。
10 存储模型的时候遇到failed write file data ,一般先检查下文件路径和权限、磁盘空间吧,存储模型基本不会报错
### 数据相关
1 历史对话的传入:
``` json
datas = [
'''<用户>问题1<AI>答案1<用户>问题2<AI>答案2<用户>问题2<AI>'''
]
```
2 数据量级别SFT的指令数据可多可少
## TODO
1 发布最新训练的80B SFT模型
2 Lora相干的代码更新

View File

@ -42,7 +42,7 @@ def split(x, s):
def main(src_model_path, dst_model_path, layer_num): def main(src_model_path, dst_model_path, layer_num):
#训练保存的原始模型
model = torch.load(src_model_path, map_location="cpu") model = torch.load(src_model_path, map_location="cpu")
params = {} params = {}
@ -74,7 +74,9 @@ def main(src_model_path, dst_model_path, layer_num):
if __name__ == '__main__': if __name__ == '__main__':
src_model_path = "/home/wangyixuan/workplace/llm_service/sse/checkpoints-epoch-2/cpm9g-8b-sft-epoch-2.pt" # 输入已有的源模型
src_model_path = "./checkpoints-epoch-1/cpm9g-8b-sft-epoch-1.pt"
# 格式转换后的模型地址
dst_model_path = "model_8b.ckpt" dst_model_path = "model_8b.ckpt"
# 百亿32 # 百亿32