DeekSeek-R1大模型本地微调-构建医疗问答模型

本次使用hugging face开源数据集(dataset),在Kaggle Notebook(Kaggle Notebook教程请见免费GPU云服务使用指南-Kaggle Notebook)免费云服务上完成对DeepSeek-R1-Distill-Llama-8B模型的本地微调。

1.注册wandb(https://wandb.ai/site)账号,获取wandb API key,来可视化训练过程。

wandb是一个免费的,用于记录实验数据的工具,很好地支持训练过程的可视化。打开wand官网(https://wandb.ai/site)注册账号,即可免费获取API key。

2.下载DeepSeek-R1-Distill-Llama-8B模型和开源数据集

由于国内无法访问hugging face,我们采用hugging face国内镜像网站(https://hf-mirror.com)下载模型和数据集(能科学上网的同学,也可以直接从hugging face下载模型和数据集)。开始前先打开Kaggle Notebook GPU加速(GPU加速方法请参考免费GPU云服务使用指南-Kaggle Notebook)。程序如下:

##创建模型下载目录
!mkdir DeepSeek-R1-Distill-Llama-8B
##创建数据集下载目录
!mkdir dataset
##把hugging face国内镜像加入环境变量
!export HF_ENDPOINT=https://hf-mirror.com
pip install -U huggingface_hub
##下载“unsloth/DeepSeek-R1-Distill-Llama-8B”蒸馏模型
!huggingface-cli download --resume-download unsloth/DeepSeek-R1-Distill-Llama-8B --local-dir DeepSeek-R1-Distill-Llama-8B

如下图所示,模型下载完成:

img

##下载开源医疗问答数据集
!huggingface-cli download --repo-type dataset --resume-download FreedomIntelligence/medical-o1-reasoning-SFT --local-dir dataset

如下图所示,数据集下载完成:

img

2.安装pyton包,开始微调(finetuning)

##安装unsloth
!pip install unsloth # install unsloth
!pip install --force-reinstall --no-cache-dir --no-deps git+https://github.com/unslothai/unsloth.git # Also get the latest version Unsloth!
##重新安装 torchvision库(因为默认安装的版本不正确)
!pip uninstall -y torch torchvision
!pip install torch torchvision
##确认我们安装成功了unsloth
!pip list | grep unsloth

如下图,unsloth安装成功:

img

##安装wandb,可视化微调过程
!pip install wandb
import wandb

##使用注册时的API key登录wandb."Your API key
"替换成在第一步生成的API keywandb.login(key = "Your API key")

##建立wandb工程
run = wandb.init(project="fint-tune deepseek r1 with open medical data",
                job_type="training",                
                anonymous="allow")

打开wandb网站(https://wandb.ai/site),可以看到如下图工程建立成功:

img

from unsloth import FastLanguageModel
import torch
max_seq_length = 2048
dtype = None
load_in_4bit = True
##指定文件目录加载model和tokenizer
model, tokenizer = FastLanguageModel.from_pretrained(model_name="/kaggle/working/DeepSeek-R1-Distill-Llama-8B",
                                                    max_seq_length=max_seq_length,                                                    
                                                    dtype=dtype,                                                    
                                                    load_in_4bit=load_in_4bit)

如下图,模型加载成功:

img

##写推理模版
prompt_style = """下面是描述任务的说明,并配有提供更多上下文的输入。编写适当完成请求的响应。
在回答之前,请仔细思考问题并创建一个循序渐进的思维链,以确保合乎逻辑和准确的回答。

### Instruction:
您是一位医学专家,在临床推理、诊断和治疗计划方面拥有先进的知识。
请回答以下医疗问题。

### Question:
{}

### Response:
<think>{}"""

##问题描述
question = "一名 61 岁的女性在咳嗽或打喷嚏等活动中长期不自主排尿,但夜间没有渗漏,接受了妇科检查和棉签测试。基于这些发现,膀胱测压最有可能揭示她的残余体积和逼尿肌收缩的什么信息?"

##模型推理
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])

模型没有微调前的回答:

好的,我现在需要回答一个关于膀胱测压的问题。让我先仔细分析一下问题的内容。 首先,问题描述了一位61岁的女性,她在咳嗽或打喷嚏时长期不自主排尿,但夜间没有渗漏。因此,她的情况可能与膀胱的残余体积和逼尿肌的状态有关。患者接受了妇科检查和棉签测试,这可能包括了膀胱的超声检查和可能的尿道镜检查。 膀胱测压通常用于评估膀胱的残余体积(DBV)和膀胱收缩力(CB)。DBV是膀胱在膨胀状态下的体积,而CB则反映了膀胱壁肌肉的收缩能力。这些因素共同决定了患者是否能够自主排尿。 在咳嗽或打喷嚏时,膀胱的压力可能增加,导致尿液无法自主排出,这可能与膀胱的残余体积较大有关,因为膀胱在膨胀时体积增加,更容易被压缩。同时,膀胱收缩力不足也可能导致患者无法及时排尿,特别是在活动时。 夜间没有渗漏,可能说明患者的膀胱在夜间能够自主排尿,这可能与膀胱的收缩力较好有关。因此,膀胱测压可以帮助医生评估这两个因素,从而制定相应的治疗方案。 可能的治疗方向包括药物治疗,如抗胆碱药物,或者非侵入性方法如膀胱刺激电疗。如果残余体积较大,可能需要内镜下减压手术或膀胱膨胀术。 总结一下,膀胱测压可以揭示残余体积和膀胱收缩力的信息,这对于治疗不自主排尿的女性非常重要。 膀胱测压能够揭示患者的膀胱残余体积(DBV)和膀胱收缩力(CB)。膀胱残余体积是膀胱在膨胀状态下的体积,反映了膀胱容积的大小,而膀胱收缩力则反映了膀胱壁肌肉的收缩能力。这些因素直接影响排尿的自主性。 在咳嗽或打喷嚏时,膀胱的压力可能增加,导致尿液无法自主排出,这可能与膀胱残余体积较大有关。同时,膀胱收缩力不足也可能导致患者无法及时排尿,特别是在活动时。夜间没有渗漏可能说明患者的膀胱在夜间能够自主排尿,这可能与膀胱的收缩力较好有关。 因此,膀胱测压能够帮助医生评估膀胱残余体积和收缩力,从而制定相应的治疗方案。治疗方向可能包括药物治疗、非侵入性方法或手术干预。<|end▁of▁sentence|>

##写训练提示词模版
train_prompt_style = """下面是描述任务的说明,并配有提供更多上下文的输入。
编写适当完成请求的响应。
在回答之前,请仔细思考问题并创建一个循序渐进的思维链,以确保合乎逻辑和准确的回答。

### Instruction:
您是一位医学专家,在临床推理、诊断和治疗计划方面拥有先进的知识。
请回答以下医疗问题。

### Question:
{}

### Response:
<think>
{}
</think>
{}"""""
EOS_TOKEN = tokenizer.eos_token  # Must add EOS_TOKEN

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_prompt_style.format(input, cot, output) + EOS_TOKEN        
        texts.append(text)   
    return {    
        "text": texts,    
    }

from datasets import load_dataset

##加载训练数据集
dataset = load_dataset("/kaggle/working/dataset", "zh",split = "train[0:500]")
##数据集格式化
dataset = dataset.map(formatting_prompts_func, batched = True)
##输出第一个问答
dataset["text"][0]

如下图,训练数据集加载成功:

img

##加载模训练
FastLanguageModel.for_training(model)

##获得lora微调容器
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_ratio for full training runs!        
        warmup_steps=5,        
        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",    
    ),
)

如下图,模型训练器创建成功:

img

##开始训练模型
trainer_stats = trainer.train()

由于时间有限,模型训练了60步。如下图使用开源医疗问答数据,训练完成:

img

##结束可视化训练过程
wandb.finish()

如下图,在wabdb网站上的可视化训练过程:

img

##测试微调效果
question = "一名 61 岁的女性在咳嗽或打喷嚏等活动中长期不自主排尿,但夜间没有渗漏,接受了妇科检查和棉签测试。基于这些发现,膀胱测压最有可能揭示她的残余体积和逼尿肌收缩的什么信息?"


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])

< think> 这个女性61岁,她咳嗽或者打喷嚏的时候不自主排尿,但夜间没有渗漏。看起来她有控制排尿的能力,不过在特定活动时就不能控制了。嗯,妇科检查和棉签测试的结果都很关键。我们先想想这些检查结果能告诉我们什么。 首先,妇科检查可能会有很多信息。嗯,可能是膀胱的容量或者是膀胱的结构有问题。然后,棉签测试啊,这个主要是用来测量膀胱的容量和收缩力的。通常,女性的膀胱容量可能会有些不同,所以测量的时候也要考虑个体差异。 再想想,膀胱测压通常有两种情况:一种是测量膀胱的容量,另一种是测量膀胱的收缩力。测量膀胱容量主要是为了确定膀胱的最大容量,这个信息对判断膀胱容量是否超出正常范围很重要。 不过,咳嗽或者打喷嚏的时候不自主排尿,这可能涉及膀胱的容量和收缩力。测量膀胱的容量能帮助我们了解在某种刺激下膀胱能容纳多少液体,而测量收缩力则能告诉我们膀胱在压力下能缩小多少。 嗯,测量膀胱的容量和收缩力,结合她的症状来看,测量膀胱的容量更能直接反映她在特定活动时的排尿控制能力。因为咳嗽或者打喷嚏的时候,她的膀胱容量可能不足以在不自主排尿的情况下维持。 哦,等一下,测量膀胱的容量是不是更能直接反映她在特定活动时的排尿控制能力呢?这听起来很合理。因为测量膀胱的容量可以直接告诉我们她在这种活动下膀胱能容纳多少液体。 嗯,总结一下,膀胱测压最有可能揭示她的残余体积和逼尿肌收缩的信息。嗯,测量膀胱容量更能直接反映她在特定活动时的排尿控制能力,毕竟她在咳嗽或者打喷嚏时会不自主排尿。 哦,没错,这就是我们需要的信息。所以,最终的结论应该是测量膀胱的容量是最有可能揭示她的残余体积和逼尿肌收缩的信息。 基于这位61岁女性的症状和检查结果,膀胱测压最有可能揭示的信息是她的膀胱容量。测量膀胱容量可以帮助判断在特定活动(如咳嗽或打喷嚏)时,膀胱能容纳多少液体,从而更直接地反映她在这种活动下排尿控制的能力。因此,测量膀胱的容量是最有可能揭示她残余体积和逼尿肌收缩的信息。<|end▁of▁sentence|>

综上:微调后的模型回答有改善。如果加大训练步数,结果会更理想。

3.保存微调(finetuning)后的模型

##保存模型
new_model_local = "DeepSeek-R1-Medical-Finetuned"
model.save_pretrained(new_model_local)
tokenizer.save_pretrained(new_model_local)

model.save_pretrained_merged("merged_models", tokenizer, save_method="merged_16bit")

DeepSeek无疑是2025开年AI圈的一匹黑马,在一众AI大模型中,DeepSeek以低价高性能的优势脱颖而出。DeepSeek的上线实现了AI界的又一大突破,各大科技巨头都火速出手,争先抢占DeepSeek大模型的流量风口。

DeepSeek的爆火,远不止于此。它是一场属于每个人的科技革命,一次打破界限的机会,一次让普通人也能逆袭契机。

DeepSeek的优点

read-normal-img

掌握DeepSeek对于转行大模型领域的人来说是一个很大的优势,目前懂得大模型技术方面的人才很稀缺,而DeepSeek就是一个突破口。现在越来越多的人才都想往大模型方向转行,对于想要转行创业,提升自我的人来说是一个不可多得的机会。

那么应该如何学习大模型

大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?”“谁的饭碗又将不保了?”等问题热议不断。

不如成为「掌握AI工具的技术人」,毕竟AI时代,谁先尝试,谁就能占得先机!

想正式转到一些新兴的 AI 行业,不仅需要系统的学习AI大模型。同时也要跟已有的技能结合,辅助编程提效,或上手实操应用,增加自己的职场竞争力。

大模型岗位需求越来越大,但是相关岗位人才难求,薪资持续走高,AI运营薪资平均值约18457元,AI工程师薪资平均值约37336元,大模型算法薪资平均值约39607元。

read-normal-img

掌握大模型技术你还能拥有更多可能性:

• 成为一名全栈大模型工程师,包括Prompt,LangChain,LoRA等技术开发、运营、产品等方向全栈工程;

• 能够拥有模型二次训练和微调能力,带领大家完成智能对话、文生图等热门应用;

• 薪资上浮10%-20%,覆盖更多高薪岗位,这是一个高需求、高待遇的热门方向和领域;

• 更优质的项目可以为未来创新创业提供基石。

可能大家都想学习AI大模型技术,也想通过这项技能真正达到升职加薪,就业或是副业的目的,但是不知道该如何开始学习,因为网上的资料太多太杂乱了,如果不能系统的学习就相当于是白学。为了让大家少走弯路,少碰壁,这里我直接把都打包整理好,希望能够真正帮助到大家。

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费在这里插入图片描述

👉AI大模型学习路线汇总👈

大模型学习路线图,整体分为7个大的阶段:(全套教程文末领取哈)

read-normal-img

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;
第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;
第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;
第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;
第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

👉大模型实战案例👈
光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。

read-normal-img

👉大模型视频和PDF合集👈
观看零基础学习书籍和视频,看书籍和视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。

read-normal-img

read-normal-img

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

read-normal-img

这份完整版的大模型 AI 学习资料已经上传优快云,朋友们如果需要可以微信扫描下方优快云官方认证二维码免费领取【保证100%免费在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值