一、ChatGLM-6B+Prefix-tuning/lora微调生成心理咨询问答
1.创意背景
在现代社会中,人们面临许多压力和挑战,比如,买房、结婚、升学、考试、工作业绩等等。身心健康成为愈发重要的关注点。随着人工智能技术的迅猛发展,我们可以利用这一技术来帮助人们改善他们的生活质量和心理健康,降低矛盾的产生,避免自杀,构建积极的社会和人生。
2.创意目标
通过AI和心理学原理的结合,提供个性化的心理健康辅助服务,可以随时随地帮助用户实现情绪管理、自我成长和内心平衡,并且不用担心隐私问题,同时能大幅度降低心理咨询的费用。
3.创意设计
- 用户画像:通过用户使用AI大语言模型进行文字、图片和视频的交互,系统了解用户的兴趣、需求和个性特点,建立起个性化的用户画像。
- 情绪分析与管理:基于用户的文字、图片、视频内容,应用内置的情感分析算法,帮助用户识别情绪变化及原因,并提供情绪管理策略和建议,包括但不限于文字、图片、音频、视频、游戏等形式。
- 自我探索与成长:结合心理学知识和个人发展目标,为用户提供定制化的成长计划和反馈,引导他们发现潜在的优势和改进空间。
- 内心宁静与放松:提供冥想、呼吸练习、轻音乐等资源,帮助用户放松身心,培养专注力和内心宁静感。
- 社交支持和分享:建立用户社区,让用户可以相互支持、分享经验和鼓励,增强社交联系和减轻孤独感。
4.最终效果
2023-7-14新增lora微调
二、数据集
1. chatglm-6b数据集格式
默认为{“content”:”这里是content,也就是数据”,”summary”:”这里是summary,可以理解为标签”}
content | summary |
---|---|
“从现在起,答应自己的事就尽力去做到,” | “答应自己要去的地方就尽力去抵达” |
“若你困于无风之地” | “,我将奏响高天之歌” |
“世事易变” | “,匪石弗转” |
“若你困于无风之地” | “我将为你奏响高天之歌” |
“漩涡无法击碎的磐岩” | “,也终究会在时光的冲刷下磨损” |
“从天堂到地狱,” | “我路过了人间” |
2.需要对数据格式进行转换。
!unzip data/data231239/smileData_v3.zip -d data/data231239/
Archive: data/data231239/smileData_v3.zip
inflating: data/data231239/smileData_v3.json
!head data/data231239/smileData_v3.json
[
{
"instruction": "假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复",
"input": "求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:",
"output": "看来你很烦恼啊。那你先了解一下孩子的意见吧。问问她喜不喜欢在你家,或者她想不想跟她的父亲一起生活。"
},
{
"instruction": "假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复",
"input": "求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:看来你很烦恼啊。那你先了解一下孩子的意见吧。问问她喜不喜欢在你家,或者她想不想跟她的父亲一起生活。求助者:我没有问过她,但是听我儿子说,她不喜欢在我们家住,而且还总抱怨。支持者:",
"output": "那你也不能就这么轻易地放弃她啊。毕竟离婚对于孩子来说也是一种负面影响。但是这也不能成为她任性变坏的资本。要看她的真实情况,然后试着帮助她。"
3.数据格式转换
数据太多,挑选1000条,这样速度快
!mkdir soul
# 训练集
import json
from pprint import pprint
# 读取 JSON 文件
with open('data/data231239/smileData_v3.json', 'r', encoding='utf-8') as f:
data = json.load(f)
result_list = []
with open('soul/train.json', 'w', encoding="utf-8") as f:
for item in data[:1000]:
temp = dict()
temp['content'] = item['instruction']+ '。'+item['input']
temp['summary'] = item['output']
json.dump(temp, f, ensure_ascii=False)
f.write('n')
# 测试集
import json
from pprint import pprint
# 读取 JSON 文件
with open('data/data231239/smileData_v3.json', 'r', encoding='utf-8') as f:
data = json.load(f)
result_list = []
with open('soul/dev.json', 'w', encoding="utf-8") as f:
for item in data[1000:200]:
temp = dict()
temp['content'] = item['instruction']+ '。'+item['input']
temp['summary'] = item['output']
json.dump(temp, f, ensure_ascii=False)
f.write('n')
!head -n2 1.jsonl
{"content": "假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:", "summary": "看来你很烦恼啊。那你先了解一下孩子的意见吧。问问她喜不喜欢在你家,或者她想不想跟她的父亲一起生活。"}
{"content": "假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:看来你很烦恼啊。那你先了解一下孩子的意见吧。问问她喜不喜欢在你家,或者她想不想跟她的父亲一起生活。求助者:我没有问过她,但是听我儿子说,她不喜欢在我们家住,而且还总抱怨。支持者:", "summary": "那你也不能就这么轻易地放弃她啊。毕竟离婚对于孩子来说也是一种负面影响。但是这也不能成为她任性变坏的资本。要看她的真实情况,然后试着帮助她。"}
三、准备环境
请注意:
- 使用%%capture不显示准备环境时出现的大量文本
- 使用paddlepaddlegpu的dev版本
- 使用paddlenlp最新版本
%%capture
#要更新pip要不容易安装失败
!pip install --upgrade pip
%%capture
!python -m pip install paddlepaddle-gpu==0.0.0.post112 -f https://www.paddlepaddle.org.cn/whl/linux/gpu/develop.html
# https://gitee.com/livingbody/PaddleNLP为我同步的最新的PaddleNLP,官方gitee的有一些旧
!git clone https://gitee.com/livingbody/PaddleNLP -b develop --depth=1
/home/aistudio
正克隆到 'PaddleNLP'...
remote: Enumerating objects: 6435, done.
remote: Counting objects: 100% (6435/6435), done.
remote: Compressing objects: 100% (4450/4450), done.
remote: Total 6435 (delta 2517), reused 3737 (delta 1674), pack-reused 0
接收对象中: 100% (6435/6435), 24.00 MiB | 5.01 MiB/s, 完成.
处理 delta 中: 100% (2517/2517), 完成.
检查连接... 完成。
%%capture
!pip install -e PaddleNLP/
四、创建chatglm-6b模型
1.模型加载
- 本地加载
- 自动下载并加载
建议数据集挂载并本地加载,这样速度快,不用等太久!
import json
import paddle
from paddle.distributed import fleet
from paddlenlp.peft import LoRAConfig, LoRAModel, PrefixConfig, PrefixModelForCausalLM
from paddlenlp.peft.prefix import (
chatglm_pad_attention_mask,
chatglm_postprocess_past_key_value,
)
from paddlenlp.transformers import ChatGLMConfig, ChatGLMForCausalLM, ChatGLMTokenizer
#读取原始的chatglm-6b模型
# model_name_or_path = 'THUDM/chatglm-6b' # 使用该路径会自动下载和加载模型
model_name_or_path = 'THUDM/chatglm-6b'
tokenizer = ChatGLMTokenizer.from_pretrained(model_name_or_path)
config = ChatGLMConfig.from_pretrained(model_name_or_path)
paddle.set_default_dtype(config.paddle_dtype)
model = ChatGLMForCausalLM.from_pretrained(
model_name_or_path,
tensor_parallel_degree=0,
tensor_parallel_rank=0,
load_state_as_np=True,
dtype=config.paddle_dtype,
)
model.eval()
[2023-07-21 10:30:01,867] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/ice_text.model
[2023-07-21 10:30:01,869] [ INFO] - Downloading https://bj.bcebos.com/paddlenlp/models/community/THUDM/chatglm-6b/added_tokens.json and saved to /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b
[2023-07-21 10:30:01,948] [ WARNING] - file<https://bj.bcebos.com/paddlenlp/models/community/THUDM/chatglm-6b/added_tokens.json> not exist
[2023-07-21 10:30:01,952] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/special_tokens_map.json
[2023-07-21 10:30:01,955] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/tokenizer_config.json
[2023-07-21 10:30:02,358] [ INFO] - Found /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/config.json
[2023-07-21 10:30:02,362] [ INFO] - Loading configuration file /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/config.json
[2023-07-21 10:30:02,366] [ WARNING] - `load_state_as_np` is deprecated, please delete it!
[2023-07-21 10:30:02,423] [ INFO] - Found /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/config.json
[2023-07-21 10:30:02,427] [ INFO] - Loading configuration file /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/config.json
[2023-07-21 10:30:02,430] [ INFO] - Already cached /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/model_state.pdparams
[2023-07-21 10:30:02,433] [ INFO] - loading weights file model_state.pdparams from cache at /home/aistudio/.paddlenlp/models/THUDM/chatglm-6b/model_state.pdparams
[2023-07-21 10:30:24,093] [ INFO] - Loaded weights file from disk, setting weights to model.
W0721 10:30:24.098392 16136 gpu_resources.cc:119] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 11.2
W0721 10:30:24.102008 16136 gpu_resources.cc:149] device: 0, cuDNN Version: 8.2.
[2023-07-21 10:30:37,643] [ WARNING] - Some weights of the model checkpoint at THUDM/chatglm-6b were not used when initializing ChatGLMForCausalLM: ['transformer.rotary_emb.inv_freq']
- This IS expected if you are initializing ChatGLMForCausalLM from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing ChatGLMForCausalLM from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).
[2023-07-21 10:30:37,646] [ WARNING] - Some weights of ChatGLMForCausalLM were not initialized from the model checkpoint at THUDM/chatglm-6b and are newly initialized: ['transformer.rotary_embeddings.inv_freq', 'lm_head.weight']
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
2.对话推理
本部分从ChatGLM-6B应用测试,包括全部安装步骤,封装好了调用代码及图形界面使用了单轮对话函数,如有其他需求,如多轮对话、图形界面等,请查看该链接
def glm_single_QA(model,tokenizer,next_inputs,input_length,output_length):
# 输入格式转换
inputs = tokenizer(
next_inputs,
return_tensors="np",
padding=True,
max_length=input_length,
truncation=True,
truncation_side="left",
)
input_map = {}
for key in inputs:
input_map[key] = paddle.to_tensor(inputs[key])
# 获取结果
infer_result = model.generate(
**input_map,
decode_strategy="sampling",
top_k=1,
# top_p =5,
max_length=output_length,
use_cache=True,
use_fast=True,
use_fp16_decoding=True,
repetition_penalty=1,
temperature = 0.95,
length_penalty=1,
)[0]
# 结果转换
output = ''
result = []
for x in infer_result.tolist():
res = tokenizer.decode(x, skip_special_tokens=True)
res = res.strip("n")
result.append(res)
output = output + res
return output
3.微调前chatglm-6b模型能力
Q_motif = "假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:"
print(Q_motif)
result=glm_single_QA(model,tokenizer,Q_motif,2048,2048)
print("A:"+result)
假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:
A:首先,我可以理解您所面临的挑战和困惑。收养一个孩子是一个艰难的决定,可能会对家庭产生深远的影响。
对于您儿子和姑姐女儿的关系,您可以尝试与他们建立良好的沟通和互动。您可以试着与他们分享您的想法和感受,以及您对收养孩子的看法。同时,您也可以尝试与他们一起探讨如何改善他们之间的关系。您还可以寻求专业心理咨询师或家庭治疗师的帮助,以帮助您更好地处理这个问题。
对于您大姑姐的女儿,您可以尝试与她建立良好的关系。您可以试着让她感受到您对她的关心和支持,并鼓励她积极参与家庭活动和家务。同时,您也可以尝试与她分享您对收养孩子的看法,以及您希望她如何参与孩子的成长和发展。
最后,我建议您寻求专业心理咨询师或家庭治疗师的帮助。他们可以帮助您更好地处理您所面临的问题,并提供专业的建议和支持。
五、大模型微调
下面是prefix-tuning和lora两种微调方式,选择一种微调方式和对应的模型实例化代码即可,两个都选会报错
1.使用prefix-tuning对chatglm-6b进行微调
-
如果想要完成自己的任务,请将–task_name_or_path后面参数修改为你的数据集所在目录
-
如果微调过程中,报错out of memory,请修改–per_device_train_batch_size以及–per_device_eval_batch_size后面的参数为1
-
训练代码来自 gitee.com/paddlepaddl…
-
注意代码版本要一致,否则会有各种错误,例如:
# 创建微调模型保存目录
!mkdir -p soul_bak/chatglm-6b
# 确认使用的是开发版的paddlepaddle-gpu
!pip list|grep paddlepaddle
paddlepaddle-gpu 0.0.0.post112
!python work/finetune_generation.py
--output_dir soul_bak/chatglm-6b
--per_device_train_batch_size 2
--per_device_eval_batch_size 2
--gradient_accumulation_steps 1
--model_name_or_path data/data217141
--task_name_or_path soul
--num_train_epochs 2
--learning_rate 3e-2
--warmup_ratio 0.03
--logging_steps 250
--eval_steps 500
--save_steps 2000
--src_length 128
--tgt_length 512
--fp16
--fp16_opt_level O2
--recompute True
--do_train
--do_eval
--disable_tqdm True
--metric_for_best_model accuracy
--load_best_model_at_end True
--do_generation False
--prefix_tuning True
--save_total_limit 1
[2023-07-21 09:14:06,561] [ INFO] dygraph_sharding_optimizer.py:27 - g_shard_use_reduce 0
[2023-07-21 09:14:06,561] [ INFO] dygraph_sharding_optimizer.py:29 - g_shard_norm_align_dp 1
[2023-07-21 09:14:06,562] [ INFO] hybrid_parallel_optimizer.py:43 - g_shard_norm_align_dp 1
[2023-07-21 09:14:06,570] [ INFO] pipeline_parallel.py:48 - g_shard_use_reduce 0
[2023-07-21 09:14:08,233] [ WARNING] - evaluation_strategy reset to IntervalStrategy.STEPS for do_eval is True. you can also set evaluation_strategy='epoch'.
[2023-07-21 09:14:08,233] [ INFO] - The default value for the training argument `--report_to` will change in v5 (from all installed integrations to none). In v5, you will need to use `--report_to all` to get the same behavior as now. You should start updating your code and make this info disappear :-).
[2023-07-21 09:14:08,233] [ INFO] - ============================================================
[2023-07-21 09:14:08,233] [ INFO] - Model Configuration Arguments
[2023-07-21 09:14:08,233] [ INFO] - paddle commit id : fa084e5e15b951900e3d1f0ea12262305cdebe30
[2023-07-21 09:14:08,233] [ INFO] - do_generation : False
[2023-07-21 09:14:08,233] [ INFO] - lora : False
[2023-07-21 09:14:08,233] [ INFO] - model_name_or_path : data/data217141
[2023-07-21 09:14:08,233] [ INFO] - prefix_tuning : True
[2023-07-21 09:14:08,234] [ INFO] -
[2023-07-21 09:14:08,234] [ INFO] - ============================================================
[2023-07-21 09:14:08,234] [ INFO] - Data Configuration Arguments
[2023-07-21 09:14:08,234] [ INFO] - paddle commit id : fa084e5e15b951900e3d1f0ea12262305cdebe30
[2023-07-21 09:14:08,234] [ INFO] - generate_num : 100
[2023-07-21 09:14:08,234] [ INFO] - num_beams : 5
[2023-07-21 09:14:08,234] [ INFO] - src_length : 128
[2023-07-21 09:14:08,234] [ INFO] - task_name_or_path : soul
[2023-07-21 09:14:08,234] [ INFO] - tgt_length : 512
[2023-07-21 09:14:08,234] [ INFO] -
[2023-07-21 09:14:08,234] [ WARNING] - Process rank: -1, device: gpu, world_size: 1, distributed training: False, 16-bits training: True
[2023-07-21 09:14:08,235] [ INFO] - loading configuration file data/data217141/config.json
[2023-07-21 09:14:08,236] [ INFO] - Model config ChatGLMConfig {
"activation": "gelu",
"attention_scale": true,
"bos_token_id": 130004,
"eos_token_id": 130005,
"gmask_token_id": 130001,
"hidden_size": 4096,
"inner_hidden_size": 16384,
"layernorm_epsilon": 1e-05,
"mask_token_id": 130000,
"max_sequence_length": 2048,
"model_type": "chatglm",
"num_attention_heads": 32,
"num_hidden_layers": 28,
"num_image_tokens": 0,
"output_predict": true,
"pad_token_id": 3,
"paddle_dtype": "float16",
"paddlenlp_version": null,
"position_encoding_2d": true,
"pre_seq_len": null,
"prefix_projection": false,
"quantization_bit": 0,
"recompute": false,
"use_cache": true,
"vocab_size": 130528
}
W0721 09:14:35.405668 3227 gpu_resources.cc:119] Please NOTE: device: 0, GPU Compute Capability: 7.0, Driver API Version: 11.2, Runtime API Version: 11.2
W0721 09:14:35.409356 3227 gpu_resources.cc:149] device: 0, cuDNN Version: 8.2.
[2023-07-21 09:14:51,868] [ WARNING] - Some weights of the model checkpoint at data/data217141 were not used when initializing ChatGLMForConditionalGeneration: ['transformer.layers.16.attention.rotary_emb.inv_freq', 'transformer.layers.13.attention.rotary_emb.inv_freq', 'transformer.layers.12.attention.rotary_emb.inv_freq', 'transformer.layers.18.attention.rotary_emb.inv_freq', 'transformer.layers.1.attention.rotary_emb.inv_freq', 'transformer.layers.11.attention.rotary_emb.inv_freq', 'transformer.layers.26.attention.rotary_emb.inv_freq', 'transformer.layers.10.attention.rotary_emb.inv_freq', 'transformer.layers.24.attention.rotary_emb.inv_freq', 'transformer.layers.6.attention.rotary_emb.inv_freq', 'transformer.layers.5.attention.rotary_emb.inv_freq', 'transformer.layers.8.attention.rotary_emb.inv_freq', 'transformer.layers.9.attention.rotary_emb.inv_freq', 'transformer.layers.7.attention.rotary_emb.inv_freq', 'transformer.layers.4.attention.rotary_emb.inv_freq', 'transformer.layers.2
- This IS expected if you are initializing ChatGLMForConditionalGeneration from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).
- This IS NOT expected if you are initializing ChatGLMForConditionalGeneration from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).
[2023-07-21 09:14:51,869] [ WARNING] - Some weights of ChatGLMForConditionalGeneration were not initialized from the model checkpoint at data/data217141 and are newly initialized: ['transformer.layers.16.attention.rotary_embeddings.inv_freq', 'transformer.layers.9.attention.rotary_embeddings.inv_freq', 'transformer.layers.0.attention.rotary_embeddings.inv_freq', 'transformer.layers.15.attention.rotary_embeddings.inv_freq', 'transformer.layers.3.attention.rotary_embeddings.inv_freq', 'transformer.layers.10.attention.rotary_embeddings.inv_freq', 'transformer.layers.7.attention.rotary_embeddings.inv_freq', 'transformer.layers.4.attention.rotary_embeddings.inv_freq', 'transformer.layers.21.attention.rotary_embeddings.inv_freq', 'transformer.layers.2.attention.rotary_embeddings.inv_freq', 'transformer.layers.14.attention.rotary_embeddings.inv_freq', 'transformer.layers.19.attention.rotary_embeddings.inv_freq', 'transformer.layers.22.attention.rotary_embeddings.inv_freq', 'transformer.layers
You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.
[2023-07-21 09:14:51,970] [ INFO] - Frozen parameters: 6.71e+09 || Trainable parameters:1.47e+07 || Total parameters:6.72e+09|| Trainable:0.22%
[2023-07-21 09:14:52,507] [ INFO] - Using half precision
[2023-07-21 09:14:52,515] [ INFO] - ============================================================
[2023-07-21 09:14:52,515] [ INFO] - Training Configuration Arguments
[2023-07-21 09:14:52,515] [ INFO] - paddle commit id : fa084e5e15b951900e3d1f0ea12262305cdebe30
[2023-07-21 09:14:52,515] [ INFO] - _no_sync_in_gradient_accumulation: True
[2023-07-21 09:14:52,515] [ INFO] - adam_beta1 : 0.9
[2023-07-21 09:14:52,515] [ INFO] - adam_beta2 : 0.999
[2023-07-21 09:14:52,516] [ INFO] - adam_epsilon : 1e-08
[2023-07-21 09:14:52,516] [ INFO] - bf16 : False
[2023-07-21 09:14:52,516] [ INFO] - bf16_full_eval : False
[2023-07-21 09:14:52,516] [ INFO] - current_device : gpu:0
[2023-07-21 09:14:52,516] [ INFO] - data_parallel_rank : 0
[2023-07-21 09:14:52,516] [ INFO] - dataloader_drop_last : False
[2023-07-21 09:14:52,516] [ INFO] - dataloader_num_workers : 0
[2023-07-21 09:14:52,516] [ INFO] - dataset_rank : 0
[2023-07-21 09:14:52,516] [ INFO] - dataset_world_size : 1
[2023-07-21 09:14:52,516] [ INFO] - device : gpu
[2023-07-21 09:14:52,516] [ INFO] - disable_tqdm : True
[2023-07-21 09:14:52,516] [ INFO] - do_eval : True
[2023-07-21 09:14:52,516] [ INFO] - do_export : False
[2023-07-21 09:14:52,516] [ INFO] - do_predict : False
[2023-07-21 09:14:52,516] [ INFO] - do_train : True
[2023-07-21 09:14:52,516] [ INFO] - eval_accumulation_steps : None
[2023-07-21 09:14:52,516] [ INFO] - eval_batch_size : 2
[2023-07-21 09:14:52,516] [ INFO] - eval_steps : 500
[2023-07-21 09:14:52,516] [ INFO] - evaluation_strategy : IntervalStrategy.STEPS
[2023-07-21 09:14:52,516] [ INFO] - flatten_param_grads : False
[2023-07-21 09:14:52,516] [ INFO] - fp16 : True
[2023-07-21 09:14:52,516] [ INFO] - fp16_full_eval : False
[2023-07-21 09:14:52,516] [ INFO] - fp16_opt_level : O2
[2023-07-21 09:14:52,517] [ INFO] - gradient_accumulation_steps : 1
[2023-07-21 09:14:52,517] [ INFO] - greater_is_better : True
[2023-07-21 09:14:52,517] [ INFO] - ignore_data_skip : False
[2023-07-21 09:14:52,517] [ INFO] - label_names : None
[2023-07-21 09:14:52,517] [ INFO] - lazy_data_processing : True
[2023-07-21 09:14:52,517] [ INFO] - learning_rate : 0.03
[2023-07-21 09:14:52,517] [ INFO] - load_best_model_at_end : True
[2023-07-21 09:14:52,517] [ INFO] - local_process_index : 0
[2023-07-21 09:14:52,517] [ INFO] - local_rank : -1
[2023-07-21 09:14:52,517] [ INFO] - log_level : -1
[2023-07-21 09:14:52,517] [ INFO] - log_level_replica : -1
[2023-07-21 09:14:52,517] [ INFO] - log_on_each_node : True
[2023-07-21 09:14:52,517] [ INFO] - logging_dir : soul_bak/chatglm-6b/runs/Jul21_09-14-08_jupyter-89263-6559395
[2023-07-21 09:14:52,517] [ INFO] - logging_first_step : False
[2023-07-21 09:14:52,517] [ INFO] - logging_steps : 250
[2023-07-21 09:14:52,517] [ INFO] - logging_strategy : IntervalStrategy.STEPS
[2023-07-21 09:14:52,517] [ INFO] - lr_scheduler_type : SchedulerType.LINEAR
[2023-07-21 09:14:52,517] [ INFO] - max_grad_norm : 1.0
[2023-07-21 09:14:52,517] [ INFO] - max_steps : -1
[2023-07-21 09:14:52,517] [ INFO] - metric_for_best_model : accuracy
[2023-07-21 09:14:52,517] [ INFO] - minimum_eval_times : None
[2023-07-21 09:14:52,517] [ INFO] - no_cuda : False
[2023-07-21 09:14:52,517] [ INFO] - num_train_epochs : 2.0
[2023-07-21 09:14:52,517] [ INFO] - optim : OptimizerNames.ADAMW
[2023-07-21 09:14:52,517] [ INFO] - optimizer_name_suffix : None
[2023-07-21 09:14:52,517] [ INFO] - output_dir : soul_bak/chatglm-6b
[2023-07-21 09:14:52,518] [ INFO] - overwrite_output_dir : False
[2023-07-21 09:14:52,518] [ INFO] - past_index : -1
[2023-07-21 09:14:52,518] [ INFO] - per_device_eval_batch_size : 2
[2023-07-21 09:14:52,518] [ INFO] - per_device_train_batch_size : 2
[2023-07-21 09:14:52,518] [ INFO] - pipeline_parallel_config :
[2023-07-21 09:14:52,518] [ INFO] - pipeline_parallel_degree : -1
[2023-07-21 09:14:52,518] [ INFO] - pipeline_parallel_micro_batch_size: 1
[2023-07-21 09:14:52,518] [ INFO] - pipeline_parallel_rank : 0
[2023-07-21 09:14:52,518] [ INFO] - prediction_loss_only : False
[2023-07-21 09:14:52,518] [ INFO] - process_index : 0
[2023-07-21 09:14:52,518] [ INFO] - recompute : True
[2023-07-21 09:14:52,518] [ INFO] - remove_unused_columns : True
[2023-07-21 09:14:52,518] [ INFO] - report_to : ['visualdl']
[2023-07-21 09:14:52,518] [ INFO] - resume_from_checkpoint : None
[2023-07-21 09:14:52,518] [ INFO] - run_name : soul_bak/chatglm-6b
[2023-07-21 09:14:52,518] [ INFO] - save_on_each_node : False
[2023-07-21 09:14:52,518] [ INFO] - save_steps : 2000
[2023-07-21 09:14:52,518] [ INFO] - save_strategy : IntervalStrategy.STEPS
[2023-07-21 09:14:52,518] [ INFO] - save_total_limit : 1
[2023-07-21 09:14:52,518] [ INFO] - scale_loss : 32768
[2023-07-21 09:14:52,518] [ INFO] - seed : 42
[2023-07-21 09:14:52,518] [ INFO] - sharding : []
[2023-07-21 09:14:52,518] [ INFO] - sharding_degree : -1
[2023-07-21 09:14:52,518] [ INFO] - sharding_parallel_degree : -1
[2023-07-21 09:14:52,518] [ INFO] - sharding_parallel_rank : 0
[2023-07-21 09:14:52,518] [ INFO] - should_log : True
[2023-07-21 09:14:52,518] [ INFO] - should_save : True
[2023-07-21 09:14:52,519] [ INFO] - should_save_model_state : True
[2023-07-21 09:14:52,519] [ INFO] - skip_memory_metrics : True
[2023-07-21 09:14:52,519] [ INFO] - tensor_parallel_degree : -1
[2023-07-21 09:14:52,519] [ INFO] - tensor_parallel_rank : 0
[2023-07-21 09:14:52,519] [ INFO] - train_batch_size : 2
[2023-07-21 09:14:52,519] [ INFO] - use_hybrid_parallel : False
[2023-07-21 09:14:52,519] [ INFO] - warmup_ratio : 0.03
[2023-07-21 09:14:52,519] [ INFO] - warmup_steps : 0
[2023-07-21 09:14:52,519] [ INFO] - weight_decay : 0.0
[2023-07-21 09:14:52,519] [ INFO] - weight_name_suffix : None
[2023-07-21 09:14:52,519] [ INFO] - world_size : 1
[2023-07-21 09:14:52,519] [ INFO] -
[2023-07-21 09:14:52,522] [ INFO] - ***** Running training *****
[2023-07-21 09:14:52,523] [ INFO] - Num examples = 1000
[2023-07-21 09:14:52,523] [ INFO] - Num Epochs = 2
[2023-07-21 09:14:52,523] [ INFO] - Instantaneous batch size per device = 2
[2023-07-21 09:14:52,523] [ INFO] - Total train batch size (w. parallel, distributed & accumulation) = 2
[2023-07-21 09:14:52,523] [ INFO] - Gradient Accumulation steps = 1
[2023-07-21 09:14:52,523] [ INFO] - Total optimization steps = 1000
[2023-07-21 09:14:52,523] [ INFO] - Total num train samples = 2000
[2023-07-21 09:14:52,524] [ INFO] - Number of trainable parameters = 14680064 (per device)
Found inf or nan, current scale is: 32768.0, decrease to: 32768.0*0.5
[2023-07-21 09:14:54,158] [ WARNING] - optimizer not run, scale_before: 32768.0, scale_after: 16384.0
Found inf or nan, current scale is: 16384.0, decrease to: 16384.0*0.5
[2023-07-21 09:14:57,539] [ WARNING] - optimizer not run, scale_before: 16384.0, scale_after: 8192.0
[2023-07-21 09:16:54,738] [ INFO] - loss: 3.24559375, learning_rate: 0.02326, global_step: 250, interval_runtime: 122.2133, interval_samples_per_second: 4.091, interval_steps_per_second: 2.046, ppl: 25.67695122484951, epoch: 0.5
[2023-07-21 09:18:56,960] [ INFO] - loss: 2.94326953, learning_rate: 0.01553, global_step: 500, interval_runtime: 122.2218, interval_samples_per_second: 4.091, interval_steps_per_second: 2.045, ppl: 18.977793453082345, epoch: 1.0
[2023-07-21 09:18:56,961] [ INFO] - ***** Running Evaluation *****
[2023-07-21 09:18:56,961] [ INFO] - Num examples = 0
[2023-07-21 09:18:56,961] [ INFO] - Total prediction steps = 0
[2023-07-21 09:18:56,961] [ INFO] - Pre device batch size = 2
[2023-07-21 09:18:56,961] [ INFO] - Total Batch size = 2
[2023-07-21 09:18:56,966] [ INFO] - eval_runtime: 0.0045, eval_samples_per_second: 0.0, eval_steps_per_second: 0.0, epoch: 1.0
[2023-07-21 09:20:59,372] [ INFO] - loss: 2.83462891, learning_rate: 0.007794, global_step: 750, interval_runtime: 122.4124, interval_samples_per_second: 4.085, interval_steps_per_second: 2.042, ppl: 17.024081661613064, epoch: 1.5
[2023-07-21 09:23:02,859] [ INFO] - loss: 2.80505469, learning_rate: 6.186e-05, global_step: 1000, interval_runtime: 123.4859, interval_samples_per_second: 4.049, interval_steps_per_second: 2.025, ppl: 16.52797979656062, epoch: 2.0
[2023-07-21 09:23:02,859] [ INFO] - ***** Running Evaluation *****
[2023-07-21 09:23:02,859] [ INFO] - Num examples = 0
[2023-07-21 09:23:02,859] [ INFO] - Total prediction steps = 0
[2023-07-21 09:23:02,859] [ INFO] - Pre device batch size = 2
[2023-07-21 09:23:02,859] [ INFO] - Total Batch size = 2
[2023-07-21 09:23:02,864] [ INFO] - eval_runtime: 0.0044, eval_samples_per_second: 0.0, eval_steps_per_second: 0.0, epoch: 2.0
[2023-07-21 09:23:02,864] [ INFO] -
Training completed.
[2023-07-21 09:23:02,865] [ INFO] - train_runtime: 490.3406, train_samples_per_second: 4.079, train_steps_per_second: 2.039, train_loss: 2.95713671875, epoch: 2.0
[2023-07-21 09:23:02,865] [ INFO] - Saving model checkpoint to soul_bak/chatglm-6b
[2023-07-21 09:23:03,034] [ INFO] - tokenizer config file saved in soul_bak/chatglm-6b/tokenizer_config.json
[2023-07-21 09:23:03,035] [ INFO] - Special tokens file saved in soul_bak/chatglm-6b/special_tokens_map.json
[2023-07-21 09:23:03,044] [ INFO] - ***** train metrics *****
[2023-07-21 09:23:03,044] [ INFO] - epoch = 2.0
[2023-07-21 09:23:03,044] [ INFO] - train_loss = 2.9571
[2023-07-21 09:23:03,044] [ INFO] - train_runtime = 0:08:10.34
[2023-07-21 09:23:03,044] [ INFO] - train_samples_per_second = 4.079
[2023-07-21 09:23:03,044] [ INFO] - train_steps_per_second = 2.039
[2023-07-21 09:23:03,046] [ INFO] - ***** Running Evaluation *****
[2023-07-21 09:23:03,046] [ INFO] - Num examples = 0
[2023-07-21 09:23:03,046] [ INFO] - Total prediction steps = 0
[2023-07-21 09:23:03,046] [ INFO] - Pre device batch size = 2
[2023-07-21 09:23:03,046] [ INFO] - Total Batch size = 2
[2023-07-21 09:23:03,051] [ INFO] - eval_runtime: 0.005, eval_samples_per_second: 0.0, eval_steps_per_second: 0.0, epoch: 2.0
[2023-07-21 09:23:03,051] [ INFO] - ***** test metrics *****
[2023-07-21 09:23:03,051] [ INFO] - epoch = 2.0
[2023-07-21 09:23:03,051] [ INFO] - eval_runtime = 0:00:00.00
[2023-07-21 09:23:03,051] [ INFO] - eval_samples_per_second = 0.0
[2023-07-21 09:23:03,051] [ INFO] - eval_steps_per_second = 0.0
2.加载prefix权重
将实例化后的模型,直接加载prefix-tuning权重,无需重载模型
%cd ~
from paddlenlp.peft import ChatGLMForCausalLM
from paddlenlp.peft.prefix import (
chatglm_pad_attention_mask,
chatglm_postprocess_past_key_value,
)
model = ChatGLMForCausalLM.from_pretrained(model, '/home/aistudio/soul_bak/chatglm-6b', chatglm_postprocess_past_key_value, chatglm_pad_attention_mask)
3.使用lora对chatglm-6b进行微调
使用v100进行微调很快完成(yuanshen文件夹下数据)
如果想要完成自己的任务,请将–task_name_or_path后面参数修改为你的数据集所在目录
如果微调过程中,报错out of memory,请修改–per_device_train_batch_size以及–per_device_eval_batch_size后面的参数为1
# 创建微调模型保存目录
!mkdir -p soul_bak/chatglm-6b_lora
!python work/finetune_generation.py
--output_dir soul_bak/chatglm-6b_lora
--per_device_train_batch_size 4
--gradient_accumulation_steps 2
--per_device_eval_batch_size 8
--model_name_or_path THUDM/chatglm-6b
--task_name_or_path soul
--num_train_epochs 2
--learning_rate 3e-4
--warmup_steps 30
--logging_steps 1
--evaluation_strategy epoch
--save_strategy epoch
--src_length 1024
--tgt_length 1024
--fp16
--fp16_opt_level O2
--do_train
--do_eval
--disable_tqdm True
--load_best_model_at_end True
--metric_for_best_model accuracy
--eval_with_do_generation False
--recompute
--save_total_limit 1
--overwrite_output_dir
--lora True
--lora_rank 8
4.加载lora权重
将实例化后的模型,直接加载lora权重,无需重载模型
from paddlenlp.peft import LoRAModel
model = LoRAModel.from_pretrained(model, 'soul_bak/chatglm-6b_lora/checkpoint-125/')
model.mark_only_lora_as_trainable()
[2023-07-21 10:31:31,437] [ WARNING] - Reset tensor_parallel_degree of lora_config to 0.
[2023-07-21 10:31:31,475] [ INFO] - Loading the LoRA weights from soul_bak/chatglm-6b_lora/checkpoint-125/lora_model_state.pdparams
[2023-07-21 10:31:31,506] [ INFO] - Load lora weight successfully
5.文本预处理,推理,输出后处理,预测文本以及将文本batch化
#预处理
def preprocess(input_text):
inputs = tokenizer(
input_text,
return_tensors="np",
padding=True,
max_length=128,
truncation=True,
truncation_side="left",
)
inputs_tensor = {}
for key in inputs:
inputs_tensor[key] = paddle.to_tensor(inputs[key])
return inputs_tensor
#推理
def infer(inputs):
result = model.generate(
**inputs,
decode_strategy="sampling",
top_k=1,
max_length=128,
bos_token_id=tokenizer.bos_token_id,
eos_token_id=tokenizer.eos_token_id,
pad_token_id=tokenizer.pad_token_id,
use_cache=True,
)
result = result[0]
return result
#后处理
def postprocess(infer_data):
result = []
for x in infer_data.tolist():
res = tokenizer.decode(x, skip_special_tokens=True)
res = res.strip("n")
result.append(res)
out_dict = {"result": result}
return out_dict
#文本预测
def predict(texts):
input_map = preprocess(texts)
infer_result = infer(input_map)
output = postprocess(infer_result)
return output
#输入batch化
def batchfy_text(texts, batch_size):
batch_texts = []
batch_start = 0
while batch_start < len(texts):
batch_texts += [texts[batch_start : min(batch_start + batch_size, len(texts))]]
batch_start += batch_size
return batch_texts
6.对比
def pre_Single_conversation(input_text):
all_texts = [
str(input_text)
]
batch_texts = batchfy_text(all_texts, 1)
for bs, texts in enumerate(batch_texts):
outputs = predict(texts)
for text, result in zip(texts, outputs["result"]):
print("{}n{}".format(text, text+result))
pre_Single_conversation(input_text = "假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:")
假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:
假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:听到你的经历,我很理解你的感受。你收养了她女儿,她也很感激你。但是,你儿子和姑姐女儿的关系紧张,可能是因为你们之间的相处方式不同。你可以尝试和他们沟通,了解他们的想法和感受。
- Q_motif = “假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:”
- 微调前:首先,我可以理解您所面临的挑战和困惑。收养一个孩子是一个艰难的决定,可能会对家庭产生深远的影响。
- 对于您儿子和姑姐女儿的关系,您可以尝试与他们建立良好的沟通和互动。您可以试着与他们分享您的想法和感受,以及您对收养孩子的看法。同时,您也可以尝试与他们一起探讨如何改善他们之间的关系。您还可以寻求专业心理咨询师或家庭治疗师的帮助,以帮助您更好地处理这个问题。
- 对于您大姑姐的女儿,您可以尝试与她建立良好的关系。您可以试着让她感受到您对她的关心和支持,并鼓励她积极参与家庭活动和家务。同时,您也可以尝试与她分享您对收养孩子的看法,以及您希望她如何参与孩子的成长和发展。
- 最后,我建议您寻求专业心理咨询师或家庭治疗师的帮助。他们可以帮助您更好地处理您所面临的问题,并提供专业的建议和支持。
- 微调后: 假设你是友善的心理辅导师,请根据咨询者的问题回答真实有用的答复。求助者:最近我遇到了一个问题。大姑姐离婚,不要女儿,于是我收养了她女儿。但是现在我儿子和姑姐女儿的关系很紧张,她自己也不做家务,我该怎么办?支持者:听到你的经历,我很理解你的感受。你收养了她女儿,她也很感激你。但是,你儿子和姑姐女儿的关系紧张,可能是因为你们之间的相处方式不同。你可以尝试和他们沟通,了解他们的想法和感受。
Q_motif = "我最近很焦虑,上班总是划水,我该怎么办?"
print(Q_motif)
result=glm_single_QA(model,tokenizer,Q_motif,2048,2048)
print("A:"+result)
我最近很焦虑,上班总是划水,我该怎么办?
A:焦虑是一种很常见的情绪,但也是可以被克服的。以下是一些建议:
1. 深呼吸:深呼吸可以帮助你放松身体和思维。试着慢慢吸气,然后慢慢呼气,重复几次。
2. 寻求支持:如果感到焦虑,可以寻求朋友或家人的支持。他们可以提供一些安慰和建议。
3. 制定计划:制定一个计划可以帮助你更好地管理时间。试着制定一个日程表,并设置优先级。
4. 寻找支持:如果感到工作划水,可以寻求同事或上司的帮助。他们可以提供一些建议和指导。
5. 学习放松技巧:学习一些放松技巧,如冥想或瑜伽,可以帮助你更好地管理焦虑。
希望这些建议能有所帮助。如果感到焦虑情绪持续存在,请考虑寻求专业帮助。
7.注意事项
- 1.微调前模型就具备一些能力;
- 2.微调可以不用全量数据,可以使用1%的数据提升速度;
- 3.使用微调后,能较好的根据自己的需求生成文本 ;
- 4.使用最新的PaddleNLP,因为api变动较大,建议参照此文。
六、创意总结
MyMind是一款基于AI大模型的心理健康辅助应用,旨在帮助用户实现情绪管理、自我成长和内心平衡。通过个性化的用户画像、情绪分析与管理、自我探索与成长、内心宁静与放松以及社交支持和分享等功能,提供全方位的心理健康支持。借助人工智能技术和专业合作伙伴的支持,MyMind将成为用户在充实人生、保持心理健康方面的得力助手。