赞
踩
紧接前文:
上篇主要介绍Llama2的基本情况和基于官方模型实测Llama2在中英上的效果,包括单轮和多轮对话。今天这篇小作文作为Llama2的下篇,主要介绍如何用中文语料对Llama 2的基座模型(7B版)进行微调并实测微调后模型的效果。本文实验完整代码请找小编索取。后续将实战Code Llama感兴趣的小伙伴可以关注下!
基座模型下载可以参考Llama 2实战(上篇):本地部署(附代码)中的模型下载部分。官方Repo: llama-recipes里面提到支持的默认数据格式有三种:grammar_dataset
, alpaca_datasetand
和samsum_dataset
。为了节约时间,选择alpaca格式的中文SFT数据集,alpaca格式的数据示例如下:
[ { "instruction": "根据给定的坐标确定最近的机场。", "input": "40.728157, -73.794853", "output": "距给定坐标最近的机场是纽约市的拉瓜迪亚机场 (LGA)。" }, { "instruction": "输出不同种类水果的列表", "input": "", "output": "1. 苹果\n2. 香蕉\n3. 橘子\n4. 芒果\n5. 草莓\n6. 葡萄\n7. 蓝莓\n8. 樱桃\n9. 猕猴桃\n10. 甜瓜\n11.菠萝\n12. 李子\n13.桃子" }, { "instruction": "找出字串中隐藏的信息", "input": "业余咖啡", "output": "隐藏的消息是“咖啡因爱好者”。" } ]
本次实验具体选择的数据集是:GuanacoDataset/guanaco_non_chat-utf8.json。完成数据下载之后,将guanaco_non_chat-utf8.json
放到 llama-recipes/ft_datasets
目录下,并重命名为 alpaca_data.json
。训练时将训练集指定为 alpaca_dataset
即可,llama-recipes 将会自动找到这个文件。至此,SFT微调数据集准备完成。
微调训练脚本使用llama_finetuning.py
脚本,具体如下:
# 单机, 多卡
export CUDA_VISIBLE_DEVICES=1,2,3
torchrun --nnodes 1 --nproc_per_node 3 llama_finetuning.py \
--enable_fsdp \
--use_peft \
--peft_method lora \
--model_name /home/model_zoo/LLM/llama2/Llama-2-7b-hf/ \
--dataset alpaca_dataset \
--pure_bf16 \
--batch_size_training 50 \
--num_epochs 2 \
--output_dir /home/LLM/llama-recipes/PEFT/model
微调结束后,在/home/LLM/llama-recipes/PEFT/model
生成adapter_config.json
和adapter_model.bin
文件,这就是微调后的参数结果。
使用如下脚本加载微调后的模型进行inference:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2023/09/03 10:15 # @Author : 卖热干面的小女孩 # @File : inference_multi_gpus_one_node.py # @联系方式 : 《微-心-公-众-号 <小窗幽记机器学习>》 import pdb import torch from transformers import LlamaForCausalLM, LlamaTokenizer from transformers import GenerationConfig from peft import PeftModel, PeftConfig peft_model_id = "./PEFT/model/" temperature = 0.0 max_new_tokens = 256 config = PeftConfig.from_pretrained(peft_model_id) model = LlamaForCausalLM.from_pretrained(config.base_model_name_or_path) model = PeftModel.from_pretrained(model, peft_model_id) tokenizer = LlamaTokenizer.from_pretrained(config.base_model_name_or_path) device = "cuda:2" model = model.to(device) model.eval() # test_prompt = "### Instruction: \n你谁? \n### Response:\n" # test_prompt = "### Instruction: \n你叫做爱坤,擅长舞蹈、篮球、武术篮球、舞蹈篮球,喜欢Rap,能唱会跳,偶像是马保国?\n### Response:\n" # test_prompt = "### Instruction: 根据以下信息,回答问题。爱坤的偶像是谁?直接给出答案即可,不要输出其他\n### Input: \n你叫做爱坤,擅长舞蹈、篮球、武术篮球、舞蹈篮球,喜欢Rap,能唱会跳,偶像是马保国?\n ### Response:\n" # test_prompt = "### Instruction: 根据以下信息:<爱坤,擅长舞蹈、篮球、武术篮球、舞蹈篮球,喜欢Rap,能唱会跳,偶像是马保国?> 回答问题。爱坤的偶像是谁?直接给出答案即可。\n### Response:\n" test_prompt = "### Instruction: 根据以下信息:<爱坤,擅长舞蹈、篮球、武术篮球、舞蹈篮球,喜欢Rap,能唱会跳,偶像是马保国?> 回答问题。爱坤崇拜谁?直接给出答案即可。\n### Response:\n" inputs = tokenizer(test_prompt, return_tensors="pt") model_input = tokenizer(test_prompt, return_tensors="pt").to(device) input_ids = model_input["input_ids"].to(device) generation_config = GenerationConfig( temperature=temperature, top_p=0.75, top_k=40, num_beams=4, repetition_penalty=2.0 ) with torch.no_grad(): generation_output = model.generate( input_ids=model_input['input_ids'], generation_config=generation_config, return_dict_in_generate=True, output_scores=True, max_new_tokens=max_new_tokens, ) s = generation_output.sequences[0] output = tokenizer.decode(s) print("output=", output)
输出结果如下:
output= <s> ### Instruction: 根据以下信息:<爱坤,擅长舞蹈、篮球、武术篮球、舞蹈篮球,喜欢Rap,能唱会跳,偶像是马保国?> 回答问题。爱坤崇拜谁?直接给出答案即可。
### Response:
爱坤崇拜马保国</s>
可以看出,经过中文语料的简单微调,可以较好地支持中文问答。
上述方式以脚本方式加载模型并做inference。那么如果想要向外提供服务,可以使用alpaca-lora提供的脚本部署Web服务。这里为了减缓模型的重复回复,添加了 repeatition penalty
CUDA_VISIBLE_DEVICES=1 python3 generate.py --base_model /home/model_zoo/LLM/llama2/Llama-2-7b-hf/ --lora_weights /home/Repository/LLM/llama-recipes/PEFT/model
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。