unsloth微调DeepSeek
https://github.com/unslothai/unsloth
https://kq4b3vgg5b.feishu.cn/wiki/WWzZwHVNei8zsWkieJ3cyHzWnFe
安装库
首先确保已在项目目录中,并已激活虚拟环境pip install --upgrade pip
升级pippip install "unsloth[cu124-torch250] @ git+https://github.com/unslothai/unsloth.git"
借助unsloth进行模型推理对话
from unsloth import FastLanguageModel
import torch
max_seq_length = 1024
dtype = None
load_in_4bit = False
device = "cuda" if torch.cuda.is_available() else "cpu" # 检查GPU是否可用
print("使用的设备:", device)
# 加载模型
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "./DeepSeek-R1-Distill-Qwen-1.5B",
max_seq_length = max_seq_length, # 最大序列长度
dtype = dtype, # 数据类型
load_in_4bit = load_in_4bit,
)
# 将模型移动到设备,unsloth不需要显示的将模型移动到设备,它会自动检测设备并移动模型
model.to(device)
# model.config.pad_token_id = model.config.eos_token_id # 设置padding token为eos token
FastLanguageModel.for_inference(model) # 启动推理模式
# 打印欢迎信息
print("欢迎来到对话模式!")
# 对话循环
while True:
# 获取用户输入,这里会等待用户输入按回车后继续下面的代码
input_text = input("你:")
# 用户输入为空,继续下一轮
if not input_text.strip():
print("请输入有效的文本!")
continue
# 使用tokenizer将用户输入转换为模型输入
inputs = tokenizer([input_text], return_tensors="pt").to(device)
#带入inputs进行对话
outputs = model.generate(
input_ids = inputs.input_ids,
max_new_tokens = 150,
use_cache = True,
# temperature = 0.6, # 温度参数,控制生成文本的多样性
# top_p = 0.9, # 控制采样的多样性
)
#此时得到得回复也是词索引,将其转换为文本
response = tokenizer.batch_decode(outputs) # response就是回复原始文本,是一个列表,里面包含了多个回复
# response = tokenizer.decode(outputs[0], skip_special_tokens=True)
print('模型:',response)
使用对话模板进行操作
from unsloth import FastLanguageModel
import torch
max_seq_length = 8192
dtype = None
load_in_4bit = False
device = "cuda" if torch.cuda.is_available() else "cpu" # 检查GPU是否可用
print("使用的设备:", device)
# 加载模型
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "./DeepSeek-R1-Distill-Qwen-1.5B",
max_seq_length = max_seq_length, # 最大序列长度
dtype = dtype, # 数据类型
load_in_4bit = load_in_4bit,
)
# 将模型移动到设备,unsloth不需要显示的将模型移动到设备,它会自动检测设备并移动模型
model.to(device)
# model.config.pad_token_id = model.config.eos_token_id # 设置padding token为eos token
FastLanguageModel.for_inference(model) # 启动推理模式
# 打印欢迎信息
print("欢迎来到对话模式!")
# 对话模板,顶部是对话的任务描述,下面是对话的问题和回答
prompt_style_chat = """请写出一个恰当的回答来完成当前对话任务。
### Instruction:
你是小易算力的智能客服,专注于为用户提供关于GPU算力资源的帮助。你可以回答关于GPU算力资源租赁、购买、出售、服务器等相关问题。如果用户问的问题与GPU、算力、服务器、AI等无关,请回答:‘不好意思,我只能回答您关于算力资源的使用问题哦’。
### Question:
{}
### Response:
<think>{}"""
# 对话循环
while True:
# 获取用户输入,这里会等待用户输入按回车后继续下面的代码
input_text = input("你:")
# 用户输入为空,继续下一轮
if not input_text.strip():
print("请输入有效的文本!")
continue
prompt = [prompt_style_chat.format(input_text, "")] # 拼接对话模板
# 使用tokenizer将用户输入转换为模型输入
inputs = tokenizer(prompt, return_tensors="pt").to(device)
#带入inputs进行对话
outputs = model.generate(
input_ids = inputs.input_ids,
max_new_tokens = 1200,
use_cache = True,
)
#此时得到得回复也是词索引,将其转换为文本
response = tokenizer.batch_decode(outputs) # response就是回复原始文本,是一个列表,里面包含了多个回复
print('模型:',response[0].split("### Response")[1]) # 打印回复
准备COT数据集
DeepSeek R1的数据集和其它大预言模型的数据集不同的是,它需要额外装备一个think字段,这个过程是用来解释模型思考过程的步骤
例如医疗领域的一个数据集:
https://huggingface.co/datasets/FreedomIntelligence/medical-o1-reasoning-SFT
训练的数据集格式应该像这样:
[
{
"Question": "你是谁",
"Complex_CoT": "好,用户让我介绍一下自己。首先我要明确自己的身份,我是小易助手,是一个由上海复易信息技术有限公司开发的智能客服。我可以回答你一些本公司的业务问题,例如算力资源,GPU信息,AI行业问题,计算机技术等,最后礼貌的告诉用户,我可以为用户提供哪些帮助。",
"Response": "您好!我是由上海复易信息技术有限公司开发的小易助手,一个专注提供算力信息的智能客服机器人。"
},
{
"Question": "介绍你自己",
"Complex_CoT": "好,用户让我介绍一下自己。首先我要明确自己的身份,我是小易助手,是一个由上海复易信息技术有限公司开发的智能客服。然后要提到我的主要功能是帮助用户处理计算资源相关的各种查询,特别是关于GPU算力资源的问题。还要说明我能提供哪些具体的服务,比如算力优化建议、任务分配指导以及技术支持等。最后提醒用户如果有其他类型的问题或需要更深入的帮助,也可以提出需求,我会尽力配合。整个回应要简洁明了,让用户清楚了解我可以提供的服务范围,并且表达出愿意继续协助的态度",
"Response": "您好!我是由小易算力开发的智能助手,您的专属顾问。我专注于为您提供与 GPU 算力资源、服务器及 AI 相关的知识和服务支持。如果您有任何关于这些领域的疑问,请随时告诉我;如果您有其他问题或任何反馈,我也乐意听取并帮忙解决。很高兴为您效劳!"
},
{
"Question": "你叫什么名字",
"Complex_CoT": "首先我要明确自己的身份,我是小易助手,是一个由上海复易信息技术有限公司开发的智能客服,最后保持礼貌的回答“我的名字叫小易助手”",
"Response": "你好!我叫“小易助手”,很高兴为你服务!"
}
]
nohup python test3.py &
后台运行tail -f nohup.out
查看命令ps aux | grep test3.py
查看是否运行完,第一个纯数字参数是进程kill 进程
提前结束
使用指定gpu推理测试CUDA_VISIBLE_DEVICES=5 python test.py
datasets库读取不同的本地训练集
# 格式化提示词,下面的字段对应数据集中的字段,对应提示词模板中的三个{}位置
def formatting_prompts_func(examples):
inputs = examples["Question"]
cots = examples["Complex_CoT"]
outputs = examples["Response"]
texts = []
for input, cot, output in zip(inputs, cots, outputs):
text = train_template.format(input, cot, output) + EOS_TOKEN # 格式化每条数据
# print('格式化后的提示词:',text)
texts.append(text)
return {
"text": texts, # 返回格式化后的文本数据
}
# 读parquet数据
# dataset = load_dataset("parquet", split = "train[0:500]",data_files="data.parquet") #读前500条
dataset = load_dataset("parquet", split = "train",data_files="data.parquet") #读所有数据
# 读取json数据
# dataset = load_dataset("json", data_files="data.json", split="train")
# 读csv前500条
dataset = load_dataset('csv', data_files='data.csv',, split="train[0:500]")
推理提示词
vllm上下下文方法
vllm上下文 system 对话提示词方法
instruction = """
你是由"小易算力"开发的智能医疗客服,如果有人问你:你是谁?告诉他你叫"小易医疗助手",你正在扮演一个医疗行业专家,你将对用户的提问,结合你的专业医疗知识去答复。”
"""
对话模板提示词方法,中间会使用{}替代文本
prompt_style_chat = """请写出一个恰当的回答来完成当前对话任务。
### Instruction:
你是一名助人为乐的助手。
### Question:
{}
### Response:
<think>{}"""
prompt_style_chat = """请写出一个恰当的回答来完成当前对话任务。
### Instruction:
你是小易算力的智能客服,专注于为用户提供关于GPU算力资源的帮助。你可以回答关于GPU算力资源租赁、购买、出售、服务器等相关问题。如果用户问的问题与GPU、算力、服务器、AI等无关,请回答:‘不好意思,我只能回答您关于算力资源的使用问题哦’。
### Question:
{}
### Response:
<think>{}"""
prompt_style_chat = """以下是一个任务说明,配有提供更多背景信息的输入。
请写出一个恰当的回答来完成该任务。
在回答之前,请仔细思考问题,并按步骤进行推理,确保回答逻辑清晰且准确。
### Instruction:
您是一位具有高级临床推理、诊断和治疗规划知识的医学专家。
请回答以下医学问题。
### Question:
{}
### Response:
<think>{}"""