1. 本地部署
1.1 从Git拉取项目到本地
ChatGLM3 是智谱AI和清华大学 KEG 实验室联合发布的对话预训练模型。
由于模型的权重文件很大,故需从HuggingFace上拉取到models目录下。
1.2 配置环境
在conda创建一个虚拟环境,其中需要python版本建议3.11以上,随后配置cuda和torch,可以先使用nvidia-smi命令查看cuda支持的最高版本,随后按照pytorch官网的命令进行安装。
切换到配置chatglm的conda环境后,使用pip install -r requirements.txt命令安装所需的包,若是单机单卡运行,可
1.3 本地运行ChatGLM3-6b
在相应文件中把模型地址进行更换,随后在cd到basic_demo后运行python cli_demo.py 或者 streamlit run web_demo_streamlit .py 进行本地运行。
2 使用Lora微调ChatGLM3-6b
首先安装微调需要的包,pip install在finetune_demo中的requirements.txt;其中若是单机单卡的环境可以不安装deepseed。Git的官方微调引导页面
安装完之后可以使用官方开源的服饰广告语推荐的数据集进行微调尝试。
先对该数据集进行格式转换,转换为 ChatGLM3 对话格式约定,例如多轮对话格式为:
[
{
"conversations": [
{
"role": "system",
"content": "<system prompt text>"
},
{
"role": "user",
"content": "<user prompt text>"
},
{
"role": "assistant",
"content": "<assistant response text>"
},
// ... Muti Turn
{
"role": "user",
"content": "<user prompt text>"
},
{
"role": "assistant",
"content": "<assistant response text>"
}
]
}
// ...
]
转换格式代码为:
import json
from typing import Union
from pathlib import Path
def _resolve_path(path: Union[str, Path]) -> Path:
return Path(path).expanduser().resolve()
def _mkdir(dir_name: Union[str, Path]):
dir_name = _resolve_path(dir_name)
if not dir_name.is_dir():
dir_name.mkdir(parents=True, exist_ok=False)
def convert_adgen(data_dir: Union[str, Path], save_dir: Union[str, Path]):
def _convert(in_file: Path, out_file: Path):
_mkdir(out_file.parent)
with open(in_file, encoding='utf-8') as fin:
with open(out_file, 'wt', encoding='utf-8') as fout:
for line in fin:
dct = json.loads(line)
sample = {'conversations': [{'role': 'user', 'content': dct['content']},
{'role': 'assistant', 'content': dct['summary']}]}
fout.write(json.dumps(sample, ensure_ascii=False) + '\n')
data_dir = _resolve_path(data_dir)
save_dir = _resolve_path(save_dir)
train_file = data_dir / 'train.json'
if train_file.is_file():
out_file = save_dir / train_file.relative_to(data_dir)
_convert(train_file, out_file)
dev_file = data_dir / 'dev.json'
if dev_file.is_file():
out_file = save_dir / dev_file.relative_to(data_dir)
_convert(dev_file, out_file)
convert_adgen('D:/workplaces/github_workplace/ChatGLM3/finetune_demo/data/AdvertiseGen', 'D:/workplaces/github_workplace/ChatGLM3/finetune_demo/data/AdvertiseGen_fix')
2.1 配置微调参数
参数在finetune-demo/configs/lora.yaml 文件中进行配置,具体参数有:
- data_config 部分
- train_file: 训练数据集的文件路径。
- val_file: 验证数据集的文件路径。
- test_file: 测试数据集的文件路径。
- num_proc: 在加载数据时使用的进程数量。
- max_input_length: 输入序列的最大长度。
- max_output_length: 输出序列的最大长度。
- training_args 部分
- output_dir: 用于保存模型和其他输出的目录。
- max_steps: 训练的最大步数。
- per_device_train_batch_size: 每个设备(如 GPU)的训练批次大小。
- dataloader_num_workers: 加载数据时使用的工作线程数量。
- remove_unused_columns: 是否移除数据中未使用的列。
- save_strategy: 模型保存策略(例如,每隔多少步保存一次)。
- save_steps: 每隔多少步保存一次模型。
- log_level: 日志级别(如 info)。
- logging_strategy: 日志记录策略。
- logging_steps: 每隔多少步记录一次日志。
- per_device_eval_batch_size: 每个设备的评估批次大小。
- evaluation_strategy: 评估策略(例如,每隔多少步进行一次评估)。
- eval_steps: 每隔多少步进行一次评估。
- predict_with_generate: 是否使用生成模式进行预测。
- generation_config 部分
- max_new_tokens: 生成的最大新 token 数量。
- peft_config 部分
- peft_type: 使用的参数有效调整类型(如 LORA)。
- task_type: 任务类型,这里是因果语言模型(CAUSAL_LM)。
- Lora 参数:
- r: LoRA 的秩。
- lora_alpha: LoRA 的缩放因子。
- lora_dropout: 在 LoRA 层使用的 dropout 概率
- P-TuningV2 参数:
- num_virtual_tokens: 虚拟 token 的数量。
2.2 进行基于Lora的微调
微调cls命令为;
cd finetune_demo
python finetune_hf.py data/AdvertiseGen_fix/ D:/workplaces/github_workplace/ChatGLM3/models/chatglm3-6b/ configs/lora.yaml
微调成功后会在outout/目录下保存若干个cheakpoint文件。
验证微调后的模型。注意 LORA没有合并训练后的模型,而是在adapter_config.json
中记录了微调型的路径。
可以在 finetune_demo/inference_hf.py
中使用我们的微调后的模型,测试命令为:
python inference_hf.py your_finetune_path --prompt your prompt
微调效果如下:
微调后:
原始模型:
需要注意的是inference_hf.py 中peft包中
AutoPeftModelForCausalLM.from_pretrained()函数在有些包的版本不对情况下肯能会报错,可以使用PeftModel.from_pretrained()函数进行模型加载。
config=PeftConfig.from_pretrained(model_dir)
base_model = AutoModelForCausalLM.from_pretrained(config.base_model_name_or_path, trust_remote_code=True, device_map='auto')
model=PeftModel.from_pretrained(base_model,model_dir)