当前位置: 首页 > news >正文

LlamaIndex ollama 搭建本地RAG应用,建立本地知识库

目录

    • 简介
    • 安装前的准备
      • 下载ollama
      • 创建llamaindex conda环境,为后面编码作准备
    • 环境变量
    • 迁移ollama到其他盘
    • 运行ollama
      • 方式一
      • 方式二
      • 禁止ollama开机自启动
      • 运行第一个模型
    • Chatbox聊天
      • 下载Chatbox
      • 配置ollama地址和模型
      • 验证
    • 建立自身特定知识数据搭配大语言模型
      • 创建项目环境
      • 代码
      • 运行结果
      • streamlit应用
    • 本文所使用的源码地址
    • 参考

简介

  • ollama:本地运行大型语言模型的工具软件。用户可以轻松下载、运行和管理各种开源 LLM。降低使用门槛,用户能快速启动运行本地模型。
  • LlamaIndex:用来连接大语言模型和外部数据的框架(外部数据指自身领域的特定知识),它将两者结合起来,提升回答的准确性。

安装前的准备

下载ollama

  • ollama官方下载地址 https://ollama.com/download ,目前最新版是0.4.2。
    在这里插入图片描述

创建llamaindex conda环境,为后面编码作准备

  • 为啥要用conda呢?

后面要编码,考虑不同项目依赖的python版本可能不同,用conda来管理,可以快速新增python环境,如果环境搞砸了,用命令删除也很方便。

  • conda下载地址 https://www.anaconda.com/download/success
    在这里插入图片描述

环境变量

参数标识与配置
OLLAMA_MODELS表示模型文件的存放目录,默认目录为当前用户目录C:\Users%username%.ollama\models
Windows 系统 建议不要放在C盘,可放在其他盘(如 d:\software\ollama\models
OLLAMA_HOST表示ollama 服务监听的网络地址,默认为127.0.0.1
如果想要允许其他电脑访问 Ollama(如局域网中的其他电脑),建议设置0.0.0.0
OLLAMA_PORT表示ollama 服务监听的默认端口,默认为11434
如果端口有冲突,可以修改设置成其他端口(如8080等)
OLLAMA_ORIGINS表示HTTP 客户端的请求来源,使用半角逗号分隔列表
如果本地使用不受限制,可以设置成星号 *
OLLAMA_KEEP_ALIVE表示大模型加载到内存中后的存活时间,默认为5m即 5 分钟
(如纯数字300 代表 300 秒,0 代表处理请求响应后立即卸载模型,任何负数则表示一直存活)
建议设置成 24h ,即模型在内存中保持 24 小时,提高访问速度
OLLAMA_NUM_PARALLEL表示请求处理的并发数量,默认为1 (即单并发串行处理请求)
建议按照实际需求进行调整
OLLAMA_MAX_QUEUE表示请求队列长度,默认值为512
建议按照实际需求进行调整,超过队列长度的请求会被抛弃
OLLAMA_DEBUG表示输出 Debug 日志,应用研发阶段可以设置成1 (即输出详细日志信息,便于排查问题)
OLLAMA_MAX_LOADED_MODELS表示最多同时加载到内存中模型的数量,默认为1 (即只能有 1 个模型在内存中)
  • 注意下OLLAMA_HOST,好像会自动创建用户环境变量。本地直接用127.0.0.1。方便调试。
    在这里插入图片描述

  • OLLAMA_MODELS环境建议配置一下,默认是在C盘,一个模型一般是几个G。比较占用空间。
    在这里插入图片描述

迁移ollama到其他盘

  • 由于ollama是直接安装在C盘,C盘如果空间紧张,可以像我一样迁移到D盘,如果觉得没有必要,可忽略此步骤。
    • 方法就是在C盘创建软链接,将真是数据放到D盘。

Administrator 是我的用户名

mklink /D C:\Users\Administrator\.ollama D:\software\Ollama\.ollama
mklink /D C:\Users\Administrator\AppData\Local\Ollama D:\software\Ollama\log
mklink /D C:\Users\Administrator\AppData\Local\Programs\Ollama D:\software\Ollama\app
  • 迁移后的结果
    在这里插入图片描述

运行ollama

方式一

  • 在程序栏中找到
    在这里插入图片描述
    点击就会运行。然后右下角会出现ollama的小图标。
    在这里插入图片描述

方式二

  • 在命令行中输入 ollama serve (我没有独显,是以CPU方式运行的)
    在这里插入图片描述

禁止ollama开机自启动

  • 如果不想让ollama开机自启动,打开任务管理器, 到 启动 栏目,选中右键 -> 禁用止自启动。

在这里插入图片描述

运行第一个模型

  • 打开https://ollama.com/ 网站在输入框中输入qwen。进入qwen2.5-coder,coder表示对编程方面的问题有优化。在这里插入图片描述
  • 在详情页面可以看到各种版本tag。可以根据自身电脑配置情况使用哪一个。一般来说模型越大就越消耗资源。
    在这里插入图片描述
  • 我选择的是当前最新版本。运行的命令是。如何没有就会先下载。
ollama run qwen2.5-coder

在这里插入图片描述

  • 运行后的界面如下图所示。
    在这里插入图片描述
  • 然后我们输入一个问题,验证是否成功。13.8与13.11哪个大?
    在这里插入图片描述
  • 可以看出答案正确,安装成功了。

Chatbox聊天

  • 面对CMD的窗口聊天体验不太好,所以我们用一下Chatbox软件。

下载Chatbox

  • 下载地址 https://chatboxai.app/en
    在这里插入图片描述

配置ollama地址和模型

  • 第一个下拉框选择 ollama , 下面的下拉框选地址和模型配置。
    在这里插入图片描述

验证

  • 我们输入一个问题,验证是否成功。13.8与13.11哪个大?

在这里插入图片描述

  • 结果正确。

  • 然后我们再试一个冷门问题介绍一下CSDN博主愤怒的苹果ext擅长什么?
    在这里插入图片描述

  • 可以看出这个问题它是不知道的。

建立自身特定知识数据搭配大语言模型

  • 一般对于模型不知道或不准确的回答有两种解决方案
    • 1、模型微调。
    • 2、建立自身特定知识数据 + 大语言模型
  • 对于要求准确度不是很高的场景一般会采用建立自身特定知识数据的方案。本文要实践的就是这种方案。

创建项目环境

  • 利用conda创建
 conda create -n llamaindex python=3.10.13conda activate  llamaindex#  安装依赖
pip install llama-index
pip install llama-index-llms-ollama
pip install llama-index-embeddings-ollama
pip install llama-index-readers-file
  • 如果不知道怎么在pycharm中应用conda环境,可以看我这篇文章 https://blog.csdn.net/baidu_19473529/article/details/143442416,就不再赘述。

  • 拉取嵌入模型.

ollama pull quentinz/bge-small-zh-v1.5

代码

  • test.py
 
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.llms.ollama import Ollama
from llama_index.core.node_parser import SentenceSplitter
import logging
import sys# 增加日志信息
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG)
logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
# 配置 嵌入模型/预训练,这里我们用quentinz/bge-small-zh-v1.5
from llama_index.embeddings.ollama import OllamaEmbedding
Settings.embed_model = OllamaEmbedding(model_name="quentinz/bge-small-zh-v1.5")
# 配置ollama的LLM模型,这里我们用qwen2.5-coder
Settings.llm = Ollama(model="qwen2.5-coder", request_timeout=600.0)#特定知识数据
data_file = ['D:/work/self/Llamaindex-sample/data/a.txt']
documents = SimpleDirectoryReader(input_files=data_file).load_data()
index = VectorStoreIndex.from_documents(documents, transformations=[SentenceSplitter(chunk_size=256)])query_engine = index.as_query_engine(similarity_top_k=5)
response = query_engine.query("介绍一下CSDN博主愤怒的苹果ext擅长什么?")
print(response)
  • 特定知识数据内容 a.txt
 CSDN博主愤怒的苹果ext擅长Ai、Fw、Fl、Br、Ae、Pr、Id、Ps等软件的安装与卸载,精通CSS、JavaScript、PHP、ASP、C、C++、C#、Java、Ruby、Perl、Lisp、python、Objective-C、ActionScript、Pascal等单词的拼写,熟悉Windows、Linux、Mac、Android、IOS、WP8等系统的开关机。

运行结果

在这里插入图片描述

  • 可以看出现在的运行结果基本上就是我们想要的结果了。

streamlit应用

  • 通过硬编码的方式去问答没有图形化界面方便,下面引入streamlit就能得到干净好看的Web问答界面了,

  • 命令行运行

 pip install streamlit
  • 代码 app.py
import streamlit as st
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings
from llama_index.embeddings.ollama import OllamaEmbedding
from llama_index.llms.ollama import Ollama
from llama_index.core.memory import ChatMemoryBuffer
import os
import tempfile
import hashlib# OLLAMA_NUM_PARALLEL:同时处理单个模型的多个请求
# OLLAMA_MAX_LOADED_MODELS:同时加载多个模型
os.environ['OLLAMA_NUM_PARALLEL'] = '2'
os.environ['OLLAMA_MAX_LOADED_MODELS'] = '2'# Function to handle file upload
def handle_file_upload(uploaded_files):if uploaded_files:temp_dir = tempfile.mkdtemp()for uploaded_file in uploaded_files:file_path = os.path.join(temp_dir, uploaded_file.name)with open(file_path, "wb") as f:f.write(uploaded_file.getvalue())return temp_dirreturn None# Function to calculate a hash for the uploaded files
def get_files_hash(files):hash_md5 = hashlib.md5()for file in files:file_bytes = file.read()hash_md5.update(file_bytes)return hash_md5.hexdigest()# Function to prepare generation configuration
def prepare_generation_config():with st.sidebar:st.sidebar.header("Parameters")max_length = st.slider('Max Length', min_value=8, max_value=5080, value=4056)temperature = st.slider('Temperature', 0.0, 1.0, 0.7, step=0.01)st.button('Clear Chat History', on_click=clear_chat_history)generation_config = {'num_ctx': max_length,'temperature': temperature}return generation_config# Function to clear chat history
def clear_chat_history():st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,你需要什么帮助吗?"}]# File upload in the sidebar
st.sidebar.header("Upload Data")
uploaded_files = st.sidebar.file_uploader("Upload your data files:", type=["txt", "pdf", "docx"],accept_multiple_files=True)generation_config = prepare_generation_config()# Function to initialize models
@st.cache_resource
def init_models():embed_model = OllamaEmbedding(model_name="quentinz/bge-small-zh-v1.5")Settings.embed_model = embed_modelllm = Ollama(model="qwen2.5-coder", request_timeout=360.0,num_ctx=generation_config['num_ctx'],temperature=generation_config['temperature'])Settings.llm = llmdocuments = SimpleDirectoryReader(st.session_state['temp_dir']).load_data()index = VectorStoreIndex.from_documents(documents)memory = ChatMemoryBuffer.from_defaults(token_limit=4000)chat_engine = index.as_chat_engine(chat_mode="context",memory=memory,system_prompt="You are a chatbot, able to have normal interactions.",)return chat_engine# Streamlit application
st.title("💻 Local RAG Chatbot 🤖")
st.caption("🚀 A RAG chatbot powered by LlamaIndex and Ollama 🦙.")# Initialize hash for the current uploaded files
current_files_hash = get_files_hash(uploaded_files) if uploaded_files else None# Detect if files have changed and init models
if 'files_hash' in st.session_state:if st.session_state['files_hash'] != current_files_hash:st.session_state['files_hash'] = current_files_hashif 'chat_engine' in st.session_state:del st.session_state['chat_engine']st.cache_resource.clear()if uploaded_files:st.session_state['temp_dir'] = handle_file_upload(uploaded_files)st.sidebar.success("Files uploaded successfully.")if 'chat_engine' not in st.session_state:st.session_state['chat_engine'] = init_models()else:st.sidebar.error("No uploaded files.")
else:if uploaded_files:st.session_state['files_hash'] = current_files_hashst.session_state['temp_dir'] = handle_file_upload(uploaded_files)st.sidebar.success("Files uploaded successfully.")if 'chat_engine' not in st.session_state:st.session_state['chat_engine'] = init_models()else:st.sidebar.error("No uploaded files.")# Initialize chat history
if 'messages' not in st.session_state:st.session_state.messages = [{"role": "assistant", "content": "你好,我是你的助手,你需要什么帮助吗?"}]# Display chat messages from history
for message in st.session_state.messages:with st.chat_message(message['role'], avatar=message.get('avatar')):st.markdown(message['content'])# Display chat input field at the bottom
if prompt := st.chat_input("Ask a question about Datawhale:"):with st.chat_message('user'):st.markdown(prompt)# Generate responseprint("st.session_state ",st.session_state)response = st.session_state['chat_engine'].stream_chat(prompt)with st.chat_message('assistant'):message_placeholder = st.empty()res = ''for token in response.response_gen:res += tokenmessage_placeholder.markdown(res + '▌')message_placeholder.markdown(res)# Add messages to historyst.session_state.messages.append({'role': 'user','content': prompt,})st.session_state.messages.append({'role': 'assistant','content': response,})
  • 运行app.py的命令
  streamlit run app.py
  • 运行后将自动打开浏览器页面
    在这里插入图片描述

  • 启动完成后,首先上传外部数据,初始化模型。

在这里插入图片描述

  • 再提问验证是否成功。
    在这里插入图片描述
  • 与前面的回答差不多就表示成功了。

本文所使用的源码地址

  • https://github.com/1030907690/Llamaindex-sample

参考

  • https://juejin.cn/post/7418086006114713619
  • https://blog.llyth.cn/1555.html
  • https://www.bilibili.com/opus/978763969531478024
  • https://github.com/datawhalechina/handy-ollama/blob/main/notebook/C7/LlamaIndex_RAG/%E4%BD%BF%E7%94%A8LlamaIndex%E6%90%AD%E5%BB%BA%E6%9C%AC%E5%9C%B0RAG%E5%BA%94%E7%94%A8.ipynb
http://www.lryc.cn/news/490940.html

相关文章:

  • draggable的el-dialog实现对话框标题可以选择
  • 2024年Android面试总结
  • 树莓派3:64位系统串口(UART)使用问题的解决方法
  • SemiDrive E3 硬件设计系列---唤醒电路设计
  • 淘宝接口高并发采集核心要点解读,开启电商数据智能应用新纪元
  • C#里怎么样快速使用LINQ实现查询?
  • 2024新版微软edge浏览器输入百度网址时自动补全tn=68018901……小尾巴的解决
  • uni-app打包H5自定义微信分享
  • 大模型专栏--大模型应用场景
  • 骑砍2霸主MOD开发(29)-顶点动画
  • -Dspring.profiles.active=dev与--spring.profiles.active=dev的区别
  • 面向对象高级(2)单例设计对象与代码块
  • 47小型项目的规划与实施
  • 堤防安全监测系统方案
  • 聊聊Flink:这次把Flink的window分类(滚动、滑动、会话、全局)、窗口函数讲透
  • mysql-分析MVCC原理
  • 由于答案过大,请对a取模。取模后的答案不是原问题的答案 取模有何意义呢 详解
  • 【c++篇】掌握动态内存的奥妙
  • 5.4.2-3 编写Java程序读取HDFS文件
  • @EnableConfigurationProperties @ConfigurationProperties
  • RK3588适配MTK7921 USB接口WiFi驱动开发
  • 【数据结构OJ】【图论】图综合练习--拓扑排序
  • 模型 I/O 与 LangChain 实践
  • C++:用红黑树封装map与set-1
  • HBU算法设计与分析 贪心算法
  • python pycharm安装教程及基本使用,超详细
  • 变量提升函数提升
  • el-table vue3统计计算数字
  • IDE应当具备的功能
  • Stable Diffusion初步见解(二)