当前位置:   article > 正文

基于ChatGLM-Med与HuaTuo的微调部署_med-chatglm

med-chatglm


如何基于中文医疗领域知识对类ChatGPT模型进行微调,以提升类ChatGPT模型在中文医疗领域的问答效果?
哈工大使用中文医疗语料数据基于LLaMA和ChatGLM微调得到下面两个模型,一起来看看微调后的效果如何。
HuaTuo:基于中文医学知识的LLaMA微调模型
论文名称:HuaTuo: Tuning LLaMA Model with Chinese Medical Knowledge
论文地址: https://arxiv.org/pdf/2304.06975v1.pdf
ChatGLM-Med: 基于中文医学知识的ChatGLM模型微调

HuaTuo模型

在医疗领域,LLM模型(如LLaMa,ChatGLM)因为缺乏一定的医学专业知识语料而表现不佳。该项目通过医学知识图谱和GPT3.5API构建了中文医学指令数据集,并对LLaMa模型进行了指令微调得到了一个针对医学领域的智能问诊模型HuaTuo,相比于未经过医学数据指令微调的原LLaMa而言,HuaTuo模型在智能问诊层面表现出色,可生成一些更为可靠的医学知识回答;与此同时,基于相同医学数据,该项目还训练了医疗版本的ChatGLM模型: ChatGLM-6B-Med。

由于医疗领域专业知识太多,而LLMs的一般领域知识往往无法满足这种专业化需求,如果直接用于智能诊断,极有可能导致诊断精度、药品推荐和医疗建议等方面的不准确性,甚至危及患者的生命。所以,将专业的医学领域知识,诊断案例数据输入到大模型进行专业化学习非常有必要。

目前,已经有一些方法尝试解决这个问题,但这些方法主要依赖于从人工交流中检索医学信息,容易出现人为错误。此外,LLMs通常只在英语语境下进行训练,这限制了它们在其他语言环境下的理解和响应能力,例如中文,因此它们在中国语境中的应用受到极大限制。

现有的方法主要采用ChatGPT进行数据辅助:比如Chatdoctor代表了将LLMs在生物医学领域的第一次尝试,通过调用ChatGPT API来生成一些医学语料数据并叠加一部分真实场景医患数据,来微调LLaMa;为了解决中文语境问题,DoctorGLM利用ChatGLM-6B作为基础模型,并用ChatDoctor数据集的中文翻译通过ChatGPT获取进行微调。这些模型出来的效果只能说还行,但距离真实落地还很远。

该项目介绍了一种针对生物医学领域、专注于中文语言的LLM模型—HuaTuo(华驼)。为了保证模型在生物医学领域回答问题的准确性,研究人员通过从中文医学知识图谱CMeKG中提取相关的医学知识,生成多样的指令数据,以确保模型回答问题的事实正确性,并收集了超过8000条指令数据进行监督微调。该模型基于开源的LLaMa-7B基础模型,整合了CMeKG的结构化和非结构化医学知识,并利用基于知识的指令数据进行微调,使得模型具有较为丰富的医学领域专业知识,从而为智能诊断作出较为专业的回答。

模型选用

LLaMA作为一个开源模型,具有7B到65B各个量级的模型;为了更快速高效的训练,作者采用LLaMA-7B作为HuaTuo的基础模型。

医学知识

医学知识的种类包括:结构化医学知识和非结构化医学知识。结构化医学知识指的是医学知识图谱等形式化的知识,而非结构化医学知识则是如医学指南等的非形式化的知识。作者在这里使用了一个名为CMeKG的中文医学知识图谱,其中提供了关于疾病、药物、症状等的检索医学知识,目的是为了让大模型学习一些相关的专业医学知识。下表1展示了CMeKG知识库中的几个医学知识样例。
在这里插入图片描述

基于知识库的指令数据

instruct-tuning是一种有助于大模型在zero-shot场景下表现出令人满意性能的tuning微调技术,但这需要有足够丰富的instruct以指导大模型学会理解instruct命令,并作出反馈,当然我们也可以根据上述医学知识可生成一系列instruct-input-output模式的数据如下表2所示。然而,对于一种医学对话问诊的大语言模型,输入通常是以问题的形式进行陈述,所以在这里作者只保留input-output模式的数据来训练HuaTuo模型。
在这里插入图片描述
在一般领域,生成的指令需要具备足够的多样性,以应对未知任务zero-shot;而在医学领域,则更加关注大型语言模型响应中的事实是否正确。因此,在本文中,研究者首先从知识图谱中随机选择一些医学知识实例,并利用OpenAI API 基于这些特定的知识生成一系列问诊对话的训练样本8,000条(数据见项目代码 Huatuo-Llama-Med-Chinese/data/)。如下表3所示
在这里插入图片描述

评估指标

自然语言生成领域中常用的评估指标是Bleu和Rouge,作者在医疗问答任务中引入了新评估指标SUS,分别代表:安全性、可用性和流畅性。其中,安全性维度评估生成的响应是否存在误导用户、对用户健康构成危险的潜在因素,例如错误的药物建议;可用性维度评估生成的响应是否反映了医疗专业知识;流畅性维度则评估生成模型作为语言模型的能力。
在这项研究中,作者构建了一个中文对话场景的医疗问诊测试集,并将HuaTuo与其他三个基准模型进行了比较。为了评估模型性能,本项目招募了五名具有医学背景的专业医师,在SUS三个维度上评估模型的安全性、可用性和流畅性。SUS刻度从1(不可接受)到3(好),其中2表示可接受的响应。平均SUS得分如下表4所示。尽管LLaMA获得了最高的安全得分,但其响应常常缺乏信息且重述问题,导致可用性得分低。另一方面,HuaTuo模型显着提高了知识可用性,同时没有太多地牺牲安全性。
在这里插入图片描述

HuaTuo微调实战

使用模型:LLaMA-7B
所用微调数据集:医学知识图谱和GPT3.5 API构建的中文医学指令数据集

配置环境

创建新的 conda 环境:huatuo,并安装所需的包

conda create -n huatuo python==3.9
pip install -r requirements.txt
  • 1
  • 2

模型下载

LoRA权重可以通过百度网盘或Huggingface下载:

1、对LLaMA进行指令微调的LoRA权重文件
2、对Alpaca进行指令微调的LoRA权重文件。

我这里将文件下载的文件都放在:/data/sim_chatgpt/huatuo 下。
在这里插入图片描述

#1.对LLaMA进行指令微调的LoRA权重文件
#基于医学知识库
lora-llama-med/
  - adapter_config.json   # LoRA权重配置文件
  - adapter_model.bin   # LoRA权重文件

#基于医学文献
lora-llama-med-literature/
  - adapter_config.json   # LoRA权重配置文件
  - adapter_model.bin   # LoRA权重文件


#2. 对Alpaca进行指令微调的LoRA权重文件
#基于医学知识库
lora-alpaca-med-alpaca/
  - adapter_config.json   # LoRA权重配置文件
  - adapter_model.bin   # LoRA权重文件

#基于医学知识库和医学文献
lora-alpaca-med-alpaca-alldata/
  - adapter_config.json   # LoRA权重配置文件
  - adapter_model.bin   # LoRA权重文件
## 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

推理过程

以基于医学知识库为例,修改 ./scripts/infer.sh 中的路径如下:
在这里插入图片描述
运行基于医学知识库的命令即可

bash ./scripts/infer.sh
  • 1

在这里插入图片描述
其他几个类似:

#基于医学知识库
bash ./scripts/infer.sh

#基于医学文献
#单轮
bash ./scripts/infer-literature-single.sh

#多轮
bash ./scripts/infer-literature-multi.sh
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

微调过程

llama模型文件路径:/data/sim_chatgpt/llama-7b-hf/models–decapoda-research–llama-7b-hf/snapshots/5f98eefcc80e437ef68d457ad7bf167c2c6a1348
修改要运行文件中模型文件路径

vi scripts/finetune.sh
  • 1
exp_tag="e1"
python finetune.py \
    --base_model '/data/sim_chatgpt/llama-7b-hf/models--decapoda-research--llama-7b-hf/snapshots/5f98eefcc80e437ef68d457ad7bf167c2c6a1348' \
    --data_path './data/llama_data.json' \
    --output_dir './lora-llama-med-'$exp_tag \
    --prompt_template_name 'med_template' \
    --micro_batch_size 128 \
    --batch_size 128 \
    --wandb_run_name $exp_tag
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

运行文件

sh scripts/finetune.sh
  • 1

报错:显存不足
在这里插入图片描述
官方在一张A100-SXM-80GB显卡上进行了训练,训练总轮次10轮,耗时约2h17m。batch_size=128的情况下显存占用在40G左右。预计3090/4090显卡(24GB显存)以上显卡可以较好支持,根据显存大小来调整batch_size。

ChatGLM-Med

使用模型:ChatGLM-6B
所用微调数据集:医学知识图谱和GPT3.5 API构建的中文医学指令数据集。

环境准备:因为该项目使用的是ChatGLM-6B模型,因此环境也与ChatGLM-6B模型的环境一致,我这里之前微调过,所以直接使用chatglm-6b的conda环境。可以参考此文

文件准备:将项目和模型文件下载下来

git clone https://github.com/SCIR-HI/Med-ChatGLM.git
  • 1

模型文件下载:
该项目已经提供了训练微调好的模型参数,直接通过百度云盘链接Google云盘链接下载即可。

我这里将模型文件下载到 /data/sim_chatgpt/ChatGLM-Med/ 下。

修改 infer.py 文件中的文件加载路径,如下:

import torch
from transformers import AutoTokenizer, AutoModel
from modeling_chatglm import ChatGLMForConditionalGeneration
tokenizer = AutoTokenizer.from_pretrained(
    "/data/sim_chatgpt/ChatGLM-Med/", trust_remote_code=True)
model = ChatGLMForConditionalGeneration.from_pretrained(
    "/data/sim_chatgpt/ChatGLM-Med").half().cuda()
while True:
    a = input("请输入您的问题:(输入q以退出)")
    if a.strip() == 'q':
        exit()
    response, history = model.chat(tokenizer, "问题:" + a.strip() + '\n答案:', max_length=256, history=[])
    print("回答:", response)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

运行报错

推理过程

python infer.py
  • 1

在这里插入图片描述
解决办法
修改 modeling_chatglm.py 文件的831行,975行,如下:
MASK, gMASK = 150000, 150001

修改后成功运行
在这里插入图片描述

微调过程

安装evaluate包

pip install evaluate
pip install wandb
  • 1
  • 2

修改要运行文件中的model_name_or_path,修改为 /data/sim_chatgpt/chatglm-6b,如下:

vi scripts/sft_medchat.sh
  • 1
wandb online
exp_tag="chatglm_tuning"

python run_clm.py \
    --model_name_or_path /data/sim_chatgpt/chatglm-6b \
    --per_device_train_batch_size 8 \
    --per_device_eval_batch_size 8 \
    --train_file ./data/train.txt \
    --max_seq_length 256 \
    --output_dir ./output/ \
    --do_train \
    --logging_steps 30 \
    --log_file ./log/$exp_tag \
    --gradient_accumulation_steps 2 \
    --learning_rate 5e-5 \
    --group_by_length False \
    --num_train_epochs 3 \
    --lr_scheduler_type linear \
    --warmup_ratio 0.1 \
    --logging_dir ./log \
    --logging_steps 10 \
    --save_strategy epoch \
    --seed 2023 \
    --remove_unused_columns False \
    --torch_dtype auto \
    --adam_epsilon 1e-3 \
    --report_to wandb \
    --run_name $exp_tag
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

执行命令

sh scripts/sft_medchat.sh
  • 1

在这里插入图片描述
尝试调小batch_size,将per_device_train_batch_size改为1试下,仍然cuda of memory,放弃。

官方是在一张A100-SXM-80GB显卡上进行了微调训练,根据经验,训练显存建议选择32G及以上。

代码过程解读:https://zhuanlan.zhihu.com/p/631732569

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/558951
推荐阅读
相关标签
  

闽ICP备14008679号