基於主動健康的主動性、預防性、精確性、個人化、共建共享、自律性六大特徵,華南理工大學未來技術學院-廣東省數位孿生人重點實驗室開源了中文領域生活空間主動健康大模型基座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。對話資料透過「病人:xxxn醫師:xxxn病人:xxxn醫師:」的形式統一為一種指令格式,如下圖所示。
input: "病人:六岁宝宝拉大便都是一个礼拜或者10天才一次正常吗,要去医院检查什么项目n医生:您好n病人:六岁宝宝拉大便都是一个礼拜或者10天才一次正常吗,要去医院检查什么项目n医生:宝宝之前大便什么样呢?多久一次呢n病人:一般都是一个礼拜,最近这几个月都是10多天n医生:大便干吗?n病人:每次10多天拉的很多n医生:"
target: "成形还是不成形呢?孩子吃饭怎么样呢?"
訓練資料當中混合了大量target文字為醫生問詢的內容而非直接的建議,這將有助於提升AI模型的問詢能力。
cd ~
git clone https://github.com/scutcyr/BianQue.git
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
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對應的路徑,參考:win11下利用conda進行pytorch安裝-cuda11. 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的訓練。我們將規劃圍繞扁鵲模型的「望聞問切」能力,結合醫學專家知識、多模態技術、多生理訊號計算等,進行多個版本的模型迭代研究。扁鵲(BianQue)模型歡迎你的貢獻!我們鼓勵你在BianQue GitHub 頁面報告問題、貢獻PR 並參與討論。我們期待與更多的大學、醫院、研究實驗室、公司等合作,共同進行下一代扁鵲模型研究。對於此類需求(以及其他不適合在GitHub 上提出的需求),請直接發送電子郵件至[email protected]。
「望聞問切」四診法由扁鵲發明。 「四診法」(望、聞、問、切),是中醫診病的基本方法。其中,「問」的能力可以被建模到語言模型當中。我們把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
cd scripts
bash run_train_model_bianque.sh
扁鵲-1.0(BianQue-1.0)目前僅經過1個epoch的訓練,儘管模型具備了一定的醫療問詢能力,但其仍然存在以下限制:
**扁鵲-2.0(BianQue-2.0)**使用了ChatGLM-6B 模型的權重,需要遵循其MODEL_LICENSE,因此,本專案僅可用於您的非商業研究目的。
本計畫由華南理工大學未來技術學院廣東省數位孿生人重點實驗室發起,得到了華南理工大學資訊網路工程研究中心、電子與資訊學院等學院部門的支撐,同時致謝廣東省婦幼保健院、廣州市婦女兒童醫療中心、中山大學附設第三醫院、合肥綜合國家科學中心人工智慧研究院等合作單位。
同時,我們感謝以下媒體或公眾號對本項目的報導(排名不分先後):
媒體通報人民日報、中國網、光明網、TOM科技、未來網、大眾網、中國發展報道網、中國日報網、新華資訊網、中華網、今日頭條、搜狐、騰訊新聞、網易新聞、中國資訊網、中國傳播網、中國都市報道網、中華城市網
公眾號廣東實驗室建置、智慧語音新青年、深度學習與NLP、AINLP
@misc { chen2023bianque ,
title = { BianQue: Balancing the Questioning and Suggestion Ability of Health LLMs with Multi-turn Health Conversations Polished by ChatGPT } ,
author = { Yirong Chen and Zhenyu Wang and Xiaofen Xing and huimin zheng and Zhipei Xu and Kai Fang and Junhong Wang and Sihang Li and Jieling Wu and Qi Liu and Xiangmin Xu } ,
year = { 2023 } ,
eprint = { 2310.15896 } ,
archivePrefix = { arXiv } ,
primaryClass = { cs.CL }
}