如何在 Elasticsearch 中设置向量搜索 - 第二部分
作者:来自 Elastic Valentin Crettaz
了解如何在 Elasticsearch 中设置向量搜索并执行 k-NN 搜索。
本文是三篇系列文章中的第二篇,深入探讨了向量搜索(也称为语义搜索)的复杂性以及它在 Elasticsearch 中的实现方式。
第一部分重点介绍了嵌入(又称向量)的基础知识以及向量搜索的底层工作原理。
凭借第一篇文章中学到的所有向量搜索知识,第二部分将指导你了解如何在 Elasticsearch 中设置向量搜索和执行 k-NN 搜索。
在第三部分中,我们将利用前两部分中学到的知识,并在此基础上深入研究如何在 Elasticsearch 中制作强大的混合搜索查询。
首先介绍一些背景
尽管 Elasticsearch 直到 8.0 版(带有 _knn_search API 端点的技术预览)才支持向量搜索,但自 7.0 版发布以来,已经可以使用 dense_vector 字段类型存储向量。那时,向量只是作为二进制文档值存储,但没有使用我们在第一篇文章中介绍的任何算法进行索引。这些密集向量构成了 Elasticsearch 中即将推出的向量搜索功能的前提。
如果你有兴趣深入了解导致 Elasticsearch 中当前实现向量搜索的讨论,你可以参考此问题,其中详细介绍了 Elastic 为将此功能推向市场而必须克服的所有障碍。简而言之,由于 Elasticsearch 已经大量使用 Lucene 作为其底层搜索引擎,我们还决定使用与我们的向量引擎相同的技术,并以非常透明的方式解释了该决定背后的理由。
历史问题已经解决,现在让我们开始工作。
如何设置 k-NN
Elasticsearch 本身就提供向量搜索,无需安装任何特定程序。我们只需要创建一个索引,该索引定义至少一个类型为 density_vector 的字段,向量数据将存储在该字段中并/或被索引。
下面的映射显示了一个名为 title_vector 的 3 维 dense_vector 字段。在此字段中存储和索引的密集向量将使用我们在本系列第一篇文章中介绍的 dot_product 相似度函数。值得注意的是,在 8.11 之前,hnsw(即 Hierarchical Navigable Small Worlds)是 Apache Lucene 支持的唯一用于索引密集向量的算法。从那时起,其他算法被添加,未来,Elasticsearch 可能会提供用于索引和搜索密集向量的其他方法,但由于它完全依赖于 Apache Lucene,因此这将取决于这方面的进展。
"title_vector": {"type": "dense_vector","dims": 3,"index": true,"similarity": "dot_product","index_options": {"type": "hnsw","ef_construction": 128,"m": 24 }
}
下表总结了 Elasticsearch 提供的 dense_vector 字段类型的所有可用配置参数:
参数 | 必需 | 描述 |
---|---|---|
dims | Yes (<8.11) No (8.11+) | 向量维数,在 8.9.2 之前不能超过 1024,在 8.10.0 之后不能超过 2048,在 8.11.0 之后不能超过 4096。此外,从 8.11 开始,此参数不再需要,将默认为第一个索引向量的维数。 |
element_type | No | 向量元素值的数据类型,若不指定,则默认为 `float`(4 个字节),也可以使用 `byte`(1 个字节)和 `bit`。 |
index | No | 指示是否在专用且优化的数据结构中索引向量(如果为 “true”)或仅将其存储为二进制文档值(如果为“false”)。在 8.10 之前,如果未指定,则默认值为“false”。从 8.11 开始,如果未指定,则默认值为 “true”。 |
similarity | Yes (<8.11) No (8.11+) | 直到 8.10 版本,如果 `index` 为 `true`,则此参数是必需的,并定义用于 k-NN 搜索的向量相似度度量。可用的度量包括:a) `l2_norm`:L2 距离 b) `dot_product`:点积相似度 c) `cosine`:余弦相似度 d) `max_inner_product`:最大内积相似度。还请注意,只有当你的向量已经归一化(即,它们是幅度为 1 的单位向量)时,才应使用 `dot_product`,否则使用 `cosine` 或 `max_inner_product`。从 8.11 版本开始,如果未指定,则如果 element_type 为 `bit`,则此参数默认为 `l2_norm`,否则为 `cosine`。 |
index_options | No | 以下是 `type` 参数可能的值(具体取决于版本):a) 直到 8.11,仅支持 `hnsw`。b) 在 8.12 中,标量量化启用了 `int8_hnsw` c) 在 8.13 中,添加了 `flat` 及其标量量化的 `int8_flat` 兄弟 d) 在 8.15 中,添加了 `int4_hnsw` 和 `int4_flat` e) 在 8.18 中,二进制量化启用了 `bbq_hnsw` 和 `bbq_flat`。你可以查看官方文档以了解它们的详细描述(https://www.elastic.co/guide/en/elasticsearch/reference/current/dense-vector.html#dense-vector-params)以及如何配置每个算法。 |
从上表可以看出,自 8.11 版本以来,想量场的定义已大大简化:
关于 8.12 中添加的标量量化支持,请记住,我们在本系列的第一部分中讨论过这种压缩技术。我们不会在本文中深入探讨,但你可以在另一篇 Elastic Search Labs 文章中了解有关如何在 Lucene 中实现这一点的更多信息。同样,我们不会深入研究 8.18 中添加的更好的二进制量化 (BBQ),我们邀请你在本文中了解有关该新突破性算法的更多信息。
就这些了!只需定义和配置一个 dense_vector 字段,我们现在就可以索引向量数据,以便使用 knn 搜索选项或 knn DSL 查询(在 8.12 中引入)在 Elasticsearch 中运行向量搜索查询。Elasticsearch 支持两种不同的向量搜索模式:1) 使用 script_score 查询进行精确搜索和 2) 使用 knn 搜索选项或 knn 查询(8.12+)进行近似最近邻搜索。接下来我们将描述这两种模式。
精确搜索
如果你回想一下本系列的第一篇文章,我们回顾了向量搜索概况,那么精确向量搜索可以归结为在整个向量空间中执行线性搜索或强力搜索(brute-force search)。基本上,查询向量将根据每个存储的向量进行测量,以找到最近的邻居。在此模式下,向量不需要在 HNSW 图中编入索引,而只需存储为二进制文档值,相似度计算由自定义 Painless 脚本运行。
首先,我们需要以不对向量进行索引的方式定义向量场映射,这可以通过在映射中指定 index: false 和 no 相似度度量来实现:
# 1. Create a simple index with a dense_vector field of dimension 3
PUT /my-index
{"mappings": {"properties": {"price": {"type": "integer"},"title_vector": {"type": "dense_vector","dims": 3,"index": false}}}
}# 2. Load that index with some data
POST my-index/_bulk
{ "index": { "_id": "1" } }
{ "title_vector": [2.2, 4.3, 1.8], "price": 23}
{ "index": { "_id": "2" } }
{ "title_vector": [3.1, 0.7, 8.2], "price": 9}
{ "index": { "_id": "3" } }
{ "title_vector": [1.4, 5.6, 3.9], "price": 124}
{ "index": { "_id": "4" } }
{ "title_vector": [1.1, 4.4, 2.9], "price": 1457}
这种方法的优点是向量不需要索引,这大大降低了提取时间,因为不需要构建底层 HNSW 图。但是,根据数据集的大小和硬件,随着数据量的增加,搜索查询可能会很快变慢,因为添加的向量越多,访问每个向量所需的时间就越长(即线性搜索的复杂度为 O(n))。
创建索引并加载数据后,我们现在可以使用以下 script_score 查询运行精确搜索:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"query": {"script_score": {"query" : {"bool" : {"filter" : {"range" : {"price" : {"gte": 100}}}}},"script": {"source": "cosineSimilarity(params.queryVector, 'title_vector') + 1.0","params": {"queryVector": [0.1, 3.2, 2.1]}}}}
}
如你所见,script_score 查询由两个主要元素组成,即查询和脚本。在上面的示例中,查询部分指定了一个过滤器(即 price >= 100),该过滤器限制了将针对其执行脚本的文档集。如果未指定查询,则相当于使用 match_all 查询,在这种情况下,脚本将针对索引中存储的所有向量执行。根据向量的数量,搜索延迟可能会大幅增加。
由于向量未编入索引,因此没有内置算法可以测量查询向量与存储向量的相似性,这必须通过脚本来完成,幸运的是,Painless 提供了我们迄今为止学到的大多数相似性函数,例如:
l1norm(vector, field)
: L1 distance (Manhattan distance)l2norm(vector, field)
: L2 distance (Euclidean distance)hamming(vector, field)
: Hamming distancecosineSimilarity(vector, field)
: Cosine similaritydotProduct(vector, field):
Dot product similarity
由于我们正在编写脚本,因此也可以构建我们自己的相似性算法。 Painless 通过提供对 doc[<field>].vectorValue(允许迭代向量数组)和 doc[<field>].magnitude(返回向量的长度)的访问来实现这一点。
总而言之,尽管精确搜索的扩展性不佳,但它可能仍然适用于某些非常小的用例,但如果你知道数据量会随着时间的推移而增长,则需要考虑改用 k-NN 搜索。 这就是我们接下来要介绍的内容。
近似 k-NN 搜索
大多数情况下,如果你有大量数据并且需要使用 Elasticsearch 实现向量搜索,则你将选择此模式。索引延迟稍高一些,因为 Lucene 需要构建底层 HNSW 图来存储和索引所有向量。它在搜索时的内存要求方面也要求更高一些,之所以称为 “近似”,是因为其准确度永远不可能像精确搜索那样达到 100%。尽管如此,近似 k-NN 的搜索延迟要低得多,并且允许我们扩展到数百万甚至数十亿个向量,前提是你的集群大小合适。
让我们看看它是如何工作的。首先,让我们创建一个具有足够向量场映射的示例索引来索引向量数据(即 index: true + 特定 similarity 定义)并用一些数据加载它:
# 1. Create a simple index with a dense_vector field of dimension 3
PUT /my-index
{"mappings": {"properties": {"price": {"type": "integer"},"title_vector": {"type": "dense_vector","dims": 3,"index": true, # default since 8.11"similarity": "cosine", # default since 8.11"index_options": {"type": "int8_hnsw", # default value since 8.12"ef_construction": 128,"m": 24 }}}}
}# 2. Load that index with some data
POST my-index/_bulk
{ "index": { "_id": "1" } }
{ "title_vector": [2.2, 4.3, 1.8], "price": 23}
{ "index": { "_id": "2" } }
{ "title_vector": [3.1, 0.7, 8.2], "price": 9}
{ "index": { "_id": "3" } }
{ "title_vector": [1.4, 5.6, 3.9], "price": 124}
{ "index": { "_id": "4" } }
{ "title_vector": [1.1, 4.4, 2.9], "price": 1457}
简单的 k-NN 搜索
运行这两个命令后,我们的想量数据现在已在标量量化的 HNSW 图中正确索引,可供搜索。直到 8.11 版,运行简单 k-NN 搜索的唯一方法是使用 knn 搜索选项,该选项与你习惯的 query 部分位于同一级别,如以下查询所示:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100}
}
在上面的搜索负载中,我们可以看到没有像词汇搜索那样的 query 部分,而是 knn 部分。我们正在搜索与指定查询向量最接近的两个(k:2)相邻向量。
从 8.12 开始,引入了新的 knn 搜索查询(knn search query),以允许更高级的混合搜索用例,这是我们将在下一篇文章中讨论的主题。除非你具备将 k-NN 查询与其他查询相结合所需的专业知识,否则 Elastic 建议坚持使用更易于使用的 knn 搜索选项。首先要注意的是,新的 knn 搜索查询没有 k 参数,而是像任何其他查询一样使用 size 参数。第二件值得注意的是,新的 knn 查询通过利用将一个或多个过滤器与 knn 搜索查询相结合的 bool 查询来实现对 k-NN 搜索结果的后过滤,如下面的代码所示:
POST my-index/_search
{"size": 3,"_source": false,"fields": [ "price" ],"query" : {"bool" : {"must" : {"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"num_candidates": 100}},"filter" : {"range" : {"price" : {"gte": 100}}}}}
}
上述查询首先检索具有最近邻向量的前 3 个文档,然后过滤掉 price 小于 100 的文档。值得注意的是,使用这种后过滤,如果过滤器过于激进,你可能最终得不到任何结果。还请注意,此行为不同于通常的布尔全文查询,其中首先执行过滤部分以减少需要评分的文档集。如果你有兴趣了解有关 knn 顶级搜索选项和新 knn 搜索查询之间的差异的更多信息,你可以前往另一篇很棒的搜索实验室文章了解更多详细信息。
现在让我们继续了解有关 num_candidates 参数的更多信息。num_candidates 的作用是增加或减少找到真正最近邻候选的可能性。该数字越高,搜索速度越慢,但找到真正最近邻的可能性也越大。每个分片上将考虑 num_candidates 个向量,并将前 k 个向量返回到协调器节点,协调器节点将合并所有分片本地结果并返回全局结果中的前 k 个向量,如下图 1 所示:

向量 id4 和 id2 分别是第一个分片上的 k 个局部最近邻,id5 和 id7 分别是第二个分片上的 k 个局部最近邻。在对它们进行合并和重新排序后,协调器节点将返回 id4 和 id5 作为搜索查询的两个全局最近邻。
多个 k-NN 搜索
如果你的索引中有多个向量字段,则可以发送多个 k-NN 搜索,因为 knn 部分还接受查询数组,如下所示:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": [{"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100,"boost": 0.4},{"field": "content_vector","query_vector": [0.1, 3.2, 2.1],"k": 5,"num_candidates": 100,"boost": 0.6}]
}
我们可以看到,每个查询可以采用不同的 k 值以及不同的提升因子。提升因子相当于权重,总得分将是两个得分的加权平均值。
过滤的 k-NN 搜索
与我们之前在 script_score 查询中看到的类似,knn 部分也接受过滤器的规范,以减少近似搜索应运行的向量空间。例如,在下面的 k-NN 搜索中,我们将搜索限制为仅搜索价格大于或等于 100 的文档。
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100,"filter" : {"range" : {"price" : {"gte": 100}}}}
}
现在,你可能想知道数据集是否先按 price 过滤,然后对过滤后的数据集运行 k-NN 搜索(预过滤),还是反过来,即先检索最近邻居,然后按 price 过滤(后过滤)。实际上,两者都有一点。如果过滤器过于激进,预过滤的问题在于 k-NN 搜索必须在非常小且可能稀疏的向量空间上运行,并且不会返回非常准确的结果。而后过滤可能会剔除大量高质量的最近邻居。
因此,即使 knn 部分 filter 被视为预过滤器,它也会在 k-NN 搜索期间工作,以确保至少可以返回 k 个邻居。如果你对其工作原理感兴趣,可以查看以下处理此事的 Lucene 问题。
具有预期相似度的过滤 k-NN 搜索
在上一节中,我们了解到,在指定过滤器时,我们可以减少搜索延迟,但我们也冒着将向量空间大幅减少为与查询向量部分或大部分不相似的向量的风险。为了缓解这个问题,k-NN 搜索还可以指定所有返回向量预计具有的最小相似度值(minimum similarity)。重用上一个查询,它看起来会像这样:
POST my-index/_search
{"_source": false,"fields": [ "price" ],"knn": {"field": "title_vector","query_vector": [0.1, 3.2, 2.1],"k": 2,"num_candidates": 100,"similarity": 0.975,"filter" : {"range" : {"price" : {"gte": 100}}}}
}
基本上,它的工作方式是,通过跳过任何与提供的过滤器不匹配或相似度低于指定过滤器的向量来探索向量空间,直到找到 k 个最近邻居。如果算法不能接受至少 k 个结果(由于过滤器过于严格或预期相似度太低),则将尝试进行强力搜索(brute-force),以便至少返回 k 个最近邻居。
关于如何确定最小预期相似度的简短说明。这取决于你在向量场映射中选择了哪种相似度度量。如果你选择了 l2_norm,它是一个距离函数(即相似度随着距离的增加而减小),你将需要在 k-NN 查询中设置最大预期距离,即你认为可接受的最大距离。换句话说,与查询向量的距离介于 0 和最大预期距离之间的向量将被视为足够 “接近” 以相似。
如果你选择了 dot_product 或 cosine,它们是相似度函数(即,相似度随着向量角度变宽而降低),你将需要设置最小预期相似度。与查询向量具有最小预期相似度和 1 之间的相似度的向量将被视为足够 “接近” 以致相似。
应用于上面的示例过滤查询和我们之前已索引的示例数据集,下面的表 1 总结了查询向量和每个索引向量之间的余弦相似度。我们可以看到,向量 3 和 4 被过滤器选中(price >= 100),但只有向量 3 具有最小预期相似度(即 0.975)才能被选中。
Vector | Cosine similarity | Price |
---|---|---|
1 | 0.8473 | 23 |
2 | 0.5193 | 9 |
3 | 0.9844 | 124 |
4 | 0.9683 | 1457 |
k-NN 的局限性
现在我们已经回顾了 Elasticsearch 中 k-NN 搜索的所有功能,让我们看看你需要注意的几个限制:
- 直到 8.11,k-NN 搜索都无法在嵌套文档内的向量字段上运行。从 8.12 开始,此限制已被取消。但是,这种嵌套的 knn 查询不支持指定过滤器。
- search_type 始终设置为 dfs_query_then_fetch,并且无法动态更改它。
- 在使用跨集群搜索跨不同集群进行搜索时,不支持 ccs_minimize_roundtrips 选项。
- 这已经提到过几次了,但由于 Lucene 使用的 HNSW 算法的性质(以及任何其他近似最近邻搜索算法),“近似” 实际上意味着返回的 k 个最近邻并不总是真实的。
调整 k-NN
你可以想象,你可以使用很多选项来优化 k-NN 搜索的索引和搜索性能。我们不会在本文中介绍它们,但如果你真的想在 Elasticsearch 集群中实施 k-NN 搜索,我们强烈建议你在官方文档中查看它们。
超越 k-NN
到目前为止,我们看到的一切都利用了密集(dense)向量模型(因此是致密向量字段类型),其中向量通常包含非零值。Elasticsearch 还提供了使用稀疏(sparse)向量模型执行语义搜索的另一种方法。
Elastic 创建了一个稀疏 NLP 向量模型,称为 Elastic Learned Sparse EncodeR,简称 ELSER,这是一个域外(即未在特定域上训练)稀疏向量模型,不需要任何微调。它是在约 30000 个术语的词汇表上进行预训练的,并且作为一个稀疏模型,这意味着向量具有相同数量的值,其中大多数为零。
它的工作方式非常简单。在索引时,使用推理摄取处理器生成稀疏向量(术语/权重对),并将其存储在 sparse_vector 类型的字段中,这是 dense_vector 向量字段类型的稀疏对应项。在查询时,特定的 DSL 查询(也称为 sparse_vector)将用 ELSER 模型词汇表中的可用术语替换原始查询术语,这些术语已知与它们的权重最相似。
我们不会在本文中深入探讨 ELSER,但如果你渴望了解它的工作原理,你可以查看这篇开创性的文章以及官方文档,其中详细解释了该主题。
快速浏览一些即将推出的相关主题
Elasticsearch 还支持结合词汇搜索和向量搜索,这将是本系列下一篇也是最后一篇文章的主题。
到目前为止,我们必须在 Elasticsearch 之外生成嵌入向量,并将它们明确传递到我们所有的查询中。是否可以只提供查询文本,然后模型就会动态生成嵌入?好消息是,这可以通过 Elasticsearch 来实现,方法是利用名为 query_vector_builder 的构造(用于密集向量)或使用新的 semantic_text 字段类型和 semantic DSL 查询(用于稀疏向量),你可以在这篇文章中了解有关这些技术的更多信息。
让我们总结一下
在本文中,我们深入研究了 Elasticsearch 向量搜索支持。我们首先分享了 Elastic 寻求提供准确向量搜索的一些背景,以及我们决定使用 Apache Lucene 作为向量索引和搜索引擎的原因。
然后,我们介绍了在 Elasticsearch 中执行向量搜索的两种主要方法,即利用 script_score 查询来运行精确的强力搜索,或者通过 knn 搜索选项或 8.12 中引入的 knn 搜索查询使用近似最近邻搜索。
我们展示了如何运行简单的 k-NN 搜索,然后,我们回顾了使用过滤器和预期相似性配置 knn 搜索选项和查询的所有可能方法,以及如何同时运行多个 k-NN 搜索。
总结一下,我们列出了 k-NN 搜索的一些当前限制以及需要注意的事项。我们还邀请你查看可用于优化 k-NN 搜索的所有可能选项。
如果你喜欢你正在阅读的内容,请务必查看本系列的其他部分:
- 第 1 部分:向量搜索快速入门
- 第 3 部分:使用 Elasticsearch 进行混合搜索(敬请期待!)
想要获得 Elastic 认证?了解下一次 Elasticsearch 工程师培训何时开始!
Elasticsearch 包含许多新功能,可帮助你为你的用例构建最佳搜索解决方案。深入了解我们的示例笔记本以了解更多信息,开始免费云试用,或立即在你的本地机器上试用 Elastic。
原文:How to set up vector search in Elasticsearch - Elasticsearch Labs
相关文章:

如何在 Elasticsearch 中设置向量搜索 - 第二部分
作者:来自 Elastic Valentin Crettaz 了解如何在 Elasticsearch 中设置向量搜索并执行 k-NN 搜索。 本文是三篇系列文章中的第二篇,深入探讨了向量搜索(也称为语义搜索)的复杂性以及它在 Elasticsearch 中的实现方式。 第一部分重…...
【CXX-Qt】0 Rust与Qt集成实践指南(CXX-Qt)
CXX-Qt 是一个用于在 Rust 和 Qt 之间实现安全互操作的库。与通常的 Rust Qt 绑定不同,它提供了一种不同的方式来桥接 Qt 代码和 Rust 代码。CXX-Qt 认识到 Qt 和 Rust 代码具有不同的习惯,因此不能直接从一个语言包装到另一个语言。相反,它使…...
C++ 设计模式-适配器模式
适配器模式示例,包括多电压支持、类适配器实现、安全校验等功能: #include <iostream> #include <memory> #include <stdexcept>// 抽象目标接口:通用电源接口 class PowerOutlet {public:virtual ~PowerOutlet() = default;virtual int outputPower() c…...
【Elasticsearch】文本分析Text analysis概述
文本分析概述 文本分析使 Elasticsearch 能够执行全文搜索,搜索结果会返回所有相关的结果,而不仅仅是完全匹配的结果。 如果你搜索“Quick fox jumps”,你可能希望找到包含“A quick brown fox jumps over the lazy dog”的文档,…...

【IDEA】2017版本的使用
目录 一、常识 二、安装 1. 下载IDEA2017.exe 2. 安装教程 三、基本配置 1. 自动更新关掉 2. 整合JDK环境 3. 隐藏.idea文件夹和.iml等文件 四、创建Java工程 1. 新建项目 2. 创建包结构,创建类,编写main主函数,在控制台输出内容。…...
ES6 Proxy 用法总结以及 Object.defineProperty用法区别
Proxy 是 ES6 引入的一种强大的拦截机制,用于定义对象的基本操作(如读取、赋值、删除等)的自定义行为。相较于 Object.defineProperty,Proxy 提供了更灵活、全面的拦截能力。 1. Proxy 语法 const proxy new Proxy(target, hand…...
数据结构——【二叉树模版】
#思路 1、二叉树不同于数的构建,在树节点类中,有数据,左子结点,右子节点三个属性,在树类的构造函数中,添加了变量maxNodes,用于后续列表索引的判断 2.GetTreeNode()函数是常用方法,…...

关闭浏览器安全dns解决访问速度慢的问题
谷歌浏览器加载速度突然变慢了?检查安全DNS功能(DoH)是否被默认开启。 谷歌浏览器在去年已经推出安全DNS功能(即DoH) , 启用此功能后可以通过加密的DNS增强网络连接安全性。例如查询请求被加密后网络运营商将无法嗅探用户访问的地址,因此对于增强用户的…...

【AIGC】语言模型的发展历程:从统计方法到大规模预训练模型的演化
博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯语言模型的发展历程:从统计方法到大规模预训练模型的演化1 统计语言模型(Statistical Language Model, SLM):统…...
Spring Boot 中的事务管理:默认配置、失效场景及集中配置
Spring Boot 提供了强大的事务管理功能,基于 Spring 的 Transactional 注解。本文将详细介绍事务的默认配置、事务失效的常见场景、以及事务的几种集中配置方式,并给出相应的代码片段。 一、事务的默认配置 在 Spring Boot 中,默认情况下&am…...

DeepSeek 助力 Vue 开发:打造丝滑的进度条
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...

deepseek的CoT优势、两阶段训练的有效性学习笔记
文章目录 1 DeepSeek的CoT思维链的优势1.2 open-r1的CoT训练数据1.3 ReAct任务与CoT任务适用场景 2 AI推理方向:deepseek与deepmind的两条路线的差异2.1 PRM与ORM的两大学派分支的差异2.2 DeepSeek-R1的两阶段训练概述 1 DeepSeek的CoT思维链的优势 DeepSeek跟之前…...
分享在职同时准备系统分析师和教资考试的时间安排
(在职、时间有限、同时备考系统分析师考试和小学信息技术教资面试),以下是详细的备考计划,确保计划的可行性和通过性。 一、总体安排 时间分配: 每周周末(2天)用于系统分析师考试备考。工作日晚…...
浅谈Java Spring Boot 框架分析和理解
Spring Boot是一个简化Spring开发的框架,它遵循“约定优于配置”的原则,通过内嵌的Tomcat、Jetty或Undertow等容器,使得开发者能够快速构建独立运行的、生产级别的基于Spring框架的应用程序。Spring Boot包含了大量的自动配置功能,…...

【开发心得】CentOS7编译Redis7.4.2打包RPM完整方案
概述 由于最近客户需要解决redis版本升级问题,故而全网寻找安全版本,redis7.4.x版本求而为果,只能自己编译了。 截止发文时间2025-02-12 最新稳定版的redis版本号为7.4.2 Security fixes (CVE-2024-46981) Lua script commands may lead t…...
【网络安全】常见网络协议
1. 网络协议概述 网络协议是网络上两个或多个设备使用的一组规则,用于描述传输顺序和数据结构。网络协议充当数据包中信息附带的指令。这些指令告诉接收设备如何处理数据。协议就像一种通用语言,让世界各地的设备能够相互通信和理解。 尽管网络协议在网…...

电路笔记(元器件):AD 5263数字电位计(暂记)
AD5263 是四通道、15 V、256位数字电位计,可通过SPI/I2C配置具体电平值。 配置模式: W引脚作为电位器的抽头,可在A-B之间调整任意位置的电阻值。也可将W与A(或B)引脚短接,A-W间的电阻总是0欧姆,通过数字接口调整电位器…...
MongoDB 的使用场景
一、内容管理系统 1. 博客平台 文章内容、作者信息、标签、评论等数据结构多样,MongoDB 的无模式特性可轻松应对。比如 WordPress 等博客系统,使用 MongoDB 能灵活存储不同格式和长度的文章内容,以及与文章相关的各种元数据。 2. 新闻网站…...
MongoDB 是什么
MongoDB 是一款文档型数据库,属于 NoSQL 数据库范畴。 一、基本概念 MongoDB 以文档的形式存储数据,文档类似于 JSON 对象,由键值对组成,它以 BSON(Binary JSON)格式存储在磁盘上,这种格式支持…...
Python3操作MongoDB批量upsert
个人博客地址:Python3操作MongoDB批量upsert | 一张假钞的真实世界 代码如下: mongoClient MongoClient(mongodb://172.16.72.213:27017/) opsDb mongoClient.ops azScheduled opsDb.azScheduledFlowbulkOpers [] for flow in scheduledFlows.valu…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
Nginx server_name 配置说明
Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

华为OD机考-机房布局
import java.util.*;public class DemoTest5 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseSystem.out.println(solve(in.nextLine()));}}priv…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving
地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...
云原生周刊:k0s 成为 CNCF 沙箱项目
开源项目推荐 HAMi HAMi(原名 k8s‑vGPU‑scheduler)是一款 CNCF Sandbox 级别的开源 K8s 中间件,通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度,为容器提供统一接口,实现细粒度资源配额…...