使用SFT和VLLM微调和部署Llama3-8b模型

2024-04-22 16:44

本文主要是介绍使用SFT和VLLM微调和部署Llama3-8b模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1. 环境安装
  • 2. accelerator准备
  • 3. 加载llama3和数据
  • 4. 训练参数配置
  • 5. 微调
  • 6. vllm部署
  • 7. Llama-3-8b-instruct的使用
  • 参考

1. 环境安装

pip install -q -U bitsandbytes
pip install -q -U git+https://github.com/huggingface/transformers.git
pip install -q -U git+https://github.com/huggingface/peft.git
pip install -q -U git+https://github.com/huggingface/accelerate.git
pip install trl

2. accelerator准备

import os
import torch
from datasets import load_dataset
from transformers import (AutoModelForCausalLM,AutoTokenizer,BitsAndBytesConfig,HfArgumentParser,TrainingArguments,pipeline,logging,
)
from peft import LoraConfig, PeftModel
from trl import SFTTrainer
from accelerate import FullyShardedDataParallelPlugin, Accelerator
from torch.distributed.fsdp.fully_sharded_data_parallel import FullOptimStateDictConfig, FullStateDictConfigfsdp_plugin = FullyShardedDataParallelPlugin(state_dict_config=FullStateDictConfig(offload_to_cpu=True, rank0_only=False),optim_state_dict_config=FullOptimStateDictConfig(offload_to_cpu=True, rank0_only=False),
)accelerator = Accelerator(fsdp_plugin=fsdp_plugin)

3. 加载llama3和数据

因为使用的是base模型,所以没有一个严格的提示模板需要遵循。使用的数据集遵循LLama3的模板格式,因此对于使用Llama3聊天格式的下游任务来说应该没问题。如果你使用自己的数据,你可以自定义格式,在下游任务中也使用相同的格式即可。

base_model_id = "meta-llama/Meta-Llama-3-8B"
dataset_name = "scooterman/guanaco-llama3-1k"
new_model = "llama3-8b-SFT"from datasets import load_dataset
dataset = load_dataset(dataset_name, split="train")import torch
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfigmodel = AutoModelForCausalLM.from_pretrained(base_model_id, device_map="auto")
tokenizer = AutoTokenizer.from_pretrained(base_model_id,add_eos_token=True,add_bos_token=True, 
)
tokenizer.pad_token = tokenizer.eos_token

4. 训练参数配置

许多教程只是简单地粘贴一个参数列表,让读者自己去弄清楚每个参数的作用。下面我添加了注释来解释每个参数的作用!

# Output directory where the results and checkpoint are stored
output_dir = "./results"# Number of training epochs - how many times does the model see the whole dataset
num_train_epochs = 1 #Increase this for a larger finetune# Enable fp16/bf16 training. This is the type of each weight. Since we are on an A100
# we can set bf16 to true because it can handle that type of computation
bf16 = True# Batch size is the number of training examples used to train a single forward and backward pass. 
per_device_train_batch_size = 4# Gradients are accumulated over multiple mini-batches before updating the model weights. 
# This allows for effectively training with a larger batch size on hardware with limited memory
gradient_accumulation_steps = 2# memory optimization technique that reduces RAM usage during training by intermittently storing 
# intermediate activations instead of retaining them throughout the entire forward pass, trading 
# computational time for lower memory consumption.
gradient_checkpointing = True# Maximum gradient normal (gradient clipping)
max_grad_norm = 0.3# Initial learning rate (AdamW optimizer)
learning_rate = 2e-4# Weight decay to apply to all layers except bias/LayerNorm weights
weight_decay = 0.001# Optimizer to use
optim = "paged_adamw_32bit"# Number of training steps (overrides num_train_epochs)
max_steps = 5# Ratio of steps for a linear warmup (from 0 to learning rate)
warmup_ratio = 0.03# Group sequences into batches with same length
# Saves memory and speeds up training considerably
group_by_length = True# Save checkpoint every X updates steps
save_steps = 100# Log every X updates steps
logging_steps = 5

5. 微调

建立一个wandb帐户来监控这次微调任务。

pip install wandb
import wandb
training_arguments = TrainingArguments(output_dir=output_dir,num_train_epochs=num_train_epochs,per_device_train_batch_size=per_device_train_batch_size,gradient_accumulation_steps=gradient_accumulation_steps,optim=optim,save_steps=save_steps,logging_steps=logging_steps,learning_rate=learning_rate,weight_decay=weight_decay,bf16=bf16,max_grad_norm=max_grad_norm,max_steps=max_steps,warmup_ratio=warmup_ratio,group_by_length=group_by_length,report_to="wandb"
)trainer = SFTTrainer(model=model,train_dataset=dataset,dataset_text_field="text",tokenizer=tokenizer,args=training_arguments,
)trainer.train()# Save trained model
trainer.model.save_pretrained(new_model)

6. vllm部署

为了部署这个模型以进行极快的推理,使用VLLM并托管一个OpenAI兼容端点。可能需要重新启动内核,然后运行下面的单元。

pip install vllm
python -O -u -m vllm.entrypoints.openai.api_server \--host=127.0.0.1 \--port=8000 \--model=brev-llama3-8b-SFT \--tokenizer=meta-llama/Meta-Llama-3-8B \--tensor-parallel-size=2

7. Llama-3-8b-instruct的使用

Instruct 版本对话prompt结构:

<|begin_of_text|><|start_header_id|>system<|end_header_id|>{{ system_prompt }}<|eot_id|><|start_header_id|>user<|end_header_id|>{{ user_msg_1 }}<|eot_id|><|start_header_id|>assistant<|end_header_id|>{{ model_answer_1 }}<|eot_id|>

16 GB 的 RAM,包括 3090 或 4090 等消费级 GPU

import transformers
import torchmodel_id = "meta-llama/Meta-Llama-3-8B-Instruct"pipeline = transformers.pipeline("text-generation",model=model_id,model_kwargs={"torch_dtype": torch.bfloat16},device="cuda",
)messages = [{"role": "system", "content": "You are a pirate chatbot who always responds in pirate speak!"},{"role": "user", "content": "Who are you?"},
]prompt = pipeline.tokenizer.apply_chat_template(messages, tokenize=False, add_generation_prompt=True
)terminators = [pipeline.tokenizer.eos_token_id,pipeline.tokenizer.convert_tokens_to_ids("<|eot_id|>")
]outputs = pipeline(prompt,max_new_tokens=256,eos_token_id=terminators,do_sample=True,temperature=0.6,top_p=0.9,
)
print(outputs[0]["generated_text"][len(prompt):])

量化版,4 bits加载需要大约 7 GB 的内存运行

pipeline = transformers.pipeline("text-generation",model=model_id,model_kwargs={"torch_dtype": torch.float16,"quantization_config": {"load_in_4bit": True},"low_cpu_mem_usage": True,},
)

参考

  1. https://huggingface.co/blog/llama3#how-to-prompt-llama-3
  2. https://ai.meta.com/blog/meta-llama-3/
  3. https://pytorch.org/torchtune/stable/tutorials/llama3.html

这篇关于使用SFT和VLLM微调和部署Llama3-8b模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/926315

相关文章

使用Go语言开发一个命令行文件管理工具

《使用Go语言开发一个命令行文件管理工具》这篇文章主要为大家详细介绍了如何使用Go语言开发一款命令行文件管理工具,支持批量重命名,删除,创建,移动文件,需要的小伙伴可以了解下... 目录一、工具功能一览二、核心代码解析1. 主程序结构2. 批量重命名3. 批量删除4. 创建文件/目录5. 批量移动三、如何安

springboot的调度服务与异步服务使用详解

《springboot的调度服务与异步服务使用详解》本文主要介绍了Java的ScheduledExecutorService接口和SpringBoot中如何使用调度线程池,包括核心参数、创建方式、自定... 目录1.调度服务1.1.JDK之ScheduledExecutorService1.2.spring

Java使用Tesseract-OCR实战教程

《Java使用Tesseract-OCR实战教程》本文介绍了如何在Java中使用Tesseract-OCR进行文本提取,包括Tesseract-OCR的安装、中文训练库的配置、依赖库的引入以及具体的代... 目录Java使用Tesseract-OCRTesseract-OCR安装配置中文训练库引入依赖代码实

Python使用Pandas对比两列数据取最大值的五种方法

《Python使用Pandas对比两列数据取最大值的五种方法》本文主要介绍使用Pandas对比两列数据取最大值的五种方法,包括使用max方法、apply方法结合lambda函数、函数、clip方法、w... 目录引言一、使用max方法二、使用apply方法结合lambda函数三、使用np.maximum函数

SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程

《SpringBoot中整合RabbitMQ(测试+部署上线最新完整)的过程》本文详细介绍了如何在虚拟机和宝塔面板中安装RabbitMQ,并使用Java代码实现消息的发送和接收,通过异步通讯,可以优化... 目录一、RabbitMQ安装二、启动RabbitMQ三、javascript编写Java代码1、引入

Qt 中集成mqtt协议的使用方法

《Qt中集成mqtt协议的使用方法》文章介绍了如何在工程中引入qmqtt库,并通过声明一个单例类来暴露订阅到的主题数据,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一,引入qmqtt 库二,使用一,引入qmqtt 库我是将整个头文件/源文件都添加到了工程中进行编译,这样 跨平台

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java中String字符串使用避坑指南

《Java中String字符串使用避坑指南》Java中的String字符串是我们日常编程中用得最多的类之一,看似简单的String使用,却隐藏着不少“坑”,如果不注意,可能会导致性能问题、意外的错误容... 目录8个避坑点如下:1. 字符串的不可变性:每次修改都创建新对象2. 使用 == 比较字符串,陷阱满

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定