120 lines
6.4 KiB
Python
120 lines
6.4 KiB
Python
|
|
import pandas as pd
|
|||
|
|
from tqdm import tqdm
|
|||
|
|
import torch
|
|||
|
|
import os
|
|||
|
|
# 设置环境变量禁用 TensorFlow
|
|||
|
|
os.environ["USE_TORCH"] = "1"
|
|||
|
|
os.environ["USE_TF"] = "0"
|
|||
|
|
|
|||
|
|
import torch
|
|||
|
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
|||
|
|
|
|||
|
|
# 设置设备
|
|||
|
|
device = torch.device("mps" if torch.backends.mps.is_available() else "cpu")
|
|||
|
|
print(f"使用设备: {device}")
|
|||
|
|
|
|||
|
|
# 基础模型路径
|
|||
|
|
base_model_path = "../Qwen2.5-7B-Instruct"
|
|||
|
|
# 微调模型路径
|
|||
|
|
finetuned_model_path = "../qwen-medical" # 修改为您的微调模型路径
|
|||
|
|
|
|||
|
|
# 加载基础模型
|
|||
|
|
base_tokenizer = AutoTokenizer.from_pretrained(base_model_path, trust_remote_code=True)
|
|||
|
|
base_model = AutoModelForCausalLM.from_pretrained(
|
|||
|
|
base_model_path,
|
|||
|
|
torch_dtype=torch.float16,
|
|||
|
|
trust_remote_code=True
|
|||
|
|
).to(device)
|
|||
|
|
|
|||
|
|
# 加载微调后模型
|
|||
|
|
finetuned_tokenizer = AutoTokenizer.from_pretrained(finetuned_model_path, trust_remote_code=True)
|
|||
|
|
finetuned_model = AutoModelForCausalLM.from_pretrained(
|
|||
|
|
finetuned_model_path,
|
|||
|
|
torch_dtype=torch.float16,
|
|||
|
|
trust_remote_code=True
|
|||
|
|
).to(device)
|
|||
|
|
print("模型加载完成")
|
|||
|
|
|
|||
|
|
# 准备评估数据
|
|||
|
|
# 创建医疗就诊测试数据
|
|||
|
|
eval_dataset = [
|
|||
|
|
{
|
|||
|
|
"Question": "我最近经常感到胸闷气短,特别是在运动后,这可能是什么问题?",
|
|||
|
|
"Answer": "您描述的症状可能与心肺功能有关。建议及时就医检查,进行心电图、胸片等相关检查以明确诊断。同时请注意:1. 暂时减少剧烈运动 2. 保持规律作息 3. 记录症状发生的具体情况"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"Question": "孩子发烧38.5度,已经持续一天了,除了发烧没有其他明显症状,该怎么处理?",
|
|||
|
|
"Answer": "对于儿童发烧,建议以下措施:1. 多补充水分 2. 物理降温(温水擦浴) 3. 必要时使用退烧药 4. 如果发烧持续超过48小时或出现其他症状及时就医 5. 注意观察精神状态和体温变化"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"Question": "男,十二岁。右股骨下端疼痛2个月,夜间加重。查体:右股骨下端局部肿胀、皮温增高。X线示右胫上端日光射线样改变。首先考虑的诊断是\nA.骨巨细胞瘤 \nB.慢性骨髓炎\nC.股骨结节骨软骨病 \nD.骨样骨瘤 \nE. 骨肉瘤",
|
|||
|
|
"Answer": "基于提供的症状和影像学表现,12岁男孩右股骨下端的疼痛具有夜间加重的特点,并伴有局部肿胀和温度升高,X光片显示日光射线样改变,这些都非常符合骨肉瘤的特征。\n\n虽然选项中还有其他可能性,但结合年龄、症状以及特异性的X光表现,最可能的诊断是 E. 骨肉瘤。"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"Question": "经常性反酸打嗝,体重下降,腹部CT完全正常、肝肾功能正常,癌胚抗原指标正常,这种情况下最可能的诊断是什么",
|
|||
|
|
"Answer": "根据提供的症状和检查结果,最可能的诊断是胃食管反流病(GERD)。这种病常见于长期的反酸和打嗝,而CT检查和肝肾功能的正常则排除了其他更严重的疾病。当然,进一步的检查如胃镜可能有助于确诊和排除其他可能性。"
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"Question": "一名中年男性自述鼻涕中带血已经有三个月了,面且伴有有耳堵和听力减退,无发热。根据鼻咽部的症状和体征,这种情况下最可能的诊断是什么?",
|
|||
|
|
"Answer": "根据提供的症状以及病程的描述,这名男性患者可能患有鼻咽癌的可能性较高。以下是分析理由:1. **持续时间**:鼻涕中带血已持续三个月,这种情况排除了普通感冒或短期炎症的可能,指向一种更慢性或严重的病变。\n\n2. **症状组合**:鼻涕带血、耳堵及听力减退,这些症状在结合在一起时较为典型地指向鼻咽部的问题。耳堵和听力减退尤其提示可能是由于肿瘤压迫或阻塞了耳咽管。\n\n3. **无发热**:在长期的炎症或感染中,通常会伴随发热现象,而患者并未出现此症状,这降低了急性鼻窦炎等感染的可能性。\n\n鉴于这些症状的组合和其持续的时间,早期鼻咽癌的可能性较高。当然,最终的确诊还需通过影像学检查(如CT或MRI)以及病理活检来确认。不论如何,这种情况下,尽早就医进行详细检查是至关重要的,以便及时获得准确的诊断和适当的治疗。"
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
eval_dataset = pd.DataFrame(eval_dataset)
|
|||
|
|
test_questions = eval_dataset["Question"].tolist()
|
|||
|
|
comparison_results = []
|
|||
|
|
|
|||
|
|
# 对每个测试样例进行对比评估
|
|||
|
|
for question in tqdm(test_questions):
|
|||
|
|
# 使用微调模型生成回答
|
|||
|
|
formatted_prompt = f"下面列出了一个问题. 请写出问题的答案.### 问题:{question}### 答案:"
|
|||
|
|
|
|||
|
|
# 微调模型推理
|
|||
|
|
finetuned_inputs = finetuned_tokenizer(formatted_prompt, return_tensors="pt").to(device)
|
|||
|
|
|
|||
|
|
finetuned_outputs = finetuned_model.generate(
|
|||
|
|
**finetuned_inputs,
|
|||
|
|
max_new_tokens=512,
|
|||
|
|
temperature=0.7,
|
|||
|
|
top_p=0.9,
|
|||
|
|
do_sample=True
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
finetuned_response = finetuned_tokenizer.decode(finetuned_outputs[0], skip_special_tokens=True)
|
|||
|
|
finetuned_response = finetuned_response.replace(formatted_prompt, "") # 移除提示词
|
|||
|
|
|
|||
|
|
# 基础模型推理
|
|||
|
|
base_inputs = base_tokenizer(formatted_prompt, return_tensors="pt").to(device)
|
|||
|
|
|
|||
|
|
base_outputs = base_model.generate(
|
|||
|
|
**base_inputs,
|
|||
|
|
max_new_tokens=512,
|
|||
|
|
temperature=0.7,
|
|||
|
|
top_p=0.9,
|
|||
|
|
do_sample=True
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
base_response = base_tokenizer.decode(base_outputs[0], skip_special_tokens=True)
|
|||
|
|
base_response = base_response.replace(formatted_prompt, "") # 移除提示词
|
|||
|
|
|
|||
|
|
# 保存结果
|
|||
|
|
comparison_results.append({
|
|||
|
|
"question": question,
|
|||
|
|
"finetuned_response": finetuned_response,
|
|||
|
|
"base_response": base_response,
|
|||
|
|
"reference_answer": eval_dataset[eval_dataset["Question"] == question]["Answer"].values[0] #type: ignore
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
# 保存对比结果
|
|||
|
|
comparison_df = pd.DataFrame(comparison_results)
|
|||
|
|
comparison_df.to_csv("./model_comparison.csv", index=False)
|
|||
|
|
|
|||
|
|
print(f"对比评估完成,结果已保存至 model_comparison.csv")
|
|||
|
|
|
|||
|
|
# 简单统计
|
|||
|
|
print("\n===== 对比结果统计 =====")
|
|||
|
|
for i, result in enumerate(comparison_results):
|
|||
|
|
print(f"\n问题 {i+1}: {result['question']}")
|
|||
|
|
print(f"参考答案: {result['reference_answer']}")
|
|||
|
|
print(f"微调模型: {result['finetuned_response'][:100]}...")
|
|||
|
|
print(f"基础模型: {result['base_response'][:100]}...")
|
|||
|
|
print("-" * 50)
|