internlm2-chat-1.8b在Ollama中启用Embedding:本地向量检索RAG基础搭建

张开发
2026/4/18 18:38:18 15 分钟阅读

分享文章

internlm2-chat-1.8b在Ollama中启用Embedding:本地向量检索RAG基础搭建
internlm2-chat-1.8b在Ollama中启用Embedding本地向量检索RAG基础搭建1. 项目概述与目标今天我们来解决一个很实际的问题如何让本地的AI模型不仅能够聊天还能记住和理解你自己的文档内容。想象一下你有一些技术文档、公司资料或者个人笔记想让AI基于这些内容来回答问题而不是仅仅依靠它预训练的知识。这就是我们要搭建的RAG检索增强生成系统。简单来说就是先让AI理解你的文档内容然后把相关内容找出来最后基于这些内容生成回答。这样得到的答案更准确、更相关也更有针对性。我们将使用internlm2-chat-1.8b这个轻量级但能力不错的模型结合Ollama这个方便的本地部署工具一步步搭建完整的向量检索系统。2. 环境准备与工具安装2.1 基础环境要求在开始之前确保你的系统满足以下要求操作系统Linux推荐Ubuntu 20.04、macOS或Windows 10内存至少8GB RAM16GB更佳存储空间10GB可用空间Python版本3.8或更高版本2.2 安装OllamaOllama是我们部署和管理模型的核心工具安装很简单# Linux/macOS安装 curl -fsSL https://ollama.ai/install.sh | sh # Windows安装 # 访问 https://ollama.ai/download 下载安装包安装完成后验证是否成功ollama --version2.3 下载internlm2-chat-1.8b模型通过Ollama拉取我们需要的模型ollama pull internlm2:1.8b这个命令会自动下载约3.6GB的模型文件根据你的网络速度可能需要一些时间。2.4 安装Python依赖库我们需要一些Python库来处理文档和向量计算pip install langchain chromadb sentence-transformers unstructured这些库分别用于langchain构建AI应用的工作流chromadb本地向量数据库sentence-transformers文本转向量unstructured解析各种文档格式3. Embedding功能启用与配置3.1 理解Embedding的作用Embedding嵌入就像是给文字拍了一张数学照片把一段话转换成一串数字向量。这个数字串能够捕捉文字的语义信息意思相近的文字会有相似的数字串。在我们的RAG系统中Embedding有两个重要作用把文档内容转换成向量存入数据库把用户问题转换成向量来搜索相关文档3.2 配置Ollama的Embedding端点虽然internlm2-chat-1.8b主要是个聊天模型但我们可以通过Ollama的API来获取Embedding功能。首先启动Ollama服务ollama serve服务默认在11434端口启动。我们可以通过API调用来测试Embedding功能import requests import json def test_embedding(): url http://localhost:11434/api/embeddings data { model: internlm2:1.8b, prompt: 测试Embedding功能 } response requests.post(url, jsondata) if response.status_code 200: embedding_vector response.json()[embedding] print(fEmbedding向量长度: {len(embedding_vector)}) print(f前10个值: {embedding_vector[:10]}) else: print(请求失败:, response.text) test_embedding()如果一切正常你会看到输出一个长度为4096的数字向量这就是你的文字被转换成的数学照片。4. 本地向量数据库搭建4.1 初始化Chroma向量数据库Chroma是一个轻量级的本地向量数据库非常适合我们的需求import chromadb from chromadb.config import Settings # 创建本地向量数据库 client chromadb.Client(Settings( chroma_db_implduckdbparquet, persist_directory./chroma_db # 数据保存目录 )) # 创建或获取一个集合类似数据库中的表 collection client.create_collection(namedocuments)4.2 文档处理与向量化流程现在我们来创建完整的文档处理流程from langchain.text_splitter import RecursiveCharacterTextSplitter from langchain.document_loaders import TextLoader import os def process_documents(folder_path): # 初始化文本分割器 text_splitter RecursiveCharacterTextSplitter( chunk_size1000, # 每个文本块约1000字符 chunk_overlap200 # 块之间重叠200字符保持上下文 ) documents [] metadatas [] ids [] # 遍历文件夹中的所有文本文件 for filename in os.listdir(folder_path): if filename.endswith(.txt): file_path os.path.join(folder_path, filename) loader TextLoader(file_path) docs loader.load() # 分割文档 splits text_splitter.split_documents(docs) for i, split in enumerate(splits): documents.append(split.page_content) metadatas.append({source: filename, chunk: i}) ids.append(f{filename}_chunk_{i}) return documents, metadatas, ids # 使用示例 documents, metadatas, ids process_documents(./my_documents)4.3 批量生成向量并入库有了文档内容后我们需要生成向量并存入数据库def add_documents_to_db(documents, metadatas, ids): # 批量生成Embedding避免频繁API调用 embeddings [] for doc in documents: # 调用Ollama的Embedding接口 response requests.post( http://localhost:11434/api/embeddings, json{model: internlm2:1.8b, prompt: doc} ) embeddings.append(response.json()[embedding]) # 添加到向量数据库 collection.add( documentsdocuments, metadatasmetadatas, idsids, embeddingsembeddings ) print(f成功添加 {len(documents)} 个文档块到数据库) # 执行添加操作 add_documents_to_db(documents, metadatas, ids)5. RAG系统完整实现5.1 检索增强生成工作流现在我们来构建完整的RAG系统def rag_query(question, top_k3): # 第一步将问题转换为向量 response requests.post( http://localhost:11434/api/embeddings, json{model: internlm2:1.8b, prompt: question} ) question_embedding response.json()[embedding] # 第二步在向量数据库中搜索相似内容 results collection.query( query_embeddings[question_embedding], n_resultstop_k ) # 第三步构建增强的提示词 context \n\n.join(results[documents][0]) enhanced_prompt f基于以下参考信息回答问题。如果信息不足请说明。 参考信息 {context} 问题{question} 回答 # 第四步调用模型生成回答 response requests.post( http://localhost:11434/api/generate, json{ model: internlm2:1.8b, prompt: enhanced_prompt, stream: False } ) return response.json()[response] # 测试查询 question 什么是机器学习 answer rag_query(question) print(问题:, question) print(回答:, answer)5.2 优化提示词模板为了让模型更好地利用检索到的信息我们可以优化提示词模板def create_enhanced_prompt(context, question): return f你是一个专业的助手请严格根据提供的参考信息回答问题。 参考信息 {context} 请根据以上参考信息回答下面的问题。如果参考信息中没有相关答案请如实说明根据提供的资料无法回答这个问题。 问题{question} 回答5.3 处理长文档和复杂查询对于更复杂的场景我们可以增加一些高级处理def advanced_rag_query(question, top_k5): # 生成问题向量 response requests.post( http://localhost:11434/api/embeddings, json{model: internlm2:1.8b, prompt: question} ) question_embedding response.json()[embedding] # 检索相关文档 results collection.query( query_embeddings[question_embedding], n_resultstop_k ) # 重组检索结果按相关性排序 contexts [] for doc, metadata in zip(results[documents][0], results[metadatas][0]): contexts.append({ content: doc, source: metadata[source], score: metadata.get(score, 0) }) # 选择最相关的3个上下文 selected_contexts sorted(contexts, keylambda x: x[score], reverseTrue)[:3] context_text \n\n.join([f[来自 {ctx[source]}]\n{ctx[content]} for ctx in selected_contexts]) # 生成增强提示词 prompt create_enhanced_prompt(context_text, question) # 调用模型 response requests.post( http://localhost:11434/api/generate, json{ model: internlm2:1.8b, prompt: prompt, stream: False } ) return { answer: response.json()[response], sources: [ctx[source] for ctx in selected_contexts] }6. 实战应用与效果测试6.1 准备测试文档让我们创建一个简单的测试文档来验证系统效果# 创建示例文档 with open(./test_docs/ai_intro.txt, w, encodingutf-8) as f: f.write(人工智能是计算机科学的一个分支旨在创建能够执行通常需要人类智能的任务的系统。 机器学习是人工智能的一个子领域它使计算机能够在没有明确编程的情况下学习和改进。 深度学习是机器学习的一个分支使用神经网络模拟人脑的工作方式。 自然语言处理使计算机能够理解、解释和生成人类语言。) # 处理文档并建立向量数据库 documents, metadatas, ids process_documents(./test_docs) add_documents_to_db(documents, metadatas, ids)6.2 测试不同类型的问题现在让我们测试系统的效果# 测试直接答案型问题 question1 什么是机器学习 result1 advanced_rag_query(question1) print(问题1:, question1) print(回答1:, result1[answer]) print(参考来源:, result1[sources]) print(- * 50) # 测试推理型问题 question2 机器学习和深度学习有什么关系 result2 advanced_rag_query(question2) print(问题2:, question2) print(回答2:, result2[answer]) print(参考来源:, result2[sources]) print(- * 50) # 测试超出知识范围的问题 question3 人工智能的历史发展是怎样的 result3 advanced_rag_query(question3) print(问题3:, question3) print(回答3:, result3[answer]) print(参考来源:, result3[sources])6.3 性能优化建议在实际使用中你可能需要关注以下优化点# 批量处理Embedding生成减少API调用 def batch_embedding(texts, batch_size10): embeddings [] for i in range(0, len(texts), batch_size): batch texts[i:ibatch_size] # 这里可以使用批量Embedding接口如果支持 for text in batch: response requests.post( http://localhost:11434/api/embeddings, json{model: internlm2:1.8b, prompt: text} ) embeddings.append(response.json()[embedding]) return embeddings # 添加缓存机制 import hashlib from functools import lru_cache lru_cache(maxsize1000) def get_cached_embedding(text): text_hash hashlib.md5(text.encode()).hexdigest() # 先检查本地缓存 if os.path.exists(f./cache/{text_hash}.npy): return np.load(f./cache/{text_hash}.npy) else: response requests.post( http://localhost:11434/api/embeddings, json{model: internlm2:1.8b, prompt: text} ) embedding response.json()[embedding] np.save(f./cache/{text_hash}.npy, embedding) return embedding7. 总结与后续优化通过本文的步骤我们成功搭建了一个基于internlm2-chat-1.8b和Ollama的本地RAG系统。这个系统能够处理本地文档将你的文本文件转换为向量并存储智能检索根据问题找到最相关的文档内容增强生成基于检索到的内容生成准确回答实际使用建议对于技术文档、知识库内容效果最好文档预处理很重要确保文本清晰分段调整chunk_size和top_k参数来优化效果可能的扩展方向支持更多文档格式PDF、Word、网页等添加用户反馈机制持续优化检索效果实现多模态检索支持图片、表格等内容添加对话历史管理支持多轮对话这个本地RAG系统为你提供了一个强大的知识管理工具让你能够基于自己的文档库获得精准的AI辅助。无论是个人学习还是团队协作都能显著提升信息获取和处理的效率。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。

更多文章