一、前言
向量数据库的核心能力在于存储和检索非结构数据,如文本、图像、音频。多用于RAG(检索增强生成)、推荐系统、多媒体检索等应用场景。 本篇将探索向量数据库的使用,并结合前面Qwen模型的业务场景,进一步提高写作助手中内容生成的质量(即RAG)。
本篇要实现的目标:利用阿里云提供的免费CPU部署Milvus服务, 通过向量数据库可视化工具Attu创建数据库和表,并通过代码写入并检索向量数据,实现Mivlus向量数据库的环境搭建和基础开发!
本专栏最终要实现的架构为:
往期Qwen模型文章:
快速掌握大语言模型-Qwen2-7B-Instruct落地1-CSDN博客
快速掌握大语言模型-Qwen2-7B-Instruct落地2-CSDN博客
二、术语
2.1 向量
在AI领域,向量特指向量嵌入 (Vector Embeddings),即通过机器学习模型将非结构化数据(如文本、图像、音频等)转换为高维数值向量,以捕捉其语义或特征信息。 非结构化数据通过向量化,除了具备语义捕捉能力、还能借助向量数据库专门的索引技术(如近似最近邻搜索)快速处理海量非结构化数据的相似性查询,这是传统数据库难以实现的。
2.2 Milvus
Milvus是一个专为处理高维向量数据设计的开源向量数据库,支持数百亿级数据规模,在多数开源向量数据库中综合表现突出(一般是其他的2~5倍)。
提供三种部署方式:本地调试Milvus Lite、企业级小规模数据的Milvus Standalone(一亿以内向量)、企业级大规模数据的Milvus Distributed (数百亿向量)。
2.3 Attu
Milvus向量数据库的可视化工具,通过Attu可以轻松实现创建数据库、合集(表)、导入并查询数据等功能。
2.4 Conda
Conda允许用户创建多个独立的虚拟环境,每个环境可配置不同的Python版本、软件包及依赖项。例如,为向量数据库项目创建Python 3.10环境,同时为机器学习项目保留Python 3.8环境,实现环境间的完全隔离。
常用命令包括:
- 创建环境:
conda create --name milvus python=3.10
- 激活/退出环境:
conda activate milvus
或 conda deactivate
三、Milvus服务部署
利用阿里云提供的限时免费CPU服务器,部署Milvus Standalone服务
3.1 运行Milvus Standalone
执行下面命令启动Milvus服务,默认启动的Web端口是9091,API端口为19530
3.1.1 下载配置文件
wget https://github.com/milvus-io/milvus/releases/download/v2.5.10/milvus-standalone-docker-compose.yml -O docker-compose.yml
3.1.2 启动服务
sudo docker compose up -d
3.2 阿里云服务器开放端口
阿里云服务器通过安全组开放端口,在安全组选择增加入方向规则,添加9091、19530端口规则
3.3 访问Milvus Web
- 访问地址: http://阿里云公网IP:9091/webui/
3.4 Attu可视化工具
3.4.1 下载Attu并登录
下载地址:https://github.com/zilliztech/attu/releases
3.4.2 创建数据库
3.4.3 创建合集
四、代码
4.1 conda创建Milvus虚拟环境
# 创建名为milvus的虚拟环境
conda create --name milvus python=3.10
# 激活环境
conda activate milvus
# 下载Milvus依赖,并指定到虚拟环境的依赖包中 (虚拟环境路径可以通过conda env list查看)
python -m pip install -U pymilvus --target "E:\soft\anaconda3\envs\milvus\Lib\site-packages"
4.2 新增数据
为了方便说明暂时新增一批假数据,其中内容的向量数据只有10个维度只是为了方便演示,实际业务的维度要根据选取的embedding模型决定, 例如我们选择的bge-large-zh模型的嵌入维度是1024。
from pymilvus import MilvusClient, db
import numpy as np
from pymilvus.orm import collection
# 定义 Milvus 服务的主机地址
host = "阿里云公网IP"
# 创建一个 Milvus 客户端实例,连接到指定的 Milvus 服务
client = MilvusClient(uri=f"http://{host}:19530",db_name="db001") # 连接到 Milvus 服务并选择数据库 "db001"
collection_name = "writing_demon" # 指定要连接的集合名称 "writing_demon"
data = [
{"content_vector": [0.358037489, -0.605049978, 0.1841401835, -0.2201354, 0.902943892, 0.1988681388, 0.06012088, 0.6976997, 0.24442501, 0.848104], "content_full": "你好啊", "biz_id": 2343},
{"content_vector": [0.45127891, -0.34567823, 0.87654321, -0.12345678, 0.56789012, 0.23456789, -0.65432109, 0.34567891, -0.78901234, 0.43210987], "content_full": "今天天气怎么样?", "biz_id": 2344},
{"content_vector": [-0.12345678, 0.65432109, -0.34567891, 0.78901234, -0.23456789, 0.56789012, -0.87654321, 0.45127891, -0.60234957, 0.18414013], "content_full": "请问有什么可以帮助您?", "biz_id": 2345},
{"content_vector": [0.78901234, -0.23456789, 0.56789012, -0.87654321, 0.45127891, -0.60234957, 0.18414013, -0.34567891, 0.65432109, -0.12345678], "content_full": "很高兴为您服务!", "biz_id": 2346},
{"content_vector": [-0.65432109, 0.34567891, -0.78901234, 0.23456789, -0.56789012, 0.87654321, -0.45127891, 0.60234957, -0.18414013, 0.34567823], "content_full": "请问需要咨询什么问题?", "biz_id": 2347},
{"content_vector": [0.23456789, -0.56789012, 0.87654321, -0.45127891, 0.60234957, -0.18414013, 0.34567823, -0.78901234, 0.12345678, -0.65432109], "content_full": "感谢您的耐心等待", "biz_id": 2348},
{"content_vector": [-0.78901234, 0.23456789, -0.56789012, 0.87654321, -0.45127891, 0.60234957, -0.18414013, 0.34567823, -0.12345678, 0.65432109], "content_full": "您的订单已确认", "biz_id": 2349},
{"content_vector": [0.56789012, -0.87654321, 0.45127891, -0.60234957, 0.18414013, -0.34567823, 0.78901234, -0.23456789, 0.65432109, -0.12345678], "content_full": "请提供更多详细信息", "biz_id": 2350},
{"content_vector": [-0.34567891, 0.78901234, -0.23456789, 0.56789012, -0.87654321, 0.45127891, -0.60234957, 0.18414013, -0.34567823, 0.78901234], "content_full": "您的请求已处理", "biz_id": 2351},
{"content_vector": [0.60234957, -0.18414013, 0.34567823, -0.78901234, 0.12345678, -0.65432109, 0.23456789, -0.56789012, 0.87654321, -0.45127891], "content_full": "请核对您的信息", "biz_id": 2352},
{"content_vector": [-0.45127891, 0.60234957, -0.18414013, 0.34567823, -0.78901234, 0.12345678, -0.65432109, 0.23456789, -0.56789012, 0.87654321], "content_full": "操作成功完成", "biz_id": 2353},
{"content_vector": [0.18414013, -0.34567823, 0.78901234, -0.12345678, 0.65432109, -0.23456789, 0.56789012, -0.87654321, 0.45127891, -0.60234957], "content_full": "欢迎再次访问", "biz_id": 2354},
{"content_vector": [-0.87654321, 0.45127891, -0.60234957, 0.18414013, -0.34567823, 0.78901234, -0.12345678, 0.65432109, -0.23456789, 0.56789012], "content_full": "您的反馈已收到", "biz_id": 2355},
{"content_vector": [0.34567823, -0.78901234, 0.12345678, -0.65432109, 0.23456789, -0.56789012, 0.87654321, -0.45127891, 0.60234957, -0.18414013], "content_full": "系统正在处理中", "biz_id": 2356},
{"content_vector": [-0.23456789, 0.56789012, -0.87654321, 0.45127891, -0.60234957, 0.18414013, -0.34567823, 0.78901234, -0.12345678, 0.65432109], "content_full": "请保持网络畅通", "biz_id": 2357},
{"content_vector": [0.65432109, -0.12345678, 0.60234957, -0.18414013, 0.34567823, -0.78901234, 0.23456789, -0.56789012, 0.87654321, -0.45127891], "content_full": "验证码已发送", "biz_id": 2358},
{"content_vector": [-0.56789012, 0.87654321, -0.45127891, 0.60234957, -0.18414013, 0.34567823, -0.78901234, 0.12345678, -0.65432109, 0.23456789], "content_full": "密码重置成功", "biz_id": 2359},
{"content_vector": [0.78901234, -0.23456789, 0.56789012, -0.87654321, 0.45127891, -0.60234957, 0.18414013, -0.34567823, 0.65432109, -0.12345678], "content_full": "账户余额不足", "biz_id": 2360},
{"content_vector": [-0.12345678, 0.65432109, -0.23456789, 0.56789012, -0.87654321, 0.45127891, -0.60234957, 0.18414013, -0.34567823, 0.78901234], "content_full": "服务即将到期", "biz_id": 2361},
{"content_vector": [0.45127891, -0.60234957, 0.18414013, -0.34567823, 0.78901234, -0.12345678, 0.65432109, -0.23456789, 0.56789012, -0.87654321], "content_full": "优惠券已领取", "biz_id": 2362}
]
res = client.insert(
collection_name= collection_name,
data=data
)
执行后通过Attu查看数据
4.3 查询数据
通过向量查询相似度最高的一条数据
import numpy as np
from pymilvus.orm import collection
# 定义 Milvus 服务的主机地址
host = "阿里云公网IP"
# 创建一个 Milvus 客户端实例,连接到指定的 Milvus 服务
client = MilvusClient(uri=f"http://{host}:19530",db_name="db001") # 连接到 Milvus 服务并选择数据库 "db001"
collection_name = "writing_demon" # 指定要连接的集合名称 "writing"
# 示例向量,查询需要二维数组
query_vector = [[0.358037489, -0.605049978, 0.1841401835, -0.2201354, 0.902943892, 0.1988681388, 0.06012088, 0.6976997, 0.24442501, 0.848104]]
res = client.search(
collection_name= collection_name, # 合集名称
data=query_vector, # 查询向量
search_params={
"metric_type": "COSINE", # 向量相似性度量方式,COSINE 表示余弦相似度(适用于文本/语义相似性场景); 可选 IP/COSINE/L2
"params": {"level":1},
}, # 搜索参数
limit=1, # 查询结果数量
output_fields=["id","content","biz_id"], # 查询结果需要返回的字段
consistency_level="Bounded" # 数据一致性级别,Bounded允许在有限时间窗口内读取旧数据,相比强一致性(STRONG)提升 20 倍查询性能,适合高吞吐场景;
)
print(res)