chatglm3-6b微调实战

chatglm3-6b-sft

chatglm3-6b, chatglm-3b微调/LORA/推理/单机多卡/deepspeed/支持多轮对话
源码:https://github.com/yongzhuo/ChatGLM3-SFT

踩坑(截至20231031)

0.官方prompt, 支持chatml(system), system可以改,但是要注意<|user|>最好放第一位, 如果换成<|assistant|>直接预测、微调会变得很差

<|system|>
You are ChatGLM3, a large language model trained by Zhipu.AI. Follow the user's instructions carefully. Respond using markdown.
<|user|>
Hello
<|assistant|>
Hello, I'm ChatGLM3. What can I assist you today?
  1. torch>=2.0, 否则微调会报很多错误(单纯推理可以用低版本);
  2. tokenizer.encode输出为 [gMASK, sop, 真实文本token]
    "[MASK]": 64789,
    "[gMASK]": 64790,
    "[sMASK]": 64791,
    "sop": 64792,
    "eop": 64793,
    "<|system|>": 64794,
    "<|user|>": 64795,
    "<|assistant|>": 64796,
    "<|observation|>": 64797
  1. modeling_chatglm.py自带get_masks()的代码full_attention_mask -= padding_mask.unsqueeze(-1) - 1改为
    full_attention_mask = full_attention_mask.long() - padding_mask.unsqueeze(-1).long() - 1
  2. 不支持gradient_checkpointing, 修复的话需要modeling_chatglm.py新增get_input_embeddings, set_input_embeddings;
  3. 官方prompt, chatglm3支持工具调用
<|system|>
Answer the following questions as best as you can. You have access to the following tools:
[
    {
        "name": "get_current_weather",
        "description": "Get the current weather in a given location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "The city and state, e.g. San Francisco, CA",
                },
                "unit": {"type": "string"},
            },
            "required": ["location"],
        },
    }
]
<|user|>
今天北京的天气怎么样?
<|assistant|>
好的,让我们来查看今天的天气
<|assistant|>get_current_weather
'''python
tool_call(location="beijing", unit="celsius")
'''
<|observation|>
{"temperature": 22}
<|assistant|>
根据查询结果,今天北京的气温为 22 摄氏度。
  1. 官方prompt构建chat实现代码:
def build_chat_input(self, query, history=None, role="user"):
    if history is None:
        history = []
    input_ids = []
    for item in history:
        content = item["content"]
        if item["role"] == "system" and "tools" in item:
            content = content + "\n" + json.dumps(item["tools"], indent=4, ensure_ascii=False)
        input_ids.extend(self.build_single_message(item["role"], item.get("metadata", ""), content))
    input_ids.extend(self.build_single_message(role, "", query))
    input_ids.extend([self.get_command("<|assistant|>")])
    return self.batch_encode_plus([input_ids], return_tensors="pt", is_split_into_words=True)

环境配置

transformers==4.27.1
torch>=2.0
sentencepiece
cpm_kernels
mdtex2html
accelerate
protobuf
gradio

微调样例

地址: chatglm3_6b/ft_chatglm3

配置: chatglm3_6b/ft_chatglm3/config.py
训练: python train.py
接口: python post_api.py

实验日志

微调日志(metalwoz数据集, 英文主题多轮对话)

在这里插入图片描述

在这里插入图片描述

推理样例(LoRA, R=8)

回答得比较短了, 也确实遵循了主题

在这里插入图片描述

在这里插入图片描述

参考/感谢

免责申明

本项目相关资源仅供学术研究之用,使用涉及第三方代码的部分时,请严格遵循相应的开源协议。模型生成的内容受模型计算、随机性和量化精度损失等因素影响,本项目不对其准确性作出保证。对于模型输出的任何内容,本项目不承担任何法律责任,亦不对因使用相关资源和输出结果而可能产生的任何损失承担责任。

型输出的任何内容,本项目不承担任何法律责任,亦不对因使用相关资源和输出结果而可能产生的任何损失承担责任。

其他-lora合并

可以直接model.merge_and_unload(),也可以参考https://github.com/ymcui/Chinese-LLaMA-Alpaca/blob/main/scripts/merge_llama_with_chinese_lora.py

代码样例
print_named_parameters(model, True)
model = load_model_state(model=model, model_save_dir=MODEL_SAVE_DIR)
model = prepare_model_for_half_training(model,
        use_gradient_checkpointing=False,
        output_embedding_layer_name="lm_head",
        layer_norm_names=["post_attention_layernorm",
                          "final_layernorm",
                          "input_layernorm",
                          ],
        )
print_named_parameters(model, True)
if USE_CUDA:
    model = model.half().cuda()
else:
    model = model.bfloat16()
print_named_parameters(model, True)
model = model.merge_and_unload()
print_named_parameters(model, True)

model.train(False)
model.save_pretrained("merge_and_unload")
参数结果(已生效)
merge前:
('base_model.model.transformer.encoder.layers.0.self_attention.query_key_value.weight', torch.float16, False, tensor([
        [ 0.0064,  0.0006,  0.0198,  ..., -0.0052, -0.0012, -0.0023],
('base_model.model.transformer.encoder.layers.0.self_attention.query_key_value.lora_A.default.weight', torch.float16, False, tensor([
        [-0.0134,  0.0130,  0.0087,  ..., -0.0275, -0.0126, -0.0121],

merge后:
('transformer.encoder.layers.0.self_attention.query_key_value.weight', torch.bfloat16, False, tensor([
        [ 0.0069, -0.0003,  0.0182,  ..., -0.0044, -0.0007, -0.0022],
推理结果(已生效)
merge前:
gMASK sop<|system|>
You are a helpful assistant,10 words per answer.
<|user|>
What's the weather like today?
<|assistant|>
It's sunny and warm.
<|user|>

merge后:
gMASK sop<|system|>
You are a helpful assistant, 10 words per answer.
<|user|>
What's the weather like today?
<|assistant|>
It's sunny and warm.
<|user|>
<think>嗯,用户想找关于ChatGLM3-6B模型微调的代码示例。首先,我需要回顾一下提供的引用内容。引用1和2提到官方文档里有全量微调、P-Tuning v2、SFT和LoRA的示例,包括多轮对话和输入输出格式的样例。引用3是关于ChatGLM2-6B的P-Tuning实践,里面详细讲了环境准备、数据集准备、依赖安装、训练和评估步骤。引用4则提供了一个GitHub仓库的链接,里面有chatglm3-6b的微调实战代码,包括LORA、多卡训练等。 用户可能已经看过官方文档,但需要具体的代码示例,特别是实际的实现步骤。可能需要区分不同微调方法,比如全量微调、P-Tuning v2和LoRA。引用3和4中的实际项目可能更实用,尤其是GitHub上的代码库,用户可能更倾向于实际操作步骤。 接下来,应该分步骤给出不同微调方法的示例。例如,全量微调可能需要准备数据集、加载模型、设置训练参数等。P-Tuning v2可能涉及使用特定的训练脚本和配置。LoRA则需要使用相应的库,比如peft,并调整模型参数。 需要注意的是,用户可能需要环境准备的指导,比如安装CUDA、PyTorch、相关依赖库。此外,数据集格式的要求也很重要,比如JSON格式和特定的键名如"prompt"和"response"。 可能还需要提到微调后的推理步骤,如何加载训练好的模型进行测试。同时,引用中的GitHub项目可能有踩坑经验,可以提醒用户注意常见问题,比如依赖版本冲突或显存不足。 最后,生成相关问题时要覆盖不同微调方法、数据集处理、环境配置、性能优化等,帮助用户进一步探索。</think>以下为关于ChatGLM3-6B模型微调的代码示例及实现步骤说明: ### 一、微调方法及代码示例 #### 1. **全量微调(SFT)** ```python from transformers import AutoModel, TrainingArguments, Trainer # 加载预训练模型 model = AutoModel.from_pretrained("THUDM/chatglm3-6b", trust_remote_code=True) # 配置训练参数 training_args = TrainingArguments( output_dir="./output", per_device_train_batch_size=4, gradient_accumulation_steps=2, learning_rate=2e-5, num_train_epochs=3, fp16=True ) # 自定义数据集加载函数 def load_dataset(file_path): # 需包含"prompt"和"response"字段的JSON格式数据 ... trainer = Trainer( model=model, args=training_args, train_dataset=load_dataset("data/train.json") ) trainer.train() ``` > 说明:全量微调会更新所有模型参数,需要较大显存[^1][^2] #### 2. **P-Tuning v2微调** ```bash # 使用官方提供的训练脚本 git clone https://github.com/THUDM/ChatGLM3 cd ChatGLM3/finetune_ptuning python main.py \ --dataset your_data \ --prompt_column prompt \ --response_column response \ --quantization_bit 4 ``` > 特点:仅更新部分参数,显存需求较低[^3] #### 3. **LoRA微调** ```python from peft import LoraConfig, get_peft_model # 添加LoRA适配器 lora_config = LoraConfig( r=8, lora_alpha=16, target_modules=["query_key_value"], lora_dropout=0.05, bias="none" ) model = get_peft_model(model, lora_config) ``` > 优势:参数效率高,适合单卡训练[^4] ### 二、关键实现步骤 1. **环境准备** ```bash conda create -n chatglm python=3.10 pip install torch==2.0.1+cu118 -f https://download.pytorch.org/whl/torch_stable.html pip install -r requirements.txt # 包含transformers, peft等 ``` 2. **数据集格式** ```json { "prompt": "解释量子计算", "response": "量子计算是利用量子力学原理...", "history": [] } ``` 3. **多卡训练配置** ```python training_args = TrainingArguments( deepspeed="./configs/deepspeed.json", gradient_checkpointing=True ) ``` ### 三、微调后推理 ```python from transformers import AutoTokenizer tokenizer = AutoTokenizer.from_pretrained("THUDM/chatglm3-6b", trust_remote_code=True) model = AutoModel.from_pretrained("./output/checkpoint-1000", trust_remote_code=True).cuda() response, history = model.chat( tokenizer, "如何提升模型微调效果?", history=[] ) print(response) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值