基于昇腾服务器微调glm4-9b-chat案例
1 概述
1.1 案例介绍
2024年6月,智谱AI发布的GLM-4-9B系列开源模型,在语义、数学、推理、代码和知识等多方面的数据集测评中,GLM-4-9B和GLM-4-9B-Chat均表现出超越Llama-3-8B的卓越性能。并且,本代模型新增对26种语言的支持,涵盖日语、韩语、德语等。除此之外,智谱AI还推出了支持1M上下文长度的GLM-4-9B-Chat-1M模型和基于GLM-4-9B的多模态模型。以下为GLM-4-9B系列模型的具体评测结果。
本案例基于昇腾服务器训练广告词生成的案例,通过本次案例可以使开发者更好的了解,本次试验采取了11万数据进行测试。
通过本次案例可以让用户更好的了解昇腾资源,通过微调使问答能力让我们得到的结果更满意。
1.2 适用对象
- 企业
- 个人开发者
- 高校学生
1.3 案例时间
本案例总时长预计120分钟。
1.4 案例流程
说明:
- 购买昇腾服务器;
- 从git上面拉取代码;
- 在魔塔社区下载模型;
- 使用Lora微调模型;
- 对模型评估;
- 推理微调之后的模型;
1.5 资源总览
本案例预计花费总计43元,体验完成后请及时释放资源,避免产生多余的费用。(待定昇腾环境资源目前还没上线)
资源名称 |
规格 |
单价(元) |
时长(分钟) |
ModelArts |
pytorch_2.1.0-cann_8.0.rc1-py_3.9-euler_2.10.7-aarch64-snt9b |
21 |
120 |
2 购买服务器
2.1 选择西南贵阳一
在选择区域这一块选择西南贵阳一区
公共镜像 pytorch_2.1.0-cann_8.0.rc1-py_3.9-euler_2.10.7-aarch64-snt9b,磁盘规格100GB,点击立即创建。
2.2 打开服务器
点击右侧打开服务器
3 安装所需要的环境
3.1 安装python版本的型号
创建python版本的型号,”+”——"Notebook”
将以下的代码放到代码行里面,点击运行按钮创建环境。
conda create -n glm4 python==3.10 -y
3.2 安装openMind Hub Client和openMind Library
使用终端安装环境“+“——“ Termianl”
以下命令在终端运行
source /usr/local/Ascend/ascend-toolkit/set_env.sh
进入新建的python环境
conda activate glm4
安装openMind Hub Client(可能出现以下的错误不用理会,不影响下面的操作)
pip install openmind_hub
安装”openMind Library”,并安装”PyTorch”框架及其依赖(可能出现以下的错误不用理会,不影响下面的操作)
pip install openmind[pt]
安装”LLaMa Factory”
git clone --depth 1 https://github.com/hiyouga/LLaMA-Factory.git
cd LLaMA-Factory
pip install -e ".[torch-npu,metrics]"
pip install numpy==1.23.5
4 拉取模型和所需要的代码
4.1 模型链接和下载
GLM-4-9B模型系列由社区开发者在魔乐社区贡献,包括:
- GLM-4-9B:https://modelers.cn/models/AI-Research/glm-4-9b
- GLM-4-9B-Chat:https://modelers.cn/models/AI-Research/glm-4-9b
- GLM-4-9B-Chat-1m:https://modelers.cn/models/AI-Research/glm-4-9b-chat-1m
# 首先保证已安装git-lfs(https://git-lfs.com)
pip install modelscope
modelscope download --model ZhipuAI/glm-4-9b-chat --local_dir ./glm4-9b-chat
用户可以使用LLaMa Factory,以GLM-4-9B-Chat为例,具体如下:
在空白处右键点击——>点击“New File“——>”inference_glm4_9b_chat.py “复制进去创建文件
新建推理脚本”inference_glm4_9b_chat.py”推理脚本内容为:(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
# 检查是否支持NPU设备
device = "npu" if torch.npu.is_available() else "cpu"
print(f"Using device: {device}", flush=True)
# 加载预训练模型和分词器
tokenizer = AutoTokenizer.from_pretrained("glm4-9b-chat", trust_remote_code=True)
model = AutoModelForCausalLM.from_pretrained(
"glm4-9b-chat",
torch_dtype=torch.bfloat16,
low_cpu_mem_usage=True,
trust_remote_code=True
).to(device).eval()
# 定义生成参数
gen_kwargs = {
"max_length": 2500,
"do_sample": True,
"top_k": 1,
"temperature": 0.7, # 可以调整温度来控制生成的多样性
}
# 初始化对话历史
conversation_history = []
def generate_response(user_input):
# 将用户的输入添加到对话历史中
conversation_history.append({"role": "user", "content": user_input})
# 构建输入模板,包含所有对话历史
inputs = tokenizer.apply_chat_template(
conversation_history,
add_generation_prompt=True,
tokenize=True,
return_tensors="pt",
return_dict=True
)
# 将输入移动到 NPU 设备
inputs = inputs.to(device)
# 生成回复
with torch.no_grad():
outputs = model.generate(**inputs, **gen_kwargs)
outputs = outputs[:, inputs['input_ids'].shape[1]:] # 去掉输入部分,只保留生成的回复
# 解码生成的回复
response = tokenizer.decode(outputs[0], skip_special_tokens=True)
# 将模型的回复添加到对话历史中
conversation_history.append({"role": "assistant", "content": response})
# 立即打印回复并刷新输出
print(f"Assistant: {response}", flush=True)
return response
# 多轮对话循环
print("开始多轮对话,输入 'exit' 结束对话。", flush=True)
while True:
user_input = input("User: ")
if user_input.lower() == 'exit':
print("结束对话。", flush=True)
break
generate_response(user_input)
# 如果有需要处理的异常,可以在主程序块中添加 try-except
if __name__ == "__main__":
try:
# 上面的代码已经放在了主程序块中,这里不需要重复
pass
except Exception as e:
print(f"An error occurred: {e}", flush=True)
执行推理脚本:
python inference_glm4_9b_chat.py
输入以下问题:
问题1:类型#上衣材质#牛仔布颜色#白色风格#简约图案#刺绣衣样式#外套衣款式#破洞
问题2:类型#裤风格#英伦风格#简约
问题3:类型#裙裙下摆#弧形裙腰型#高腰裙长#半身裙裙款式#不规则*裙款式#收腰
推理结果如下:
按下“Ctrl”键加c键退出问答环节
4.2 数据集下载
我们使用单张昇腾NPU,基于LLaMa Factory框架,采用广告文案生成数据集进行Lora,让模型能够根据用户输入的商品关键字生成对应的广告文案。
数据集
广告文案数据集(AdvertiseGen)任务为根据输入(content)生成一段广告词(summary),分为训练集和验证集。其中,训练集大小为114K,验证集大小为1K。每个样本有”content”和”summary”两个键,分别保存商品关键字和商品文案。
以下是部分示例:
{
"content": "类型#上衣*版型#宽松*版型#显瘦*图案#线条*衣样式#衬衫*衣袖型#泡泡袖*衣款式#抽绳",
"summary": "这件衬衫的款式非常的宽松,利落的线条可以很好的隐藏身材上的小缺点,穿在身上有着很好的显瘦效果。领口装饰了一个可爱的抽绳,漂亮的绳结展现出了十足的个性,配合时尚的泡泡袖型,尽显女性甜美可爱的气息。"
}
下载”AdvertiseGen”数据集
感谢社区开发者在魔乐社区贡献的”AdvertiseGen”数据集,使用”Git”将数据集下载至LLaMA-Factory文件下。
重复3.2小节重新创建个终端
conda activate glm4
cd LLaMA-Factory/
git clone https://modelers.cn/AI-Research/AdvertiseGen.git
4.3 数据预处理
在空白处右键点击——>点击“New File“——>” preprocess_adv_gen.py “复制进去创建文件
新建推理脚本” preprocess_adv_gen.py”推理脚本内容为:(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)
下载完成后,需要将 ”train.json” 和 ”dev.json” 两个文件的数据处理成 “alpaca” 数据格式。因此,在LLaMA-Factory文件下创建 ”preprocess_adv_gen.py” 脚本,脚本内容具体如下:(按下“Ctrl”键加上"s"键保存文件)
import json
import argparse
import os
import stat
DEFAULT_FLAGS = os.O_WRONLY | os.O_CREAT
DEFAULT_MODES = stat.S_IWUSR | stat.S_IRUSR
def parse_args():
parse = argparse.ArgumentParser()
parse.add_argument("--data_path", type=str)
parse.add_argument("--save_path", type=str)
args = parse.parse_args()
return args
def read_data(data_path):
data = []
with open(data_path, "r", encoding="utf-8") as f:
lines = f.readlines()
for line in lines:
data.append(json.loads(line))
return data
def convert_to_alpaca_format(data):
results = []
for sample in data:
example = {}
example["instruction"] = sample["content"]
example["output"] = sample["summary"]
results.append(example)
return results
def save_data(data, save_path):
with os.fdopen(os.open(save_path, DEFAULT_FLAGS, DEFAULT_MODES), "w", encoding="utf-8") as f:
json.dump(data, f, indent=4, ensure_ascii=False)
if __name__ == "__main__":
args = parse_args()
data = read_data(args.data_path)
data = convert_to_alpaca_format(data)
save_data(data, args.save_path)
通过以下命令执行脚本,将数据预处理的结果分别存为”adv_gen_train.json”和“adv_gen_dev.json“。
# xxx为train,json和dev.json文件路径
python preprocess_adv_gen.py --data_path AdvertiseGen/train.json --save_path ./AdvertiseGen/adv_gen_train.json
python preprocess_adv_gen.py --data_path AdvertiseGen/dev.json --save_path ./AdvertiseGen/adv_gen_dev.json
修改LLaMa Factory下的data/dataset_info.json文件,添加数据集描述:
在空白处右键点击——>点击“New File“——>” shuju.py”——>”将以下代码复制到新建的文件里面
(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)
import json
# 定义要添加的内容
addition = {
"adv_gen_train": {
"file_name": "/home/ma-user/work/LLaMA-Factory/AdvertiseGen/adv_gen_train.json",
"columns": {
"prompt": "instruction",
"response": "output"
}
},
"adv_gen_dev": {
"file_name": "/home/ma-user/work/LLaMA-Factory/AdvertiseGen/adv_gen_dev.json",
"columns": {
"prompt": "instruction",
"response": "output"
}
}
}
# 读取现有的 dataset_info.json 文件
with open('/home/ma-user/work/LLaMA-Factory/data/dataset_info.json', 'r') as file:
data = json.load(file)
# 将新内容添加到现有数据中
data.update(addition)
# 写回 dataset_info.json 文件
with open('/home/ma-user/work/LLaMA-Factory/data/dataset_info.json', 'w') as file:
json.dump(data, file, indent=2)
执行以下命令将路径写进dataset_info.json文件
python shuju.py
5 微调模型
5.1 微调配置文件
修改” /home/ma-user/work/LLaMA-Factory/src/llamafactory/model”文件下的” loader.py”代码,在68、120、149行代码下面添加以下的代码。如图所示。
(在”init_kwargs = _get_init_kwargs(model_args)“下一行添加以下代码)
init_kwargs["trust_remote_code"] = True
在“LLaMa Factory/ examples/train_lora/路径下创建新的文件:
在空白处右键点击——>点击“New File“——>” shuju.py”——>”将以下代码复制到新建的文件里面
(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)
### model
model_name_or_path: /home/ma-user/work/LLaMA-Factory/glm4-9b-chat/ # 当前仅支持本地加载,填写GLM-4-9B-Chat本地权重路径
### method
stage: sft
do_train: true
finetuning_type: lora
lora_target: all
lora_rank: 8
lora_alpha: 32
lora_dropout: 0.1
### dataset
dataset: adv_gen_train
template: glm4
cutoff_len: 256
preprocessing_num_workers: 16
#可以根据自己需求修改模型输出的路径
### output
output_dir: /home/ma-user/work/LLaMA-Factory/glm4-9b-lora/
logging_steps: 10
save_steps: 500
plot_loss: true
overwrite_output_dir: true
### train
per_device_train_batch_size: 16
gradient_accumulation_steps: 1
learning_rate: 5.0e-4
max_steps: 1000
lr_scheduler_type: cosine
warmup_ratio: 0.1
bf16: true
ddp_timeout: 180000000
通过下面的命令启动微调:(在LLaMA-Factory路径下添加以下的命令)
export ASCEND_RT_VISIBLE_DEVICES=0
llamafactory-cli train examples/train_lora/glm4_9b_chat_lora_sft.yaml
5.2 评估模型
训练结束后,通过”LLaMa Factory”使用微调完成的权重在”adv_gen_dev.json”数据集上预测”BLEU”和”ROUGE”分数。在”LLaMa Factory/examples/train_lora/”路径下新建”glm4_9b_chat_lora_predict.yaml”评估配置文件,具体操作步骤如下:
在空白处右键点击——>点击“New File“——>” glm4_9b_chat_lora_predict.yaml”——>”将以下代码复制到新建的文件里面
(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)
### model
model_name_or_path: /home/ma-user/work/LLaMA-Factory/glm4-9b-chat/ # 当前仅支持本地加载,填写GLM-4-9B-Chat本地权重路径
#修改训练好模型的路径
adapter_name_or_path: /home/ma-user/work/LLaMA-Factory/glm4-9b-lora/checkpoint-1000/
### method
stage: sft
do_predict: true
finetuning_type: lora
### dataset
eval_dataset: adv_gen_dev
template: glm4
cutoff_len: 256
preprocessing_num_workers: 16
### output
output_dir: /home/ma-user/work/LLaMA-Factory/glm4-9b-lora/predict/
overwrite_output_dir: true
### eval
per_device_eval_batch_size: 128
predict_with_generate: true
按下“Ctrl”键加上"s"键保存文件
通过下面的命令启动评估:
export ASCEND_RT_VISIBLE_DEVICES=0
llamafactory-cli train examples/train_lora/glm4_9b_chat_lora_predict.yaml
5.3 推理
微调结束后,在”LLaMa Factory”路径下新建”examples/inference/“路径下创建新的为:
在空白处右键点击——>点击“New File“——>” glm4_9b_chat_lora_sft.yaml”——>”将以下代码复制到新建的文件里面
(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)
model_name_or_path: /home/ma-user/work/LLaMA-Factory/glm4-9b-chat/ # 当前仅支持本地加载,填写GLM-4-9B-Chat本地权重路径
adapter_name_or_path: /home/ma-user/work/LLaMA-Factory/glm4-9b-lora/checkpoint-1000/ #当前仅支持训练之后模型的权重路径
template: glm4
finetuning_type: lora
通过下面的命令启动推理:
llamafactory-cli chat examples/inference/glm4_9b_chat_lora_sft.yaml
5.4 效果对比
提出以下类似的问题:
问题1:类型#上衣材质#牛仔布颜色#白色风格#简约图案#刺绣衣样式#外套衣款式#破洞
问题2:类型#裤风格#英伦风格#简约
问题3:类型#裙裙下摆#弧形裙腰型#高腰裙长#半身裙裙款式#不规则*裙款式#收腰
微调之前的效果:
微调之后的效果:
- 点赞
- 收藏
- 关注作者
评论(0)