45:57Chase AI
Log in to leave a comment
No posts yet
在本地环境构建 RAG 系统时,首先遇到的障碍就是 VRAM 容量以及库之间极其严重的版本冲突。8 比特量化模型每 10 亿个参数大约占用 1GB 的 VRAM。考虑到 Windows 或 macOS 系统本身的占用,至少需要留出 20% 的空余空间。如果没有这些余量,你会看到令牌(Token)生成速度掉到每秒 2 个左右的惨状。特别是 lightrag-hku 框架,一旦遇到最新的 numpy 2.x 版本,往往会抛出运行时错误。
首先打开终端并输入 pip install numpy==1.26.4 --force-reinstall 来固定版本。接着安装 nest_asyncio,并在代码最顶端加上 nest_asyncio.apply()。如果不这样做,在 Jupyter Notebook 中异步循环会发生冲突,导致整个进程停止。如果 GPU 显存在 8GB 以下,初始化 LightRAG 时请将 embedding_batch_num 设置为 10 以下,并将 llm_model_max_async 降低到 4 左右。仅此项设置就能防止无故导致系统崩溃的 OOM(内存溢出)现象,并能帮你节省 2 小时的无谓折腾。
如果只是简单地将文本以块的形式存储,信息之间的上下文就会被切断。但是,如果能正确解析 Obsidian 的双向链接([[link]])结构,就能构建出相当出色的知识图谱。核心在于在 LLM 读取之前剔除不必要的 Markdown 符号。仅仅清理掉这些杂乱的符号,就能节省近 30% 的令牌消耗。
养成在撰写笔记时在顶部的 YAML 区域添加 type、domain 等字段的习惯,这会显著提升搜索过滤速度。在 Python 的 re 模块中使用 r"\[\[(.+?)\]\]" 模式提取文档间的连接纽带,然后将其转换为 JSONL 格式的关系数据集。文件名也很重要。相比于“2024-04-14”之类的日期,使用知识的核心主题作为标题才能让索引后的节点发挥应有的作用。这样连接的数据不仅能实现简单搜索,还能完成跨概念的推理。
运行本地 LLM 时,最浪费资源的行为就是反复计算已经算过的嵌入(Embedding)。Python 的默认缓存会在程序关闭时全部丢失。因此,需要使用基于 SQLite 的 DiskCache 来创建物理存储。当问题之间的余弦相似度超过 0.95 时,设计为不调用 LLM 而是直接返回缓存的回答。应用这种语义缓存后,可以将响应时间缩短至 100ms 左右。
方法很简单。通过 pip install diskcache 获取库,并创建一个存储嵌入文本和向量对的类。如果在这里加入时间权重算法效果会更好:
其逻辑是让刚刚修改的笔记出现在搜索结果的前列。将嵌入缓存的 TTL(生存时间)设置为 1 小时,生成式回答缓存设置为 2 小时左右,即可针对重复性提问建立即时响应体系。
笔记中包含的架构图或截图比文字承载的信息量要大得多。在搜索中漏掉这些是一种损失。使用 CLIP 模型可以将图像和文本放置在同一空间中,这样即使只输入“数据流程图”,也能找到相关的图像。如果没有高性能 GPU,可以将 CLIP-ViT-B-32 模型转换为 OpenVINO 格式并在 CPU 上运行。
在 Markdown 文件中找到图像路径后,将其前后的 200 字左右的文本捆绑在一起。然后使用 Phi-3.5-vision 等轻量化本地 VLM 自动提取图像说明(Caption)。将此说明向量与图像特征向量一同存储在 Qdrant 等本地向量数据库中。经过这一处理,搜索结果中将包含连文字都难以表达的复杂图片。
每改动一个文件就重新对整个库进行索引是低效的。使用 Python 的 watchdog 库可以感知文件保存的瞬间,并仅更新变动的部分。但由于在写作过程中索引不断运行会导致 CPU 负荷过重,因此防抖(Debouncing)处理是必不可少的。
在编写脚本时,使用 watchdog.observers 监视文件夹,当发生修改事件时,等待 5 秒左右再开始作业。还需要额外存储每个文件的 SHA-256 哈希值,并加入比对过程以确认内容是否真的发生了变化。只挑选出哈希值发生变化的文件,删除原有节点并推入新向量。这样一来,保存笔记的同时就能立即反映到搜索系统中的实时知识库就完成了。这意味着你不再需要手动点击更新按钮。