基于ChatGLM-Med与HuaTuo的微调部署
如何基于领域知识对类ChatGPT模型进行微调,以提升类ChatGPT模型在领域的问答效果?有下面两个模型,一起来看看微调后的效果如何。: 基于中文医学知识的ChatGLM模型微调:基于中文医学知识的LLaMA微调模型。
如何基于中文医疗领域知识对类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
模型下载
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权重文件
##
推理过程
以基于医学知识库为例,修改 ./scripts/infer.sh 中的路径如下:
运行基于医学知识库的命令即可
bash ./scripts/infer.sh
其他几个类似:
#基于医学知识库
bash ./scripts/infer.sh
#基于医学文献
#单轮
bash ./scripts/infer-literature-single.sh
#多轮
bash ./scripts/infer-literature-multi.sh
微调过程
llama模型文件路径:/data/sim_chatgpt/llama-7b-hf/models–decapoda-research–llama-7b-hf/snapshots/5f98eefcc80e437ef68d457ad7bf167c2c6a1348
修改要运行文件中模型文件路径
vi scripts/finetune.sh
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
运行文件
sh scripts/finetune.sh
报错:显存不足
官方在一张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
模型文件下载:
该项目已经提供了训练微调好的模型参数,直接通过百度云盘链接或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)
运行报错
推理过程
python infer.py
解决办法
修改 modeling_chatglm.py 文件的831行,975行,如下:
MASK, gMASK = 150000, 150001
修改后成功运行
微调过程
安装evaluate包
pip install evaluate
pip install wandb
修改要运行文件中的model_name_or_path,修改为 /data/sim_chatgpt/chatglm-6b,如下:
vi scripts/sft_medchat.sh
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
执行命令
sh scripts/sft_medchat.sh
尝试调小batch_size,将per_device_train_batch_size改为1试下,仍然cuda of memory,放弃。
官方是在一张A100-SXM-80GB显卡上进行了微调训练,根据经验,训练显存建议选择32G及以上。
更多推荐
所有评论(0)