基于昇腾服务器微调glm4-9b-chat案例

举报
HuaweiCloudDeveloper 发表于 2025/04/21 10:34:29 2025/04/21
【摘要】 该案例基于昇腾服务器,以广告词生成任务为例,使用 11 万数据对 GLM4-9B-Chat 模型进行微调。涵盖服务器购买、环境安装、模型与数据集下载、数据预处理、模型微调、评估及推理等流程,介绍了在昇腾环境下基于 LLaMa Factory 框架进行模型优化的具体操作与方法。

1 概述

1.1 案例介绍

20246月,智谱AI发布的GLM-4-9B系列开源模型,在语义、数学、推理、代码和知识等多方面的数据集测评中,GLM-4-9BGLM-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 案例流程

图片1.png

说明:

  1. 购买昇腾服务器;
  2. git上面拉取代码;
  3. 在魔塔社区下载模型;
  4. 使用Lora微调模型;
  5. 对模型评估;
  6. 推理微调之后的模型;

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 选择西南贵阳一

在选择区域这一块选择西南贵阳一区

图片2.png

公共镜像 pytorch_2.1.0-cann_8.0.rc1-py_3.9-euler_2.10.7-aarch64-snt9b,磁盘规格100GB,点击立即创建。

图片3.png

2.2 打开服务器

点击右侧打开服务器

图片4.png

3 安装所需要的环境

3.1 安装python版本的型号

创建python版本的型号,”+”——"Notebook”

图片6.png 

将以下的代码放到代码行里面,点击运行按钮创建环境。

conda create -n glm4 python==3.10 -y

图片7.png                 

3.2 安装openMind Hub Client和openMind Library

使用终端安装环境“+“——“ Termianl”

图片8.png

以下命令在终端运行

source /usr/local/Ascend/ascend-toolkit/set_env.sh

进入新建的python环境

conda activate glm4

安装openMind Hub Client(可能出现以下的错误不用理会,不影响下面的操作)

图片9.png

pip install openmind_hub

安装”openMind Library”,并安装”PyTorch”框架及其依赖(可能出现以下的错误不用理会,不影响下面的操作)

图片10.png

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-9Bhttps://modelers.cn/models/AI-Research/glm-4-9b
  • GLM-4-9B-Chathttps://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-lfshttps://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 “复制进去创建文件

图片11.png

新建推理脚本”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:类型#裙下摆#弧形裙腰型#高腰裙长#半身裙裙款式#不规则*裙款式#收腰

推理结果如下:

图片12.png

按下“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

图片13.png

4.3 数据预处理

在空白处右键点击——>点击“New File“——>” preprocess_adv_gen.py复制进去创建文件

图片14.png

新建推理脚本 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    

图片15.png

修改LLaMa Factory下的data/dataset_info.json文件,添加数据集描述:

在空白处右键点击——>点击“New File“——>” shuju.py”——>”将以下代码复制到新建的文件里面

(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)

图片16.png

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

图片17.png

5 微调模型

5.1 微调配置文件

修改” /home/ma-user/work/LLaMA-Factory/src/llamafactory/model”文件下的” loader.py”代码,在68120149行代码下面添加以下的代码。如图所示。

(在”init_kwargs = _get_init_kwargs(model_args)“下一行添加以下代码)

init_kwargs["trust_remote_code"] = True

图片18.png

图片19.png 

在“LLaMa Factory/ examples/train_lora/路径下创建新的文件:

在空白处右键点击——>点击“New File“——>” shuju.py”——>”将以下代码复制到新建的文件里面

(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)

图片20.png

图片21.png

### 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

图片23.png 

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“键保存文件)

图片24.png

### 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

图片25.png

5.3 推理

微调结束后,在”LLaMa Factory”路径下新建”examples/inference/“路径下创建新的为:

在空白处右键点击——>点击“New File“——>” glm4_9b_chat_lora_sft.yaml”——>”将以下代码复制到新建的文件里面

(将以下代码复制到新建的文档里面,按下“Crtl”加上“s“键保存文件)

图片26.png

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:类型#裙下摆#弧形裙腰型#高腰裙长#半身裙裙款式#不规则*裙款式#收腰

微调之前的效果:

图片27.png 

微调之后的效果:

图片28.png

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。