怎么如何训练模型大模型ChatGLM-6B?

1.ChatGLM模型介绍ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有 62 亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需 6GB 显存)。ChatGLM-6B 使用了和 ChatGPT 相似的技术,针对中文问答和对话进行了优化。经过约 1T 标识符的中英双语训练,辅以监督微调、反馈自助、人类反馈强化学习等技术的加持,62 亿参数的 ChatGLM-6B 已经能生成相当符合人类偏好的回答。详细信息请参考: 链接.2. 大模型参数微调因为大模型参数比较多,不论是重新预训练还是微调,相应的硬件成本和人工成本也比较高,为了解决这一问题,网上主要涌现了基于Lora 和 基于 P-Tuning v2 的高效参数微调方法,两者的原理如下: P-Tuning v2:相当于在模型每层的embedding层和Self-Attention部分拼接可训练的参数,在微调时只更新这部分参数为主上图中黄色部分即为每层新增的可训练参数
LoRA:相当于对原始全量参数矩阵做低秩分解,在微调时整体参数不动,只更新新增的参数,然后再训练完成之后,将其和原始全量参数合并,从而达到微调的目的途中橙色的梯形为新增参数,在训练完之后,会和原始模型参数作合并形成h在这个过程中参数优化两从dd下降到 2r*d,这部分涉及到举证的低秩分解,感兴趣的同学可以去学习一下相关的矩阵论知识;那么这两种微调方法有哪些异同点呢:
相同点:都是固定原始大模型参数不动,通过新增可训练参数微调然后与原始模型参数共同作用,从而起到微调大模型参数的效果
异同点:新增加参数的方式不同,其次LoRA的方式不会增加推理时间,因为参数在推理时,整体的还是d*d,对于这里感兴趣的同学可以了解这篇 文章. 3. P-Tuning 微调实战ChatGLM-6B模型3.1 chatglm-6b训练环境构建官网微调链接,其中给的微调环境配置如下:protobuf
transformers==4.27.1
cpm_kernels
torch>=1.10
gradio
mdtex2html
sentencepiece
accelerate
但是在实际搭建环境的过程中要考虑到自己的硬件设备,主要GPU驱动这块。我的硬件设备信息如下:系统: Windows 10GPU算力:3060 12GCPU型号:16核 32G因为主要是显卡驱动这块需要适配,所以我把我的驱动信息附图显示显卡驱动为512.29,CUDA版本为11.6,因此在配torch环境时需要适配,我的anaconda环境版本安装如下:Package
Version
----------------------------- ------------
aiofiles
22.1.0
aiohttp
3.8.4
aiosignal
1.3.1
aiosqlite
0.18.0
altair
4.2.2
anaconda-client
1.11.1
anaconda-navigator
2.4.0
anaconda-project
0.11.1
anyio
3.5.0
argon2-cffi
21.3.0
argon2-cffi-bindings
21.2.0
asttokens
2.0.5
async-timeout
4.0.2
attrs
22.1.0
Babel
2.11.0
backcall
0.2.0
backports.functools-lru-cache 1.6.4
backports.tempfile
1.0
backports.weakref
1.0.post1
beautifulsoup4
4.12.2
bleach
4.1.0
boltons
23.0.0
brotlipy
0.7.0
certifi
2023.5.7
cffi
1.15.1
chardet
4.0.0
charset-normalizer
2.0.4
click
8.0.4
clyent
1.2.2
colorama
0.4.6
coloredlogs
15.0.1
comm
0.1.2
conda
23.5.2
conda-build
3.23.3
conda-content-trust
0.1.3
conda-pack
0.6.0
conda-package-handling
2.0.2
conda_package_streaming
0.7.0
conda-repo-cli
1.0.41
conda-token
0.4.0
conda-verify
3.4.2
cpm-kernels
1.0.11
cryptography
39.0.1
datasets
2.11.0
debugpy
1.5.1
decorator
5.1.1
defusedxml
0.7.1
dill
0.3.6
entrypoints
0.4
executing
0.8.3
fastapi
0.95.0
fastjsonschema
2.16.2
ffmpy
0.3.0
filelock
3.9.0
flatbuffers
23.5.26
frozenlist
1.3.3
fsspec
2023.6.0
fst-pso
1.8.1
future
0.18.3
FuzzyTM
2.0.5
glob2
0.7
gradio
3.24.1
gradio_client
0.0.8
h11
0.14.0
httpcore
0.16.3
httpx
0.23.3
huggingface-hub
0.16.4
humanfriendly
10.0
icetk
0.0.4
idna
3.4
ipykernel
6.19.2
ipython
8.12.0
ipython-genutils
0.2.0
ipywidgets
8.0.4
jedi
0.18.1
jieba
0.42.1
Jinja2
3.1.2
joblib
1.3.1
json5
0.9.6
jsonpatch
1.32
jsonpointer
2.1
jsonschema
4.17.3
jupyter
1.0.0
jupyter_client
8.1.0
jupyter-console
6.6.3
jupyter_core
5.3.0
jupyter-events
0.6.3
jupyter_server
2.5.0
jupyter_server_fileid
0.9.0
jupyter_server_terminals
0.4.4
jupyter_server_ydoc
0.8.0
jupyter-ydoc
0.2.4
jupyterlab
3.6.3
jupyterlab-pygments
0.1.2
jupyterlab_server
2.22.0
jupyterlab-widgets
3.0.5
latex2mathml
3.75.2
libarchive-c
2.9
linkify-it-py
2.0.0
loguru
0.7.0
lxml
4.9.2
markdown-it-py
2.2.0
MarkupSafe
2.1.1
matplotlib-inline
0.1.6
mdit-py-plugins
0.3.3
mdtex2html
1.2.0
mdurl
0.1.2
menuinst
1.4.19
miniful
0.0.6
mistune
0.8.4
mpmath
1.3.0
multidict
6.0.4
multiprocess
0.70.14
navigator-updater
0.4.0
nbclassic
0.5.5
nbclient
0.5.13
nbconvert
6.5.4
nbformat
5.7.0
nest-asyncio
1.5.6
nltk
3.8.1
notebook
6.5.4
notebook_shim
0.2.2
numpy
1.25.1
onnx
1.14.0
onnxruntime-gpu
1.14.1
openai
0.27.4
orjson
3.8.10
packaging
23.0
pandas
2.0.3
pandocfilters
1.5.0
parso
0.8.3
pathlib
1.0.1
pickleshare
0.7.5
Pillow
9.4.0
pip
23.1.2
pkginfo
1.9.6
platformdirs
2.5.2
pluggy
1.0.0
ply
3.11
prometheus-client
0.14.1
prompt-toolkit
3.0.36
protobuf
4.23.4
psutil
5.9.0
pure-eval
0.2.2
pyarrow
11.0.0
pycosat
0.6.4
pycparser
2.21
pydantic
1.10.7
pydub
0.25.1
pyFUME
0.2.25
Pygments
2.15.1
PyJWT
2.4.0
pyOpenSSL
23.0.0
PyQt5
5.15.7
PyQt5-sip
12.11.0
pyreadline3
3.4.1
pyrsistent
0.18.0
PySocks
1.7.1
python-dateutil
2.8.2
python-json-logger
2.0.7
python-multipart
0.0.6
pytz
2022.7
pywin32
305.1
pywinpty
2.0.10
PyYAML
6.0
pyzmq
25.1.0
qtconsole
5.4.2
QtPy
2.2.0
regex
2023.6.3
requests
2.29.0
responses
0.18.0
rfc3339-validator
0.1.4
rfc3986
1.5.0
rfc3986-validator
0.1.1
rouge-chinese
1.0.3
ruamel.yaml
0.17.21
ruamel.yaml.clib
0.2.6
ruamel-yaml-conda
0.17.21
safetensors
0.3.1
semantic-version
2.10.0
Send2Trash
1.8.0
sentencepiece
0.1.97
setuptools
65.6.3
simpful
2.10.0
sip
6.6.2
six
1.16.0
sklearn
0.0.post7
sniffio
1.2.0
soupsieve
2.4
stack-data
0.2.0
starlette
0.26.1
sympy
1.12
terminado
0.17.1
text2vec
1.1.7
textvec
3.0
tinycss2
1.2.1
tokenizers
0.13.3
toml
0.10.2
tomli
2.0.1
toolz
0.12.0
torch
1.13.1+cu116
torchaudio
0.13.1+cu116
torchvision
0.14.1+cu116
tornado
6.2
tqdm
4.65.0
traitlets
5.7.1
transformers
4.27.1
typing_extensions
4.6.3
tzdata
2023.3
uc-micro-py
1.0.1
ujson
5.4.0
urllib3
1.26.16
uvicorn
0.21.1
wcwidth
0.2.5
webencodings
0.5.1
websocket-client
0.58.0
websockets
11.0.1
wheel
0.38.4
widgetsnbextension
4.0.5
win-inet-pton
1.1.0
win32-setctime
1.1.0
wincertstore
0.2
xxhash
3.2.0
y-py
0.5.9
yarl
1.8.2
ypy-websocket
0.8.2
zstandard
0.19.0
3.2 代码构建3.2.1 拉取数据和代码在搭建好代码运行环境后,我们需要从官方拉取代码,下载相应数据代码拉取地址链接数据拉取地址链接3.2.2 使用pycharm配置参数整个代码框架如下图所示,将数据集加压拷贝到ptuning即可点击main.py的参数配置界面,配置初始化参数:参数配置如下:--do_train
--train_file
AdvertiseGen/train.json
--validation_file
AdvertiseGen/dev.json
--prompt_column
content
--response_column
summary
--overwrite_cache
--model_name_or_path
THUDM/chatglm-6b
--output_dir
output/adver_out
--overwrite_output_dir
--max_source_length
64
--max_target_length
64
--per_device_train_batch_size
1
--per_device_eval_batch_size
1
--gradient_accumulation_steps
16
--predict_with_generate
--max_steps
3000
--logging_steps
10
--save_steps
1000
--learning_rate
2e-2
--pre_seq_len
128
--quantization_bit
4
3.3 执行训练点击运行按钮,即可看到执行日志在微调过程中,内存占用7G左右,耗时10小时+3.4 模型训练部署测试经过10个小时的训练,模型已经训练完毕,相关日志如下:接下来我们测试一下模型训练后的效果,需要对模型进行推理测试,测试代码如下:import os
import torch
from transformers import AutoConfig, AutoModel, AutoTokenizer
# 载入Tokenizer
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True)
# Fine-tuning 后的表现测试
config = AutoConfig.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True, pre_seq_len=128)
model = AutoModel.from_pretrained("THUDM/chatglm-6b", config=config, trust_remote_code=True).half()
# 此处使用你的 ptuning 工作目录
prefix_state_dict = torch.load(os.path.join("E:/NLP/1.chatGLM/ChatGLM-6B-main/ptuning/output/adver_out/checkpoint-3000", "pytorch_model.bin"))
#将训练的权重与原始权重进行拼接
new_prefix_state_dict = {}
for k, v in prefix_state_dict.items():
new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v
model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict)
print(f"Quantized to 4 bit--12G及以下显卡必须使用量化")
model = model.quantize(4)
model = model.cuda()
model.transformer.prefix_encoder.float()
model = model.eval()
#模型测试
response, history = model.chat(tokenizer, "类型#上衣\*材质#牛仔布\*颜色#白色\*风格#简约\*图案#刺绣\*衣样式#外套\*衣款式#破洞", history=[])
response
模型测试结果如下:推理过程显存占用情况如下:为了对比优化后确实比之前效果好,使用原始模型进行测试推理可以发现使用数据微调后的模型表现要优于原始模型!
ChatGLM-6B 是一个开源的、支持中英双语的对话语言模型,基于 General Language Model (GLM) 架构,具有62亿参数。结合模型量化技术,用户可以在消费级的显卡上进行本地部署(INT4 量化级别下最低只需6GB显存)。ChatGLM-6B 是一个文本生成式对话模型,可以用于问答、闲聊等多种场景。它是由清华大学自然语言处理与社会人文计算实验室(THUNLP)开发的。ChatGLM-6B 初具中文问答和对话功能,并支持在单张 2080Ti 上进行推理使用。具体来说,ChatGLM-6B 有如下特点:充分的中英双语预训练: ChatGLM-6B 在 1:1 比例的中英语料上训练了 1T 的 token 量,兼具双语能力。优化的模型架构和大小: 吸取 GLM-130B 训练经验,修正了二维 RoPE 位置编码实现,使用传统 FFN 结构。6B(62亿)的参数大小,也使得研究者和个人开发者自己微调和部署 ChatGLM-6B 成为可能。较低的部署门槛: FP16 半精度下,ChatGLM-6B 需要至少 13GB 的显存进行推理,结合模型量化技术,这一需求可以进一步降低到 10GB(INT8) 和 6GB(INT4), 使得 ChatGLM-6B 可以部署在消费级显卡上。更长的序列长度: 相比 GLM-10B(序列长度1024),ChatGLM-6B 序列长度达 2048,支持更长对话和应用。人类意图对齐训练: 使用了监督微调(Supervised Fine-Tuning)、反馈自助(Feedback Bootstrap)、人类反馈强化学习(Reinforcement Learning from Human Feedback) 等方式,使模型初具理解人类指令意图的能力。输出格式为 markdown,方便展示。1. 环境搭建基础环境配置如下:配置项参数操作系统CentOS 7GPU8 卡 A800 80GB GPUsPython3.10NVIDIA驱动程序版本515.65.01CUDA工具包11.7NCCLnccl_2.14.3-1+cuda11.7cuDNN8.8.1.3_cuda11备注:表中是 ChatGLM-6B 全参数微调的配置,如果是 LORA 微调,单卡 A100 40GB 就可以。具体安装如下:安装cudavim ~/.bashrcexport PATH=/usr/local/cuda/bin:$PATHexport LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH安装cudnnsudo cp cudnn-linux-x86_64-8.8.0.121_cuda11-archive/include/cudnn*.h /usr/local/cuda/include/sudo cp cudnn-linux-x86_64-8.8.0.121_cuda11-archive/lib/libcudnn* /usr/local/cuda/lib64/sudo chmod a+r /usr/local/cuda/include/cudnn*.h /usr/local/cuda/lib64/libcudnn*安装pytorchrequirements.txtprotobuf>=3.19.5,<3.20.1transformers>=4.26.1icetkcpm_kernelsgradiopip3 install --user -r requirements.txtpip install --user torch==1.10.0+cu111 torchvision==0.11.0+cu111 torchaudio==0.10.0 -f torch-1.10.0+cu111-cp39-cp39-linux_x86_64.whl -f torchvision-0.11.0+cu111-cp39-cp39-linux_x86_64.whl -f torchaudio-0.10.0+cu111-cp39-cp39-linux_x86_64.whl2. 使用DeepSpeed数据并行进行全参数微调下载代码:git clone https://github.com/THUDM/ChatGLM-6B.git
cd ChatGLM-6B
cd ptuning修改 ds_train_finetune.sh 脚本使用 DeepSpeed 进行全参数微调。LR=1e-5
MASTER_PORT=$(shuf -n 1 -i 10000-65535)
deepspeed --num_gpus=8 --master_port $MASTER_PORT main.py \
--deepspeed deepspeed.json \
--do_train \
--preprocessing_num_workers 32 \
--train_file AdvertiseGen/train.json \
--test_file AdvertiseGen/dev.json \
--prompt_column content \
--response_column summary \
--cache_dir cache/batch16 \
--model_name_or_path THUDM/chatglm-6b \
--output_dir ./output/adgen-chatglm-6b-ft-$LR \
--overwrite_output_dir \
--max_source_length 512 \
--max_target_length 512 \
--per_device_train_batch_size 16 \
--per_device_eval_batch_size 1 \
--gradient_accumulation_steps 1 \
--predict_with_generate \
--logging_steps 10 \
--save_steps 1000 \
--learning_rate $LR \
--fp16修改 main.py 文件中的 num_train_epoch 参数(默认 num_train_epoch = 3):log_level = training_args.get_process_log_level()
logger.setLevel(log_level)
# datasets.utils.logging.set_verbosity(log_level)
transformers.utils.logging.set_verbosity(log_level)
transformers.utils.logging.enable_default_handler()
transformers.utils.logging.enable_explicit_format()
# Log on each process the small summary:
training_args.num_train_epochs = 1
logger.warning(
f"Process rank: {training_args.local_rank}, device: {training_args.device}, n_gpu: {training_args.n_gpu}"
+ f"distributed training: {bool(training_args.local_rank != -1)}, 16-bits training: {training_args.fp16}"
)
logger.info(f"Training/evaluation parameters {training_args}")运行过程:[2023-05-08 14:57:37,931] [INFO] [launch.py:229:main] WORLD INFO DICT: {'localhost': [0, 1, 2, 3, 4, 5, 6, 7]}
[2023-05-08 14:57:37,932] [INFO] [launch.py:235:main] nnodes=1, num_local_procs=8, node_rank=0
[2023-05-08 14:57:37,932] [INFO] [launch.py:246:main] global_rank_mapping=defaultdict(<class 'list'>, {'localhost': [0, 1, 2, 3, 4, 5, 6, 7]})
[2023-05-08 14:57:37,932] [INFO] [launch.py:247:main] dist_world_size=8
[2023-05-08 14:57:37,932] [INFO] [launch.py:249:main] Setting CUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7
[2023-05-08 14:58:06,040] [INFO] [comm.py:586:init_distributed] Initializing TorchBackend in DeepSpeed with backend nccl
05/08/2023 14:58:07 - WARNING - __main__ - Process rank: 0, device: cuda:0, n_gpu: 1distributed training: True, 16-bits training: True
05/08/2023 14:58:07 - INFO - __main__ - Training/evaluation parameters Seq2SeqTrainingArguments(
_n_gpu=1,
adafactor=False,
adam_beta1=0.9,
adam_beta2=0.999,
adam_epsilon=1e-08,
auto_find_batch_size=False,
bf16=False,
bf16_full_eval=False,
data_seed=None,
dataloader_drop_last=False,
dataloader_num_workers=0,
dataloader_pin_memory=True,
ddp_bucket_cap_mb=None,
ddp_find_unused_parameters=None,
ddp_timeout=1800,
debug=[],
deepspeed=deepspeed.json,
disable_tqdm=False,
do_eval=False,
do_predict=False,
do_train=True,
eval_accumulation_steps=None,
eval_delay=0,
eval_steps=None,
evaluation_strategy=no,
fp16=True,
fp16_backend=auto,
fp16_full_eval=False,
fp16_opt_level=O1,
fsdp=[],
fsdp_config={'fsdp_min_num_params': 0, 'xla': False, 'xla_fsdp_grad_ckpt': False},
fsdp_min_num_params=0,
fsdp_transformer_layer_cls_to_wrap=None,
full_determinism=False,
generation_config=None,
generation_max_length=None,
generation_num_beams=None,
gradient_accumulation_steps=1,
gradient_checkpointing=False,
greater_is_better=None,
group_by_length=False,
half_precision_backend=auto,
hub_model_id=None,
hub_private_repo=False,
hub_strategy=every_save,
hub_token=<HUB_TOKEN>,
ignore_data_skip=False,
include_inputs_for_metrics=False,
jit_mode_eval=False,
label_names=None,
label_smoothing_factor=0.0,
learning_rate=1e-05,
length_column_name=length,
load_best_model_at_end=False,
local_rank=0,
log_level=passive,
log_level_replica=warning,
log_on_each_node=True,
logging_dir=./output/adgen-chatglm-6b-ft-1e-5/runs/May08_14-58-06_wenliang-chatgpt2-0,
logging_first_step=False,
logging_nan_inf_filter=True,
logging_steps=10,
logging_strategy=steps,
lr_scheduler_type=linear,
max_grad_norm=1.0,
max_steps=-1,
metric_for_best_model=None,
mp_parameters=,
no_cuda=False,
num_train_epochs=1,
optim=adamw_hf,
optim_args=None,
output_dir=./output/adgen-chatglm-6b-ft-1e-5,
overwrite_output_dir=True,
past_index=-1,
per_device_eval_batch_size=1,
per_device_train_batch_size=16,
predict_with_generate=True,
prediction_loss_only=False,
push_to_hub=False,
push_to_hub_model_id=None,
push_to_hub_organization=None,
push_to_hub_token=<PUSH_TO_HUB_TOKEN>,
ray_scope=last,
remove_unused_columns=True,
report_to=['tensorboard'],
resume_from_checkpoint=None,
run_name=./output/adgen-chatglm-6b-ft-1e-5,
save_on_each_node=False,
save_safetensors=False,
save_steps=1000,
save_strategy=steps,
save_total_limit=None,
seed=42,
sharded_ddp=[],
skip_memory_metrics=True,
sortish_sampler=False,
tf32=None,
torch_compile=False,
torch_compile_backend=None,
torch_compile_mode=None,
torchdynamo=None,
tpu_metrics_debug=False,
tpu_num_cores=None,
use_ipex=False,
use_legacy_prediction_loop=False,
use_mps_device=False,
warmup_ratio=0.0,
warmup_steps=0,
weight_decay=0.0,
xpu_backend=None,
)GPU显存占用:Mon May
8 19:19:51 2023
+-----------------------------------------------------------------------------+
NVIDIA-SMI 510.108.03
Driver Version: 510.108.03
CUDA Version: 11.6
-------------------------------+----------------------+----------------------+
GPU
Name
Persistence-M
Bus-Id
Disp.A
Volatile Uncorr. ECC
Fan
Temp
Perf
Pwr:Usage/Cap
Memory-Usage
GPU-Util
Compute M.
MIG M.
===============================+======================+======================
0
NVIDIA A800-SXM...
On
00000000:0E:00.0 Off
0
N/A
63C
P0
242W / 400W
76982MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
1
NVIDIA A800-SXM...
On
00000000:13:00.0 Off
0
N/A
59C
P0
434W / 400W
77174MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
2
NVIDIA A800-SXM...
On
00000000:49:00.0 Off
0
N/A
56C
P0
292W / 400W
77174MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
3
NVIDIA A800-SXM...
On
00000000:4F:00.0 Off
0
N/A
71C
P0
444W / 400W
77174MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
4
NVIDIA A800-SXM...
On
00000000:91:00.0 Off
0
N/A
70C
P0
449W / 400W
77174MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
5
NVIDIA A800-SXM...
On
00000000:97:00.0 Off
6
N/A
56C
P0
435W / 400W
77172MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
6
NVIDIA A800-SXM...
On
00000000:CD:00.0 Off
0
N/A
62C
P0
267W / 400W
77174MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
7
NVIDIA A800-SXM...
On
00000000:D2:00.0 Off
0
N/A
62C
P0
349W / 400W
76980MiB / 81920MiB
100%
Default
Disabled
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
Processes:
GPU
GI
CI
PID
Type
Process name
GPU Memory
ID
ID
Usage
=============================================================================
+-----------------------------------------------------------------------------+输出文件:tree ./output/adgen-chatglm-6b-ft-1e-5
├── all_results.json
├── checkpoint-1000

├── config.json

├── configuration_chatglm.py

├── generation_config.json

├── global_step1000


├── mp_rank_00_model_states.pt


├── zero_pp_rank_0_mp_rank_00_optim_states.pt


├── zero_pp_rank_1_mp_rank_00_optim_states.pt


├── zero_pp_rank_2_mp_rank_00_optim_states.pt


├── zero_pp_rank_3_mp_rank_00_optim_states.pt


├── zero_pp_rank_4_mp_rank_00_optim_states.pt


├── zero_pp_rank_5_mp_rank_00_optim_states.pt


├── zero_pp_rank_6_mp_rank_00_optim_states.pt


└── zero_pp_rank_7_mp_rank_00_optim_states.pt

├── ice_text.model

├── latest

├── modeling_chatglm.py

├── pytorch_model-00001-of-00002.bin

├── pytorch_model-00002-of-00002.bin

├── pytorch_model.bin.index.json

├── quantization.py

├── rng_state_0.pth

├── rng_state_1.pth

├── rng_state_2.pth

├── rng_state_3.pth

├── rng_state_4.pth

├── rng_state_5.pth

├── rng_state_6.pth

├── rng_state_7.pth

├── special_tokens_map.json

├── tokenization_chatglm.py

├── tokenizer_config.json

├── trainer_state.json

├── training_args.bin

└── zero_to_fp32.py
├── trainer_state.json
└── train_results.json3. 效果评估这里我们看一道简单的数学题:题目:小明有15颗糖,他想分成3份,每份分别分给3个小朋友,每份糖的数量相等,请问每份应该分几颗糖?ChatGLM-6B的回答如下:假设每份糖的数量为x颗糖,则根据题意可以列出以下方程组:
3x + 3(15 - x) = 15
其中,3x表示小明将15颗糖平均分成三份后,每份拥有的数量,而15 - x则表示小明原本拥有的糖数量。
化简第二个方程式得到: 2x = 5 解得 x = 2.5,因为每个小朋友平均需要15-2.5=12.5颗糖。 因此,每份应该分到 2.5 颗糖。这个回答明显是错误的,我们看一下微调之后的答案:每份5颗糖没问题,但是后面一句有点多余了。4. 训练效率{'loss': 1.5377, 'learning_rate': 5.410753547871278e-06, 'epoch': 0.46}
46%|██████████████████████████████████████████████████████████▌
2309/5003 [4:22:39<4:46:55,
6.39s/it][2023-05-08 19:37:09,312] [INFO] [logging.py:96:log_dist] [Rank 0] step=2310, skipped=4, lr=[5.390765540675595e-06, 5.390765540675595e-06], mom=[(0.9, 0.999), (0.9, 0.999)]
[2023-05-08 19:37:09,512] [INFO] [timer.py:199:stop] epoch=0/micro_step=2310/global_step=2310, RunningAvgSamplesPerSec=20.097073671272955, CurrSamplesPerSec=20.104466204429873, MemAllocated=21.59GB, MaxMemAllocated=58.13GB
{'loss': 1.5591, 'learning_rate': 5.390765540675595e-06, 'epoch': 0.46}
46%|██████████████████████████████████████████████████████████▊
2319/5003 [4:23:43<4:45:37,
6.39s/it][2023-05-08 19:38:13,172] [INFO] [logging.py:96:log_dist] [Rank 0] step=2320, skipped=4, lr=[5.370777533479913e-06, 5.370777533479913e-06], mom=[(0.9, 0.999), (0.9, 0.999)]
[2023-05-08 19:38:13,372] [INFO] [timer.py:199:stop] epoch=0/micro_step=2320/global_step=2320, RunningAvgSamplesPerSec=20.097130490030704, CurrSamplesPerSec=20.114929649570247, MemAllocated=21.59GB, MaxMemAllocated=58.13GB
{'loss': 1.5622, 'learning_rate': 5.370777533479913e-06, 'epoch': 0.46}
47%|███████████████████████████████████████████████████████████
2329/5003 [4:24:47<4:44:43,
6.39s/it][2023-05-08 19:39:17,049] [INFO] [logging.py:96:log_dist] [Rank 0] step=2330, skipped=4, lr=[5.35078952628423e-06, 5.35078952628423e-06], mom=[(0.9, 0.999), (0.9, 0.999)]
[2023-05-08 19:39:17,249] [INFO] [timer.py:199:stop] epoch=0/micro_step=2330/global_step=2330, RunningAvgSamplesPerSec=20.097173576588506, CurrSamplesPerSec=20.12554582582786, MemAllocated=21.59GB, MaxMemAllocated=58.13GB
{'loss': 1.5325, 'learning_rate': 5.35078952628423e-06, 'epoch': 0.47}
47%|███████████████████████████████████████████████████████████▎
2339/5003 [4:25:51<4:43:35,
6.39s/it][2023-05-08 19:40:20,941] [INFO] [logging.py:96:log_dist] [Rank 0] step=2340, skipped=4, lr=[5.330801519088548e-06, 5.330801519088548e-06], mom=[(0.9, 0.999), (0.9, 0.999)]
[2023-05-08 19:40:21,141] [INFO] [timer.py:199:stop] epoch=0/micro_step=2340/global_step=2340, RunningAvgSamplesPerSec=20.097229636997643, CurrSamplesPerSec=20.10217475453911, MemAllocated=21.59GB, MaxMemAllocated=58.13GB
{'loss': 1.5225, 'learning_rate': 5.330801519088548e-06, 'epoch': 0.47}
47%|███████████████████████████████████████████████████████████▋
2349/5003 [4:26:55<4:42:41,
6.39s/it][2023-05-08 19:41:24,845] [INFO] [logging.py:96:log_dist] [Rank 0] step=2350, skipped=4, lr=[5.310813511892865e-06, 5.310813511892865e-06], mom=[(0.9, 0.999), (0.9, 0.999)]
[2023-05-08 19:41:25,045] [INFO] [timer.py:199:stop] epoch=0/micro_step=2350/global_step=2350, RunningAvgSamplesPerSec=20.0972429517267, CurrSamplesPerSec=20.11341719660344, MemAllocated=21.59GB, MaxMemAllocated=58.13GB
{'loss': 1.5457, 'learning_rate': 5.310813511892865e-06, 'epoch': 0.47}
47%|███████████████████████████████████████████████████████████▉
2359/5003 [4:27:59<4:41:31,
6.39s/it][2023-05-08 19:42:28,736] [INFO] [logging.py:96:log_dist] [Rank 0] step=2360, skipped=4, lr=[5.290825504697182e-06, 5.290825504697182e-06], mom=[(0.9, 0.999), (0.9, 0.999)]
[2023-05-08 19:42:28,936] [INFO] [timer.py:199:stop] epoch=0/micro_step=2360/global_step=2360, RunningAvgSamplesPerSec=20.097272216166992, CurrSamplesPerSec=20.09995682150088, MemAllocated=21.59GB, MaxMemAllocated=58.13GB
{'loss': 1.5437, 'learning_rate': 5.290825504697182e-06, 'epoch': 0.47}
47%|████████████████████████████████████████████████████████████
2365/5003 [4:28:37<4:40:51,
6.39s/it]可以最后的参数:[4:28:37<4:40:51,
6.39s/it]也就是每次迭代需要6.39秒,对于100万的数据,需要: 1000000/16/8*6/3600\approx13 小时。其中16表示 batch size,8表示8张卡。100万的数据13小时可以微调完成。参考吃果冻不吐果冻皮:使用DeepSpeed/P-Tuning v2对ChatGLM-6B进行微调ChatGLMGitHub - THUDM/ChatGLM-6B: ChatGLM-6B: An Open Bilingual Dialogue Language Model
开源双语对话语言模型
介绍ChatGLM-6B是开源的文本生成式对话模型,基于General Language Model(GLM)框架,具有62亿参数,结合模型蒸馏技术,实测在2080ti显卡训练中上(INT4)显存占用**6G**左右,**优点**:1.较低的部署门槛: FP16 半精度下,ChatGLM-6B 需要至少 13GB 的显存进行推理,结合模型量化技术,一需求可以进一步降低到 10GB(INT8) 和 6GB(INT4), 使得 ChatGLM-6B 可以部署在消费级显卡上。2,更长的序列长度: 相比 GLM-10B(序列长度1024),ChatGLM2-6B 序列长度达32K,支持更长对话和应用。3,人类意图对齐训练: 使用了监督微调(Supervised Fine-Tuning)、反馈自助(Feedback Bootstrap)、人类反馈强化学习(Reinforcement Learning from Human Feedback) 等方式,使模型初具理解人类指令意图的能力。输出格式为 markdown,方便展示。目前已开源监督微调方法,**不足**:1,模型容量较小: 6B 的小容量,决定了其相对较弱的模型记忆和语言能力,随着自己训练数据数量和轮次增加,会逐步丧失原来的对话能力,智谱ai于魁飞博士给的训练数据再好在1000条左右。2,较弱的多轮对话能力:ChatGLM-6B 的上下文理解能力还不够充分,在面对长答案生成,以及多轮对话的场景时,可能会出现上下文丢失和理解错误的情况。解决方式:外挂知识库的形式,例如ChatGLM-6B 结合 langchain 实现本地知识库[link](工作台 - Heywhale.com)3,训练完自己的数据后,遗忘掉之前对话的能力,出现灾难性遗忘,解决办法在自己专业领域数据上可以加入通用开源的对话微调数据集一起训练,**制作不易,收藏关注哈,一起交流.......**1,安装1.1,ChatGLM2-6B官方开源的训练方式基于P-Tuning v2微调,链接: [git_link](https://github.com/THUDM/ChatGLM2-6B/)基于QLoRA链接: [git_link](https://github.com/shibing624/MedicalGPT)1.2,ChatGLM-6B基于P-Tuning v2微调,链接: [git_link](https://github.com/THUDM/ChatGLM-6B)**两个版本区别,文章末尾介绍**以下ChatGLM2-6B微调步骤下载ChatGLM2-6Bgit clone https://github.com/THUDM/ChatGLM2-6B
cd ChatGLM2-6B
pip install -r requirements.txt
cd ptuning/
pip install rouge_chinese nltk jieba datasets2, 使用自己数据集 2.1
构建自己的数据集样例数据下载链接链接: [Dataset](https://cloud.tsinghua.edu.cn/f/b3f119a008264b1cabd1/?dl=1)将自己的数据集换成以下格式{
"content": "类型#上衣*版型#宽松*版型#显瘦*图案#线条*衣样式#衬衫*衣袖型#泡泡袖*衣款式#抽绳",
"summary": "这件衬衫的款式非常的宽松,利落的线条可以很好的隐藏身材上的小缺点,穿在身上有着很好的显瘦效果。领口装饰了一个可爱的抽绳,漂亮的绳结展现出了十足的个性,配合时尚的泡泡袖型,尽显女性甜美可爱的气息。"
}解释:构建数据集是一个 JSON 格式文件,其中一个列表中包含多个字典[ { "content": "问句1",
"summary": "答案1“}{ "content": "问句1",
"summary": "答案1“}
{....} ]2.2 修改 train.sh 和 evaluate.sh修改 train.sh 和 evaluate.sh 中的 train_file、validation_file和test_file为你自己的 JSON 格式数据集路径,并将 prompt_column 和 response_column 改为 JSON 文件中输入文本和输出文本对应的 KEY。我修改的train.sh示例如下:## 切记如果粘贴我的这个示例代码,请删除注释
PRE_SEQ_LEN=128
LR=2e-2
NUM_GPUS=2
# 双卡
torchrun --standalone --nnodes=1 --nproc-per-node=$NUM_GPUS main.py \
--do_train \
--train_file di/train.json \
# 训练文件地址
--validation_file di/fval.json \
# 验证文件地址
--prompt_column content \
# 训练集中prompt名称
--response_column summary \
# 训练集中答案明细
--overwrite_cache \
# 重复训练一个训练集时候可删除
--model_name_or_path THUDM/chatglm-6b \
# 加载模型文件地址,可修改为本地路径,第五章讲怎么找
--output_dir output/adgen-chatglm-6b-pt-$PRE_SEQ_LEN-$LR \
# 保存训练模型文件地址
--overwrite_output_dir \
--max_source_length 64 \
# 最大输入文本的长度
--max_target_length 128 \
--per_device_train_batch_size 1 \
# batch_size 根据显存调节
--per_device_eval_batch_size 1 \
--gradient_accumulation_steps 16 \
--predict_with_generate \
--max_steps 2000 \
# 最大保存模型的步数
--logging_steps 10 \
# 打印日志间隔
--save_steps 500 \
# 多少部保存一次模型
--learning_rate $LR \
--pre_seq_len $PRE_SEQ_LEN \
--quantization_bit 4
# 可修改为int8
参数具体解释train.sh 中的 PRE_SEQ_LEN 和 LR 分别是 soft prompt 长度和训练的学习率,可以进行调节以取得最佳的效果。P-Tuning-v2 方法会冻结全部的模型参数,可通过调整 quantization_bit 来被原始模型的量化等级,不加此选项则为 FP16 精度加载。在默认配置 quantization_bit=4、per_device_train_batch_size=1、gradient_accumulation_steps=16 下,INT4 的模型参数被冻结,一次训练迭代会以 1 的批处理大小进行 16 次累加的前后向传播,等效为 16 的总批处理大小,此时最低只需 6.7G 显存。若想在同等批处理大小下提升训练效率,可在二者乘积不变的情况下,加大 per_device_train_batch_size 的值,但也会带来更多的显存消耗,请根据实际情况酌情调整。2.3,开始训练bash train.sh示例:两个显卡分别占用8.3G显存3,验证模型将 evaluate.sh 中的 CHECKPOINT 更改为训练时保存的 checkpoint 名称,运行以下指令进行模型推理和评测:bash evaluate.sh模型会输出正确答案和预测结果文件。4,模型部署4.1 自己验证 ,更换模型路径将对应的demo或代码中的THUDM/chatglm2-6b换成经过 P-Tuning 微调之后 checkpoint 的地址(在示例中为 ./output/adgen-chatglm-6b-pt-8-1e-2/checkpoint-3000)。注意,目前的微调还不支持多轮数据,所以只有对话第一轮的回复是经过微调的。在 P-tuning v2 训练时模型只保存 PrefixEncoder 部分的参数,所以在推理时需要同时加载原 ChatGLM-6B 模型以及 PrefixEncoder 的权重,因此需要指定 evaluate.sh 中的参数:首先载入Tokenizer:from transformers import AutoConfig, AutoModel, AutoTokenizer
# 载入Tokenizer
tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm2-6b", trust_remote_code=True)
加载的自己训练 P-Tuning 的 checkpoint:config = AutoConfig.from_pretrained("THUDM/chatglm-6b", trust_remote_code=True, pre_seq_len=128)
model = AutoModel.from_pretrained("THUDM/chatglm-6b", config=config, trust_remote_code=True)
prefix_state_dict = torch.load(os.path.join(CHECKPOINT_PATH, "pytorch_model.bin"))
new_prefix_state_dict = {}
for k, v in prefix_state_dict.items():
if k.startswith("transformer.prefix_encoder."):
new_prefix_state_dict[k[len("transformer.prefix_encoder."):]] = v
model.transformer.prefix_encoder.load_state_dict(new_prefix_state_dict)
# Comment out the following line if you don't use quantization
model = model.quantize(4) #或者8
model = model.half().cuda()
model.transformer.prefix_encoder.float()
model = model.eval()
response, history = Domain im Kundenauftrag registriert(tokenizer, "你好", history=[])你也可以直接运行支持加载 P-Tuning v2 checkpoint 的 web demo,记得参照上面代码修改配置文件bash web_demo.sh可能需要修改 web_demo.sh 的内容以符合你实际的 checkpoint 情况。5,预训练模型地址一般存放位置在本机本章第二步执行bash train.sh,终端会打印出模型加载的位置,找到位置后替换一般存放的位置是类似XXXhome_pathXXX/.cache/huggingface/hub/models--THUDM--chatglm2-6b/snapshots/aa51e62ddc9c9f334858b0af44cf59b05c70148a/查看包含这些目录config.json
configuration_chatglm.py
modeling_chatglm.py
pytorch_model.bin
quantization.py替换掉 demo.py 文件中THUDM/chatglm-6b为自己路径 6 如需要使用多轮对话数据对模型进行微调,可以提供聊天历史,例如以下是一个三轮对话的训练数据:{"prompt": "长城h3风扇不转。继电器好的。保险丝好的传感器新的风扇也新的这是为什么。就是继电器缺一个信号线", "response": "用电脑能读数据流吗?水温多少", "history": []}
{"prompt": "95", "response": "上下水管温差怎么样啊?空气是不是都排干净了呢?", "history": [["长城h3风扇不转。继电器好的。保险丝好的传感器新的风扇也新的这是为什么。就是继电器缺一个信号线", "用电脑能读数据流吗?水温多少"]]}
{"prompt": "是的。上下水管都好的", "response": "那就要检查线路了,一般风扇继电器是由电脑控制吸合的,如果电路存在断路,或者电脑坏了的话会出现继电器不吸合的情况!", "history": [["长城h3风扇不转。继电器好的。保险丝好的传感器新的风扇也新的这是为什么。就是继电器缺一个信号线", "用电脑能读数据流吗?水温多少"], ["95", "上下水管温差怎么样啊?空气是不是都排干净了呢?"]]}训练时需要指定 --history_column 为数据中聊天历史的 key(在此例子中是 history),将自动把聊天历史拼接。要注意超过输入长度 max_source_length 的内容会被截断。可以参考以下指令:bash train_chat.sh7,遇到的问题和解决办法记得点赞关注,有问题留言哈,看到就立马回复7.1,出现一个问题了。 RuntimeError: Default process group has not been initialized, please make sure to call init_process_group.训练的时候估计transforms版本,我也遇到了,我回退到transformers==4.27.1 就可以了7.2 ,问题:ValueError: Unable to create tensor, you should probably activate truncation and/or padding with 'padding=True' 'truncation=True' to have batched tensors with the same length. Perhaps your features 。。ERROR:torch.distributed.elastic.multiprocessing.api:failed (exitcode: 1) local_rank: 0 (pid: 16858) of binarytorch.distributed.elastic.multiprocessing.errors.ChildFailedError: 解决方式显存不够,调小batch_size就可以了 8,ChatGLM2-6B和ChatGLM-6B区别ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本,在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上,ChatGLM2-6B 引入了如下新特性:更强大的性能:基于 ChatGLM 初代模型的开发经验,我们全面升级了 ChatGLM2-6B 的基座模型。ChatGLM2-6B 使用了 GLM 的混合目标函数,经过了 1.4T 中英标识符的预训练与人类偏好对齐训练,评测结果显示,相比于初代模型,ChatGLM2-6B 在 MMLU(+23%)、CEval(+33%)、GSM8K(+571%) 、BBH(+60%)等数据集上的性能取得了大幅度的提升,在同尺寸开源模型中具有较强的竞争力。更长的上下文:基于 FlashAttention 技术,我们将基座模型的上下文长度(Context Length)由 ChatGLM-6B 的 2K 扩展到了 32K,并在对话阶段使用 8K 的上下文长度训练,允许更多轮次的对话。但当前版本的 ChatGLM2-6B 对单轮超长文档的理解能力有限,我们会在后续迭代升级中着重进行优化。更高效的推理:基于 Multi-Query Attention 技术,ChatGLM2-6B 有更高效的推理速度和更低的显存占用:在官方的模型实现下,推理速度相比初代提升了 42%,INT4 量化下,6G 显存支持的对话长度由 1K 提升到了 8K。更开放的协议:ChatGLM2-6B 权重对学术研究完全开放,在获得官方的书面许可后,亦允许商业使用。

我要回帖

更多关于 如何训练模型 的文章

 

随机推荐