news 2026/7/5 23:21:48

【AI大模型应用开发】【项目实战】9.基于GPT2搭建医疗问诊机器人

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【AI大模型应用开发】【项目实战】9.基于GPT2搭建医疗问诊机器人

1. 项目简介

1.1 项目背景

  • 目标:聊天机器人是一种基于自然语言处理技术的智能对话系统,能够模拟人类的自然语言交流,与用户进行对话和互动。聊天机器人能够理解用户的问题或指令,并给出相应的回答或建议,其目标是提供友好、智能、 自然的对  话体验
  • 应用:当前,聊天机器人在多个领域得到广泛应用,首先,它们常用于在线客服系统,能够快速、   准确地回答用户的常见问题,解决疑问;其次,聊天机器人可以作为个人助手,提供个性化的推荐、建议和日程安排等服务,提升用户体验;此外,聊天机器人还被应用于社交娱乐、语言学习、旅游指南等领域,为用户提供有趣、便捷的对话体验

常见的相关聊天机器人产品:

本项目基于医疗领域数据构建了智能医疗问答系统, 目的是为用户提供准确、高效、优质的医疗问答服务

1.2 环境准备

  • python>=3.8
  • transformers>=4.2.0
  • pytorch>=1.7.0

1.3 项目整体结构

2. 数据介绍

data文件夹里面包含2个文件:

  • medical_train.txt  训练数据
  • medical_valid.txt 验证数据

medical_train.txt, medical_valid.txt文件的内容均为对话文本,原始train文档中中—共包含91487条数据, valid文档中包含1244条数据, 每两行数据为—段对话内容,注意:如果想要实现多轮对话,那么不同对话间实现多条对话语句对即可

数据举例:

帕金森叠加综合征的辅助治疗有些什么? 综合治疗;康复训练;生活护理指导;低频重复经颅磁刺激治疗 卵巢癌肉瘤的影像学检查有些什么? 超声漏诊;声像图;MR检查;肿物超声;术前超声;CT检查

数据格式:每段医患对话之间用\n隔开,一共约3w对聊天记录

3. 数据处理

3.1 数据处理简介

目的:将中文文本数据处理成模型能够识别的张量(数字)形式,基本流程如下:

实现过程:

        运行preprocess.py,data/medical_train.txt对话语料进行tokenize然后进行序列化保存到data/medical_train.txt.pkl medical_train.pkl中序列化的对象的类型为List[List],记录对话列表中,每个对话包含的token

注意:这里省略的了数据格式的转换, 目的: 将非txt的文档转换为txt的形式,并符合上述数据格式要求

3.2 代码实现

(1).数据张量转换

代码路径: /data_preprocess/preprocess.py

        代码实现了一个针对医疗对话语料的预处理脚本。它的核心功能是将原始的文本对话数据(txt格式),通过BERT 的分词器(Tokenizer)转化为模型可理解的Token ID 序列,并遵循 BERT 处理多轮对话的标准格式([CLS] seq1 [SEP] seq2 [SEP] ...,最后将处理好的数据保存为二进制文件(pkl格式)以供后续训练直接读取        

# 导入依赖模块 # 导入分词器 # BertTokenizerFast, BertTokenizer:从 Hugging Face 的 transformers 库导入 BERT 分词器。 # Fast 版本基于 Rust 实现,处理速度比标准版快很多 from transformers import BertTokenizerFast, BertTokenizer import pickle # # 将数据保存为pkl文件,方便下次读取 from tqdm import tqdm # 加在进度条 import os def data_preprocess(train_txt_path, train_pkl_path): """ 对原始语料进行tokenizer,将每段对话处理成如下形式:"[CLS]sentence1[SEP]sentence2[SEP]sentence3[SEP]" :param train_txt_path: 原始文本路径 :param train_pkl_path: 输出 pkl 文件路径 :return: """ # 初始化分词器与特殊字符 # 初始化tokenizer,使用BertTokenizerFast从预训练的中文Bert模型(bert-base-chinese)创建一个tokenizer对象 # tokenizer = BertTokenizerFast.from_pretrained('/Users/ligang/PycharmProjects/llm/prompt_tasks/bert-base-chinese', # 使用 BertTokenizerFast 加载自定义的词汇表文件 ../vocab/vocab.txt,并显式指定了 BERT 的三个特殊 Token: # [SEP]:分隔符,用于区分不同的句子或对话轮次。 # [PAD]:填充符,用于将不同长度的序列对齐到相同长度。 # [CLS]:起始符,通常放在序列开头,其最终隐藏状态可作为整个序列的聚合表示 ) tokenizer = BertTokenizerFast('../vocab/vocab.txt', sep_token="[SEP]", pad_token="[PAD]", cls_token="[CLS]") # 打印词表大小 print(f'tokenizer.vocab_size-->{tokenizer.vocab_size}') sep_id = tokenizer.sep_token_id # 获取分隔符[SEP]的token ID cls_id = tokenizer.cls_token_id # 获取起始符[CLS]的token ID # [SEP] 和 [CLS] 对应的数字 ID print(f'sep_id-->{sep_id}') print(f'cls_id-->{cls_id}') # # # # # 读取训练数据集, 读取与切分原始语料 with open(train_txt_path, 'rb') as f: data = f.read().decode("utf-8") # 以UTF-8编码读取文件内容 # print(data) # 根据换行符区分不同的对话段落,需要区分Windows和Linux\mac环境下的换行符 # 兼容跨平台换行符:通过判断文本中是否包含 \r\n(Windows换行符)来决定按 \r\n\r\n 还是 \n\n 进行切分。 # 这里以双换行符作为不同对话段落(样本)的分界线 if "\r\n" in data: train_data = data.split("\r\n\r\n") else: train_data = data.split("\n\n") # # print(len(train_data)) # 打印对话段落数量 print(train_data[:2]) # 核心 Tokenize 逻辑 # 开始进行tokenize # 保存所有的对话数据,每条数据的格式为:"[CLS]seq1[SEP]seq2[SEP]seq3[SEP]" dialogue_len = [] # 记录所有对话tokenize分词之后的长度,用于统计中位数与均值 dialogue_list = [] # 记录所有对话: 记录处理后的数据 # # # # # for index, dialogue in enumerate(tqdm(train_data)): # print(f'dialogue-->{dialogue}') # 同样兼容单换行符,将一段对话按行切分成多个独立的句子(sequences) if "\r\n" in dialogue: sequences = dialogue.split("\r\n") else: sequences = dialogue.split("\n") # print(f'sequences--》{sequences}') # 初始化 input_ids 列表,并将 [CLS] 的 ID 作为序列的开头 input_ids = [cls_id] # 每个dialogue以[CLS]seq1[sep]seq2[sep] for sequence in sequences: # 调用 tokenizer.encode(sequence, add_special_tokens=False) 将文本转为 ID 列表。 # 关键点:这里必须设置 add_special_tokens=False,因为代码需要手动控制 [SEP] 的插入位置, # 防止 BERT 自动在句首句尾添加额外的 [CLS] 或 [SEP] input_ids += tokenizer.encode(sequence, add_special_tokens=False) # 将每个对话句子进行tokenize,并将结果拼接到input_ids列表中 # input_ids += tokenizer.encode(sequence) # 将每个对话句子进行tokenize,并将结果拼接到input_ids列表中 input_ids.append(sep_id) # 每个seq之后添加[SEP],表示seqs会话结束 # 记录当前对话的总长度,并将完整的 input_ids 存入 dialogue_list dialogue_len.append(len(input_ids)) # 将对话的tokenize后的长度添加到对话长度列表中 dialogue_list.append(input_ids) # 将tokenize后的对话添加到对话列表中 #保存数据 with open(train_pkl_path, "wb") as f: pickle.dump(dialogue_list, f) if __name__ == '__main__': train_txt_path = '../data/medical_valid.txt' train_pkl_path = '../data/medical_valid.pkl' data_preprocess(train_txt_path, train_pkl_path)
tokenizer.vocab_size-->13317 sep_id-->102 cls_id-->101 413 ['小孩五岁,脐周淋巴结肿大,小孩五岁,脐周淋巴结肿大,输液后不痛也不烧了,就是淋巴大了,原来9.3mm*3.4mm现在10mm*5mm又吃了半月克拉霉素和猴头菌提取物颗粒查了一下,变成10mm*6mm更大了,怎么办呀?请医生帮助,谢谢\n你好,考虑肠系膜淋巴结炎,本病常与上呼吸道感染有联系。临床表现为发热、腹痛、呕吐,或发生腹泻或便秘。腹痛有时象绞痛在右下腹部,也可在其他部位,本病多属病毒感染,一般自然痊愈,及时的对症治疗即可', '断指再植血管危象的手术治疗有些什么?\n断指再植;静脉皮瓣游离移植'] 100%|██████████| 413/413 [00:00<00:00, 965.28it/s]
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/5 23:21:33

版本兼容设计事件类预留版本字段:

public class OrderEvent {private final String version "1.0"; // 未来可扩展 }监控三件套// 监控处理时长/失败率/QPS Around("annotation(org.springframework.context.event.EventListener)") public Object monitor(ProceedingJoinPoint pjp) {Time…

作者头像 李华
网站建设 2026/7/5 14:49:46

C++ STL之互斥锁与条件变量详解

C STL之互斥锁与条件变量详解 一、从数据竞争说起 多线程同时读写同一内存&#xff0c;结果不确定&#xff0c;这就是数据竞争。C 标准库提供了 mutex 系列锁和 condition_variable 来解决线程同步问题。从 C11 到 C17&#xff0c;同步原语逐步完善&#xff0c;每个都有明确的适…

作者头像 李华
网站建设 2026/7/4 3:06:07

C++ STL 之随机数生成详解

C STL 之随机数生成详解 为什么 C 的 rand() 不该用 C 标准库的 rand() 有三个硬伤&#xff1a; 周期极短&#xff1a;绝大多数实现周期仅 231 − 1&#xff08;约 21 亿&#xff09;&#xff0c;在大量采样时必然重复。低位不随机&#xff1a;rand() % n 依赖低 12 位&#xf…

作者头像 李华
网站建设 2026/7/3 21:32:04

GPIO详细介绍

一.GPIO是什么GPIO 单片机通用引脚&#xff0c;用来输出高低电平、读取外部电平&#xff0c;是单片机和硬件交互最基础的通道。二. 输入输出模式2.1、 输入类&#xff08;4 种&#xff09;浮空输入 &#xff1a;引脚无上下拉&#xff0c;悬空时电平随机&#xff0c;仅适合外部…

作者头像 李华
网站建设 2026/7/4 10:53:55

汽车软件测试,难点到底在哪?

代码规模大、修改频繁&#xff0c;回归测试成本极高 功能安全要求高&#xff0c;但测试覆盖和合规证明难以量化 标准多且复杂&#xff0c;人工检查容易遗漏 项目节奏快&#xff0c;测试往往成为瓶颈&#xff0c;而不是保障 更现实的一点是&#xff1a;不是工程师不够努力&…

作者头像 李华
网站建设 2026/7/3 23:28:28

2026年7月零代码网站搭建与企业无代码建站工具测评:谁更适合你,

一、四个建站工具总表 品牌建站方式更适合谁价格工具特点案例方向BBWEYYAISAAS覆盖5000行业包括零售、工厂、外贸、本地生活700元-3000元一年&#xff0c;买3送3年&#xff0c;年均降至350-1500元/年&#xff0c;每月还配有5-7折的优惠名额&#xff0c;年费至低降至175元/年彻…

作者头像 李华