从零开始搭建向量数据库:基于 Xinference 和 Milvus 的文本搜索实践

news2025/7/15 4:18:39
引言

在 AI 和大数据时代,向量数据库正成为处理非结构化数据(如文本、图像)的利器。最近,我尝试用 Xinference 和 Milvus 搭建一个简单的文本搜索系统,从读取本地文本文件到实现交互式查询和高亮显示匹配结果,整个过程充满了挑战和乐趣。这篇文章将分享我的实践步骤、技术难点及解决方案,希望能帮助有同样兴趣的朋友少走弯路。

项目目标

我的目标是:

  1. 从本地 document.txt 文件读取多条文本数据(例如 name:liubao,age:32)。
  2. 使用 Xinference生成文本的嵌入向量。
  3. 将向量存储到 Milvus中,构建向量数据库。
  4. 实现交互式查询功能,返回相似文本并高亮匹配部分。

硬件环境:一台普通的 Windows 电脑(16GB 内存,无 GPU),纯 CPU 运行。16G很勉强,idea直接就干你一半内存,你气不气

技术选型
  • Xinference:一个轻量级推理框架,支持多种嵌入模型,我选择了 bge-small-en-v1.5,适合 CPU 环境。
  • Milvus:开源向量数据库,用于存储和搜索嵌入向量。
  • Python:核心编程语言,搭配 requests、pymilvus 和 colorama 等库。
  • Docker:运行 Milvus 服务。
实现步骤

1. 环境搭建

  • 安装 Conda 和 Python:我创建了一个名为 xiangliang 的 Conda 环境,使用 Python 3.10。
    conda create -n xiangliang python=3.10
    conda activate xiangliang
  • 安装 Xinference
    pip install xinference
    注意:我原本也尝试用 Docker 运行 Xinference 时遇到启动问题,最终切换到本地 Conda 部署。
  • 安装 Milvus: 使用 Docker 部署 standalone 版本:
    去下载docker-compose.yml,注意重命名改成docker-compose.yml,然后运行
    docker compose up -d
    #如果你是老版本的用docker-compose up -d
  • 下载attu可视化向量数据库管理工具:Releases · zilliztech/attu · GitHub
    默认直接登录就行
  • 安装依赖
    pip install pymilvus requests torch --index-url https://download.pytorch.org/whl/cpu
    pip install transformers colorama
2. 数据准备

我创建了一个 document.txt 文件,包含 10 条测试数据,例如:

name:liubao,age:32
name:zhangwei,age:25
name:lihua,age:40
name:wangming,age:28
name:chenxi,age:35
name:yangyang,age:22
name:zhaojie,age:45
name:liuyi,age:30
name:sunhao,age:27
name:zhouqi,age:33

这些数据模拟了简单的个人信息,用于测试搜索效果。

3. 初始化向量数据库

脚本 test.py 负责读取文件、生成向量并存储到 Milvus:

import requests
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
import re

# 读取文件
with open("document.txt", "r", encoding="utf-8") as file:
    lines = file.readlines()
texts = [re.sub(r'\s+', ' ', line).strip() for line in lines if line.strip()]

# Xinference 生成向量
model_url = "http://localhost:9997/v1/models"
payload = {"model_name": "bge-small-en-v1.5", "model_type": "embedding"}
response = requests.post(model_url, json=payload)
model_uid = response.json()["model_uid"]
embed_url = "http://localhost:9997/v1/embeddings"
embeddings = [requests.post(embed_url, json={"model": model_uid, "input": text}).json()["data"][0]["embedding"] for text in texts]

# 存储到 Milvus
connections.connect(host='localhost', port='19530')
fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True),
    FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=384),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=65535)
]
collection = Collection(name="text_collection", schema=CollectionSchema(fields=fields))
collection.drop()  # 清理旧数据
collection = Collection(name="text_collection", schema=CollectionSchema(fields=fields))
ids = list(range(1, len(texts) + 1))
collection.insert([ids, embeddings, texts])
collection.create_index("embedding", {"metric_type": "COSINE", "index_type": "IVF_FLAT", "params": {"nlist": 1024}})
collection.load()

print("Inserted", collection.num_entities, "entities")

运行前启动 Xinference:

xinference-local

在xiangliang的虚拟环境中运行python test.py正常情况下会生成数据到向量数据库中

4. 实现交互式查询和高亮

脚本 query.py 提供交互式搜索功能,并高亮匹配结果:

import requests
from pymilvus import connections, Collection
import re
from colorama import init, Fore, Style

init()  # 初始化 colorama

connections.connect(host='localhost', port='19530')
collection = Collection(name="text_collection")
collection.load()

model_uid = "bge-small-en-v1.5-a5JDNlUy"
embed_url = "http://localhost:9997/v1/embeddings"

def highlight_match(text, query):
    pattern = re.compile(re.escape(query), re.IGNORECASE)
    return pattern.sub(f"{Fore.RED}{Style.BRIGHT}\\g<0>{Style.RESET_ALL}", text)

def search_query(query_text):
    payload = {"model": model_uid, "input": query_text}
    query_embedding = requests.post(embed_url, json=payload).json()["data"][0]["embedding"]
    results = collection.search(
        data=[query_embedding],
        anns_field="embedding",
        param={"metric_type": "COSINE", "params": {"nprobe": 10}},
        limit=5,
        output_fields=["text"]
    )
    threshold = 0.7
    found = False
    for result in results[0]:
        similarity = result.distance
        if similarity >= threshold:
            text = result.entity.get("text")
            highlighted_text = highlight_match(text, query_text)
            print(f"Similarity: {similarity:.4f}, Text: {highlighted_text}...")
            found = True
    if not found:
        print(f"没有找到相似度高于 {threshold} 的结果")

while True:
    query = input("请输入查询词(输入 'exit' 退出):")
    if query.lower() == "exit":
        break
    search_query(query)

可以看到根据搜索词,分值高的在前,匹配上的高亮了 

5. 技术难点与解决方案
  • Xinference 模型选择:最初尝试用 all-MiniLM-L6-v2,但 Xinference 不支持,最终改为内置的 bge-small-en-v1.5。
  • 连接问题:多次遇到 ConnectionRefusedError,通过确保 xinference-local 运行并检查端口解决。
  • 高亮显示:Windows CMD 不支持 ANSI 码,引入 colorama 实现跨平台兼容。
  • 单一结果问题:初始数据只有一条,查询总是返回它,后来增加了多条数据并设置相似度阈值。
成果展示
  • 输入 liubao:返回高亮的 name:liubao,age:32,相似度约 0.85。
  • 输入 25:返回 name:zhangwei,age:25,相似度约 0.82。
  • 输入无关词 xyz:显示“没有找到相似度高于 0.7 的结果”。
总结与反思

这个项目让我深入理解了向量数据库的工作原理,从文本嵌入到相似性搜索的全流程。虽然只用了 CPU,但性能完全满足小型应用需求。未来可以尝试:

  • 扩展数据规模,测试更大集合的性能。
  • 优化查询速度,例如调整 Milvus 的索引参数。
  • 将结果输出到 Web 界面,增强用户体验。

最后:简单的整体过程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2319682.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

scrapy入门(深入)

Scrapy框架简介 Scrapy是:由Python语言开发的一个快速、高层次的屏幕抓取和web抓取框架&#xff0c;用于抓取web站点并从页面中提取结构化的数据&#xff0c;只需要实现少量的代码&#xff0c;就能够快速的抓取。 新建项目 (scrapy startproject xxx)&#xff1a;新建一个新的…

docker模拟Dos_SYN Flood拒绝服务攻击 (Ubuntu20.04)

目录 ✅ 一、实验环境准备&#xff08;3 个终端&#xff09; &#x1f449; 所以最终推荐做法&#xff1a; 2️⃣ 配置 seed-attacker 为攻击者&#xff0c;开启 telnet 服务&#xff1a; 3️⃣ 配置 victim-10.9.0.5 为受害者服务器&#xff0c;开启 telnet 客户端并监听&…

基于PySide6的CATIA自动化工具开发实战——空几何体批量清理系统

一、功能概述 本工具通过PySide6构建用户界面&#xff0c;结合PyCATIA库实现CATIA V5的自动化操作&#xff0c;提供两大核心功能&#xff1a; ​空几何体清理&#xff1a;智能识别并删除零件文档中的无内容几何体&#xff08;Bodies&#xff09;​空几何图形集清理&#xff1…

Spring 声明式事务应该怎么学?

1、引言 Spring 的声明式事务极大地方便了日常的事务相关代码编写&#xff0c;它的设计如此巧妙&#xff0c;以至于在使用中几乎感觉不到它的存在&#xff0c;只需要优雅地加一个 Transactional 注解&#xff0c;一切就都顺理成章地完成了&#xff01; 毫不夸张地讲&#xff…

从 0 到 1 掌握鸿蒙 AudioRenderer 音频渲染:我的自学笔记与踩坑实录(API 14)

最近我在研究 HarmonyOS 音频开发。在音视频领域&#xff0c;鸿蒙的 AudioKit 框架提供了 AVPlayer 和 AudioRenderer 两种方案。AVPlayer 适合快速实现播放功能&#xff0c;而 AudioRenderer 允许更底层的音频处理&#xff0c;适合定制化需求。本文将以一个开发者的自学视角&a…

支持多系统多协议且可提速的下载工具

在网络下载需求日益多样的当下&#xff0c;一款好用的下载器能极大提升效率。今天就给大家介绍 AB Download Manager&#xff0c;它免费又开源&#xff0c;能适配 Windows 和 Linux 系统&#xff0c;带来超便捷的下载体验。 AB Download Manager 采用先进的多线程技术&#xf…

如何在 HTML 中创建一个有序列表和无序列表,它们的语义有何不同?

大白话如何在 HTML 中创建一个有序列表和无序列表&#xff0c;它们的语义有何不同&#xff1f; 1. HTML 中有序列表和无序列表的基本概念 在 HTML 里&#xff0c;列表是一种用来组织信息的方式。有序列表就是带有编号的列表&#xff0c;它可以让内容按照一定的顺序呈现&#…

【武汉·4月11日】Parasoft联合光庭信息研讨会|邀您共探AI赋能新机遇

Parasoft联合光庭信息Workshop邀您共探AI赋能新机遇 AI浪潮已至&#xff0c;你准备好了吗&#xff1f; 在智能网联汽车飞速发展的今天&#xff0c;AI技术正以前所未有的速度重塑行业生态。如何把握AI机遇&#xff0c;赋能企业创新&#xff1f; 4月11日&#xff0c;自动化软件…

闻所闻尽:穿透声音的寂静,照见生命的本真

在《楞严经》的梵音缭绕中&#xff0c;"闻所闻尽"四个字如晨钟暮鼓&#xff0c;叩击着每个修行者的心门。这个源自观世音菩萨耳根圆通法门的核心概念&#xff0c;既是佛门修行的次第指引&#xff0c;更蕴含着东方哲学对生命本质的终极叩问。当我们穿越时空的帷幕&…

VLAN综合实验报告

一、实验拓扑 网络拓扑结构包括三台交换机&#xff08;LSW1、LSW2、LSW3&#xff09;、一台路由器&#xff08;AR1&#xff09;以及六台PC&#xff08;PC1-PC6&#xff09;。交换机之间通过Trunk链路相连&#xff0c;交换机与PC、路由器通过Access或Hybrid链路连接。 二、实验…

Midjourney使用教程—2.作品修改

当您已生成第一张Midjourney图像的时候&#xff0c;接下来该做什么&#xff1f;了解我们用于修改图像的工具&#xff01;使用 Midjourney 制作图像后&#xff0c;您的创意之旅就不会止步于此。您可以使用各种工具来修改和增强图像。 一、放大操作 Midjourney每次会根据提示词…

3.5 平滑滤波

请注意:笔记内容片面粗浅&#xff0c;请读者批判着阅读&#xff01; 一、引言 平滑空间滤波是数字图像处理中用于降低噪声和模糊细节的核心技术&#xff0c;常用于图像预处理或特定场景下的视觉效果优化。其核心思想是通过邻域像素的加权平均或统计操作&#xff0c;抑制高频噪…

Sympy入门之微积分基本运算

Sympy是一个专注于符号数学计算的数学工具&#xff0c;使得用户可以轻松地进行复杂的符号运算&#xff0c;如求解方程、求导数、积分、级数展开、矩阵运算等。本文&#xff0c;我们将详细讲解Sympy在微积分运算中的应用。 获取方式 pip install -i https://mirrors.tuna.tsin…

Qemu-STM32(十):STM32F103开篇

简介 本系列博客主要描述了STM32F103的qemu模拟器实现&#xff0c;进行该项目的原因有两点: 作者在高铁上&#xff0c;想在STM32F103上验证一个软件框架时&#xff0c;如果此时掏出开发板&#xff0c;然后接一堆的线&#xff0c;旁边的人估计会投来异样的目光&#xff0c;特别…

在 ABAP 开发工具 (ADT-ABAP Development Tools) 中创建ABAP 项目

第一步&#xff1a;安装 SAP NetWeaver 的 ABAP 开发工具 (ADT) 开发工具下载地址&#xff1a;https://tools.hana.ondemand.com/#abap 也可以在SAP Development Tools下载工具页面直接跳转到对应公开课教程页面&#xff0c;按课程步骤下载eclipse解压安装即可&#xff0c;过程…

【架构】单体架构 vs 微服务架构:如何选择最适合你的技术方案?

文章目录 ⭐前言⭐一、架构设计的本质差异&#x1f31f;1、代码与数据结构的对比&#x1f31f;2、技术栈的灵活性 ⭐二、开发与维护的成本博弈&#x1f31f;1、开发效率的阶段性差异&#x1f31f;2、维护成本的隐形陷阱 ⭐三、部署与扩展的实战策略&#x1f31f;1、部署模式的本…

【鸿蒙开发】Hi3861学习笔记- WIFI应用AP建立网络

00. 目录 文章目录 00. 目录01. LwIP简介02. AP模式简介03. API描述3.1 RegisterWifiEvent3.2 UnRegisterWifiEvent3.3 GetStationList3.4 GetSignalLevel3.5 EnableHotspot3.6 DisableHotspot3.7 SetHotspotConfig3.8 GetHotspotConfig3.9 IsHotspotActive 04. 硬件设计05. 模…

大模型的微调技术(高效微调原理篇)

背景 公司有需求做农业方向的大模型应用以及Agent助手&#xff0c;那么适配农业数据就非常重要。但众所周知&#xff0c;大模型的全量微调对算力资源要求巨大&#xff0c;在现实的限制条件下基本“玩不起”&#xff0c;那么高效微调技术就非常必要。为了更好地对微调技术选型和…

区间震荡指标

区间震荡指标的逻辑如下&#xff1a; 一、函数注解 1. Summation函数 功能&#xff1a; 计算给定价格序列Price的前Length个数据点的和&#xff0c;或在数据点数量超过Length时&#xff0c;计算滚动窗口内的价格和。 参数&#xff1a; Price(1)&#xff1a;价格序列&#…

HCIE-SLAAC

文章目录 SLAAC &#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;Datacom专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2025年03月21日10点58分 SLAAC 帮助设备发现本地直连链路相连的设备&#xff0c;并获取与地址自动配置的相关前缀和其他…