(2)Lora
这种方法有点类似于矩阵分解,可训练层维度和预训练模型层维度一致为d,先将维度d通过全连接层降维至r,再从r通过全连接层映射回d维度,r<
【注意】安装的时候,如果第一次安装错了版本,直接重新走下面的步骤的时候很可能启动时,milvus-minio秒退!!
(1)创建目录:
mkdir Milvus
(2)下载YAML文件
wget https://github.com/milvus-io/milvus/releases/download/v2.1.4/milvus-standalone-docker-compose.yml -O docker-compose.yml
(3)在YAML文件所在目录下启动Milvus
sudo docker compose up -d # docker v2,若是v1则使用docker-compose;使用docker compose version查看docker版本
【注意】
① 如果没有docker命令,则安装:
sudo snap install docker
② 这个命令开始执行之后会自动下载Milvus对应的镜像文件,需要等待一段时间。 当镜像下载完成后,相应的容器也会启动。
(4)查看Milvus的启动状态:
sudo docker compose ps
(5)停止Milvus
sudo docker compose down
(1) Milvus_cli
(2) Attu可视化管理界面官方安装教程
400 Bad Request
。milvus | attu |
---|---|
2.0.x | 2.0.5 |
2.1.x | 2.1.5 |
2.2.x | 2.2.6 |
① 使用Docker Compose方式进行安装,
step1:通过Docker Compose方式安装完成milvus(即下载完YAML文件);
step2:编辑下载好的YAML文件,在service语句块添加以下内容:
attu:
container_name: attu
image: zilliz/attu:v2.1.5
environment:
MILVUS_URL: milvus-standalone:19530
ports:
- "8001:3000" # 我的8000端口一直提示被占用,所以换成了8001端口
depends_on:
- "standalone"
step3:启动milvus:sudo docker-compose up -d
② 使用docker安装
docker run -p 8001:3000 -e MILVUS_URL={your machine IP}:19530 zilliz/attu:v2.1.5
step4:安装完成后,在连网的浏览器输入:http://{ your machine IP }:8001即可进入attu登录界面。
(your machine IP为安装milvus的机器ip;下图为attu的登陆界面,没有放开账号密码认证。)
pymilvus.exceptions.MilvusException:
Milvus | pymilvus |
---|---|
2.2.12 | 2.2.14 |
2.2.11 | 2.2.13 |
2.1.4 | 2.1.3 |
2.1.2 | 2.1.2 |
数据类型 | 说明 |
---|---|
NONE | |
BOOL | |
INT8 | 支持主键字段 |
INT16 | 支持主键字段 |
INT32 | 支持主键字段 |
INT64 | 支持主键字段 |
FLOAT | |
DOUBLE | |
STRING | |
VARCHAR | |
BINARY_VECTOR | 二值型向量,可以在该类型字段上创建索引 (适用下表中的后两种索引) |
FLOAT_VECTOR | 浮点型向量,可以在该类型字段上创建索引(适用下表中的前九种索引) |
UNKNOWN |
索引类型 | 说明 | 可用的度量类型 |
---|---|---|
FLAT | 适用于需要 100% 召回率且数据规模相对较小(百万级)的向量相似性搜索应用 | “L2”, “IP” |
IVFLAT / IVF_FLAT | 基于量化的索引,适用于追求查询准确性和查询速度之间理想平衡的场景(高速查询、要求高召回率) | “L2”, “IP” |
IVF_SQ8 | 基于量化的索引,适用于磁盘或内存、显存资源有限的场景(高速查询、磁盘和内存资源有限、接受召回率的小幅妥协) | “L2”, “IP” |
IVF_PQ | 基于量化的索引,适用于追求高查询速度、低准确性的场景(超高速查询、磁盘和内存资源有限、接受召回率的实质性妥协) | “L2”, “IP” |
HNSW | 基于图的索引,适用于追求高查询效率的场景(高速查询、要求尽可能高的召回率、内存资源大的情景) | “L2”, “IP” |
ANNOY | 基于树的索引,适用于追求高召回率的场景(低维向量空间) | “L2”, “IP” |
RHNSW_FLAT | 基于量化和图的索引,高速查询、需要尽可能高的召回率、内存资源大的情景 | “L2”, “IP” |
RHNSW_PQ | 基于量化和图的索引,超高速查询、磁盘和内存资源有限、接受召回率的实质性妥协 | “L2”, “IP” |
RHNSW_SQ | 基于量化和图的索引,高速查询、磁盘和内存资源有限、接受召回率的小幅妥协 | “L2”, “IP” |
BIN_FLAT | - | “JACCARD”, “TANIMOTO”, “HAMMING”, “SUBSTRUCTURE”, “SUPERSTRUCTURE” |
BIN_IVF_FLAT | - | “JACCARD”, “TANIMOTO”, “HAMMING” |
(1)创建conda环境Milvus,并安装pymilvus
pip install pymilvus
【注意】操作时使用docker-compose ps -a
查看milvus运行状态,确保milvus容器处在开启状态。
pip install faiss-cpu==1.7.3
# 或者conda环境中安装
conda install faiss-cpu -c pytorch # cpu 版本
conda install faiss-gpu cudatoolkit=8.0 -c pytorch # GPU 版本 For CUDA8
python中使用:
# langchain中的模块
from langchain.vectorstores import Pinecone
GitHub网址:https://github.com/pgvector/pgvector
详细内容参见博客:https://blog.csdn.net/lucky_chaichai/article/details/118575261
已知信息:{context}
根据上述已知信息,简洁和专业的来回答用户的问题。如果无法从中得到答案,请说 “根据已知信息无法回答该问题” 或 “没有提供足够的相关信息”,不允许在答案中添加编造成分,答案请使用中文。
问题是:{question}
pip install langchain
LLM API模块:langchain.llms
文本分块器:langchain.text_splitter(text_splitter中常用分类器介绍)
向量模型加载、向量化模块:langchain.embeddings
向量存储、索引模块:from langchain.vectorstores import Milvus, FAISS, Pinecone, Chroma
文件操作模块:langchain.docstore、angchain.document_loaders
langchain.agents
‘\n’
换行不起作用,需要替换为‘
’
;gr.Interface()、gr.Blocks()两种方式搭建UI界面:
组件/事件监听器 | 描述 |
---|---|
State(value) | 隐藏组件,用于存储一些组件交互需要使用的变量,可以通过组件之间的交互改变其值,可以使用obj.value获取其值 |
Markdown(value) | Markdown格式的文本输入输出,在页面上遵循Markdown规范显示文本(value) |
Tab(value) | “标签页”布局组件,在一个页面上可以多个tab切换,value为tab上显示的文字 |
Row(variant) | 行类型,“default”(无背景)、“panel”(灰色背景色和圆角)或“compact”(圆角和无内部间隙) |
Column(scale) | “列布局”组件,scale为与相邻列相比的相对宽度 |
Accordion(label) | 折叠框组件, label为折叠筐的名称(会显示在组件上) |
Chatbot(value) | 对话框组件,value为对话框默认值,一般为 [[我方None, 他方init_message], …],该组件在“触发”的fn函数中一般作为上述格式的list使用 |
Textbox(placeholder) | 文本框组件,placeholder为在文本区域提供占位符提示的字符串 |
Radio() | |
Button(value, interactive) | 按钮组件,value为按钮上面显示的文字;interactive=False则按钮为禁用状态 |
Dropdown(choices, label, value) | 下拉框组件,choices为list,其中元素为可选项;label下拉框的名称(会显示在组件上);value为list中的默认选项 |
Number(value, label) | 创建数字输入和显示数字输出的组件,value为该组件默认值,label为该组件名称(会显示在组件上) |
change(fn, input, output) | 触发事件,当前组件(如Dropdown)的输入值改变时将会触发这个事件,fn根据输入input生成输出output,input、output均为组件或组件列表,fn的每个参数对应一个输入组件,每个返回值对应一个输出组件 |
click(fn, input, output) | 触发事件,当前组件(如Button)点击时将会触发这个事件 |
setup() | |
submit(fn, input, output) | 触发事件,当前组件(如Textbox)提交(回车)时将会触发这个事件 |
streamlit run webui_st.py
简单的聊天对话框示例:
import time
import streamlit as st
class MsgType:
'''
目前仅支持文本类型的输入输出,为以后多模态模型预留图像、视频、音频支持。
'''
TEXT = 1
IMAGE = 2
VIDEO = 3
AUDIO = 4
class ST_CONFIG:
user_bg_color = '#77ff77'
user_icon = 'https://tse2-mm.cn.bing.net/th/id/OIP-C.LTTKrxNWDr_k74wz6jKqBgHaHa?w=203&h=203&c=7&r=0&o=5&pid=1.7'
robot_bg_color = '#ccccee'
robot_icon = 'https://ts1.cn.mm.bing.net/th/id/R-C.5302e2cc6f5c7c4933ebb3394e0c41bc?rik=z4u%2b7efba5Mgxw&riu=http%3a%2f%2fcomic-cons.xyz%2fwp-content%2fuploads%2fStar-Wars-avatar-icon-C3PO.png&ehk=kBBvCvpJMHPVpdfpw1GaH%2brbOaIoHjY5Ua9PKcIs%2bAc%3d&risl=&pid=ImgRaw&r=0'
default_mode = '知识库问答'
defalut_kb = ''
def robot_say(msg, kb=''):
st.session_state['history'].append(
{'is_user': False, 'type': MsgType.TEXT, 'content': msg, 'kb': kb})
def user_say(msg):
st.session_state['history'].append(
{'is_user': True, 'type': MsgType.TEXT, 'content': msg})
def format_md(msg, is_user=False, bg_color='', margin='10%'):
'''
将文本消息格式化为markdown文本, 指定user 和 robot消息背景色、左右位置等
Parameters
----------
msg: 文本内容
bg_color: 指定markdown文本的背景颜色
'''
if is_user:
bg_color = bg_color or ST_CONFIG.user_bg_color
text = f'''
{bg_color};
margin-left:{margin};
word-break:break-all;
float:right;
padding:2%;
border-radius:2%;">
{msg}
'''
else:
bg_color = bg_color or ST_CONFIG.robot_bg_color
text = f'''
{bg_color};
margin-right:{margin};
word-break:break-all;
padding:2%;
border-radius:2%;">
{msg}
'''
return text
def message(msg,
is_user=False,
msg_type=MsgType.TEXT,
icon='',
bg_color='',
margin='10%',
kb='',
):
'''
渲染单条消息(包括双方头像、聊天文本)。目前仅支持文本
返回第2列对象
'''
# 定义界面中的列,若参数为一个整数n,则意为插入n个等尺寸列;若为列表[1, 10, 1]则意为插入3列,数值为各列之间的倍数(数值为小数,则指占界面百分比)
# 该函数中,列cols[0]为robot头像,cols[2]为user头像,cols[1]为聊天消息(markdown文本)
cols = st.columns([1, 10, 1])
empty = cols[1].empty() # 将第2列初始化为空
if is_user:
icon = icon or ST_CONFIG.user_icon
bg_color = bg_color or ST_CONFIG.user_bg_color
cols[2].image(icon, width=40) # 第3列展示user头像
if msg_type == MsgType.TEXT:
text = format_md(msg, is_user, bg_color, margin)
empty.markdown(text, unsafe_allow_html=True) # 将第2列填充user的Markdown文本
else:
raise RuntimeError('only support text message now.')
else:
icon = icon or ST_CONFIG.robot_icon
bg_color = bg_color or ST_CONFIG.robot_bg_color
cols[0].image(icon, width=40) # 第1列展示robot头像
if kb:
cols[0].write(f'({kb})') # 用于向Web应用程序添加任何内容??
if msg_type == MsgType.TEXT:
text = format_md(msg, is_user, bg_color, margin)
empty.markdown(text, unsafe_allow_html=True) # 将第2列填充robot的Markdown文本
else:
raise RuntimeError('only support text message now.')
return empty
def output_messages(
user_bg_color='',
robot_bg_color='',
user_icon='',
robot_icon='',
):
with chat_box.container(): # 为st添加一个多元素容器(chat_box为前面定义的st的占位符)
last_response = None
for msg in st.session_state['history']:
bg_color = user_bg_color if msg['is_user'] else robot_bg_color
icon = user_icon if msg['is_user'] else robot_icon
empty = message(msg['content'],
is_user=msg['is_user'],
icon=icon,
msg_type=msg['type'],
bg_color=bg_color,
kb=msg.get('kb', '')
)
if not msg['is_user']:
last_response = empty
return last_response
if __name__ == "__main__":
webui_title = """
langchain-ChatGLM WebUI
"""
robot_say_ininfo = ('您好:\n\n'
'欢迎使用本机器人聊天界面(初版),基于streamlit我还在努力中哦~~') # 注意这个写法,只有一对引号的话第二行会为其他背景色
LLM_MODEL = 'baichuan-130b'
EMBEDDING_MODEL = 'ernie-3.0-base-zh'
modes = ['LLM 对话', '知识库问答', 'Bing搜索问答', '知识库测试']
st.set_page_config(webui_title, layout='wide') # webui_title是浏览器选项卡中显示的页面标题
# session_state在st rerun过程中定义、存储共享变量,可以存储任何对象;只可能在应用初始化时被整体重置。而rerun不会重置session state。
# 调用其中变量的方法:st.session_state.[变量的key]
st.session_state.setdefault('history', []) # history为变量的key,[]为初始值
# 定义“等待提示”,注意每次对界面操作都会加载一次!!!?
with st.spinner(f'正在加载模型({LLM_MODEL} + {EMBEDDING_MODEL}),请耐心等候...'):
time.sleep(2)
# 定义侧边栏
with st.sidebar:
robot_say(robot_say_ininfo)
def on_mode_change():
m = st.session_state.mode
robot_say(f'已切换到"{m}"模式')
index = 0
mode = st.selectbox('对话模式', modes, index,
on_change=on_mode_change, key='mode') # on_change为复选框操作出发的变化函数
print('mode:', mode) # 打印的结果即为mode里面的值(字符串)
chat_box = st.empty() # 为st应用添加一个占位符
# 创建表单容器,clear_on_submit=True表示在用户按下提交按钮后,表单内的所有小部件都将重置为其默认值
with st.form('my_form', clear_on_submit=True):
cols = st.columns([8, 1])
question = cols[0].text_input(
'temp', key='input_question', label_visibility='collapsed') # 第1列为文本输入框
print('question:', question) # 打印结果即为文本框中输入的文本
def on_send():
q = st.session_state.input_question
user_say(q)
print("st.session_state['history']:", st.session_state['history'])
last_response = output_messages()
# last_response.markdown(
# format_md(st.session_state['history'][-1]['content'], False),
# unsafe_allow_html=True
# )
submit = cols[1].form_submit_button('发送', on_click=on_send) # 第2列为按钮,on_click为点击按钮出发的操作函数
output_messages() # 不执行这个函数页面会不展示聊天历史
import openai
openai.api_key = "EMPTY"
openai.api_base = "http://localhost:8000/v1"
def test_chat_completion_stream(model = "chatglm2-6b"):
# 流式的测试,参考:https://github.com/lm-sys/FastChat/blob/main/tests/test_openai_api.py
messages = [
{"role": "user",
"content": "Hello! What is your name?"}
]
res = openai.ChatCompletion.create(model=model, messages=messages, stream=True)
for chunk in res:
content = chunk["choices"][0]["delta"].get("content", "")
print(content, end="", flush=True)
print()
def text_chat_completion(model = "chatglm2-6b"):
# create a chat completion
completion = openai.ChatCompletion.create(
model=model,
messages=[{"role": "user", "content": "Hello! What is your name?"}]
)
# print the completion
print(completion.choices[0].message.content)
【注意】(Ubuntu)在输入问题的时候删除错别字重新输入后,回车会报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe3 in position 15: invalid continuation byte
1)安装
pip install fschat
1)安装
pip install fastapi
pip install uvicorn
其他参考:
从LangChain+LLM的本地知识库问答到LLM与知识图谱、数据库的结合