扁鹊(BianQue)

华南理工大学开源中文主动健康大模型扁鹊(BianQue),包含 BianQue-1.0 与 BianQue-2.0 两个版本。该模型基于千万级健康对话大数据构建,核心创新在于引入“询问链”机制,模拟医生多轮问诊过程,解决用户描述不清的问题。BianQue-1.0 基于 ChatYuan 微调,强化问询能力;BianQue-2.0 基于 ChatGLM-6B,增强建议与知识查询能力。项目提供完整的代码部署、API 调用及微调教程,适用于慢性病管理、心理咨询等主动健康场景的研究与应用。


基于主动健康的主动性、预防性、精确性、个性化、共建共享、自律性六大特征,华南理工大学未来技术学院 - 广东省数字孪生人重点实验室开源了中文领域生活空间主动健康大模型基座 ProactiveHealthGPT。
我们期望,生活空间主动健康大模型基座 ProactiveHealthGPT 可以帮助学术界加速大模型在慢性病、心理咨询等主动健康领域的研究与应用。本项目为 生活空间健康大模型扁鹊(BianQue)。
我们经过调研发现,在健康领域,用户通常不会在一轮交互当中清晰地描述自己的问题,而当前常见的开源医疗问答模型(例如:ChatDoctor、本草 (HuaTuo)、DoctorGLM、MedicalGPT-zh)侧重于解决单轮用户描述的问题,而忽略了'用户描述可能存在不足'的情况。哪怕是当前大火的 ChatGPT 也会存在类似的问题:如果用户不强制通过文本描述让 ChatGPT 采用一问一答的形式,ChatGPT 也偏向于针对用户的描述,迅速给出它认为合适的建议和方案。然而,实际的医生与用户交谈往往会存在'医生根据用户当前的描述进行持续多轮的询问'。并且医生在最后根据用户提供的信息综合给出建议,如下图所示。我们把医生不断问询的过程定义为 询问链(CoQ, Chain of Questioning),当模型处于询问链阶段,其下一个问题通常由对话上下文历史决定。

我们结合当前开源的中文医疗问答数据集(MedDialog-CN、IMCS-V2、CHIP-MDCFNPC、MedDG、cMedQA2、Chinese-medical-dialogue-data),分析其中的单轮/多轮特性以及医生问询特性,结合实验室长期自建的生活空间健康对话大数据,构建了千万级别规模的扁鹊健康大数据 BianQueCorpus。对话数据通过'病人:xxx\n 医生:xxx\n 病人:xxx\n 医生:'的形式统一为一种指令格式,如下图所示。

input: "病人:六岁宝宝拉大便都是一个礼拜或者 10 天才一次正常吗,要去医院检查什么项目\n 医生:您好\n 病人:六岁宝宝拉大便都是一个礼拜或者 10 天才一次正常吗,要去医院检查什么项目\n 医生:宝宝之前大便什么样呢?多久一次呢\n 病人:一般都是一个礼拜,最近这几个月都是 10 多天\n 医生:大便干吗?\n 病人:每次 10 多天拉的很多\n 医生:"
target: "成形还是不成形呢?孩子吃饭怎么样呢?"
训练数据当中混合了大量 target 文本为医生问询的内容而非直接的建议,这将有助于提升 AI 模型的问询能力。
cd ~
git clone https://github.com/scutcyr/BianQue.git
需要注意的是 torch 的版本需要根据你的服务器实际的 cuda 版本选择,详情参考 pytorch 安装指南。
cd BianQue
conda env create -n proactivehealthgpt_py38 --file proactivehealthgpt_py38.yml
conda activate proactivehealthgpt_py38
pip install cpm_kernels
pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116
补充:Windows 下的用户推荐参考如下流程配置环境
cd BianQue
conda create -n proactivehealthgpt_py38 python=3.8
conda activate proactivehealthgpt_py38
pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116
pip install -r requirements.txt
pip install rouge_chinese nltk jieba datasets
# 以下安装为了运行 demo
pip install streamlit
pip install streamlit_chat
【补充】Windows 下配置 CUDA-11.6:下载并且安装 CUDA-11.6、下载 cudnn-8.4.0,解压并且复制其中的文件到 CUDA-11.6 对应的路径。
在 Python 当中调用 BianQue-2.0 模型:
import torch
from transformers import AutoModel, AutoTokenizer
# GPU 设置
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
# 加载模型与 tokenizer
model_name_or_path = 'scutcyr/BianQue-2'
model = AutoModel.from_pretrained(model_name_or_path, trust_remote_code=True).half()
model.to(device)
tokenizer = AutoTokenizer.from_pretrained(model_name_or_path, trust_remote_code=True)
# 单轮对话调用模型的 chat 函数
user_input = "我的宝宝发烧了,怎么办?"
input_text = "病人:" + user_input + "\n 医生:"
response, history = model.chat(tokenizer, query=input_text, history=None, max_length=2048, num_beams=1, do_sample=True, top_p=0.75, temperature=0.95, logits_processor=None)
# 多轮对话调用模型的 chat 函数
# 注意:本项目使用"\n 病人:"和"\n 医生:"划分不同轮次的对话历史
# 注意:user_history 比 bot_history 的长度多 1
user_history = ['你好', '我最近失眠了']
bot_history = ['我是利用人工智能技术,结合大数据训练得到的智能医疗问答模型扁鹊,你可以向我提问。']
# 拼接对话历史
context = "\n".join([f"病人:{user_history[i]}\n 医生:{bot_history[i]}" for i in range(len(bot_history))])
input_text = context + "\n 病人:" + user_history[-1] + "\n 医生:"
response, history = model.chat(tokenizer, query=input_text, history=None, max_length=2048, num_beams=1, do_sample=True, top_p=0.75, temperature=0.95, logits_processor=None)
本项目提供了 bianque_v2_app.py 作为 BianQue-2.0 模型的使用示例,通过以下命令即可开启服务,然后,通过 http://<your_ip>:9005 访问。
streamlit run bianque_v2_app.py --server.port 9005
特别地,在 bianque_v2_app.py 当中,可以修改以下代码更换指定的显卡:
os.environ['CUDA_VISIBLE_DEVICES'] = '1'
对于 Windows 单显卡用户,需要修改为:os.environ['CUDA_VISIBLE_DEVICES'] = '0',否则会报错!
可以通过更改以下代码指定模型路径为本地路径:
model_name_or_path = "scutcyr/BianQue-2"
我们还提供了 bianque_v1_app.py 作为 BianQue-1.0 模型的使用示例,以及 bianque_v1_v2_app.py 作为 BianQue-1.0 模型和 BianQue-2.0 模型的联合使用示例。
基于扁鹊健康大数据 BianQueCorpus,我们选择了 ChatGLM-6B 作为初始化模型,经过全量参数的指令微调训练得到了新一代 BianQue【BianQue-2.0】。与扁鹊 -1.0 模型不同的是,扁鹊 -2.0 扩充了药品说明书指令、医学百科知识指令以及 ChatGPT 蒸馏指令等数据,强化了模型的建议与知识查询能力。以下为两个测试样例。


通过以下命令实现联合使用扁鹊 -2.0 与扁鹊 -1.0 构建主动健康服务:
streamlit run bianque_v1_v2_app.py --server.port 9005
以下为应用例子:前面若干轮为经过扁鹊 -1.0 模型进行问询的过程,最后一轮回复为经过扁鹊 -2.0 模型的回答。

扁鹊 -1.0(BianQue-1.0)是一个经过指令与多轮问询对话联合微调的医疗对话大模型。我们经过调研发现,在医疗领域,往往医生需要通过多轮问询才能进行决策,这并不是单纯的'指令 - 回复'模式。用户在咨询医生时,往往不会在最初就把完整的情况告知医生,因此医生需要不断进行询问,最后才能进行诊断并给出合理的建议。基于此,我们构建了扁鹊 -1.0(BianQue-1.0),拟在强化 AI 系统的问询能力,从而达到模拟医生问诊的过程。我们把这种能力定义为'望闻问切'当中的'问'。综合考虑当前中文语言模型架构、参数量以及所需要的算力,我们采用了 ClueAI/ChatYuan-large-v2 作为基准模型,在 8 张 NVIDIA RTX 4090 显卡上微调了 1 个 epoch 得到扁鹊 -1.0(BianQue-1.0),用于训练的中文医疗问答指令与多轮问询对话混合数据集包含了超过 900 万条样本,这花费了大约 16 天的时间完成一个 epoch 的训练。我们将计划围绕扁鹊模型的'望闻问切'能力,结合医学专家知识、多模态技术、多生理信号计算等,进行多个版本的模型迭代研究。
'望闻问切'四诊法由扁鹊发明。'四诊法'(望、闻、问、切),是中医诊病的基本方法。其中,'问'的能力可以被建模到语言模型当中。我们把 AI 模型的'问'能力定义为: '问'能力:AI 模型能够根据病人输入的信息,结合医学知识来进行恰当的问询,并且结合进一步的问询得到的病人的信息,给出'合适的诊断或建议'。'问'的过程通常是一个多轮对话过程。
以下是 2 个简单的例子:
例子 1 用户:我最近感觉全身疲惫 扁鹊 -1.0:是劳累了,还是熬夜了? 用户:这周都在熬夜赶论文 扁鹊 -1.0:嗯,熬夜容易引起各种不适,如头晕、乏力、失眠、多梦等,多休息,可以口服谷维素、维生素 B1 和安神补脑液,避免熬夜。
例子 2 用户:我最近经常失眠 扁鹊 -1.0:失眠多久了? 用户:两周了 扁鹊 -1.0:睡眠怎么样? 用户:上床几小时才睡得着 扁鹊 -1.0:可以口服一些药物 用户:有具体推荐吗 扁鹊 -1.0:需要先检查一下 用户:那我需要做什么检查? 扁鹊 -1.0:心电图
import os
from transformers import T5Tokenizer, T5ForConditionalGeneration, AutoTokenizer
import torch
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
tokenizer = T5Tokenizer.from_pretrained("scutcyr/BianQue-1.0")
model = T5ForConditionalGeneration.from_pretrained("scutcyr/BianQue-1.0")
model = model.to(device)
def preprocess(text):
text = text.replace("\n", "\\n").replace("\t", "\\t")
return text
def postprocess(text):
return text.replace("\\n", "\n").replace("\\t", "\t")
def answer(user_history, bot_history, sample=True, top_p=1, temperature=0.7):
'''sample:是否抽样。生成任务,可以设置为 True;
top_p:0-1 之间,生成的内容越多样
max_new_tokens=512 lost...'''
if len(bot_history)>0:
context = "\n".join([f"病人:{user_history[i]}\n 医生:{bot_history[i]}" for i in range(len(bot_history))])
input_text = context + "\n 病人:" + user_history[-1] + "\n 医生:"
else:
input_text = "病人:" + user_history[-1] + "\n 医生:"
return "我是利用人工智能技术,结合大数据训练得到的智能医疗问答模型扁鹊,你可以向我提问。"
input_text = preprocess(input_text)
print(input_text)
encoding = tokenizer(text=input_text, truncation=True, padding=True, max_length=768, return_tensors="pt").to(device)
if not sample:
out = model.generate(**encoding, return_dict_in_generate=True, output_scores=False, max_new_tokens=512, num_beams=1, length_penalty=0.6)
else:
out = model.generate(**encoding, return_dict_in_generate=True, output_scores=False, max_new_tokens=512, do_sample=True, top_p=top_p, temperature=temperature, no_repeat_ngram_size=3)
out_text = tokenizer.batch_decode(out["sequences"], skip_special_tokens=True)
print('医生:'+postprocess(out_text[0]))
return postprocess(out_text[0])
answer_text = answer(user_history=["你好!",
"我最近经常失眠",
"两周了",
"上床几小时才睡得着"],
bot_history=["我是利用人工智能技术,结合大数据训练得到的智能医疗问答模型扁鹊,你可以向我提问。",
"失眠多久了?",
"睡眠怎么样?"])
conda env create -n bianque_py38 --file py38_conda_env.yml
conda activate bianque_py38
pip install torch==1.13.1+cu116 torchvision==0.14.1+cu116 torchaudio==0.13.1 --extra-index-url https://download.pytorch.org/whl/cu116
数据集构建 参考.data/cMedialog_example.csv 格式,构建你的数据集
基于扁鹊 -1.0 模型微调你的模型 修改./scripts/run_train_model_bianque.sh,通过绝对路径指定 PREPROCESS_DATA,并且调整其他变量,然后运行:
cd scripts
bash run_train_model_bianque.sh
扁鹊 -1.0(BianQue-1.0)当前仅经过 1 个 epoch 的训练,尽管模型具备了一定的医疗问询能力,但其仍然存在以下局限:
**扁鹊 -2.0(BianQue-2.0)**使用了 ChatGLM-6B 模型的权重,需要遵循其 MODEL_LICENSE。
本项目开源的扁鹊系列模型旨在推动主动健康领域的智能化发展。通过引入多轮问询机制,模型能够更贴近真实医生的诊疗逻辑,有效弥补了传统单轮问答模型在信息获取上的不足。BianQue-1.0 专注于强化'问'的能力,模拟医生问诊过程;BianQue-2.0 则在基础之上增强了知识查询与建议生成能力,并结合药品说明书等指令数据提升了专业度。
未来,团队计划围绕扁鹊模型的'望闻问切'能力体系,结合医学专家知识、多模态技术及多生理信号计算,持续进行模型迭代。这不仅有助于提升 AI 在慢性病管理、心理咨询等场景的应用效果,也为学术界提供了可复现的主动健康大模型基座,助力相关研究的加速开展。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online