update reademe files

This commit is contained in:
anrongqiao 2024-04-26 00:53:14 +08:00
parent cd7d47839c
commit 179ef5d0bc
9 changed files with 309 additions and 3 deletions

View File

@ -2,9 +2,7 @@
启元九格大模型由启元实验室牵头联合清华大学、哈尔滨工业大学、中国科学院计算技术研究所、北京大学、南开大学等优势单位共同研制。该版本通用大模型参数量为80亿具有高效训练与推理和高效适配与部署的技术特点具备文本问答、文本分类、机器翻译、文本摘要等自然语言处理能力。 启元九格大模型由启元实验室牵头联合清华大学、哈尔滨工业大学、中国科学院计算技术研究所、北京大学、南开大学等优势单位共同研制。该版本通用大模型参数量为80亿具有高效训练与推理和高效适配与部署的技术特点具备文本问答、文本分类、机器翻译、文本摘要等自然语言处理能力。
九格百亿级通用基础大模型的参数量为8B80亿 九格百亿级通用基础大模型的参数量为8B80亿。具体的模型训练、推理等内容见[quick start](https://www.osredm.com/jiuyuan/CPM-9G-8B/tree/master/quick_start_clean/readmes/README_ALL.md)
模型路径https://qy-obs-6d58.obs.cn-north-4.myhuaweicloud.com/checkpoints-epoch-1.tar.gz
docker 路径https://qy-obs-6d58.obs.cn-north-4.myhuaweicloud.com/cpmlive-flash-0.0.4.tar
# 迈向通用智能的大模型技术系列课程 # 迈向通用智能的大模型技术系列课程
系列课程全方位介绍人工智能和大模型技术的基础知识和前沿课题,理论学习和实践应用相结合。课程既有“人工智能与大模型通论”和“神经网络与预训练模型”等基础知识,也有“九格大模型生态体系”和“领域大模型实战”等实战主题,基本内容包括大模型训练、微调、知识增强、伦理安全、多模态、具身智能、自主智能体等话题,高级选题包括多语言处理、面向科学研究的大模型应用、高效计算技术、评测与数据科学等话题。课程旨在通过一系列精心设计的单元为学习者提供大型通用人工智能的学习之旅。 系列课程全方位介绍人工智能和大模型技术的基础知识和前沿课题,理论学习和实践应用相结合。课程既有“人工智能与大模型通论”和“神经网络与预训练模型”等基础知识,也有“九格大模型生态体系”和“领域大模型实战”等实战主题,基本内容包括大模型训练、微调、知识增强、伦理安全、多模态、具身智能、自主智能体等话题,高级选题包括多语言处理、面向科学研究的大模型应用、高效计算技术、评测与数据科学等话题。课程旨在通过一系列精心设计的单元为学习者提供大型通用人工智能的学习之旅。

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,218 @@
# 九格大模型使用文档
模型的训练、推理环境及其硬件的信息:
[环境配置、硬件信息](https://www.osredm.com/jiuyuan/CPM-9G-8B/tree/master/quick_start_clean/readmes/README_ENV.md)
为了帮助您快速了解CPM-9G的使用我们准备了一个快速入门教程目标是基于CPM-9G基座模型通过指令微调的方式构建一个Chat模型。
## 数据
本教程使用的数据是Alpaca Zh一个开源中文指令微调数据集。[数据集](https://github.com/Instruction-Tuning-with-GPT-4/GPT-4-LLM/blob/main/data/alpaca_gpt4_data_zh.json)
### 数据预处理
#### 1. 准备jsonl文件
首先需要将原始数据处理位jsonl形式每一行一个json每行包含两个字段分别是input和output以下是一个例子
{"input":"", "output": "我爱北京。"}实际预训练时数据多为txt格式可以参照以下过程将txt格式的文件转换为jsonl格式
```js
# convert_txt2jsonl.py
import json
import sys
for line in sys.stdin:
if line.strip() == "":
continue
temp_json = {"input": "", "output": line.strip()}
print(json.dumps(temp_json, ensure_ascii=False))
```
使用方式为:
```js
cat pretrain.txt | python convert_txt2jsonl.py > pretrain.jsonl
```
在本Quick Start教程中已准备好jsonl数据,路径为raw_data/alpaca_zh.jsonl示例如下
```js
{"input": "<用户>保持健康的三个提示。<AI>", "output": "以下是保持健康的三个提示:\n\n1. 保持身体活动。每天做适当的身体运动,如散步、跑步或游泳,能促进心血管健康,增强肌肉力量,并有助于减少体重。\n\n2. 均衡饮食。每天食用新鲜的蔬菜、水果、全谷物和脂肪含量低的蛋白质食物,避免高糖、高脂肪和加工食品,以保持健康的饮食习惯。\n\n3. 睡眠充足。睡眠对人体健康至关重要,成年人每天应保证 7-8 小时的睡眠。良好的睡眠有助于减轻压力,促进身体恢复,并提高注意力和记忆力。"}
{"input": "<用户>三原色是什么?<AI>", "output": "三原色通常指的是红色、绿色和蓝色RGB。它们是通过加色混合原理创建色彩的三种基础颜色。在以发光为基础的显示设备中如电视、计算机显示器、智能手机和平板电脑显示屏, 三原色可混合产生大量色彩。其中红色和绿色可以混合生成黄色,红色和蓝色可以混合生成品红色,蓝色和绿色可以混合生成青色。当红色、绿色和蓝色按相等比例混合时,可以产生白色或灰色。\n\n此外在印刷和绘画中三原色指的是以颜料为基础的红、黄和蓝颜色RYB。这三种颜色用以通过减色混合原理来创建色彩。不过三原色的具体定义并不唯一不同的颜色系统可能会采用不同的三原色。"}
{"input": "<用户>描述原子的结构。<AI>", "output": "原子是物质的基本单位,它由三种基本粒子组成:质子、中子和电子。质子和中子形成原子核,位于原子中心,核外的电子围绕着原子核运动。\n\n原子结构具有层次性。原子核中质子带正电中子不带电中性。原子核非常小且致密占据了原子总质量的绝大部分。电子带负电通常围绕核运动形成若干层次称为壳层或电子层。电子数量与质子数量相等使原子呈电中性。\n\n电子在每个壳层中都呈规律分布并且不同壳层所能容纳的电子数也不同。在最里面的壳层一般只能容纳2个电子其次一层最多可容纳8个电子再往外的壳层可容纳的电子数逐层递增。\n\n原子核主要受到两种相互作用力的影响强力和电磁力。强力的作用范围非常小主要限制在原子核内具有极强的吸引作用使核子质子和中子紧密结合在一起。电磁力的作用范围较大主要通过核外的电子与原子核相互作用发挥作用。\n\n这就是原子的基本结构。原子内部结构复杂多样不同元素的原子核中质子、中子数量不同核外电子排布分布也不同形成了丰富多彩的化学世界。"}
```
#### 2. 数据二进制化
为了提升数据读取的效率方便进行大规模分布式预训练我们以二进制的形式读取训练数据。因此在训练开始前需要将上一步准备好的jsonl格式的数据文件二进制化需要的代码路径为quick_start/data_binarize.py使用前需要将环境变量设置为您的本地路径
```js
sys.path.insert(0, "/data/public/CPM-9G/9G-Train")
```
以下是一个使用示例:
假设当前的数据在raw_data路径下raw_data/alpaca_zh.jsonl
```js
python data_binarize.py --input [PATH to raw_data] --data_type json --output_path [PATH to raw_data_bin] --output_name data
```
处理完成后在输出路径即OUTPUT PATH下会生成data和meta.bin两个文件其中data是二进制后的数据文件meta.bin则记录了这份数据的规模、大小等信息示例如下
```js
{"file_name": "data", "block_begin": 0, "block_end": 45, "nbytes": 738321350, "nlines": 4432310, "mask": false, "block_size": 16777216}
```
**请注意当前的框架需要保证block_end数大于所用的GPU总数。**
例如用32卡训练时需满足block_end>32如果文件较小可以在二进制化之前对多个小文件进行拼接以满足大规模训练的需求。
在本Quick Start中我们为jsonl数据到二进制数据的转换过程准备了脚本
```js
for i in {1..10};do
cat raw_data/alpaca_zh.jsonl >> raw_data/alpaca_zh_repeat.jsonl
done
```
```js
mkdir raw_data_repeat
mv raw_data/alpaca_zh_repeat.jsonl raw_data_repeat/data.jsonl
python data_binarize.py --input raw_data_repeat --data_type json --output_path bin_data_repeat --output_name data
```
#### 3. 准备数据读取脚本
鉴于不同的预训练数据所包含的字段可能有所差别,我们还兼容了字段转换的环节,如果按照上述标准流程做的数据预处理,那么转换方式将十分简单,代码如下:
```js
# transform_script.py
import random
def rand(n: int, r: random.Random):
return int(r.random() * n)
def transform(data, num_sample: int, r: random.Random):
return {"input": data["input"], "output": data["output"]}我们还支持多个数据集的混合读入并设置不同数据集的比例。为此需要准备一个数据混合的json文件来指导训练过程中的数据读取策略示例如下
[
{
"dataset_name": "alpaca_zh",
"task_name": "alpaca_zh",
"weight": 1.0,
"path": "/data/public/CPM-9G/quick_start/bin_data_repeat",
"incontext_weight": [
1.0
],
"transforms": "/data/public/CPM-9G/quick_start/transform_data.py"
}
]
```
该文件中各字段的解释如下:
- dataset_name:数据集名称;
- task_name:数据集所属任务task_name+dataset_name 将作为训练过程中识别数据集的标签task_name 则可用于训练过程中针对任务分别汇总 loss 信息、token 吞吐量等;
- weight:浮点数,采样权重;(注意此权重仅代表每个数据集的样本数配比,实际 token 吞吐量的配比还与每个样本的平均 token数量有关)
- path:meta.bin、二进制数据的父目录即前文所述的 raw_data_bin;
- transforms:数据转换脚本对应的路径;
- incontext_weight: 训练样本叠加方式,[1.0] 表示 100% 的概率采样一个样本,[0.8, 0.2] 表示 80% 的概率采样一个样本, 20% 概率采样两个样本进行拼接,[0.75, 0.1, 0.15] 表示 15% 概率采样三个样本、 10% 的概率采样两个样本进行拼接、75% 采样一个样本;
- 数据集的配比(即 weight 参数)需要重点调整,对于模型的训练稳定性和最终在各类数据上的能力表现有重大影响;
- 我们在此文件中指定了数据文件的路径、转换脚本路径等信息,后续训练仅需要系统该文件的路径即可。
## 模型训练
模型训练代码的位置9G-Train/apps/cpm9g/pretrain_cpm9g.py
需要将代码中环境变量设置为您的代码路径:
```js
#CPM-9G/apps/cpm9g/pretrain_cpm9g.py:17
sys.path.insert(0, "/data/public/CPM-9G/9G-Train")
```
1 训练脚本:
```js
#! /bin/bash
# use 8 GPU for example, pretrain may need 32 GPU
export MASTER_ADDR=`hostname`
export MASTER_PORT=12345
EXP_PATH=. # 修改为您的实验路径,用于存储训练日志和模型
CODE_PATH=/data/public/CPM-9G/9G-Train # 修改为您的代码路径
DATA_PATH=/data/public/CPM-9G/quick_start/datasets.json # 修改为您的datasets.json路径
CHECKPOINT=/data/public/CPM-9G/models/7b-base/7b.pt # 修改为您的基座模型路径
mkdir -p ${EXP_PATH}/logs/debug
mkdir -p ${EXP_PATH}/logs/tensorboard/cpm9g/
CONFIG_NAME="${CODE_PATH}/apps/cpm9g/config/7b"
# --------------- 运行参数 ---------------
OPTS=""
OPTS+=" --model-config ${CONFIG_NAME}/config.json"
OPTS+=" --vocab ${CONFIG_NAME}/vocab.txt"
OPTS+=" --batch-size 12"
OPTS+=" --train-iters 2000" # 训练步数,达到此步数后,学习率降到最小值
OPTS+=" --save-iters 100" # 存储步数,每隔此步数,存储一个模型文件
OPTS+=" --save-name cpm9g_checkpoint" # 模型名称前缀
OPTS+=" --max-length 4096" # 最多token数量
OPTS+=" --lr 1.5e-5" # 峰值学习率
OPTS+=" --inspect-iters 100" # 检查步数,每隔此步数,输出一次模型梯度的详细信息
OPTS+=" --warmup-iters 50" # 热启动步数
OPTS+=" --lr-decay-style noam" # 学习率变化策略
OPTS+=" --weight-decay 0.1" # 正则化参数
OPTS+=" --clip-grad 1.0" # 正则化参数
OPTS+=" --loss-scale 1048576" # 和训练稳定性相关,一般情况下不需修改
OPTS+=" --loss-scale-steps 32" # 和训练稳定性相关,一般情况下不需修改
OPTS+=" --offload" # 使用cpu offload将优化器参数转移到cpu一般情况下无需修改
OPTS+=" --flash cuda"
# OPTS+=" --load-grad"
# --------------- 写文件路径 ---------------
## checkpoint
OPTS+=" --save ${EXP_PATH}/checkpoints/cpm9g/"
OPTS+=" --save-model ${EXP_PATH}/models/cpm9g/"
## logs/local/logs 等价于 /data/logs软链
OPTS+=" --log-dir ${EXP_PATH}/logs/train/"
OPTS+=" --tensorboard ${EXP_PATH}/tensorboard/cpm9g/"`date +"%Y%m%d%H%M%S"`
# --------------- 读文件路径 ---------------
OPTS+=" --dataset ${DATA_PATH}"
OPTS+=" --load ${CHECKPOINT}"
OPTS+=" --start-step 1"
# --------------- 透传参数 ---------------
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}"
$CMD
```
## 模型推理
1 模型推理代码
```js
import os
from libcpm import CPM9G
import argparse, json, os
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--pt", type=str, help="the path of ckpt")
parser.add_argument("--config", type=str, help="the path of config file")
parser.add_argument("--vocab", type=str, help="the path of vocab file")
args = parser.parse_args()
model_config = json.load(open(args.config, 'r'))
model_config["new_vocab"] = True
model = CPM9G(
"",
args.vocab,
-1,
memory_limit = 30 << 30,#memory limit 左边的参数根据gpu的显存设置如果是A100可以设置为 72 << 30这样的话就可以用到更多的显存
model_config=model_config,
load_model=False,
)
model.load_model_pt(args.pt)
datas = [
'''<用户>马化腾是谁?<AI>''',
'''<用户>你是谁?<AI>''',
'''<用户>我要参加一个高性能会议,请帮我写一个致辞。<AI>''',
]
# print(model.inference(datas, max_length=30)) # inference batch
for data in datas:
res = model.inference(data, max_length=4096)
print(res['result'])
# print(model.random_search(data))
if __name__ == "__main__":
main()
```

View File

@ -0,0 +1,90 @@
# Docker使用
我们提供可以运行模型训练和推理的docker便于在新环境下快速使用九格大模型。您也可以使用Conda配置运行环境。Conda配置方式请见下一节。
#### docker 路径 https://qy-obs-6d58.obs.cn-north-4.myhuaweicloud.com/cpmlive-flash-0.0.4.tar
## 镜像加载
### rootless 启动
允许用户在不影响主机系统的情况下运行应用程序和服务,并且可以轻松地共享和分发环境
```js
srun -p gpu1 --nodelist=g2001 -N 1 -n 8 -c 8 --gres=gpu:8 --pty bash
module load rootless-docker/default
```
**注意使用bash不能用zsh**
start_rootless_docker.sh运行成功的话此时执行docker ps可以看到当前没有正在运行的容器如果有正在运行的容器说明rootless模式没有启动成功请联系管理员。
### 加载镜像
```js
docker load -i cpmlive-flash-0.0.4.tar
docker tag [IMAGE_ID] cpmlive-flash:0.0.4
```
如果加载镜像遇到archive/tar invailid tar header的问题是因为docker下载不全check下docker下载结果。以红山上上传的docker为准
### 启动容器
```
docker run -it -d -v [HOST_PATH1]:[DOCKER_PATH1] -v [HOST_PATH2]:[DOCKER_PATH2] --gpus all --shm-size=4g --sh cpmlive-flash:0.0.4 bash非rootless 启动
```
如果有docker权限、且rootless执行错误的情况下可以尝试下非rootless启动
加载镜像同rootles过程
### 启动容器
```
docker run -it -d -v [HOST_PATH1]:[DOCKER_PATH1] -v [HOST_PATH2]:[DOCKER_PATH2] --gpus all --network host --shm-size=4g cpmlive-flash:0.0.4 bash
```
参数解释如下:
- -v [HOST_PATH1]:[DOCKER_PATH1]: 这个选项用于将主机(宿主机)文件系统中的目录或文件挂载到容器中的目录。[HOST_PATH1] 是主机路径,[DOCKER_PATH1] 是容器中对应的路径;
- --gpus all: 这个选项用于在容器中启用 GPU 支持,并将所有可用的 GPU 分配给容器。需要在 Docker 守护程序中启用 NVIDIA Container Toolkit 才能使用此选项;
- --network host: 这个选项用于让容器共享主机网络命名空间,使容器可以直接访问主机上的网络接口和服务;
- --shm-size 容器的share memory根据主机的情况设置如果训练推理需要的内存比较多可以增大share memory值
### 进入容器
docker exec -it [CONTAINER_ID] bash
### 退出容器
Ctrl+d
### 删除容器
docker stop [CONTAINER_ID]
### 查看正在运行容器
docker ps
## Conda环境配置
### 训练环境配置
1. 使用python 3.8.10创建conda环境
```js
conda create -n cpm-9g python=3.8.102. 安装Pytorch
conda install pytorch==1.13.1 torchvision==0.14.1 torchaudio==0.13.1 pytorch-cuda=11.6 -c pytorch -c nvidia3. 安装BMTrain
pip install bmtrain==0.2.3.post24. 安装flash-attn
pip install flash-attn==2.0.85. 安装其他依赖包
pip install einops
pip install pytrie
```
如果需要自己配置conda的训练供参考的配置
驱动版本Driver Version: 470.57.02
cuda11.4-11.6之间都可以
### 推理环境配置
```js
1. 安装nvidia-nccl
pip install nvidia-nccl-cu11==2.19.3配置环境变量
nccl_root=`python -c "import nvidia.nccl;import os; print(os.path.dirname(nvidia.nccl.__file__))"`
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$nccl_root/lib
echo $LD_LIBRARY_PATH2. 安装LibCPM
pip installlibcpm-1.0.0-cp38-cp38-linux_x86_64.whl
```
# 硬件资源
| 模型 | 资源 | 最小算力 |
| :-------- | :----- | :----: |
| 百亿模型 |内存 |训练:140G, 推理:1G|
| 百亿模型 |显存 |训练:49G, 推理:20G|
| 千亿模型 |内存 |训练: - , 推理:2G|
| 千亿模型 |显存 |训练: - , 推理:4 * 50G|
另外
- pretrain 和全量微调需要的资源是相同的
- 百亿模型是在单卡A100上测试
- 千亿的训练是用8卡A100推理是用4张A100