本人项目地址大全:Victor94-king/NLP__ManVictor: 优快云 of ManVictor
写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!!
写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!!
写在前面: 笔者更新不易,希望走过路过点个关注和赞,笔芯!!!
在 24G 显存的单卡 4090 上微调训练 deepseek-ai/DeepSeek-R1-Distill-Qwen-32B;即使该模型的权重文件大小已经达到 62G,这是因为 unsloth 和 lora 的量化微调和部分参数微调优化可以大幅节约显存占用。
因为设置了**max_steps=**60 限制了只执行60步以便快速完成实验。去掉这个参数后,SFTTrainer 即可根据数据量自动计算微调步数了。这次进行了 FreedomIntelligence/medical-o1-reasoning-SFT 数据集 24772 条数据的全量微调,epoch为默认值3,微调结果如下:
- 训练总步数 (Total steps) : 9288 步
- **训练总轮次 (Epochs) : 3.0 轮 **
- 每轮数据量: 24,772 条数据
- 训练时间: 总计 28小时28分37秒(102517.8411 秒)
本次训练在贝联云算力平台( https://cloud.lccomputing.com )上完成。
完整训练代码如下:
import wandb
# 登录 wandb.ai 用于实验跟踪
wandb.login(key="放置你的wandb.ai网站上的token")
# 初始化wandb项目
run = wandb.init(
project='Lora-R1-Distill-Qwen on Medical COT Dataset',
job_type="training",
anonymous="allow"
)
####################################################################################################
# 1.加载模型
# 使用 unsloth 优化的 FastLanguageModel 加载模型
from unsloth import FastLanguageModel
max_seq_length = 4096 # 最大序列长度
dtype = None # 数据类型,None表示自动选择
load_in_4bit = True # 使用4bit量化加载模型以节省显存
# 加载预训练模型和分词器
model, tokenizer = FastLanguageModel.from_pretrained(
#model_name = "unsloth/DeepSeek-R1-Distill-Qwen-7B",
model_name = "/models/deepseek-ai/DeepSeek-R1-Distill-Qwen-32B",
local_files_only=True, # 避免联网
max_seq_length = max_seq_length,
dtype = dtype,
load_in_4bit = load_in_4bit,
#token = hf_token,
)
print(model)
####################################################################################################
# 2. 定义提示模板,并在微调前做一次推理
prompt_style = """以下是描述任务的指令,以及提供更多上下文的输入。
请写出恰当完成该请求的回答。
在回答之前,请仔细思考问题,并创建一个逐步的思维链,以确保回答合乎逻辑且准确。
### Instruction:
你是一位在临床推理、诊断和治疗计划方面具有专业知识的医学专家。
请回答以下医学问题。
### Question:
{}
### Response:
<think>{}"""
train_prompt_style = prompt_style + """
</think>
{}"""
# 测试用医学问题
question = "一名70岁的男性患者因胸痛伴呕吐16小时就医,心电图显示下壁导联和右胸导联ST段抬高0.1~0.3mV,经补液后血压降至80/60mmHg,患者出现呼吸困难和不能平卧的症状,体检发现双肺有大量水泡音。在这种情况下,最恰当的药物处理是什么?"
# 设置模型为推理模式
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("### 微调前模型推理结果:")
print(response[0].split("### Response:")[1])
####################################################################################################
# 3. 处理数据集
EOS_TOKEN = tokenizer.eos_token # 添加结束符标记
#格式化提示函数,用于处理数据集中的示例
def formatting_prompts_func(examples):
# 从examples中提取问题、思维链和回答
inputs = examples["Question"] # 医学问题列表
cots = examples["Complex_CoT"] # 思维链列表
outputs = examples["Response"] # 回答列表
# 存储格式化后的文本
texts = []
# 遍历每个示例,将问题、思维链和回答组合成指定格式
for input, cot, output in zip(inputs, cots, outputs):
# 使用train_prompt_style模板格式化文本,并添加结束符
text = train_prompt_style.format(input, cot, output) + EOS_TOKEN
texts.append(text)
# 返回格式化后的文本字典
return {
"text": texts,
}
# 加载数据集并应用格式化
from datasets import load_dataset,load_from_disk
dataset = load_dataset(
"json", # 指定数据格式为 JSON
data_files="/dat

最低0.47元/天 解锁文章
4702

被折叠的 条评论
为什么被折叠?



