參考了多個醫療大模型,如扁鵲、靈心等,重新思考了下微調的方案以及數據集的格式;基於ChatGLM/其它LLM整合多種微調方法的非官方實現的框架,審視其數據集格式,以及調試效果,進行微調。
最終基於liucongg/ChatGLM-Finetuning開源框架成功的微調出來我想要的結果。
服務器環境
阿里雲PAI平臺
開源庫下載
在服務器上通過git一鍵下載即可:
ChatGLM-6B下載
直接在服務器上,通過魔塔社區的sdk下載代碼一鍵下載即可:
我加了一句代碼打印出下載地址,然後通過mv
命令拷貝到指定路徑下。
#模型下載
from modelscope import snapshot_download
model_dir = snapshot_download('ZhipuAI/ChatGLM-6B')
print(model_dir)
指令數據集準備
數據集的格式嚴格參考開源庫的格式,這裏的格式直接參考/data/xxx.json
數據格式即可。
{"instruction": "一名年齡在70歲的女性,出現了暈厥、不自主顫抖、情緒不穩等症狀,請詳細說明其手術治療和術前準備。", "input": "", "output": "該病需要進行電極導線、脈衝發生器和永久心臟起搏器置入術,並需要使用鎮靜藥物和局麻對病人進行手術治療。術前準備包括1-3天的時間進行術前檢查和生活方式的調整。"}
{"instruction": "一個患者的卵巢小細胞癌轉移至其它部位,是否有必要進行手術治療?", "input": "", "output": "當卵巢小細胞癌轉移至其它部位時,手術治療的效果可能不理想,因此一般不推薦進行手術治療。針對轉移病竈,可以採用化療、放療等治療手段進行綜合治療。"}
{"instruction": "一位60歲男性患者由於肝動脈瘤出現肝功能異常,具體表現爲黃疸,該如何診治?", "input": "", "output": "該患者可能出現了肝動脈瘤併發症之一的梗阻性黃疸,需要進行腹部平片、彩色多普勒超聲、CTA、動脈造影等檢查後確定診斷,治療方面應按照病因治療,如若爲肝動脈炎、動脈粥樣硬化等病因,應該採取手術治療,而若是單純的肝動脈瘤,可以進行介入治療或手術治療。"}
{"instruction": "患者男,28歲,關節部位紅腫疼痛,排尿困難,近期有過微生物感染史。請問可能患的是什麼疾病?如何治療?", "input": "", "output": "可能患有反應性關節炎。治療方案可以採用沙利度胺、潑尼松等藥物。同時還要注意休息和飲食。"}
{"instruction": "一名患者因腹脹、納差等症狀就診,檢查發現肝大、腹水及肝功能損害,診斷爲肝澱粉樣變性,請問該患者應該接受哪些治療方案?", "input": "", "output": "該患者應該接受瀰漫性系膜硬化、苯丙氨酸氮芥等治療方案。"}
{"instruction": "治療方法上有何不同", "input": "", "output": "急性非ST段擡高型心肌梗死的治療主要是通過改善生活方式和控制危險因素來預防,緊急情況下可能需要靜脈注射血栓溶解藥物;而自身免疫性肝炎的治療則包括藥物治療和手術治療,如激素、免疫抑制劑、肝移植等"}
{"instruction": "一位中年男性感染了軍團桿菌,導致出現了瀰漫性血管內凝血、充血性心力衰竭等併發症,應該怎樣進行輔助檢查和診斷?", "input": "", "output": "首先應該做特殊實驗室檢查和血常規和生化檢查,進一步的輔助診斷可考慮X線檢查,X線胸片檢查、化驗檢查、血清學檢查以及實驗室檢查等方法。"}
{"instruction": "膽管癌和偏頭痛的主要症狀有何區別?", "input": "", "output": "膽管癌的主要症狀包括黃疸、肝腫大等消化系統症狀,而偏頭痛的主要症狀是頭部疼痛。"}
{"instruction": "胡女士出現了黃疸、噁心、嘔吐等症狀,可能患了什麼疾病?", "input": "", "output": "胡女士可能患有膽道張力低下綜合徵。建議儘快到內科進行檢查,並進行西醫和中醫治療。"}
{"instruction": "一位妊娠31周孕婦在家中自行服用草藥,隨後出現嘔吐、腹痛、噁心、疲勞、皮膚瘙癢、黃疸等症狀,血液檢查顯示血清轉氨酶升高,交叉免疫電泳檢測顯示未見明顯異常。 ", "input": "", "output": "可能是由於在未諮詢醫生的情況下自行服用草藥導致的急性妊娠期肝內膽汁淤積症。建議及時就醫,如需緊急治療可在醫生指導下使用膽酸螯合劑、皮質激素等藥物,並密切監測胎兒狀態與身體其他部位不適情況。"}
開始訓練,按文檔準備好腳本 run.sh;根據自己的服務器卡數選擇即可,修改模型路徑,數據集參數即可。
腳本內容:
生成的文件:
合併Lora參數文件
需要將Lora微調後的參數文件與原模型參數文件合併,執行腳本即可。
python merge_lora.py
當然要替換下里面的路徑參數。最終生成的參數文件:
推理
執行腳本predict.py文件即可,但裏面的代碼有些問題,用修改後的即可,同樣需要修改路徑參數
# -*- coding:utf-8 -*-
# @project: ChatGLM-Finetuning
# @filename: predict
# @author: 劉聰NLP
# @zhihu: https://www.zhihu.com/people/LiuCongNLP
# @contact: [email protected]
# @time: 2023/12/6 20:41
"""
文件說明:
"""
import argparse
import torch
from model import MODE
import os
# 啓用CUDA
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
def parse_args():
parser = argparse.ArgumentParser()
# Model
parser.add_argument("--device", type=str, default="0", help="")
parser.add_argument("--mode", type=str, default="glm", help="")
parser.add_argument("--model_path", type=str, default="/mnt/workspace/demos/ChatGLM-Finetuning/output-glm/epoch-2-step-262", help="")
parser.add_argument("--max_length", type=int, default=500, help="")
parser.add_argument("--do_sample", type=bool, default=True, help="")
parser.add_argument("--top_p", type=float, default=0.8, help="")
parser.add_argument("--temperature", type=float, default=0.8, help="")
return parser.parse_args()
def predict_one_sample(instruction, input, model, tokenizer, args):
result, _ = model.chat(tokenizer, instruction + input, max_length=args.max_length, do_sample=args.do_sample,
top_p=args.top_p, temperature=args.temperature)
return result
if __name__ == '__main__':
args = parse_args()
model = MODE[args.mode]["model"].from_pretrained(args.model_path, device_map="auto",
torch_dtype=torch.float16)
tokenizer = MODE[args.mode]["tokenizer"].from_pretrained(args.model_path)
instruction = "一位年輕女性患者出現了風團性斑塊、丘疹等症狀,請問此病可以由哪些科室進行治療?"
input = ""
r = predict_one_sample(instruction, input, model, tokenizer, args)
print(r)
返回結果:
總結
liucongg/ChatGLM-Finetuning開源庫提供了Lora指令微調的方式,其邏輯主要還是編寫了一套新的train代碼,支持指令的微調。