微调DeepSeek
参考文章:
https://colab.research.google.com/drive/1N0Sf9yn8Tjs5gMJv-rez-0hzxBUDK3xK?usp=sharing#scrollTo=WasZ83hyd5F8
安装unsloth
pip install unsloth
pip install --force-reinstall --no-cache-dir --no-deps git+https://github.com/unslothai/unsloth.git
pip install bitsandbytes unsloth_zoo
用modelscope下载模型(国内)
#安装modelscope
pip install modelscope
#下载模型
modelscope download --model deepseek-ai/DeepSeek-R1-Distill-Qwen-7B --local_dir ./DeepSeek-R1-Distill-Qwen-7B
选择DeepSeek基础模型
from
unsloth
import
FastLanguageModel
import
torch
max_seq_length =
2048
# Choose any! We auto support RoPE Scaling internally!
dtype =
None
# None for auto detection. Float16 for Tesla T4, V100, Bfloat16 for Ampere+
load_in_4bit =
True
# Use 4bit quantization to reduce memory usage. Can be False.
model, tokenizer = FastLanguageModel.from_pretrained(
model_name =
"./DeepSeek-R1-Distill-Qwen-8B"
,
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
# token = "hf_...",
)
调用AI
prompt_style = """Below is an instruction that describes a task, paired with an input that provides further context.
Write a response that appropriately completes the request.
Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.
### Instruction:
You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning.
Please answer the following medical question.
### Question:
{}
### Response:
<think>{}"""
question = "一个患有急性阑尾炎的病人已经发病5天,腹痛稍有减轻但仍然发热,在体检时发现右下腹有压痛的包块,此时应如何处理?"
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])
微调
train_prompt_style = """Below is an instruction that describes a task, paired with an input that provides further context.
Write a response that appropriately completes the request.
Before answering, think carefully about the question and create a step-by-step chain of thoughts to ensure a logical and accurate response.
### Instruction:
You are a medical expert with advanced knowledge in clinical reasoning, diagnostics, and treatment planning.
Please answer the following medical question.
### Question:
{}
### Response:
{}
"""
def formatting_prompts_func(examples):
inputs = examples["input"]
#cots = examples["CoT"]
outputs = examples["output"]
texts = []
for input_data, output in zip(inputs, outputs):
text = train_prompt_style.format(input_data, output) + EOS_TOKEN
texts.append(text)
return {
"text": texts,
}
file_path = 'data.txt' # 替换为你的文件路径
with open(file_path, 'r', encoding='utf-8') as file:
text_data = file.read()
# 按 3 个换行符分割记录
records = text_data.strip().split('\n\n\n')
# 将每条记录按单换行符分割为字段
data = [record.split('\n') for record in records]
# 转换为 DataFrame
df = pd.DataFrame(data, columns=['input', 'output'])
dataset = Dataset.from_pandas(df)
dataset = dataset.map(formatting_prompts_func, batched = True)
print(dataset["text"][0])
model = FastLanguageModel.get_peft_model(
model,
r = 16, # Choose any number > 0 ! Suggested 8, 16, 32, 64, 128
target_modules = ["q_proj", "k_proj", "v_proj", "o_proj",
"gate_proj", "up_proj", "down_proj",],
lora_alpha = 16,
lora_dropout = 0, # Supports any, but = 0 is optimized
bias = "none", # Supports any, but = "none" is optimized
# [NEW] "unsloth" uses 30% less VRAM, fits 2x larger batch sizes!
use_gradient_checkpointing = "unsloth", # True or "unsloth" for very long context
random_state = 3407,
use_rslora = False, # We support rank stabilized LoRA
loftq_config = None, # And LoftQ
)
from trl import SFTTrainer
from transformers import TrainingArguments
from unsloth import is_bfloat16_supported
model._unwrapped_old_generate = None
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
dataset_text_field = "text",
max_seq_length = max_seq_length,
dataset_num_proc = 2,
packing = False, # Can make training 5x faster for short sequences.
args = TrainingArguments(
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4,
warmup_steps = 5,
max_steps = 60,
# num_train_epochs = 1, # For longer training runs!
learning_rate = 2e-4,
fp16 = not is_bfloat16_supported(),
bf16 = is_bfloat16_supported(),
logging_steps = 1,
optim = "adamw_8bit",
weight_decay = 0.01,
lr_scheduler_type = "linear",
seed = 3407,
output_dir = "outputs",
report_to = "none", # Use this for WandB etc
),
)
trainer_stats = trainer.train()
my_model="MyDeepSeek-8B"
model.save_pretrained(my_model) # Local saving
tokenizer.save_pretrained(my_model)
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])