# ChatGLM-6B

## 模型介绍

ChatGLM-6B 是清华大学开源的开源的、支持中英双语的对话语言模型，基于 [General Language Model (GLM)](https://github.com/THUDM/GLM) 架构，具有 62 亿参数。ChatGLM-6B 使用了和 ChatGPT 相似的技术，针对中文问答和对话进行了优化。经过约 1T 标识符的中英双语训练，辅以监督微调、反馈自助、人类反馈强化学习等技术的加持，62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答。


## 数据集
本仓库以 [ADGEN](https://aclanthology.org/D19-1321.pdf) (广告生成) 数据集为例介绍代码的使用方法，该数据集任务为根据输入（content）生成一段广告词（summary）。数据集可从 [Google Drive](https://drive.google.com/file/d/13_vf0xRTQsyneRKdD1bZIr93vBGOczrk/view?usp=sharing) 或者 [Tsinghua Cloud](https://cloud.tsinghua.edu.cn/f/b3f119a008264b1cabd1/?dl=1) 下载处理好的 ADGEN 数据集，将解压后的AdvertiseGen目录放到 [ptuning](./ptuning)本目录下。

## 环境配置

环境使用1节点8张 Z100L-32G。

推荐使用docker方式运行，提供[光源](https://www.sourcefind.cn/#/service-details)拉取的docker镜像：image.sourcefind.cn:5000/dcu/admin/base/pytorch:1.10.0-centos7.6-dtk-22.10.1-py37-latest

进入docker:

    cd /opt/dtk/.hip
    source replace_origin.sh
    pip3 install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
    pip3 install rouge_chinese nltk jieba datasets -i https://mirrors.aliyun.com/pypi/simple
此外，需要安装 Deepspeed，可从开发者社区下载对应版本安装包[Deepspeed](https://cancon.hpccube.com:65024/directlink/4/deepspeed/dtk22.10/deepspeed-0.6.3+1b2721a.dtk2210-cp37-cp37m-manylinux2014_x86_64.whl)进行安装。

## P-tuning v2微调
本仓库实现了对于ChatGLM-6B模型基于[P-Tuning v2](https://github.com/THUDM/P-tuning-v2)的微调。P-Tuning v2是由清华大学提出的一种高效参数微调方法，采用该方法可以将需要微调的参数量减少到原来的 0.1%。

### 实验设置

    max_source_length=64
    max_target_length=64
    max_steps=3000
    pre_seq_len=128
    learning_rate=5e-3
    per_device_train_batch_size=16
    gradient_accumulation_steps=1
    fp16

### 训练
该微调脚本运行环境为1节点，4张DCU-Z100-32G

微调训练命令

    cd ptuning
    bash pt_train.sh

### 训练Loss收敛情况
![](./ptuning/logs/6B_ds_pt_bs16_accum1_4cards_zero2_5e-3.jpg)

### 推理测评
在 P-tuning v2 训练时模型只保存 PrefixEncoder 部分的参数，所以在推理时需要同时加载原 ChatGLM-6B 模型以及 PrefixEncoder 的权重，可直接运行一下命令：

    cd ptuning
    bash evaluate_pt.sh

测试结果:
| Checkpoint | Training Loss |BLEU-4 | Rouge-1 |  Rouge-2 | Rouge-l |
| :------: | :------: |:------: | :------: |:------: | :------: |
| 2000 steps |  3.57 | 7.9777 | 31.0344 |  6.981 | 24.7393 |

## Finetune全参数微调
### 实验设置

    max_source_length=64
    max_target_length=64
    max_steps=5000
    pre_seq_len=128
    learning_rate=5e-5
    per_device_train_batch_size=32
    gradient_accumulation_steps=1
    fp16

### 训练
该微调脚本运行环境为1节点，4张DCU-Z100-32G

微调训练命令

    cd ptuning
    bash ft_train.sh

### 训练Loss收敛情况
![](./ptuning/logs/6B_ds_ft_bs32_accum1_4cards_zero3_5e-5.jpg)

### 推理测评

    cd ptuning
    bash evaluate_ft.sh

测试结果:
| Checkpoint | Training Loss |BLEU-4 | Rouge-1 |  Rouge-2 | Rouge-l |
| :------: | :------: |:------: | :------: |:------: | :------: |
| 3000 steps |  2.3398 | 7.6501 | 29.2229 | 6.466 | 23.8506 |


<!-- ## 评估结果
|               | Finetune | P-tuning v2 | LoRA |
| ------------- | ----------- | ----- | ------------- |
| BLEU-4        | 8.01    | 8.10 | 7.62 |
| Rouge-1       | 31.23  | 31.12 | 30.60 |
| Rouge-2       | 7.36    | 7.11 | 6.96 |
| Rouge-l       | 25.08  | 24.97 | 24.80 |
| Training Loss | 3.00 | 3.57 | 3.32 | -->
## 模型使用
运行如下命令：

    python cli_demo.py

程序会在命令行中进行交互式的对话，在命令行中输入指示并回车即可生成回复，输入 clear 可以清空对话历史，输入 stop 终止程序。

## 重新 pretrain

由于当前的 [GLM-130B](https://github.com/THUDM/GLM-130B#news) 与 ChatGLM 的模型结构非常类似，所以对于有训练 GLM-130B 的用户来说，可以通过修改 ChatGLM 的 config.json 使用堆参数的方式将参数量达到130B。该项目为了满足用户对 ChatGLM 重新 pretrain 的需求，继续添加了 simple-pretrain 目录，旨在提供一种改动最小的 pretrain 示例。pretrain步骤如下：

1. 将 simple-pretrain/ptuning 下的文件移到本 ptuning 目录下，替换相关文件

2. 将 modeling_chatglm.py 移到[ ChatGLM 模型](https://huggingface.co/THUDM/chatglm-6b)所在目录替换原始 modeling_chatglm.py 

3. 在本 ptuning 目录下：

   ```
   bash ds_pretrain.sh
   ```

说明：convert.py 可以将原始的txt数据转换成 chatglm 可用的 json 形式的数据集格式。该示例使用指环王1书籍作为预训练数据集。

### 实验设置

```
LR=1e-5

MASTER_PORT=$(shuf -n 1 -i 10000-65535)

HIP_VISIBLE_DEVICES=0,1,2,3 deepspeed --num_gpus=4 --master_port $MASTER_PORT main.py \
    --deepspeed deepspeed.json \
    --do_train \
    --train_file The-Lord-of-the-Rings-1.json \
    --prompt_column prompt \
    --response_column response \
    --overwrite_cache \
    --model_name_or_path THUDM/chatglm-6b \
    --output_dir ./output/pretrain \
    --overwrite_output_dir \
    --max_source_length 8 \
    --max_target_length 128 \
    --per_device_train_batch_size 16 \
    --per_device_eval_batch_size 4 \
    --gradient_accumulation_steps 4 \
    --predict_with_generate \
    --max_steps 2000 \
    --logging_steps 5 \
    --save_steps 1000 \
    --learning_rate $LR \
    --fp16
```

### 训练loss收敛情况

由于该示例预训练数据集较小，loss会降的至较低水平到0.1左右。

![img](https://developer.hpccube.com/codes/modelzoo/chatglm/-/raw/main/ptuning/logs/pretrain.jpeg)

## 强化学习(RLHF)微调方案

目前在 DCU 上 ChatGLM 使用强化学习微调有两种方案可以走通：

- 使用 Lora，只更新低秩适应层，可以直接参考项目：https://github.com/hiyouga/ChatGLM-Efficient-Tuning/blob/main/examples/covid_doctor.md
- 使用 DeepSpeed-Chat 方案全参微调，目前已经适配完成，欢迎尝试：https://github.com/yuguo-Jack/ChatGLM-6B-in-DeepSpeed-Chat

## 源码仓库及问题反馈

https://developer.hpccube.com/codes/modelzoo/chatglm

## 参考

[THUDM/ChatGLM-6B](https://github.com/THUDM/ChatGLM-6B/tree/main)

