LLM系列 | 20 : Llama2 实战(下篇)-中文语料微调(附完整代码)

2023-09-16 21:34:30

简介

紧接前文:

  • 万字长文细说ChatGPT的前世今生
  • Llama 2实战(上篇):本地部署(附代码)

上篇主要介绍Llama2的基本情况和基于官方模型实测Llama2在中英上的效果,包括单轮和多轮对话。今天这篇小作文作为Llama2的下篇,主要介绍如何用中文语料对Llama 2的基座模型(7B版)进行微调并实测微调后模型的效果。本文实验完整代码请找小编索取。后续将实战Code Llama感兴趣的小伙伴可以关注下!

数据准备

基座模型下载可以参考Llama 2实战(上篇):本地部署(附代码)中的模型下载部分。官方Repo: llama-recipes里面提到支持的默认数据格式有三种:grammar_dataset, alpaca_datasetandsamsum_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.jsonadapter_model.bin文件,这就是微调后的参数结果。

模型inference

使用如下脚本加载微调后的模型进行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
更多推荐

基于Java+微信小程序实现《模拟考试平台》

博主介绍:✌全网粉丝30W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌🍅文末获取源码联系🍅👇🏻精彩专栏推荐订阅👇🏻不然下次找不到哟2022-2024年最全的计算机软件毕业设计选题

学习笔记-接口测试(postman、jmeter)

目录一、什么是接口测试二、前端和后端三、get请求和post请求的区别四、cookie和session五、接口测试的依据六、HTTP状态码七、通用接口用例八、postman接口测试九、Jmeter接口测试一、什么是接口测试通常做的接口测试指的是系统对外的接口,比如你需要从别的系统来获取到或者同步资源与信息,他们会提供给

华为云云耀云服务器L实例评测|宝塔一站式安装数据库MySQL+Redis教程

目录前言一、传统服务器安装数据库1.安装MySQL2.安装Redis二、云耀云服务器L安装MySQL1.云耀云服务器L实例购买2.远程登录并重置密码3.云耀云服务器L初始化宝塔面板4.宝塔面板安装数据库5.MySQL第三方登录三、云耀云服务器L安装Redis1.宝塔面板安装Redis2.Redis密码设置及第三方登录总

Linux开发工具之编辑器-vim

vim简单来说就是一款文本编辑器,用于写代码,更是一款多模式编辑器vim的基本概念vim有许多种模式,但是铁三角是以下三种模式:命令模式,插入模式,底行模式1正常/普通/命令模式(默认打开)控制屏幕光标的移动,字符、字或行的删除,移动复制某区段及进入插入模式,底行模式2插入模式只有在插入模式下,才可以做文字输入,按「E

【C# 基础精讲】try-catch语句块

try-catch语句块是C#中用于异常处理的关键机制。异常是在程序执行过程中可能出现的错误或意外情况,而try-catch语句块允许您在执行代码时捕获并处理这些异常,从而保证程序的稳定性和健壮性。本文将深入探讨try-catch语句块的结构、用法和最佳实践。1.try-catch语句块的结构一个try-catch语句

打造自己的美颜应用:使用视频直播美颜sdk的步骤

当下,视频直播已经成为人们分享自己生活、技能和兴趣的流行方式。但是,随着竞争的加剧,提供高质量视频直播体验变得至关重要。其中一个重要因素是美颜效果,这已经成为吸引观众的重要因素之一。幸运的是,现在有许多视频直播美颜sdk可供开发人员使用,无需从头开始构建美颜功能。本文将详细介绍如何使用这些sdk来打造自己的美颜应用。步

【C# 基础精讲】文件流和文本处理

文件流是C#中用于进行文件读写操作的重要概念,它提供了一种逐字节或逐块访问文件内容的机制。文本处理则是指在读取和写入文件时,对文本数据进行解析、操作和转换的过程。在本文中,我们将深入探讨文件流的概念、种类以及使用方法,并介绍在文本处理过程中常见的操作和技巧。1.文件流的基本概念文件流是C#中处理文件读写的抽象,它提供了

什么是集成测试?集成测试方法有哪些?

1、基本概念:将软件集成起来后进行测试。集成测试又叫子系统测试、组装测试、部件测试等。集成测试主要是针对软件高层设计进行测试,一般来说是以模块和子系统为单位进行测试。2、集成测试包含的层次:1.模块内的集成,主要是测试模块内各个接口间的交互集成关系;2.子系统内的集成,测试子系统内各个模块间的交互关系;3.系统集成,测

MYSQL02高级_目录结构、默认数据库、表文件、系统独立表空间

文章目录①.MySQL目录结构②.查看默认数据库③.MYSQL5.7和8表文件③.系统、独立表空间①.MySQL目录结构①.如何查看关联mysql目录[root@mysql8~]#find/-namemysql/var/lib/mysql/var/lib/mysql/mysql/etc/selinux/targeted

带你读懂任正非先生的最新讲话——与ICPC代表讲话纪要(一)

2023年9月19日,在ICPC中国赛区北京总部的官网(设立在北京大学)上发布了一条新闻:《今天我们汇聚一堂,明天我们将奔向四面八方——任正非与ICPC基金会及教练和金牌获得者的学生的谈话纪要》。2023年8月21日和8月26日,任正非先生分别会见ICPC基金会一行,以及ICPC各代表队的教练和金牌获奖学生,并与他们进

实现高并发内存池(C++)

什么是内存池池化技术所谓“池化技术”,就是程序先向系统申请过量的资源,然后自己管理以备不时之需。之所以要申请过量的资源,是因为每次申请该资源都有较大的开销,不如提前申请好,这样使用时就会变得非常快捷,大大提高程序运行效率。在计算机中,有很多使用“池”这种技术的地方,除了内存池,还有连接池、线程池、对象池等。以服务器上的

热文推荐