BGE-M3模型结合Milvus向量数据库强强联合实现混合检索

news2024/11/28 19:28:02

在基于生成式人工智能的应用开发中,通过关键词或语义匹配的方式对用户提问意图进行识别是一个很重要的步骤,因为识别的精准与否会影响后续大语言模型能否检索出合适的内容作为推理的上下文信息(或选择合适的工具)以给出用户最符合预期的回答。

在本篇文章中,我将尽可能详细地介绍想达成准确识别用户提问意图的解决方案之一,即基于功能强大的BGE-M3模型和Milvus向量数据库实现混合检索(稠密向量 dense vector 和 稀疏向量 sparse vector)。

下面会先对混合检索,BGE-M3以及Milvus向量数据库做一个介绍,后面再对BGE-M3官方提供的使用Milvus的示例代码进行讲解,并基于自定义数据进行混合检索的实验效果进行呈现和分析。

何为混合检索

其实就是将多种单一检索技术结合起来使用的一种检索方式,目的是充分利用不同检索技术各自的优势,以达到更好的检索效果。接下来介绍两种比较常用的检索技术,嵌入检索(稠密检索)和 以BM25算法为代表的稀疏检索

嵌入检索 (embedding retrieval)

指的是使用稠密向量(dense vector)表示来进行信息检索的方法。

稠密向量有以下特点:

  1. 向量中大部分元素非零,是高维的实数向量,通常由深度学习模型生成;
  2. 重点在于向量空间中的相似性计算,一般使用余弦相似度、点积等计算方法。这允许语义上相似的文本可以被较好理解,即使它们的词语重叠较少;
  3. 能够捕捉文本的语义信息,而不是仅仅匹配关键词,但计算成本较高,需要更强大的计算资源。
稀疏检索 (sparse retrieval)

指的是使用稀疏向量(sparse vector)表示来进行信息检索的方法。

稀疏向量有以下特点:

  1. 通常由词袋模型 (Bag-of-Words, BoW)、TF-IDF 等传统方法生成,向量维度通常对应词汇表中的词语,其值表示词频或 TF-IDF 权重,向量中大部分元素为零;
  2. 主要基于关键词匹配,使用余弦相似度等方法计算向量之间的相似性;
  3. 计算效率高,对语义理解能力有限。

区别总结(Gemini 1.5 Flash回答):

特性嵌入检索稀疏检索
向量表示稠密向量 (dense vector)稀疏向量 (sparse vector)
表示方法使用深度学习模型生成使用词袋模型 (BoW)、TF-IDF 等传统方法生成
捕捉信息语义信息关键词信息
计算复杂度
应用场景语义搜索,问答系统基于关键词的搜索引擎

总之,嵌入检索和稀疏检索是两种不同的信息检索方法,它们各有优缺点,实际应用中常常结合使用,形成混合检索系统,以达到更好的检索效果。

BGE-M3 模型

BAAI/bge-m3 是一个由北京人工智能研究院(BAAI)开源的嵌入模型,主要用于生成文本嵌入(text embeddings)。它是一个多功能、多语言、多粒度的模型。M3指的就是多功能性(Multi-Functionality)、多语言性(Multi-Linguality)和多粒度(Multi-Granularity)。

  1. 多功能性 (Multi-Functionality): 该模型可以同时执行嵌入式模型的三个常见检索功能:稠密检索、多向量检索和稀疏检索。这意味着它能够灵活地应对不同的检索需求,并结合不同检索方法的优势。

  2. 多语言性 (Multi-Linguality): 该模型支持100多种语言。 这意味着它可以处理多种语言的文本,并进行跨语言检索。

  3. 多粒度性 (Multi-Granularity): 该模型能够处理不同粒度的输入,从短句到长达8192个词元的长文档。 这意味着它可以处理各种长度的文本,而不会受到输入长度的限制。

Milvus开源向量数据库介绍

官网介绍:https://milvus.io/intro

Github: https://github.com/milvus-io/milvus

Milvus 是一个以高效检索和高扩展性为特点的开源向量数据库,支持对大量的非结构化数据(如文本,图像还有多模态数据信息等)进行组织和检索。

Milvus 使用 GoC++ 编程语言开发实现, 并通过CPU/GPU指令级优化,以实现最佳的向量搜索性能。

Milvus 提供多种本地部署方式,以适应不同规模和需求的应用场景(引导Gemini 1.5 Flash回答如下):

1. 基于 Kubernetes (K8s) 的全分布式架构:

  • 适用场景: 处理数万甚至数十万每秒查询请求,向量数据规模达到数十亿级别的大规模应用。需要高可扩展性和实时数据更新能力。
  • 关键特性: 水平扩展性强,高可用性,实时数据处理。
  • 主要差异: 部署最复杂,但性能和可扩展性最高。需要预先配置好 Kubernetes 集群。

安装部署参考:官方文档

2. 单机模式 (Docker或者Docker Compose):

  • 适用场景: 小型应用、测试、开发和概念验证项目。相比全分布式模式,部署更简单。
  • 关键特性: 使用 Docker 简化部署。适用于单节点环境。
  • 主要差异: 可扩展性比分布式模式低。不适合高吞吐量或大型数据集。

安装部署参考:官方文档

3. Milvus Lite:

  • 适用场景: 快速入门、学习和小型实验项目,尤其是在 Python 环境中。强调易用性和极简的设置。
  • 关键特性: 通过 pip install 命令轻松安装。轻量级,快速上手。
  • 主要差异: 可扩展性和功能最受限制。主要用于学习和原型设计,不适合生产环境部署或大型数据集。

安装部署参考:官方文档

总结表格:

部署模式可扩展性数据规模实时更新部署复杂度使用场景
基于 K8s 的全分布式架构数十亿大规模生产环境,高吞吐量
单机模式 (Docker)中等是 (受限)中等小型应用,测试,开发
Milvus Lite极低小型极低快速入门,学习,小型原型设计

简而言之,选择哪种部署模式取决于应用的规模和需求。对于海量数据集和高查询量,基于 Kubernetes 的部署是必要的。对于小型需求,单机模式或 Milvus Lite 提供更简单快速的设置。

本地实验前准备

下载 BGE-M3
git lfs install
git clone https://huggingface.co/BAAI/bge-m3

模型大小 total 2.2G

以Docker Compose方式部署Milvus & 下载 pymilvus 和 FlagEmbedding

在后续结合bge-m3模型实现基于语义的混合检索实验中,我们使用docker compose安装部署Milvus的方式,并搭配 pymilvus 第三方python库进行使用。

官方文档:Run Milvus with Docker Compose

运行命令如下

# 安装
wget https://github.com/milvus-io/milvus/releases/download/v2.5.0-beta/milvus-standalone-docker-compose.yml -O docker-compose.yml
# 运行
sudo docker-compose up -d
# 终端显示
Creating milvus-etcd  ... done
Creating milvus-minio ... done
Creating milvus-standalone ... done

pymilvus和FlagEmbedding(此库方便我们加载bge模型)安装命令:

pip install -U pymilvus
pip install -U FlagEmbedding
数据准备

因为我后期想搭一个基于提问内容自动匹配合适的api去调用并将返回结果作为大语言模型推理上下文信息的问答机器人小应用,所以我准备了对不同api调用功能目进行描述的几条**中文**短文本作为检索知识库内容。

我在聚合数据平台申请了三个api,分别是:

  1. 黄金数据:提供黄金品种查询服务,支持黄金现货、黄金期货等品种查询;提供黄金价格查询服务,支持查询最新价、开盘价、最高价、最低价等价格信息。
  2. 股票数据:根据股票编号查询股票信息,包括涨跌额、股票名称、开盘价、收盘价、当前价格、最高最低价、竞买价等信息;支持沪深、香港、美国三个市场的股票数据查询,覆盖全球各地的股票信息。
  3. 新闻头条:提供最新的新闻头条信息,包括国内、国际、体育、娱乐、科技等各类资讯,让用户获取及时的新闻报道;支持按照不同的新闻分类进行查询,用户可以选择感兴趣的领域,如体育、科技、娱乐等,获取相关的新闻内容。

根据api的功能描述,建立检索知识库列表如下:

docs = [
    "提供黄金品种查询服务,支持黄金现货、黄金期货等品种查询;提供黄金价格查询服务,支持查询最新价、开盘价、最高价、最低价等价格信息。",
    "根据股票编号查询股票信息,包括涨跌额、股票名称、开盘价、收盘价、当前价格、最高最低价、竞买价等信息;支持沪深、香港、美国三个市场的股票数据查询,覆盖全球各地的股票信息。",
    "提供最新的新闻头条信息,包括国内、国际、体育、娱乐、科技等各类资讯,让用户获取及时的新闻报道;支持按照不同的新闻分类进行查询,用户可以选择感兴趣的领域,如体育、科技、娱乐等,获取相关的新闻内容。"]

代码实现

Milvus team 提供了使用 bge-m3 模型生成稀疏&稠密向量搭配Milvus向量数据库实现混合检索的示例代码,本次实验将以该代码作为参考,在其基础上进行适当修改调整。

  1. 导入相关库;(本次实验不试用reranker进行精筛所以 use_reranker 设置为 False
# A demo showing hybrid semantic search with dense and sparse vectors using Milvus.
#
# You can optionally choose to use the BGE-M3 model to embed the text as dense
# and sparse vectors, or simply use random generated vectors as an example.
#
# You can also use the BGE CrossEncoder model to rerank the search results.
#
# Note that the sparse vector search feature is only available in Milvus 2.4.0 or
# higher version. Make sure you follow https://milvus.io/docs/install_standalone-docker.md
# to set up the latest version of Milvus in your local environment.

# To connect to Milvus server, you need the python client library called pymilvus.
# To use BGE-M3 model, you need to install the optional `model` module in pymilvus.
# You can get them by simply running the following commands:
#
# pip install pymilvus
# pip install pymilvus[model]

# If true, use BGE-M3 model to generate dense and sparse vectors.
# If false, use random numbers to compose dense and sparse vectors.
use_bge_m3 = True
# If true, the search result will be reranked using BGE CrossEncoder model.
use_reranker = False

# The overall steps are as follows:
# 1. embed the text as dense and sparse vectors
# 2. setup a Milvus collection to store the dense and sparse vectors
# 3. insert the data to Milvus
# 4. search and inspect the result!
import random
import string
import numpy as np

from FlagEmbedding import BGEM3FlagModel

from pymilvus import (
    utility,
    FieldSchema, CollectionSchema, DataType,
    Collection, AnnSearchRequest, RRFRanker, connections, WeightedRanker
)
  1. 指定bge-m3模型路径并以fp32精度(全精度浮点数)加载模型;
model_dir = "bge-m3"
model = BGEM3FlagModel(model_dir) 
  1. 定义检索文本内容列表和用户提问示例;
docs = [
    "提供黄金品种查询服务,支持黄金现货、黄金期货等品种查询;提供黄金价格查询服务,支持查询最新价、开盘价、最高价、最低价等价格信息。",
    "根据股票编号查询股票信息,包括涨跌额、股票名称、开盘价、收盘价、当前价格、最高最低价、竞买价等信息;支持沪深、香港、美国三个市场的股票数据查询,覆盖全球各地的股票信息。",
    "提供最新的新闻头条信息,包括国内、国际、体育、娱乐、科技等各类资讯,让用户获取及时的新闻报道;支持按照不同的新闻分类进行查询,用户可以选择感兴趣的领域,如体育、科技、娱乐等,获取相关的新闻内容。"
]
# 用户提问示例
query = "请问黄金品种AU99.99价格如何?"
  1. 将检索文本列表编码为稀疏和稠密向量;
passage_embeddings = model.encode(
    docs, 
    return_dense=True, 
    return_sparse=True, 
    return_colbert_vecs=False)

passage_embeddings 变量打印出来看看

{'dense_vecs': array([[-0.05132515,  0.0243751 , -0.06081232, ..., -0.03952702,
         0.02319626, -0.03473093],
       [-0.07099452, -0.01123387, -0.05009558, ..., -0.00663427,
         0.05279079,  0.01525173],
       [-0.03272525, -0.00253467, -0.04763371, ..., -0.00828949,
         0.0147302 , -0.05601017]], dtype=float32), 'lexical_weights': [defaultdict(<class 'int'>, {'6': 0.20276982, '2212': 0.17947777, '78563': 0.27358395, '182114': 0.24308087, '115106': 0.25357044, '3367': 0.19385284, '4': 0.17282556, '7499': 0.17129068, '15895': 0.11740263, '24781': 0.07431586, '153133': 0.18931584, '844': 0.06803232, '74': 0.10644381, '16806': 0.14869832, '16677': 0.054120254, '14498': 0.116243124, '4185': 0.07396346, '27964': 0.13261327, '37': 0.056129213, '14812': 0.059598763, '36315': 0.082842745, '5412': 0.09079999, '30': 0.011220258}), defaultdict(<class 'int'>, {'80476': 0.13337892, '50653': 0.23055996, '30862': 0.24856994, '5730': 0.24488933, '115106': 0.2854578, '5412': 0.22158799, '4': 0.17879836, '5384': 0.09052652, '85266': 0.091248944, '44040': 0.12723388, '22878': 0.106443286, '37': 0.06931204, '108279': 0.10546562, '4185': 0.05373253, '27964': 0.12790793, '14498': 0.093488105, '6633': 0.05225729, '36563': 0.106637016, '16806': 0.10283494, '14812': 0.045356337, '36315': 0.081632964, '97954': 0.14599079, '11795': 0.08332152, '844': 0.018887743, '74': 0.1779946, '7499': 0.18943872, '206056': 0.08312804, '6728': 0.12673198, '6665': 0.11565392, '3893': 0.115120836, '41953': 0.10232154, '60114': 0.1253739, '12833': 0.22091916, '78868': 0.14010657, '7153': 0.11074717, '40727': 0.100175254, '43': 0.08830682, '30': 0.025547896}), defaultdict(<class 'int'>, {'6': 0.21939242, '2212': 0.21460007, '110004': 0.16313581, '21606': 0.2181344, '3878': 0.15887201, '7781': 0.21819039, '5412': 0.19437945, '4': 0.15980814, '5384': 0.13158405, '13853': 0.108550005, '5559': 0.08813208, '28788': 0.17125762, '23942': 0.15054022, '7355': 0.15029378, '844': 0.0729285, '62335': 0.095689975, '144343': 0.23023936, '3933': 0.0954708, '10501': 0.16799492, '95579': 0.13417137, '32292': 0.12720525, '27835': 0.17556949, '74': 0.18231188, '7499': 0.20008457, '17236': 0.10246284, '13647': 0.12076213, '136229': 0.2379455, '115106': 0.23003161, '1441': 0.04709647, '8827': 0.11257933, '123701': 0.1811453, '17010': 0.15106374, '3322': 0.003149774, '84492': 0.07179478, '8105': 0.079666495, '30': 0.075698406})], 'colbert_vecs': None}

passage_embeddings 变量是一个dict数据结构,有三个key值,分别是 dense_vecs, lexical_weights, colbert_vecs

passage_embeddings.keys()
# dict_keys(['dense_vecs', 'lexical_weights', 'colbert_vecs'])
passage_embeddings["dense_vecs"].shape
# (3, 1024) 3x1024维的一个dense vector
passage_embeddings["lexical_weights"]
# 生成的稀疏向量,sparse vector,存在一个list当中,有三个元素,元素类型是 collections.defaultdict
passage_embeddings["colbert_vecs"]
# colbert_vecs 这个Multi-Vector没生成,所以对应的值为 None
  1. 将用户提问 query 编码为稀疏和稠密向量;
query_embeddings_raw = model.encode(
  [query], 
  return_dense=True, 
  return_sparse=True, 
  return_colbert_vecs=False)
  1. 连接 Milvus(确保docker compose是up的状态)并创建 collection和index;
connections.connect("default", host="localhost", port="19530")
# 列出当前所有collection
utility.list_collections()
# 输出显示为空列表

基于schema创建一个新的名为 hybrid_demo 的collection

# Specify the data schema for the new Collection.
fields = [
    # Use auto generated id as primary key
    FieldSchema(name="pk", dtype=DataType.VARCHAR,
                is_primary=True, auto_id=True, max_length=100),
    # Store the original text to retrieve based on semantically distance
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=512),
    # Milvus now supports both sparse and dense vectors, we can store each in
    # a separate field to conduct hybrid search on both vectors.
    FieldSchema(name="sparse_vector", dtype=DataType.SPARSE_FLOAT_VECTOR),
    # 注意这个的dim要和dense vector的维度保持一致,即1024
  	# 注意dtype也是要和dense vector的精度保持一致,即fp32
    FieldSchema(name="dense_vector", dtype=DataType.FLOAT_VECTOR,
                dim=1024),
]
schema = CollectionSchema(fields, "")
col_name = 'hybrid_demo'
# Now we can create the new collection with above name and schema.
col = Collection(col_name, schema, consistency_level="Strong")

接着我们需要为每一个向量字段创建index,创建的indices会被加载到内存中以实现高效检索。

# We need to create indices for the vector fields. The indices will be loaded into memory for efficient search.
sparse_index = {"index_type": "SPARSE_INVERTED_INDEX", "metric_type": "IP"}
col.create_index("sparse_vector", sparse_index)
dense_index = {"index_type": "FLAT", "metric_type": "IP"}
col.create_index("dense_vector", dense_index)
col.load()
  1. 将生成的表示检索文本内容的稀疏&稠密向量加入到创建的collection中;
docs_embeddings = {}
docs_embeddings["dense"] = passage_embeddings["dense_vecs"]
docs_embeddings["sparse"] = passage_embeddings["lexical_weights"]
# 3. insert text and sparse/dense vector representations into the collection
entities = [docs, docs_embeddings["sparse"], docs_embeddings["dense"]]
col.insert(entities)
col.flush()
  1. 开始混合检索
query_embeddings = {}
query_embeddings["dense"] = query_embeddings_raw["dense_vecs"]
query_embeddings["sparse"] = [dict(query_embeddings_raw["lexical_weights"][0])]

因为检索文档数量较少只有三条,所以top k中k的值设置为1

# 4. search and inspect the result!
k = 1 # we want to get the top 1 docs closest to the query

# Prepare the search requests for both vector fields
sparse_search_params = {"metric_type": "IP"}
sparse_req = AnnSearchRequest(query_embeddings["sparse"],
                              "sparse_vector", sparse_search_params, limit=k)
dense_search_params = {"metric_type": "IP"}
dense_req = AnnSearchRequest(query_embeddings["dense"],
                             "dense_vector", dense_search_params, limit=k)

# Search topK docs based on dense and sparse vectors and rerank with RRF.
res = col.hybrid_search([sparse_req, dense_req], rerank=RRFRanker(),
                        limit=k, output_fields=['text'])

# Currently Milvus only support 1 query in the same hybrid search request, so
# we inspect res[0] directly. In future release Milvus will accept batch
# hybrid search queries in the same call.
res = res[0]

打印出最为匹配的文档内容,检索正确:

print(res)
["id: 454220910858869856, distance: 0.032786883413791656, entity: {'text': '提供黄金品种查询服务,支持黄金现货、黄金期货等品种查询;提供黄金价格查询服务,支持查询最新价、开盘价、最高价、最低价等价格信息。'}"]

再试两个query:

Query 一:

query = "请问科技圈发生了什么热点事件?"
print(res)
["id: 454220910858869858, distance: 0.032786883413791656, entity: {'text': '提供最新的新闻头条信息,包括国内、国际、体育、娱乐、科技等各类资讯,让用户获取及时的新闻报道;支持按照不同的新闻分类进行查询,用户可以选择感兴趣的领域,如体育、科技、娱乐等,获取相关的新闻内容。'}"]

Query 二:

query = "请问股票代码为CSCO的美股今日走势如何?"
print(res)
["id: 454220910858869857, distance: 0.032786883413791656, entity: {'text': '根据股票编号查询股票信息,包括涨跌额、股票名称、开盘价、收盘价、当前价格、最高最低价、竞买价等信息;支持沪深、香港、美国三个市场的股票数据查询,覆盖全球各地的股票信息。'}"]

效果还是不错的。

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

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

相关文章

OSI七层模型和TCP/IP五层模型详细介绍

这里写目录标题 一.OSI含义二.OSI七层模型1.应用层2.表示层3.会话层4.传输层5.网络层6.数据链路层7.物理层 TCP/IP五层协议1.应用层2.运输层运行在TCP上的协议运行在UDP上的协议 3.网络层IP协议配套使用的协议 4.数据链路层 四.网络协议分层的好处 一.OSI含义 OSI即是开放式通…

360推出全新的生成式 AI 搜索产品:纳米搜索,要重塑搜索产品

【大力财经】直击互联网最前线&#xff1a;360 集团在 2024 年 11 月 27 日开发布会&#xff0c;重磅推出了一款全新的生成式 AI 搜索产品——纳米搜索&#xff0c;并且已经上架到苹果 App Store 以及应用宝等安卓应用商店&#xff0c;直接与百度、阿里夸克、秘塔 AI、Perplexi…

【超全】目标检测模型分类对比与综述:单阶段、双阶段、有无锚点、DETR、旋转框

《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…

c#:winform引入bartender

1、vs新建项目 ①选择Windows窗体应用&#xff08;.NET Framework&#xff09; 2、将bartender引入vs中 ①找到bartender的安装目录&#xff0c;复制Seagull.BarTender.Print.dll文件 ②粘贴到项目->bin->Debug文件&#xff0c;并可创建Model文件夹&#xff1a;为了存放…

vue 实现关键字高亮效果

vue 实现关键字高亮效果 这是啥子意思呢&#xff0c;就是类似于百度搜索&#xff0c;根据关键词搜索结果&#xff0c;搜索结果中&#xff0c;与关键词相同的字显示红色&#xff0c;仅此而已&#xff0c;没有什么大的功能。简单写一下demo。 环境 我使用的是 vue3 ts 的语法来…

初始Python篇(7)—— 正则表达式

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; Python 目录 正则表达式的概念 正则表达式的组成 元字符 限定符 其他字符 正则表达式的使用 正则表达式的常见操作方法 match方法的…

[DL]深度学习_扩散模型正弦时间编码

1 扩散模型时间步嵌入 1.1 时间步正弦编码 在扩散模型按时间步 t 进行加噪去噪过程时&#xff0c;需要包括反映噪声水平的时间步长 t 作为噪声预测器的额外输入。但是最初与图像配套的时间步 t 是数字&#xff0c;需要将代表时间步 t 的数字编码为向量嵌入。嵌入时间向量的宽…

【Linux】网络基本配置命令

一、使用网络配置命令 1.常用网络配置文件 1.1. /etc/hosts “/etc/hosts”文件保存着IP地址和主机名或域名的静态映射关系。当用户使用一个主机名或域名时&#xff0c;系统会在该文件中查找与它对应的IP地址。 [rootlocalhost ~]# cat /etc/hosts 127.0.0.1 localhost l…

如何搭建一个小程序:从零开始的详细指南

在当今数字化时代&#xff0c;小程序以其轻便、无需下载安装即可使用的特点&#xff0c;成为了连接用户与服务的重要桥梁。无论是零售、餐饮、教育还是娱乐行业&#xff0c;小程序都展现了巨大的潜力。如果你正考虑搭建一个小程序&#xff0c;本文将为你提供一个从零开始的详细…

学习threejs,使用设置lightMap光照贴图创建阴影效果

&#x1f468;‍⚕️ 主页&#xff1a; gis分享者 &#x1f468;‍⚕️ 感谢各位大佬 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍⚕️ 收录于专栏&#xff1a;threejs gis工程师 文章目录 一、&#x1f340;前言1.1 ☘️THREE.MeshLambertMaterial…

【前端】JavaScript中的柯里化(Currying)详解及实现

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: 前端 文章目录 &#x1f4af;前言&#x1f4af;什么是柯里化&#xff1f;&#x1f4af;柯里化的特点&#x1f4af;柯里化的简单示例&#x1f4af;通用的柯里化实现&#x1f4af;柯里化让代码更易读的原因&#x1f4af…

springboot 整合 rabbitMQ (延迟队列)

前言&#xff1a; 延迟队列是一个内部有序的数据结构&#xff0c;其主要功能体现在其延时特性上。这种队列存储的元素都设定了特定的处理时间&#xff0c;意味着它们需要在规定的时间点或者延迟之后才能被取出并进行相应的处理。简而言之&#xff0c;延时队列被设计用于存放那…

Java代码操作Zookeeper(使用 Apache Curator 库)

1. Zookeeper原生客户端库存在的缺点 复杂性高&#xff1a;原生客户端库提供了底层的 API&#xff0c;需要开发者手动处理很多细节&#xff0c;如连接管理、会话管理、异常处理等。这增加了开发的复杂性&#xff0c;容易出错。连接管理繁琐&#xff1a;使用原生客户端库时&…

Django实现智能问答助手-基础配置

设置 Django 项目、创建应用、定义模型和视图、实现问答逻辑&#xff0c;并设计用户界面。下面是一步一步的简要说明&#xff1a; 目录&#xff1a; QnAAssistant/ # 项目目录 │ ├── QnAAssistant/ # 项目文件夹 │ ├── init.py # 空文件 │ ├── settings.py # 项目配…

【ESP32CAM+Android+C#上位机】ESP32-CAM在STA或AP模式下基于UDP与手机APP或C#上位机进行视频流/图像传输

前言: 本项目实现ESP32-CAM在STA或AP模式下基于UDP与手机APP或C#上位机进行视频流/图像传输。本项目包含有ESP32源码(arduino)、Android手机APP源码以及C#上位机源码,本文对其工程项目的配置使用进行讲解。实战开发,亲测无误。 AP模式,就是ESP32发出一个WIFI/热点提供给电…

从〇开始深度学习(0)——背景知识与环境配置

从〇开始深度学习(0)——背景知识与环境配置 文章目录 从〇开始深度学习(0)——背景知识与环境配置写在前面1.背景知识1.1.Pytorch1.2.Anaconda1.3.Pycharm1.4.CPU与GPU1.5.整体关系 2.环境配置2.1.准备工作2.1.1.判断有无英伟达显卡2.1.2.清理电脑里的旧环境 2.1.安装Anaconda…

mac下Gpt Chrome升级成GptBrowser书签和保存的密码恢复

cd /Users/自己的用户名/Library/Application\ Support/ 目录下有 GPT\ Chrome/ Google/ GptBrowser/ GPT\ Chrome 为原来的chrome浏览器的文件存储目录. GptBrowser 为升级后chrome浏览器存储目录 书签所在的文件 Bookmarks 登录账号Login 相关的文件 拷贝到GptBrow…

圆域函数的傅里叶变换和傅里叶逆变换

空域圆域函数的傅里叶变换 空域圆域函数&#xff08;也称为空间中的圆形区域函数&#xff09;通常指的是在二维空间中&#xff0c;以原点为中心、半径为 a a a的圆内取值为1&#xff0c;圆外取值为0的函数。这种函数可以表示为&#xff1a; f ( x , y ) { 1 if x 2 y 2 ≤ …

Java基础——类型转化(强制转化)

目录 1.数字间的类型转换 &#xff08;1&#xff09; 隐式类型转换 &#xff08;2&#xff09;显式类型转换&#xff08;强制类型转换&#xff09; 2.类对象间的强制转换 &#xff08;1&#xff09; 向上转型 &#xff08;2&#xff09; 向下转型 将一个类型强制转换成另…

数据结构C语言描述5(图文结合)--广义表讲解与实现

前言 这个专栏将会用纯C实现常用的数据结构和简单的算法&#xff1b;有C基础即可跟着学习&#xff0c;代码均可运行&#xff1b;准备考研的也可跟着写&#xff0c;个人感觉&#xff0c;如果时间充裕&#xff0c;手写一遍比看书、刷题管用很多&#xff0c;这也是本人采用纯C语言…