目录
环境信息
操作系统:Ubuntu 24.04.1 LTS
模型:DeepSeek-R1-Distill-Llama-8B
训练框架:unsloth、pytorch
显卡:4090
一、准备训练数据
将自己的数据处理成prompt(输入)、completion(输出)两个字段,每条数据一行,保存成jsonl格式,如training_data.jsonl。
数据格式示例:
{"prompt": "医药和消费有什么基金推荐的","completion": "医药可以看看工银前沿的xx,她挺均衡的,对于这个行业我了解不多,你还可以看看xx指数"}
{"prompt": "请简述一下人工智能在医疗诊断中的应用及其优势。","completion": "人工智能在医疗诊断中发挥着越来越重要的作用。通过深度学习和机器学习等技术,人工智能能够辅助医生进行疾病诊断,提高诊断的准确性和效率。"}
...
二、安装环境
1、用conda创建python虚拟环境(非必要)
① conda安装:
官网地址:https://www.anaconda.com/download/success
② 执行命令:conda create unsloth python=3.11
③ 切换环境:conda activate unsloth
2、安装jupyter(非必要)
在命令行中执行:
① pip install jupyterlab
② jupyter lab
执行后会自动弹出浏览器,或手动打开浏览器访问:http://localhost:8888。显示页面如下:
点击Python 3 创建一个Notebook,后续的代码都可以在此执行。
3、安装训练环境
① 查看cuda版本,命令行输入nvidia-smi
如果提示命令不存在说明没装驱动,先装驱动去。
② 安装pytorch:
!pip install torch==2.5.0 torchvision==0.20.0 torchaudio==2.5.0 --index-url https://download.pytorch.org/whl/cu124
根据自己的显卡驱动选择对应cuda版本的torch包,将上面命令中的index-url地址换成适配自己的CUDA版本,比如换成11.8版CUDA换成
index-url https://download.pytorch.org/whl/cu118
③ 安装unsloth:
!pip install "unsloth[cu124-torch250] @ git+https://github.com/unslothai/unsloth.git"
三、开始训练
1、加载模型
提前下载好模型,model_name改成模型目录。可以到魔塔社区搜索模型名称,根据指示下载模型到本地。
https://modelscope.cn/models/deepseek-ai/DeepSeek-R1-Distill-Llama-8B/files
如果目录文件不存在,框架会尝试从huggingface下载模型,没有梯子下载不了。
from unsloth import FastLanguageModel
max_seq_length = 2048
dtype = None
load_in_4bit = True
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "../DeepSeek-R1-Distill-Llama-8B",
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
)
2、 加载训练数据集
其中train_prompt_style根据你的场景进行自定义,本示例中用于工单生成;
将data_files='training_data.jsonl'
改成自己的数据集路径.
train_prompt_style = """以下是一条描述任务的指令,附带用于生成工单的输入参数。
撰写响应时,请严格遵守业务规范和安全协议。
在生成之前,请分析输入参数并构建一个结构化的推理过程。
### Instruction:
您是一位拥有10年以上xx行业工单管理经验的高级维护计划员。
请根据以下参数和行业标准生成工作步骤。
### Question:
{}
### Response:
{}"""
EOS_TOKEN = tokenizer.eos_token
def formatting_prompts_func(examples):
inputs = examples["prompt"]
outputs = examples["completion"]
texts = []
for input, output in zip(inputs, outputs):
text = train_prompt_style.format(input, output) + EOS_TOKEN
texts.append(text)
return {
"text": texts,
}
from datasets import load_dataset
dataset = load_dataset('json', data_files='training_data.jsonl')
dataset = dataset['train'].map(formatting_prompts_func, batched = True,)
dataset['text'][0]
3、 构建训练参数并开始训练
model = FastLanguageModel.get_peft_model(
model,
r=16,
target_modules=[
"q_proj",
"k_proj",
"v_proj",
"o_proj",
"gate_proj",
"up_proj",
"down_proj",
],
lora_alpha=16,
lora_dropout=0,
bias="none",
use_gradient_checkpointing="unsloth", # True or "unsloth" for very long context
random_state=3407,
use_rslora=False,
loftq_config=None,
)
from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported
trainer = SFTTrainer(
model=model,
tokenizer=tokenizer,
train_dataset=dataset,
dataset_text_field="text",
max_seq_length=max_seq_length,
dataset_num_proc=2,
args=TrainingArguments(
per_device_train_batch_size=2,
gradient_accumulation_steps=4,
# Use num_train_epochs = 1
warmup_steps=300,
# max_steps=60,
learning_rate=2e-4,
fp16=not is_bfloat16_supported(),
bf16=is_bfloat16_supported(),
logging_steps=10,
optim="adamw_8bit",
weight_decay=0.01,
lr_scheduler_type="linear",
seed=3407,
output_dir="outputs",
num_train_epochs=1,
),
)
trainer_stats = trainer.train()
4、 训练完成后测试效果
question = "此处改成你的提问"
FastLanguageModel.for_inference(model)
inputs = tokenizer([prompt_style.format(question, "")], return_tensors="pt").to("cuda")
outputs = model.generate(
input_ids=inputs.input_ids,
attention_mask=inputs.attention_mask,
max_new_tokens=1200,
use_cache=True,
)
response = tokenizer.batch_decode(outputs)
print(response[0].split("### Response:")[1])
5、 保存训练后的模型
new_model_local = "DeepSeek-R1-xxx"
model.save_pretrained_merged(new_model_local, tokenizer, save_method = "merged_16bit",)
四、在Ollama中运行模型
① 首先安装Ollama(https://ollama.com/),步骤略。
② 接着上面的代码,如果要用Ollama运行模型,需将模型合并成gguf格式:
model.save_pretrained_gguf("DeepSeek-R1-xxx", tokenizer, quantization_method = "f16")
此时,会自动下载llama.cpp目录,如果执行报错,就打开终端手动执行命令看看什么问题,没问题后再运行上面的代码转成gguf。
cmake llama.cpp -B llama.cpp/build -DBUILD_SHARED_LIBS=OFF -DGGML_CUDA=OFF -DLLAMA_CURL=ON
转换成功后可以在DeepSeek-R1-xxx目录下看到一个unsloth.F16.gguf文件。
③ 在unsloth.F16.gguf同目录下创建ollama.modelfile文件,内容如下:
FROM unsloth.F16.gguf
TEMPLATE """{{- if .System }}{{ .System }}{{ end }}
{{- range $i, $_ := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1}}
{{- if eq .Role "user" }}<|User|>{{ .Content }}
{{- else if eq .Role "assistant" }}<|Assistant|>{{ .Content }}{{- if not $last }}<|end▁of▁sentence|>{{- end }}
{{- end }}
{{- if and $last (ne .Role "assistant") }}<|Assistant|>{{- end }}
{{- end }}"""
PARAMETER stop <|begin▁of▁sentence|>
PARAMETER stop <|end▁of▁sentence|>
PARAMETER stop <|User|>
PARAMETER stop <|Assistant|>
④ 打开命令行,用ollama创建模型:
ollama create r1:xxx -f ollama.modelfile
成功后通过 ollama ls
命令可以看到r1:xxx这个模型。
执行ollama run r1:xxx
可以进行对话。