​​​今天是9月3日,星期日,北京,天气晴,我们来切入正题。

昨天社区提了一个有趣的问题【关注落地】,典型的多轮继承和语义漂移问题【大模型在长文本上表现并不是特别好,之前有个工作介绍,大模型会重两头轻中间】:

“多轮对话中retrieval怎么做?目前对话开始的第一个问题我们直接用retrieval + model 生成结果,但是有时候用户会问更细节的问题,并且使用到了一些的context,比如 "那么如何配置呢"? 其实单独拿这句话检索是基本无效的,如何改写问题,retrieval的key是什么”

大家想到的实际上是rewrite的思想:


做个revise question,会把前几轮的对话给LLM,告诉他我们需要把问题表述的更清楚以利于检索答案,让LLM重新生成一个。同时LLM还可以输出这个问题的Keywords和Intent分类,也利于下游任务执行。


而上面说的实际上是在用户输入尾部上做的一个优化,通过改写,而其实,也可以使用基于关键词的方法来充当用户query和文档之间相似度匹配的桥梁,最近一些实验也表明,直接使用现有开源大模型进行生成式关键词抽取也在某种程度上奏效


而最近又有一个新的心得,在现有的RAG策略上,加入文档格式解析、文档内容抽取的逻辑,也是社区讲过的讲文档智能+知识图谱+LLM的行业落地策略,整个图画的不错(早上看一个项目,https://github.com/yuanjie-ai/ChatLLM,同样的思路

虽然说langchain中已经对一些文档有了支撑,比如pdf、latex等,但其针对单双栏、表格、图片等信息的表示,并没有处理逻辑,我们可以通过融合ppstructure等逻辑进行处理,也就是说knowledgebase之前,加入一个parser的逻辑。

上面说的是文档问答的事情,现在我们来看看知识图谱在整个方案中所能承担的角色,我们在之前的文章中已经说了多次,如何基于知识图谱来辅助大模型问答,在数据方面进行处理是一个重要突破口。

因此,本文主要介绍了三种目前常见的基于知识图谱生成问答对的方案,包括基于两步骤生成知识图谱QA对:DISC-MedLLM、实体为中心的自指令微调数据扩充方法:ShenNong-TCM-LLM以及知识图谱转换指令(KG2Instructions)方法:DeepKE-LLM。

其内部实现原理很有借鉴意义,供大家一起参考。

一、基于两步骤生成知识图谱QA对:DISC-MedLLM

DISC-MedLLM是一个专门针对医疗健康对话式场景而设计的医疗领域大模型。为了构建高质量的监督微调(SFT)数据集,采用了利用医学知识图谱、重建真实世界对话以及结合人类指导的偏好重述三种策略进行生成。

地址:https://github.com/FudanDISC/DISC-MedLLM

1、知识图谱数据

医学知识图谱包含大量条理清晰的医学专业知识,在此基础上生成QA训练样本,可以获得与真实世界样本相比噪声极低的数据,基于包含10k多种疾病、近20k种药物和10k多种症状的中医知识图谱构建了QA对,采用中文医学知识图谱CMeKG作为数据集。

CMeKG(Chinese Medical Knowledge Graph)是利用自然语言处理与文本挖掘技术,基于大规模医学文本数据,以人机结合的方式研发的中文医学知识图谱。

样例如下:

"triples": [
   [
    "新冠肺炎",
    "临床表现",
    "肺炎"
   ],
   [
    "新冠肺炎",
    "临床表现",
    "发热"
   ],
   [
    "新冠肺炎",
    "临床表现",
    "咳嗽"
   ],
   [
    "新冠肺炎",
    "临床表现",
    "胸闷"
   ],
   [
    "新冠肺炎",
    "临床表现",
    "乏力"
   ],
   [
    "新冠肺炎",
    "病因",
    "自身免疫系统缺陷"
   ],
   [
    "新冠肺炎",
    "病因",
    "人传人"
   ]
  ]

以疾病为中心,根据疾病节点的科室信息对知识图谱进行采样,遵循原始MedDialog数据中的科室分布,通过两个步骤获得QA对。

2、将知识图谱转为自然语言QA对

首先,利用GPT-3.5m首先将抽样知识转化为简单的自然语言QA对。将疾病相关的知识信息提供给GPT-3.5,并将其转换为"结构、知识"格式的自然语言表示。

核心的prompt很简单:

根据给出的疾病相关关系信息input,生成1到8个医疗场景下json格式的<指令,知识>的二元对,注意提供的信息中的几个字段,例如别名,你生成指令时可以使用。

当然,这里指定json格式进行生成约定,并给出一些额外的约束条件,比如多样性:

2、基于知识问答对生成单轮对话

其次,基于这些简单的QA对,GPT-3.5将其转换为医疗场景中的单轮对话,增强对话的多样性和语言表达的丰富性。

核心的prompt要求根据上一部生成的<指令,知识>二元对,生成合理对话。

根据每个<指令,知识>信息生成一个医疗场景对话,这些对话是相互独立的。你要根据指令去构造出一人问题或请求问题或请求由多种可能的询问者给出,其可以是病人、病人的家属、专业从业者、医生等等,你构造的问题应该能脱离原指令独立存在,也就是说完整的表述了理解问题所需的上下文信息。你要利用指令知识构造一人合理的对话。假设你是一个专业的ai医疗助手(doctor),你应该根据提供的<指令,知识>信息和你自己的知识回答询问者的疑问,回答不要过短。

二、实体为中心的自指令微调数据扩充方法:ShenNong-TCM-LLM

为推动LLM在中医药领域的发展和落地,提升LLM的在中医药方面的知识与回答医学咨询的能力,同时推动大模型赋能中医药传承,推出ShenNong中医药大规模语言模型。

模型基座上,以LlaMA为底座,采用LoRA (rank=16)微调得到。基于训练数据为中医药指令数据集ShenNong_TCM_Dataset。

在训练数据构造上,垂直领域相较于通用领域的不同之处在于其一般是知识密集性的,而这些知识一般是围绕一些实体的。所以,我们提出实体为中心的自指令方法entity-centric self-instruct,即围绕垂直领域中的核心实体,以及各种不同的意图场景,进行指令的生成,调用ChatGPT得到11w+的围绕中医药的指令数据。

这个entity-centric self-instruct来源于self-instruct,原始的版本是以主题和领域为核心,生成一些主题/技能或者领域上的promt。比如:

一般的system_prompt,目标是涵盖各个主题领域:topic_list

system_prompt += "1. 主题多样化,涵盖各个领域,例如:" + "、".join(random.sample(topic_list, 10)) + "等。\n"

entity-centric self-instruct则要求,其涵盖不同的实体:entity_list

system_prompt += "1. 主题多样化,涵盖不同的中医实体,例如:" + "、".join(random.sample(entity_list, 10)) + "等。\n"

我们可以从中提供的prompt构造方式上来看其实现细节,其实际上就是使用了知识图谱的实体名称:

def return_random_prompt(kg_file=None):
    system_prompt = "你需要尽可能给出多样化的,与中医(中国传统医学),中药等相关的,任务指令和对应的回答。我们将用于人工评估ChatGPT模型对指令的完成情况。要求:\n" 
    # generate random topics
    entity_list = []
    with open(kg_file, "r", encoding="utf-8") as f:
        for line in f:
            line = line.strip().split(" ")
            for w in line:
                w = w.strip()
                if "symmap_chemical" in w:
                    continue
                if "chemical_" in w:
                    continue
                if "SMIT" in w:
                    continue
                entity_list.append(w)
    # system_prompt += "1. 主题多样化,涵盖各个领域,例如:" + "、".join(random.sample(topic_list, 10)) + "等。\n"
    system_prompt += "1. 主题多样化,涵盖不同的中医实体,例如:" + "、".join(
        random.sample(entity_list, 10)
    ) + "等。\n"
    # generate random tasks
    task_list = ["开放式生成""分类""问答""编辑""摘要",
                 "写作""分析""常识推理""写文献",
                 "抽取""推荐""问诊""文献标题生成""诊断""方剂推荐""治疗推荐"]
    system_prompt += "2. 表述多样化,结合真实问题;指令类型多样化,例如:" + "、".join(random.sample(task_list, 10)) + "等。\n"
    # other requirements
    system_prompt += "3. 如果遇到无法处理的指令(只靠文本无法回答),给出无法处理的回复。\n"
    system_prompt += "4. 除非特别要求,请使用中文,指令可以是命令句、疑问句、或其他合适的类型。\n"
    system_prompt += "5. 为指令生成一个适当且涉及真实情况的<input>,不应该只包含简单的占位符。<input>应提供实质性的内容,具有挑战性。字数不超过" + str(
        random.randint(80, 120)) + "字。\n"
    system_prompt += "6. <output>应该是对指令的适当且真实的回应,不能只回复答应或拒绝请求。如果需要额外信息才能回复时,请努力预测用户意图并尝试回复。<output>的内容应少于" + str(512) + "字。\n\n"
    system_prompt += "请给出满足条件的5条JSON格式数据:\n"
    return system_prompt

其中,涉及到的中医知识图谱为TCM_KG,:https://github.com/ywjawmw/TCM_KG为基础进行构建,图谱数据样例为:

喜热饮 胃中虚火证 证候
病在肛门外肿突而硬 初发期 证候
腹痛 心经积热证 证候
水红花子 SMIT13500 symmap_chemical
槲寄生 SMIT01519 symmap_chemical
SMIT16807 Liver Tender chemical_MM
当归 SMIT05129 symmap_chemical
SMIT10590 Cough Nonproductive chemical_MM
高热烦渴 热毒炽盛证 证候
SMIT05979 Sharp Headache chemical_MM
艾叶 SMIT05580 symmap_chemical
檀香 SMIT15645 symmap_chemical
花椒 SMIT00086 symmap_chemical
拒按 气滞血瘀证 证候
辣椒 SMIT05174 symmap_chemical
SMIT11035 Abdomen Discomfort chemical_MM
SMIT12696 Common Cold chemical_MM
肠道热盛 肠道实热证 证候
反应迟钝 寒盛阳衰证 证候
疲乏 血瘀 证候
干姜 SMIT00507 symmap_chemical
骨碎补 SMIT10266 symmap_chemical
苔薄黄 阴虚火炎证 证候
阳痿 仙茅 中药
马兜铃 SMIT13155 symmap_chemical
SMIT11873 Bronchial Asthma chemical_MM
瞿麦 SMIT02387 symmap_chemical

形成的知识图谱neo4j如下:

最终形成的微调数据如下:

{
    "query""患者出现半身不遂症状,没有其他症状。请推荐中药。要求:1. 请考虑所有症状。2. 请根据输出一步步的推理过程。",
    "response""感谢您的提问。根据您提供的信息,患者出现了半身不遂症状,没有其他症状。这种情况可能是由于脑血管疾病引起的,因此,我会基于这个症状推荐一些中药。\n\n首先,我们需要了解患者症状的具体表现,例如
  是左侧或右侧不遂,上肢或下肢不遂等等。这些信息可以帮助我们确定病变的位置。\n\n其次,我们需要考虑患者的体质和病史,例如是否存在高血压、高血脂、糖尿病等慢性疾病。这些病史可能影响治疗方案的选择。\n\n在了解完这些信息之后,我们可以考虑以下中药:\n\n1. 通络活血类中药:如桃仁、红花、川芎、丹参等。这类中药可以促进血液循环,舒展血管,从而改善半身不遂症状。\n\n2. 祛风化痰类中药:如天麻、钩藤、白芍、半夏等。这类中药可以缓解病情,减轻症状,特别是对于因风痰阻塞引起的不遂症状更为有效。\n\n3. 补肾益气类中药:如枸杞子、黄精、淫羊藿、菟丝子等。这类中药可以增强身体的免疫力,提高机体的抗病能力,对于慢性病史较长的患者有一定的帮助。\n\n需要注意的是,中药的选择需要考虑具体情况,因此建议患者在就医前咨询专业医生的意见。同时,中药治疗需要长期坚持,不能轻易停药,否则可能会导致病情反复。"

}

地址:https://github.com/michael-wzhu/ShenNong-TCM-LLM

三、知识图谱转换指令(KG2Instructions)方法:DeepKE-LLM

DeepKE是一个开源可扩展的知识图谱抽取工具,可实现命名实体识别、关系抽取和属性抽取等抽取任务,并支持低资源少样本、文档篇章和多模态等复杂场景。

基于知识图谱转换指令技术对知识抽取任务,包括NER、RE、IE进行优化,可以使用人类指令来完成信息抽取任务。

构建了针对抽取加强的指令微调数据集以提升模型的知识抽取能力,其中:

基于知识图谱转换指令(KG2Instructions) 技术:基于维基百科和WikiData知识图谱,通过远程监督、Schema约束过滤等方法构建大量的指令数据**,并通过随机采样人工指令模板的方式提升指令的泛化性。

具体的,如上图所示,选择维基百科的句子,先进行实体识别,然后利用实体链接方法找到该实体在知识图谱中的真实实体,并获取实体的属性和实体关系,形成二元对,最后利用远程家监督思想将同时包含头尾实体的句子作为抽取来源。

不过,远程监督的准确率都不太高,远程监督的数据的关系是过滤过的,但肯定有错误的,所以为了解决这一问题,采用了schema约束以及人工标注过滤以提升性能。此外,人工指令模板这种扩充指令的方法上,思想比较简单,比如给定<中国,首都,北京>这个三元组,可以设计模板

“</o>是<s>的<p>”

,形成“北京是中国的首都”这一非结构化文本,然后抽取的结果就是

<中国,首都,北京>。

不过,基于人工构造模板方式有很大的局限性,因此需要进行泛化,泛化的指令可以通过GPT4进行改写以丰富。

总结

本文主要介绍了三种目前常见的基于知识图谱生成问答对的方案,包括基于两步骤生成知识图谱QA对:DISC-MedLLM、实体为中心的自指令微调数据扩充方法:ShenNong-TCM-LLM以及知识图谱转换指令(KG2Instructions)方法:DeepKE-LLM。

而随着后续大模型行业问答落地的推进,我们会逐步发现,加入关键词提取、加入版式分析等补丁策略,实际上桨大模型的重要性在逐步降低,这其实也是大势所趋。

参考文献

1、https://github.com/yuanjie-ai/ChatLLM

2、https://mp.weixin.qq.com/s?__biz=MzAxMjc3MjkyMg==&mid=2648402104&idx=1&sn=7d4924b2a5a840e4ff3de43299248b1d&chksm=83837bedb4f4f2fb0c352f46c71f588e98048958f573b621b463ad5fd628f9ea21605c5d1c86&token=81259318&lang=zh_CN#rd

3、https://mp.weixin.qq.com/s?__biz=MzAxMjc3MjkyMg==&mid=2648401531&idx=1&sn=87c577794491cd7af3c8c282f17de6b0&chksm=8383752eb4f4fc38c6e99e7c5534a9090715dfc19d856d04be9040de2f11d328867efed8dd2d&token=81259318&lang=zh_CN#rd

关于我们

老刘,刘焕勇,NLP开源爱好者与践行者,主页:https://liuhuanyong.github.io。

老刘说NLP,将定期发布语言资源、工程实践、技术总结等内容,欢迎关注。

对于想加入更优质的知识图谱、事件图谱、大模型AIGC实践、相关分享的,可关注公众号,在后台菜单栏中点击会员社区->会员入群加入。

内容中包含的图片若涉及版权问题,请及时与我们联系删除