基于大模型与 PubMed 检索的光谱数据分析系统
引言:
大模型(比如deepseek)像一个掌握了各种机器学习的本科生,但他缺乏特定领域的知识,当你(研究生导师)安排这个新招进来的本科高材生做光谱数据处理这一任务时,它绝对不如一些专业的光谱数据分析软件unscramble、LabSpec等分析得好(研二研三的师兄师姐),那么我们需要给它喂一些文献、数据以及微调它的思路。
下面是一个非常简单的例子,连接大模型与光谱数据分析,具体步骤如下:
1.本地部署一个大模型
(1)安装 Ollama
Ollama 的安装过程简单直观,支持 Windows、macOS 和 Linux 系统。以下是具体步骤:
-
下载安装包
- 访问 Ollama 官方网站(https://ollama.ai/),根据你的操作系统选择合适的安装包(Windows、macOS 或 Linux)。
-
- 下载后,双击安装包并按照提示完成安装。Windows 用户可能需要允许程序通过防火墙。
-
设置模型存储路径
默认情况下,Ollama 会将下载的模型存储在系统目录中,但你可以通过设置环境变量自定义存储路径,尤其在磁盘空间有限或需要整理模型文件时非常有用。
Windows 系统设置步骤:- 右键点击桌面上的“此电脑”或文件资源管理器中的“我的电脑”,选择“属性”。
- 在弹出的窗口中,点击左侧的“高级系统设置”。
- 在“系统属性”窗口中,点击“环境变量”。
- 在“系统变量”区域,点击“新建”,添加以下内容:
- 变量名:
OLLAMA_MODELS
- 变量值:
E:\path\to\your\custom\directory
(替换为你的自定义路径,例如E:\AI_Models
)。
- 变量名:
- 点击“确定”保存所有更改。
- 关闭并重新打开 PowerShell 或命令提示符,以确保环境变量生效。
Linux/macOS 系统设置: - 编辑用户主目录下的
.bashrc
或.zshrc
文件,添加以下行:
export OLLAMA_MODELS=/path/to/your/custom/directory
- 保存后运行
source ~/.bashrc
或source ~/.zshrc
使更改生效。
-
下载并安装大语言模型
- 打开终端(Windows 使用 PowerShell 或 CMD,Linux/macOS 使用终端)。
- 使用以下命令拉取模型(以 Llama 3.1 为例):
ollama pull llama3.1
- 等待模型下载完成,下载的模型将存储在你设置的
OLLAMA_MODELS
路径或默认路径中。 - 验证模型是否成功安装:
ollama list
命令将列出已安装的模型,确保目标模型(如llama3.1
)出现在列表中。
(2)手动导入大语言模型到 Ollama
如果你需要使用特定的模型文件(例如从 Hugging Face 下载的 GGUF 格式模型),可以手动导入到 Ollama。以下是详细步骤:
-
准备模型文件
- 确保你已下载支持 Ollama 的模型文件,常见格式为 GGML 或 GGUF(例如
qwen2.5-7b-instruct-q4_0.gguf
)。 - 将模型文件存储到本地目录,例如
E:\models\
。
- 确保你已下载支持 Ollama 的模型文件,常见格式为 GGML 或 GGUF(例如
-
创建 Modelfile
- 在模型文件所在目录下,创建一个名为
Modelfile
的文本文件(无后缀)。 - 编辑
Modelfile
,添加以下内容:
FROM E:\models\qwen2.5-7b-instruct-q4_0.gguf
将E:\models\qwen2.5-7b-instruct-q4_0.gguf
替换为你的模型文件实际路径。 - 如果需要自定义模型参数(如温度、上下文长度),可以在
Modelfile
中添加,例如:
FROM E:\models\qwen2.5-7b-instruct-q4_0.gguf PARAMETER temperature 0.7 PARAMETER max_tokens 2048
- 在模型文件所在目录下,创建一个名为
-
导入模型
- 打开终端,进入
Modelfile
所在目录。 - 运行以下命令导入模型:
ollama create qwen2.5-7b -f E:\models\Modelfile
qwen2.5-7b
是你为模型指定的名称,可自定义。E:\models\Modelfile
是Modelfile
文件的实际路径。
- 打开终端,进入
-
验证导入
- 导入完成后,运行以下命令检查模型是否成功添加:
ollama list
确保qwen2.5-7b
(或你指定的名称)出现在列表中。
- 导入完成后,运行以下命令检查模型是否成功添加:
-
运行模型
- 使用以下命令启动模型:
ollama run qwen2.5-7b
替换qwen2.5-7b
为你的模型名称。 - 启动后,你可以通过终端或 Chatbox 与模型交互,输入提示生成代码或文本。
- 使用以下命令启动模型:
2.Pycharm端调用大模型
首先确保ollama运行了后,在pycharm端安装ollama包,终端输入以下命令:
pip install ollama
安装好后,运行下面程序测试是否能顺利地调用大模型
import ollama
# pip install ollama# 定义调用函数
def call_deepseek(prompt, model="deepseek-r1:7b", max_tokens=500, temperature=0.7):"""使用 ollama 库调用本地 deepseek-r1:7b 模型生成文本。参数:prompt (str): 输入的提示文本model (str): 模型名称,默认为 deepseek-r1:7bmax_tokens (int): 生成的最大 token 数temperature (float): 控制输出的随机性,值越小越确定性返回:str: 模型生成的文本"""try:# 调用 ollama 的 generate 方法response = ollama.generate(model=model,prompt=prompt,options={"max_tokens": max_tokens,"temperature": temperature})# 从响应中提取生成的文本generated_text = response.get("response", "未返回生成文本")return generated_textexcept Exception as e:print(f"调用模型时出错: {e}")return None# 测试代码
if __name__ == "__main__":# 示例提示test_prompt = "请解释一下近红外光谱的原理"# 调用模型output = call_deepseek(test_prompt)# 打印结果if output:print("模型输出:")print(output)else:print("未能获取模型输出,请检查 Ollama 服务和模型是否正常运行。")
如果显示你的回答,则成功。
3.结合PyPDF2库本地导入相关研究领域参考文献
在目录中新建一个文件夹,导入一些本地的,你研究领域的文章:
安装PyPDF2库,输入命令如下:
pip install PyPDF2
然后测试下面代码:
# pip install ollama PyPDF2import os
import ollama
import PyPDF2# 定义读取 PDF 文件内容的函数
def read_pdf_files(folder_path, max_chars=100000000):"""读取指定文件夹中所有 PDF 文件的内容,并限制总字符数。参数:folder_path (str): PDF 文件夹路径max_chars (int): 最大字符数限制,防止 token 超限返回:str: 所有 PDF 文件内容的合并字符串"""pdf_texts = []try:# 遍历文件夹中的所有文件for filename in os.listdir(folder_path):if filename.lower().endswith('.pdf'):file_path = os.path.join(folder_path, filename)try:with open(file_path, 'rb') as file:# 创建 PDF 阅读器对象pdf_reader = PyPDF2.PdfReader(file)text = ""# 逐页读取内容for page in pdf_reader.pages:page_text = page.extract_text() or ""text += page_textpdf_texts.append(text)except Exception as e:print(f"读取文件 {filename} 时出错: {e}")# 合并所有 PDF 内容并截断combined_text = "\n".join(pdf_texts) if pdf_texts else "未找到 PDF 文件或内容为空"if len(combined_text) > max_chars:combined_text = combined_text[:max_chars] + "...[内容已截断]"print(f"PDF 内容超过 {max_chars} 字符,已截断")return combined_textexcept Exception as e:print(f"访问文件夹 {folder_path} 时出错: {e}")return ""# 定义调用函数
def call_deepseek(prompt, pdf_content="", model="deepseek-r1:7b", max_tokens=500, temperature=0.7):"""使用 ollama 库调用本地 deepseek-r1:7b 模型生成文本,结合 PDF 内容。参数:prompt (str): 输入的提示文本pdf_content (str): 从 PDF 文件中提取的内容model (str): 模型名称,默认为 deepseek-r1:7bmax_tokens (int): 生成的最大 token 数temperature (float): 控制输出的随机性,值越小越确定性返回:str: 模型生成的文本"""try:# 优化提示语,强化中文输出language_prompt = ("请以简洁、准确且易于理解的中文回答,确保回答内容仅使用中文,""避免使用其他语言,并根据提供的信息进行分析。\n\n")# 组合提示、PDF 内容和用户输入full_prompt = (f"{language_prompt}{prompt}\n\n"f"以下是相关背景信息(从 PDF 文件提取):\n{pdf_content}"if pdf_content else f"{language_prompt}{prompt}")# 调用 ollama 的 generate 方法response = ollama.generate(model=model,prompt=full_prompt,options={"max_tokens": max_tokens,"temperature": temperature})# 从响应中提取生成的文本generated_text = response.get("response", "未返回生成文本")return generated_textexcept Exception as e:print(f"调用模型时出错: {e}")print("请检查:1. Ollama 服务是否运行;2. 模型 deepseek-r1:7b 是否正确安装;3. 网络连接是否正常")return None# 测试代码
if __name__ == "__main__":# 定义 PDF 文件夹路径pdf_folder = r"D:\pythonProject\Ollama\pdf_Datas"# 读取所有 PDF 文件内容pdf_content = read_pdf_files(pdf_folder)if not pdf_content:print("未能读取任何 PDF 内容,请检查文件夹路径或文件是否存在。")# 示例提示test_prompt = "请用中文分析一下中红外光谱数据如何做迁移学习?"# 调用模型,传入 PDF 内容output = call_deepseek(test_prompt, pdf_content=pdf_content)# 打印结果if output:print("模型输出:")print(output)else:print("未能获取模型输出,请检查 Ollama 服务和模型是否正常运行。")
当然,有一个应用叫Anything LLM,能给上述提供界面,我也尝试过,可视化感觉非常好。
但是后续,要微调或者在线检索这个应用就做不了了,所以主要以python代码为主。
4.结合PubMed API在线检索相关内容参考文献
首先,我们需要安装Langchain这个库,在终端使用如下命令:
pip install langchain-community
langchain-community
提供 PubMedRetriever
,用于在线检索 PubMed 文献,接着输入如下代码:
import ollama
from typing import List, Optional
from langchain_community.retrievers import PubMedRetriever # 确保使用最新导入路径# 初始化 PubMedRetriever
client = PubMedRetriever() # 默认使用官方 PubMed API,无需自定义 base_url 和 api_key# 1. 在线文献内容检索(使用 PubMed)
def retrieve_literature_content_online(keywords: List[str], year: int = 2023) -> List[str]:"""使用 PubMed API 检索文献,并在检索成功或失败时打印信息。参数:keywords (List[str]): 搜索关键词,如 ["carbon material", "defect structure"]year (int): 限制年份,默认为 2023返回:List[str]: 匹配的文献片段列表"""try:# 构建查询字符串query = " AND ".join(keywords) + f"[{year}]"# 使用 PubMedRetriever 的 retrieve 方法documents = client.get_relevant_documents(query) # 替换 search 为 get_relevant_documents# 解析检索结果results = []for doc in documents[:3]: # 限制最多 3 篇 3->30title = doc.metadata.get('title', '未知标题') # 从 metadata 中获取标题abstract = doc.page_content if doc.page_content else '无摘要' # page_content 是摘要内容results.append(f"标题: {title}\n摘要: {abstract}")# 添加打印信息if results:print(f"已检索到 {len(results)} 篇文章")else:print("没检索到文章")return resultsexcept Exception as e:print(f"在线文献检索出错: {e}")print("没检索到文章") # 出错时也认为是没检索到return []def build_rag_prompt(peaks: List[float], literature_content: List[str]) -> str:"""基于 PubMed 检索的文献内容构建增强提示,用于发酵过程分析中拉曼光谱。参数:peaks (List[float]): 输入峰位literature_content (List[str]): 在线文献内容返回:str: 增强后的提示"""prompt = f"基于以下峰位 {peaks} cm⁻¹,结合 PubMed 在线检索的文献信息,分析发酵过程中拉曼光谱的特征及其意义:\n\n"if literature_content:prompt += "### 2024年相关研究:\n" # 2023for content in literature_content:prompt += f"- {content}\n"else:prompt += "### 无相关文献\n"prompt += "\n请结合2023年关于发酵过程的最新研究,分析这些峰位可能对应的发酵产物、代谢物或微生物活性特征(如糖类代谢、蛋白质变化、脂类积累等),并解释其在拉曼光谱中的意义。并且先概述一下你检索到的每篇文章"return prompt# 3. 调用 DeepSeek 模型
def call_deepseek(prompt: str, model: str = "deepseek-r1:7b", max_tokens: int = 1000, temperature: float = 0.7) -> Optional[str]:"""使用 ollama 调用 DeepSeek 模型生成文本。"""try:response = ollama.generate(model=model,prompt=prompt,options={"max_tokens": max_tokens,"temperature": temperature})return response.get("response", "未返回生成文本")except Exception as e:print(f"调用模型时出错: {e}")return None# 4. 主函数:在线 RAG 流程
def analyze_spectral_peaks_online(peaks: List[float]) -> Optional[str]:"""在线分析光谱峰位并生成报告,基于 PubMed 检索。参数:peaks (List[float]): 输入峰位返回:Optional[str]: 分析结果"""keywords = ["carbon material", "defect structure", "Raman spectroscopy"]literature_content = retrieve_literature_content_online(keywords)rag_prompt = build_rag_prompt(peaks, literature_content)output = call_deepseek(rag_prompt)return output# 测试代码
if __name__ == "__main__":test_peaks = [1008, 1150, 1580]result = analyze_spectral_peaks_online(test_peaks)if result:print("在线分析结果:")print(result)else:print("未能生成分析结果,请检查网络连接和模型服务。")
输出框可以得到以下结果: