avatar

Neo·元

算法的尽头,认知的倒影

  • 首页
  • 三千问道
  • 万法归宗
  • 诗酒田园
  • 关于Neo·元
主页 RAG 性能调优实战
文章

RAG 性能调优实战

发表于 最近 更新于 最近
作者 Neo
13~17 分钟 阅读

前言

完成 LangGraph Agent 的整合后,一个简单的知识库查询,消耗响应时间比较长,延迟到一分钟以上,在我笔记本性能有限的情况下,采取了一些优化措施,让性能得到了提升,下面做一些总结:

1、让Ollma使用XPU:

问题表象

打开 Langfuse 的 Trace 一看,性能瓶颈一目了然:

  • 总耗时:1 分 03 秒

  • 其中 ChatOllama 推理:1 分 02 秒

  • 输入 Token:约 4000,输出 Token:84

LLM 推理是绝对瓶颈。但问题是,我之前明明已经为 PyTorch 配置好了 XPU 加速(model_kwargs={'device': 'xpu'}),为什么 Ollama 还是慢如蜗牛?

排查与定位

在终端执行 ollama ps,输出显示:

Plaintext

qwen2.5:3b    2.2 GB    100% CPU     4096

问题终于浮出水面:Ollama 根本没跑在 GPU 上,依然在吃 CPU。

翻看 Ollama 的启动日志,我找到了关键的一行提示:

Plaintext

msg="dropping integrated GPU; to enable, set OLLAMA_IGPU_ENABLE=1"

原来,Ollama 默认会出于稳定性考虑禁用集成显卡(包括我的 Intel Arc 核显),必须手动将其唤醒。

解决方案

设置两个关键环境变量并重启 Ollama 服务:

Bash

# 先停止 Ollama 服务
net stop Ollama

# 设置环境变量(永久生效可写入系统环境变量)
$env:OLLAMA_IGPU_ENABLE = "1"
$env:OLLAMA_VULKAN = "1"

# 重新启动服务
ollama serve

再次检查 ollama ps:

Plaintext

qwen2.5:3b    2.2 GB    100% GPU     4096

Ollama 终于顺利接管并运行在 GPU 上了。

  • 本轮效果:推理速度直接提升了 2-3 倍,总响应时间从 60+ 秒降到了 40 秒左右。

2、优化Prompt:

问题分析

即使换上了 GPU 加速,响应时间依然有 40 秒左右。继续观察 Langfuse 的追踪链路,发现输入 Token 依然居高不下——接近 4000 Token。

输入为什么这么臃肿?

  1. System Prompt:包含了一套过于详尽的规则说明。

  2. 对话历史:RedisChatMessageHistory 中沉淀的历史消息。

  3. RAG 检索结果:format_docs 会把检索到的长文档完整拼接到 Prompt 中。

其中,RAG 检索结果占了“大头”。之前为了追求盲目的召回率,HYBRID_TOP_K 设置为了 10,重排序后再返回 3 条文档。每条文档的内容都不短,加起来轻松逼近千余 Token。

解决方案

  1. 截断单个文档长度

    修改 format_docs 函数,硬性限制每个检索片段的最大字符数:

    Python

    def format_docs(docs: list[Document], max_chars: int = 300) -> str:
        """将检索出来的 Document 拼接成文本,并截断每个文档的长度"""
        if not docs:
            return "暂无相关参考资料。"
    
        formatted = []
        for i, doc in enumerate(docs, 1):
            content = doc.page_content
            if len(content) > max_chars:
                content = content[:max_chars] + "..."
            formatted.append(f"[参考资料 {i}]:\n{content}")
        return "\n\n".join(formatted)
    

    每个文档只截取前 300 个字符(约合 100-150 个中文词),足够覆盖核心信息。

  2. 精简 System Prompt

    把原来冗长啰嗦的设定精简为直击要害的核心指令:

    Plaintext

    你是汽车售后客服。根据【参考知识库】回答用户的问题。
    
    【参考知识库】:
    {context}
    
    【用户问题】:
    {question}
    
    规则:
    1. 如果知识库有相关信息,礼貌回答。
    2. 如果知识库没有相关信息,回复:“抱歉,该问题暂未收录,建议拨打官方热线咨询。”
    3. 严禁凭空编造答案。
    
  • 本轮效果:输入 Token 从 ~4000 锐减至 ~2000,响应时间顺势从 40 秒压到了 25 秒左右。

3、降低混合检索参数:

问题分析

运行时间25 秒,离流畅交互依然有一段距离。我重新审视了混合检索的参数 HYBRID_TOP_K:

  • 它原本用于控制混合检索返回的初始候选池大小。

  • 之前设置为 10,意味着先粗召回 10 条,再丢给重排序模型精筛出 3 条。

  • 但问题在于:重排序本身需要计算开销,且候选池越大,拼出来的 Prompt 越长,最终反向拖慢了 LLM 生成。

实际上,在经过优质向量化和关键字检索的加持下,对于绝大多数垂直领域的问题,排名前 2 的文档已经足够覆盖正确答案。

解决方案

果断将参数收紧:

Python

# config.py
HYBRID_TOP_K: int = 4  # 从 10 改为 4
RERANK_TOP_N: int = 2  # 最终保留 2 条进入 Prompt

让混合检索只抓取最相关的 4 条核心文档,重排序模型也仅需对这 2 个候选对象做轻量打分。

从10条改成了4条后,推理响应时间瞬间降到了19秒,如果把重排序也去掉,还能在节约2秒。

4、整理:

经过这几步操作下来,响应时间从1分多钟降到了20秒左右,输入token从4000+降到了1500-2000,负载从CPU到GPU,充分利用本地笔记本电脑硬件优势。我的感觉是,优秀的架构设计与策略优化,远比盲目堆砌硬件配置来得重要。

下面放两张图,记录一下:

调试前的langfuse截图:

155.png

调试后的langfuse截图:

166.png

万法归宗
AI RAG
许可协议:  CC BY 4.0
分享

相关文章

8月 21, 2026

RAG 性能调优实战

前言 完成 LangGraph Agent 的整合后,一个简单的知识库查询,消耗响应时间比较长,延迟到一分钟以上,在我笔记本性能有限的情况下,采取了一些优化措施,让性能得到了提升,下面做一些总结: 1、让Ollma使用XPU: 问题表象 打开 Langfuse 的 Trace 一看,性能瓶颈一目了然

8月 18, 2026

浅谈治理RAG 混合检索+重排序 (续)

前言 在使用普通检索(倒排索引/BM25)的项目里,检索算法本身是看字不看意,导致命中率不高,给出的结果也不够准确,这个时候需要升级两种技术,混合检索、重排序。 先说一下混合检索、重排序: 混合检索:BM25关键词检索+向量检索+RRF公平合并(由看字变为理解意思在找) 重排序:根据原文深层理解后重

8月 17, 2026

浅谈治理RAG 升级RAG 混合检索+重排序

前言 之前搭建的LangChain和LangGraph,使用的RAG有点不太准确,会出现幻觉,即答非所问,比如: 问"变速箱油多久换一次",知识库里明明有答案,系统会回"建议参考用户手册"。 LLM 没在知识库里找到答案,但被要求必须回答,于是用通用知识硬编。 检索这块需要升级,打算采用混合检索和重

下一篇

浅谈Langfuse 生产级全链路观测与排坑指南

上一篇

最近更新

  • RAG 性能调优实战
  • 浅谈Langfuse 生产级全链路观测与排坑指南
  • 浅谈治理RAG 混合检索+重排序 (续)
  • 浅谈治理RAG 升级RAG 混合检索+重排序
  • 浅谈LangChain升级LangGraph

热门标签

AI RAG

©2026 All Rights Reserved Neo 鲁ICP备2026037083号