基于大模型与 PubMed 检索的光谱数据分析系统

发布于:2025-09-01 ⋅ 阅读:(28) ⋅ 点赞:(0)

引言:

        大模型(比如deepseek)像一个掌握了各种机器学习的本科生,但他缺乏特定领域的知识,当你(研究生导师)安排这个新招进来的本科高材生做光谱数据处理这一任务时,它绝对不如一些专业的光谱数据分析软件unscramble、LabSpec等分析得好(研二研三的师兄师姐),那么我们需要给它喂一些文献、数据以及微调它的思路。

        下面是一个非常简单的例子,连接大模型与光谱数据分析,具体步骤如下:

1.本地部署一个大模型

(1)安装 Ollama

        Ollama 的安装过程简单直观,支持 Windows、macOS 和 Linux 系统。以下是具体步骤:

  1. 下载安装包

    • 下载后,双击安装包并按照提示完成安装。Windows 用户可能需要允许程序通过防火墙。
  1. 设置模型存储路径
    默认情况下,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 使更改生效。
  2. 下载并安装大语言模型

    • 打开终端(Windows 使用 PowerShell 或 CMD,Linux/macOS 使用终端)。
    • 使用以下命令拉取模型(以 Llama 3.1 为例):
      ollama pull llama3.1
    • 等待模型下载完成,下载的模型将存储在你设置的 OLLAMA_MODELS 路径或默认路径中。
    • 验证模型是否成功安装:
      ollama list 命令将列出已安装的模型,确保目标模型(如 llama3.1)出现在列表中。

(2)手动导入大语言模型到 Ollama

        如果你需要使用特定的模型文件(例如从 Hugging Face 下载的 GGUF 格式模型),可以手动导入到 Ollama。以下是详细步骤:

  1. 准备模型文件

    • 确保你已下载支持 Ollama 的模型文件,常见格式为 GGML 或 GGUF(例如 qwen2.5-7b-instruct-q4_0.gguf)。
    • 将模型文件存储到本地目录,例如 E:\models\
  2. 创建 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
  3. 导入模型

    • 打开终端,进入 Modelfile 所在目录。
    • 运行以下命令导入模型:
      ollama create qwen2.5-7b -f E:\models\Modelfile
      • qwen2.5-7b 是你为模型指定的名称,可自定义。
      • E:\models\Modelfile 是 Modelfile 文件的实际路径。
  4. 验证导入

    • 导入完成后,运行以下命令检查模型是否成功添加:
      ollama list 确保 qwen2.5-7b(或你指定的名称)出现在列表中。
  5. 运行模型

    • 使用以下命令启动模型:
      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:7b
        max_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_text

    except 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 PyPDF2

import 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_text
                        pdf_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_text
    except 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:7b
        max_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_text

    except 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->30
            title = 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 results
    except 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"  # 2023
        for 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("未能生成分析结果,请检查网络连接和模型服务。")


输出框可以得到以下结果:          


网站公告

今日签到

点亮在社区的每一天
去签到