<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[ML 研究 - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[ML 研究 - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/cn/search-labs/blog/category/ml-research</link>
    </image>
    <link>https://www.elastic.co/cn/search-labs/blog/category/ml-research</link>
    <atom:link href="https://www.elastic.co/cn/search-labs/rss/category/ml-research.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[cn]]></language>
    <lastBuildDate>Tue, 29 Sep 2026 13:46:56 GMT</lastBuildDate>
  <item>
    <title><![CDATA[基于 Elasticsearch + Jina 嵌入的无监督文档集群]]></title>
    <description><![CDATA[一种使用 Elasticsearch 和 Jina 嵌入进行无监督文档集群的实用、可复现方法。]]></description>
    <content:encoded><![CDATA[<p>向量搜索从查询开始，但如果您没有查询呢？</p><p>组织往往会积累大量文档，例如支持工单、法律文件、新闻资讯和研究论文；在提出正确的问题之前，首先需要了解这些文档里都包含哪些内容。没有标签或训练数据，手动审查数千份文档是不切实际的。当您不知道要搜索什么时，传统搜索无济于事。</p><p>本文将介绍一种 Elasticsearch 原生方法，用于无监督文档集群和时序故事追踪，帮助解决这一发现难题。读完本文后，您就可以像这样跨天追踪故事脉络：</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8c243e0c5773440/6a17093fa6c2b98c86e7968c/100a60a7fb85da8ab3813fd071a82c93f2c3f318-1300x650.png" alt="贯穿 2025 年 2 月的时间故事链：每条彩色路径都表示一个跨天延续的故事，连线宽度表示 kNN 重叠强度。" /><p><strong>您将发现：</strong></p><ul><li><p>为什么当您希望在没有查询的情况下进行主题发现时，<strong>集群嵌入</strong>（而非检索嵌入）至关重要。</p></li><li><p>如何借助 Elasticsearch 的 k 近邻 (kNN) 和批量 <code>msearch</code>，通过密度探测质心分类按主题对文档进行分组。</p></li><li><p><a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significanttext-aggregation"><code>significant_text</code></a> 如何自动为集群添加标签，让主题在无需训练模型的情况下也能清晰呈现。</p></li><li><p>时间故事链如何将每日集群联系起来，展示主题如何逐日演变。</p></li></ul><p>该管道以来自 BBC News 和 The Guardian 的约 8,500 篇 2025 年 2 月文章作为测试语料库。新闻之所以适合作为示例，是因为它具有清晰的时间演化特征；而在任何文档发现至关重要的场景中，这种模式同样适用，例如法律审查、合规监控、研究整合和客户支持分流。</p><p><strong>技术栈：</strong></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/jina-embeddings-v5-text"><strong>Jina v5</strong></a> <strong>集群嵌入：</strong>用于主题分组的任务专用低秩自适应 (LoRA) 适配器。<a href="https://www.elastic.co/blog/elastic-jina-ai">Jina 已加入 Elastic</a>，其模型可通过 <a href="https://www.elastic.co/docs/explore-analyze/elastic-inference/eis">Elastic Inference Service (EIS)</a> 原生调用。</p></li><li><p><strong>Elasticsearch：</strong>可扩展的 <a href="https://www.elastic.co/docs/solutions/search/vector/knn">kNN</a>、<code>significant_text</code> 标签生成和向量存储。</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/diskbbq-elasticsearch-introduction"><strong>DiskBBQ：</strong></a>一种基于磁盘的向量索引格式，结合了 <a href="https://www.elastic.co/docs/reference/elasticsearch/index-settings/bbq">Better Binary Quantization (BBQ)</a> 与分层 k-means 分区，以加速近似最近邻 (ANN)。这种索引分区是向量搜索的内部机制，与本文使用的密度探测集群算法相互独立。与 <code>bbq_hnsw</code> 相比，<code>bbq_disk</code> 将量化向量存储在磁盘上，并仅在堆内存中保留分区元数据，在保持高召回率的同时，大幅降低了资源需求。</p></li><li><p><strong>全局集群 + 每日时间链接：</strong>发现与故事演变。</p></li></ul><p><strong>您需要：</strong></p><ul><li><p>Elasticsearch 部署（Elastic Cloud、Elasticsearch Serverless 或 Elastic 自托管 8.18+/9.0+）：<code>bbq_disk</code> 需要 8.18 或更高版本。可选的 diversify retriever 部分需要 9.3+ 或 serverless。</p></li><li><p><a href="https://jina.ai/embeddings/">Jina API 密钥</a>：免费层级包含 1,000 万个 token，足以覆盖核心集群管道的需求（约 425 万个 token）。可选的 retrieval-versus-clustering 对比需要进行第二轮嵌入计算。</p></li><li><p><a href="https://bonobo.capi.gutools.co.uk/register/developer">Guardian API 密钥</a>（免费）。</p></li></ul><h2>设置</h2><p>安装所需软件包：</p>pip install elasticsearch pandas numpy plotly umap-learn python-dotenv pydantic-settings datasets requests<p>可选（仅当您从此仓库运行抓取帮助程序时）：</p>pip install beautifulsoup4<p>然后在项目根目录的 <code>.env</code> 文件中配置 API 密钥：</p>ELASTIC_CLOUD_ID=your-cloud-id        # or ELASTIC_HOST=https://...
ELASTIC_API_KEY=your-api-key
JINA_API_KEY=your-jina-key
GUARDIAN_API_KEY=your-guardian-key<p>此笔记本调用 <code>load_dotenv(override=True)</code>，因此本地 <code>.env</code> 值优先。</p>Connected to Elasticsearch<h2>第 1 部分：发现式集群 —— 为什么要使用集群嵌入？</h2><p>大多数向量搜索都会使用经过训练的<strong>检索嵌入</strong>来将<em>查询</em>与相关<em>文档</em>进行匹配。这对于搜索非常合适，但并不适合用于发现。当您希望在没有任何查询的情况下找到语料库中的主题时，您需要使用能将相似文档组合在一起的嵌入。</p><p>Jina v5 通过<strong>面向特定任务的低秩适配 (LoRA) 适配器</strong>解决了这个问题。LoRA 在保持大部分基础模型权重冻结的同时，对目标内部层添加小幅低秩更新，使模型行为转向特定任务，而无需完全重新训练。同一基模型根据 <code>task</code> 参数产生不同的嵌入：</p><p>任务</p><p>训练用于</p><p>用例</p><p>检索.段落</p><p>查询-文档匹配</p><p>搜索，检索增强生成 (RAG)</p><p>聚类</p><p>主题分组（针对紧密集群进行优化）</p><p>发现与分类</p><p>集群适配器经过训练，使相同主题的文档在嵌入空间中<em>更接近</em>，而不同主题的文档则<em>更远离</em>。下面的可视化对比会更直观地呈现这种差异。</p><h3>检索与集群：可视化对比</h3><p>为了展示这种差异，我们分别使用两种任务类型对文档样本进行嵌入。集群在原始 1024 维嵌入空间中执行；Uniform Manifold Approximation and Projection (UMAP) 仅用于将这些嵌入投影到 2D 进行可视化。UMAP 保留局部邻域结构，因此可用于比较集群的分离程度。</p><p>下图展示了同一组 480 篇文档样本分别采用两种任务类型进行嵌入后，再通过 UMAP 投影到 2D 的结果。请观察集群面板中那些更紧密、彼此分离更明显的颜色分组。</p>    Full dataset: 8,495 articles
    Sources: guardian: 5749, bbc: 2746
    Date range: 2025-02-01 to 2025-02-28


    Sample: 480 docs across 8 sections
    section
    Film              60
    World news        60
    Australia news    60
    Opinion           60
    Football          60
    US news           60
    Sport             60
    Business          60


    Clustering embeddings: 480
    Retrieval embeddings:  480


    UMAP projection complete<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b3733dccad212b6/6a1709407d8d67aaeb70e6a4/9bcf7a744900560c1c6c63a2dc3af2f9bfd33e11-1100x500.png" alt="UMAP 检索与集群嵌入对比" /><p><em>检索嵌入（左）会更分散地铺开各个主题；集群嵌入（右）则会基于相同文档形成更紧密、彼此分离更明显的分组。</em></p><p>集群嵌入能够形成更紧密、视觉上也更清晰的分组。检索嵌入会更均匀地分布各个主题，因此非常适合搜索（细粒度相似度）；但对发现来说，更关键的是紧密的主题集群。</p><p>这就是为什么在本演练的其余部分中使用 <code>task="clustering"</code> 的原因。</p><h3>加载数据集</h3><p>该语料库结合了 2025 年 2 月的两个新闻来源：</p><ul><li><p><strong>BBC News</strong>通过<a href="https://huggingface.co/datasets/RealTimeData/bbc_news_alltime">RealTimeData/bbc_news_alltime</a>HuggingFace 数据集。</p></li><li><p><strong>The Guardian</strong> 通过 <a href="https://open-platform.theguardian.com/">Guardian Open Platform API</a>。</p></li></ul><p>纳入多个来源，有助于验证集群识别出的是真正的<em>主题</em>，而不是<em>某个来源特有的写作风格</em>。</p>    Total articles:  8,495
    
    Source breakdown:
    source
    guardian    5749
    bbc         2746
    
    Date range: 2025-02-01 → 2025-02-28
    Days covered: 28
    
    Sample article:
      Source:  guardian
      Title:   Carbon monoxide poisoning ruled out in death of Gene Hackman and wife, police sa
      Section: Film
      Text:    Authorities have ruled out that Gene Hackman and his wife, Betsy Arakawa, died from carbon monoxide poisoning earlier this week in their home in Santa Fe, New Mexico. The Santa Fe county sheriff, Adan...<h3>使用集群任务进行嵌入</h3><p>在调用 Jina v5 API 处理所有文档时均会传入 <code>task="clustering"</code>。嵌入会缓存到磁盘，因此后续运行会完全跳过 API。</p><p>API 调用很简单。<code>task</code> 参数是与典型嵌入使用的关键区别：</p>payload = {
    "model": "jina-embeddings-v5-text-small",
    "input": texts,
    "task": "clustering",  # ← This selects the clustering LoRA adapter
}<p>以下时间反映的是缓存命中情况。第一次对 API 运行时间更长，具体取决于语料库大小。</p>    Embeddings ready: 8,495 vectors of dimension 1024
    Time: 0.6s<h3>索引到单个 Elasticsearch 索引</h3><p>对于发现式集群，整个月的数据都会写入同一个索引 (<code>docs-clustering-all</code>)。每日分区会在后续阶段进行，用于实现时间故事链接。</p><p>索引映射对向量字段使用 <a href="https://www.elastic.co/docs/reference/elasticsearch/index-settings/bbq"><code>bbq_disk</code></a>：</p>{
  "embedding": {
    "type": "dense_vector",
    "dims": 1024,
    "index": true,
    "similarity": "cosine",
    "index_options": {
      "type": "bbq_disk"        // hierarchical k-means partitioning for ANN index lookup; separate from this post's clustering algorithm
    }
  }
}<p>1024 维 float32 向量大小为 4 KB。 <a href="https://www.elastic.co/search-labs/blog/diskbbq-elasticsearch-introduction"><code>bbq_disk</code></a> 使用分层 k-means 将向量划分为小集群，对其进行二进制量化，并将全精度向量存储在磁盘上以便进行二次评分。只有分区元数据保留在堆内存中，因此即使面对大型语料库，内存需求仍然较低。对于能够承受更多堆内存的工作负载，<a href="https://www.elastic.co/docs/reference/elasticsearch/index-settings/bbq"><code>bbq_hnsw</code></a> 构建分层可导航小世界 (HNSW) 图，以实现更快的查找，但资源消耗更高。</p><p><a href="https://www.elastic.co/docs/reference/elasticsearch/mapping-reference/dense-vector"><code>dense_vector</code></a> 字段类型支持多种量化策略：<code>bbq_disk</code> 和 <code>bbq_hnsw</code> 最适合高维嵌入，例如此处使用的 1,024 维向量。</p>    Indexed 8,495 documents into docs-clustering-all
    Time: 57.5s<h3>集群：基于密度探测的质心分类</h3><p>传统的集群算法（如 HDBSCAN）假设您可以将完整的 N×d 向量矩阵保存在内存中，并运行重复的完整遍历更新。对于 8,495 篇 1024 维文档而言，这一规模尚可管理（约 35 MB）；但如果没有额外基础设施，这种方法就无法扩展到数百万篇文档。</p><p>从概念上看，该算法类似于采用 Voronoi 分配和噪声底限的 KMeans++ 初始化；但它将 Elasticsearch <a href="https://www.elastic.co/docs/solutions/search/vector/knn">kNN 搜索</a>作为计算原语，因此几乎所有工作都在服务器端完成。</p><ol><li><p><strong>抽取 5% 的文件</strong> 作为密度探针（随机抽样，至少 50 个）。</p></li><li><p><strong>通过批量</strong> <a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-msearch"><strong><code>msearch</code></strong></a> <strong>kNN</strong> 查询探测密度。每个探针发出 kNN 查询，并记录其邻居的平均相似度。高平均相似度 = 嵌入空间中的稠密区域。<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-msearch"><code>msearch</code></a> 在单个 HTTP 调用中发送多个搜索请求，这一点至关重要：密度探测生成数百个 kNN 查询，批量处理可避免每个请求的开销。</p></li><li><p><strong>通过多样化策略选择高密度种子</strong>：将密度高于中位数的候选种子按密度从高到低排序，只有当它与每个现有种子的余弦相似度都低于分离阈值时，才按贪婪策略予以接受。这是唯一的客户端计算（8k 文档约 0.01 秒）。</p></li><li><p><strong>通过</strong> <strong><code>msearch</code></strong> <strong>kNN</strong> 按质心对所有文档进行分类：每个种子都作为一个质心，kNN 搜索会检索相似度高于阈值的邻近文档。每个文档都会被分配给返回该文档且得分最高的质心。小集群被归为噪声。</p></li></ol><p>Elasticsearch 负责处理核心计算：使用 <code>msearch</code> 进行密度探测和分类，并使用 <code>significant_text</code> 生成标签。对于该语料库（8,495 个文档），5% 的密度探针样本会发起 425 个 kNN 探针查询，<code>msearch</code> 会将其批量处理为 9 次 HTTP 调用（批大小为 50），从而避免每个探针单独发起一次请求的开销。再结合 <code>bbq_disk</code> ANN 查找，整个集群阶段便能兼顾速度与可扩展性。在集群过程中，kNN 查询会使用尽可能小的 <a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/approximate-knn-search"><code>num_candidates</code></a> 值来提升速度；而在生产环境的搜索查询中，则应使用更高的 <code>num_candidates</code> 值，以牺牲一定延迟为代价换取更高的召回率。</p><p>集群的自然大小由每个质心周围的嵌入空间密度决定，而非硬性的 <code>k</code> 上限。主题越密集的区域，形成的集群就越大；而越小众的主题，则会形成更小的集群。</p><h4>为什么不选择 KMeans 或 HDBSCAN？</h4><p>KMeans 假设集群为球形，并需要将完整的 N×d 矩阵加载到内存中。对于适合内存的语料库，<a href="https://scikit-learn.org/stable/modules/generated/sklearn.cluster.HDBSCAN.html">HDBSCAN</a> 是一个强有力的替代方案。它既可以处理任意形状的集群，也具备更易理解的密度语义。</p><p>密度探测质心方法面向的是另一类场景：您希望在同一系统中完成存储、检索和集群，或者数据规模已经大到使客户端矩阵运算变得不切实际。它使用 Elasticsearch kNN 作为计算原语，处理任意大小的集群，并将几乎所有计算保留在服务器端。</p>    Clustered global index in 31.6s
      Total clusters: 82
      Total noise:    2420 (28.5%)
      Density probes: 425 kNN queries via 9 _msearch HTTP calls<h4>理解噪声率</h4><p>约 28% 的噪声率是有意为之，并不意味着系统出现了故障。在配置的 <code>similarity_threshold</code> 下，不属于任何密集集群的文档将保持未分配状态，而不是被强制匹配到不合适的集群中。这相当于一道质量门槛：评论专栏、短文和一次性报道往往难以形成集群，因为它们缺乏构成连贯分组所需的主题密度。</p><p>阈值可调：降低 <code>similarity_threshold</code> 会产生更激进的集群（分配更多文档，但集群更松散），提高则会收紧集群并增加噪声比例。对于这种包含混合新闻内容的语料库，约 30% 的噪声比例是一个合理的平衡点。生产部署应根据特定领域的质量标准调整阈值。</p><h3>使用 significant_text 自动添加标签</h3><p>现在，每个集群都需要一个便于人工理解的标签。Elasticsearch 的 <code>significant_text</code> 聚合会找出在前景集（集群）中出现异常频繁、而在背景集（完整语料库）中不常见的词项。</p><p>其底层采用统计启发式方法（默认为 JLH 分数），平衡了绝对频率与相对频率的变化，无需机器学习，也无需调用大语言模型 (LLM)。例如，一个关于英国政治的集群，可能会浮现出 <code>starmer</code>、<code>labour</code>、<code>downing</code> 等词项，因为与整体新闻语料库相比，这些词项在该集群中出现得异常频繁。</p><p>在这一全局处理阶段，标签直接基于 <code>docs-clustering-all</code> 计算，因此前景集和背景集都取自整个月的数据。在第 2 部分中，标签会使用每日索引模式 (<code>docs-clustering-*</code>)。这是一个通配符，可让查询同时覆盖所有匹配的索引，从而为 significant_text 提供更广泛的背景，以获得更好的对比效果。</p><p>一个最小查询形状如下所示：</p>{
  "size": 0,
  "query": { "term": { "cluster_id": "72" } },
  "aggs": {
    "label_terms": {
      "significant_text": {
        "field": "text",
        "size": 5,
        "filter_duplicate_text": true
      }
    }
  }
}<p><code>significant_text</code> significant_text 也可作为一道质量门槛：未产生任何显著词项的集群，说明其缺乏可区分的词汇特征。这类分组本身并不连贯，因此应归为噪声，而不应赋予带有误导性的标签。</p><p>一个轻量级的确定性清理步骤会移除噪声较大的标签词项（如数字 token 和通用词），并在必要时回退到代表性标题。这样既保留了 Elasticsearch 原生标签的特点，也提升了可读性。</p>    Sample cluster labels:
      cluster   3  (200 docs)  arsenal | mikel | villa
      cluster   1  (198 docs)  volodymyr | ukrainian | kyiv
      cluster   0  (196 docs)  hostages | hamas | israeli
      cluster   4  (187 docs)  scrum | rugby | borthwick
      cluster  52  (185 docs)  fossil | renewable | renewables
      cluster  10  (156 docs)  labour | gwynne | mps
      cluster  40  (151 docs)  novel | novels | literary
      cluster  11  (149 docs)  mewis | sarina | wiegman
      cluster  44  (143 docs)  flooding | rainfall | rain
      cluster  13  (131 docs)  doge | musk | elon
      cluster  12  (128 docs)  murder | insp | knockholt
      cluster   5  (124 docs)  putin | backstop | starmer


    Reassigned 35 docs from incoherent clusters to noise
    Total docs: 8,495
    Clustered:  6,040 (71.1%)
    Noise:      2,455 (28.9%)<h3>集群可视化</h3><p>下方的可视化结果展示了全局集群阶段的发现，包括按日期划分的集群文档与噪声文档分布、整个月的 UMAP 投影，以及用于验证集群反映的是主题而非来源的来源构成图。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4ed087d8b6dac2a0/6a17094260084b44543c4501/99099f5adaa945ae4097c50b0d7151c7dd28872e-1000x400.png" alt="集群文档与噪声文档的每日分布" /><p>2025 年 2 月期间，集群文档与噪声文档的每日分布情况。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf5ca320bc91131ab/6a17094366c4f95828f8bfbf/477c6c7177942955a942f85f5c881da50e517915-1100x700.png" alt="全月 UMAP 投影（含所有文档）" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5f554a6bc2bc367b/6a170945a929cfa7a1ae0947/4f4302556c8974c416842452cf33bca06e90b966-1100x700.png" alt="仅显示集群文档的 UMAP 投影" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8e40c26f89ce5523/6a17094747d49c147d2d8974/327f96a79e382ef30614cb0570aa7fccd822b8f8-1100x700.png" alt="[突出显示单个集群的 UMAP 投影" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf1dd2c19ae628f1d/6a1709481949f7a630e7a9a3/acfb1524a10e24d6ff2412e7c3ec0f2b3ac75193-900x600.png" alt="每个集群的来源分布，显示基于主题的分组" /><p>UMAP 中的每个彩色岛屿都代表一个集群：一组关于同一主题的文章，纯粹是通过嵌入相似性而发现的。灰色噪声点则是未能明确归入任何集群的文章（通常是短篇文章、观点文章或一次性报道）。</p><p>来源细分图表确认，集群中的文章<strong>同时</strong>来自 BBC News 和 The Guardian。集群找到的是<em>主题</em>，而非<em>来源</em>，这正是无监督发现应该产生的结果。</p><h3>使用 diversify retriever 探索集群的广度</h3><p>普通 kNN 返回与集群质心（密集核心）最相似的文档。但真实的集群往往还会涵盖多个子主题。<a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/diversify-retriever"><strong>diversify retriever</strong></a> 使用最大边际相关性 (MMR)，呈现既与质心相关、<em>彼此之间又有所差异</em>的文档。</p><p>关键参数是<strong>λ（lambda）</strong>：</p><ul><li><p>λ = 1.0 → 纯相关性（与普通 kNN 相同）。</p></li><li><p>λ = 0.0 → 纯多样性（结果最大程度分散）。</p></li><li><p>λ = 0.5 → 均衡：既与主题保持相关，又能覆盖不同角度。</p></li></ul><p>最简 retriever 请求结构如下：</p>{
  "size": 8,
  "retriever": {
    "diversify": {
      "type": "mmr",
      "field": "embedding",
      "lambda": 0.5,
      "query_vector": "&lt;cluster-centroid-vector&gt;",
      "retriever": {
        "knn": {
          "field": "embedding",
          "query_vector": "&lt;cluster-centroid-vector&gt;",
          "k": 50,
          "num_candidates": 100
        }
      }
    }
  }
}<p>在 diversify 层级，<code>type</code>、<code>field</code> 和 <code>query_vector</code> 参数均为必需：<code>field</code> 用于告知 MMR 应使用哪个 dense_vector 字段来计算结果之间的相似度，而 <code>query_vector</code> 则提供相关性评分的参考向量。</p><p>这可以让您回答：“这个集群到底涵盖了什么？”而不仅仅是“它的中心是什么？”</p>    Exploring cluster 52 (185 docs)
    Label: fossil | renewable | renewables
    Centroid computed (dim=1024)


    ========================================================================
    Plain kNN (closest to centroid)
    ========================================================================
      1. [0.9738] Green campaigners fear ministers are poised to award billions of pounds in fresh subsidies to Drax power station, despite strong concerns...
      2. [0.9710] Thirteen more oil and gas licences could be cancelled as ministers decide new guidance for fossil fuel extraction after a landmark court...
      3. [0.9699] Experts have accused the fossil fuel industry of seeking special treatment after lobbyists argued greenhouse gas emissions from oilfields...
      4. [0.9681] Burning wood is a terrible way of producing electricity . Chopping down trees destroys habitats for wildlife, and growing new trees cannot...
      5. [0.9649] Keir Starmer will do huge damage to the global fight against climate change if he gives in to political pressure and allows the development...
      6. [0.9641] Labour will next week be confronted with stark policy choices that threaten to expose the fault lines between the Treasury and the...
      7. [0.9638] The Drax power station near Selby in north Yorkshire burns imported wood pellets  The government has agreed a new funding arrangement with...
      8. [0.9581] If you care about the world we are handing on to future generations, the news on Thursday morning was dramatic. This January was the...
    
    ========================================================================
    Diversify retriever (MMR, lambda=0.5)
    ========================================================================
      1. [0.9738] Green campaigners fear ministers are poised to award billions of pounds in fresh subsidies to Drax power station, despite strong concerns...
      2. [0.9434] Oil and gas interests have waged a coordinated campaign to kill pro-electrification policies that ban gas connections in new buildings ,...
      3. [0.9303] It was interesting to read that new licences for oil and gas production in the North Sea are being delayed by legal action ( Thirteen more...
      4. [0.9139] The US energy secretary, Chris Wright, has said he “would love to see Australia get in the game of supplying uranium and maybe going down...
      5. [0.9077] Rachel Reeves was facing criticism on Saturday night as it was confirmed that a report she cited as evidence that a third ­runway at...
      6. [0.8996] When Margaret Thatcher opened the Hadley Centre for Climate Change in 1990 journalists suggested she was attempting to appear to be doing...
      7. [0.8993] The vast majority of governments are likely to miss a looming deadline to file vital plans that will determine whether or not the world has...
      8. [0.8987] European imports of seaborne gas shipments fell by a fifth last year to their lowest level since the pandemic, according to a new report,...
    
    Overlap: 1/8 documents appear in both result sets
    
    Avg pairwise similarity (lower = more diverse):
      Plain kNN:          0.9057
      Diversify retriever: 0.6965<p>普通 kNN 的结果往往集中在主题的某一个侧面，也就是那些与质心最相似、彼此之间也最相似的文档。diversify retriever 则会展示同一集群的不同侧面，包括子主题、不同来源和多样化视角。</p><p>多样性指标定量证实了这一点：diversify retriever 结果的平均两两相似度较低，意味着返回的文档覆盖范围更广。</p><p>这适用于：</p><ul><li><p><strong>理解一个集群实际涵盖的范围</strong>，不仅要关注其中心，还要关注其边缘。</p></li><li><p><strong>生成摘要</strong>。多样化且有代表性的文档为 LLM 提供了更好的素材。</p></li><li><p><strong>寻找代表性示例</strong>，用于人工审核或下游标签生成。</p></li><li><p><strong>质量检查</strong>。如果多样化结果看起来不够连贯，就说明这个集群可能需要进一步拆分。</p></li></ul><h2>第 2 部分：时间故事链</h2><h3>跨天追踪故事</h3><p>第 1 部分对整个月的数据进行了全局集群，以发现其中的主题。为了呈现时间演化，同样的密度探测质心分类会按天在<strong>每日索引</strong>上独立运行，再将相邻日期的集群连接起来。请注意，每日集群与第 1 部分中的全局集群相互独立；每天都会生成自己的集群分配和标签，并根据当天的内容进行调整。</p><h4><strong>链接方法：采样与查询</strong></h4><p>对于第 A 天的每个集群：</p><ol><li><p>采样几个代表性文档。</p></li><li><p>对 B 天的索引运行 kNN。</p></li><li><p>统计落入 B 天每个集群的命中数量。</p></li><li><p>如果命中比例超过阈值（kNN 比例 ≥ 0.4），则记录一条链接。</p></li></ol><p>这速度很快（每个集群只查询少量文档，不是全部），并且使用 Elasticsearch 的原生 kNN，无需外部工具。</p>Preparing daily indices for temporal linkage...


Indexed 8,495 docs into 28 daily indices


Temporal links found: 808 in 145.4s

Strongest links:
  2025.02.01 'league | arsenal | premier' -&gt; 2025.02.02 'league | season | striker'  (100%)
  2025.02.03 'league | striker | loan' -&gt; 2025.02.04 'league | striker | season'  (100%)
  2025.02.03 'score | operator | gedling' -&gt; 2025.02.04 'league | striker | season'  (100%)
  2025.02.12 'playoff | leg | bayern' -&gt; 2025.02.13 'league | players | injury'  (100%)
  2025.02.14 'league | injury | football' -&gt; 2025.02.15 'league | premier | football'  (100%)
  2025.02.18 'russia | ukraine | talks' -&gt; 2025.02.19 'saudi | russia | arabia'  (100%)
  2025.02.18 'football | league | bayern' -&gt; 2025.02.19 'league | manchester | players'  (100%)
  2025.02.21 'league | premier | manchester' -&gt; 2025.02.22 'game | players | defeat'  (100%)
  2025.02.21 'rugby | calcutta | brilliant' -&gt; 2025.02.22 'game | players | defeat'  (100%)
  2025.02.26 'metals | kyiv | ukrainian' -&gt; 2025.02.27 'ukraine | russia | talks'  (100%)<p>kNN 比例达到 100% 表示源集群中的所有采样文档都落入同一个目标集群，也就是强度最高的跨日关 流水以上大多数关联都与足球相关，这很合理：英超联赛的报道每天都有，且主题一致性很高。</p><p><code>score | operator | gedling</code> → <code>league | striker | season</code> 链接是一个小众本地足球集群（Gedling 是一家非联赛俱乐部）在第二天被吸收到更广泛的英超联赛集群中的一个例子，这是每日以不同粒度重新集群的自然效果。</p><h3>构建故事链</h3><p>故事链是由连续多天的关联集群组成的序列。</p><p>单个配对链接可以显示周一与周二“英国政治”集群之间的关联。故事链则能揭示完整的发展脉络：一个故事从周一开始，在一周内持续发展，并在周五逐渐淡出。</p><p>链通过贪婪策略构建，所依据的是 kNN 比例 ≥ 0.4 的关联；这意味着源集群中至少有 40% 的采样文档会落入同一个目标集群。算法从最早出现的集群开始，并始终沿着最强的出向关联继续延伸。
</p>    Strong links (kNN fraction &gt;= 0.4): 244
    Story chains spanning 3+ days: 18
      Chain 1: 'ukrainian | kyiv | eastern' (19 days: Feb 3 → Feb 21)
      Chain 2: 'playing | opposition' (19 days: Feb 10 → Feb 28)
      Chain 3: 'tadhg | maro | cadan' (10 days: Feb 1 → Feb 10)
      Chain 4: 'invade | china | putin' (8 days: Feb 21 → Feb 28)
      Chain 5: 'elected | labour | leader' (7 days: Feb 12 → Feb 18)
      Chain 6: 'film | swift | awards' (6 days: Feb 2 → Feb 7)
      Chain 7: 'amendment | termination | reporting' (6 days: Feb 12 → Feb 17)
      Chain 8: 'officers | scene | police' (5 days: Feb 1 → Feb 5)<p>最长的链条连续 19 天追踪乌克兰–俄罗斯相关报道。考虑到 2025 年 2 月持续紧张的地缘政治局势，这并不令人意外。其次是贯穿当月 19 天的英超足球报道。更短的链条则对应于颁奖季（电影/颁奖，6 天）、六国橄榄球赛（10 天）以及英国政治领导层相关报道（7 天）。每条链都代表一条故事轨迹，这些轨迹完全是基于每日索引之间的嵌入相似性自动发现的。</p><h3>Sankey：可视化故事流</h3><p>Sankey 图是一种流向可视化图表，其中连线宽度表示连接强度。在这里，每个垂直条带代表一天，每个节点代表一个每日集群（大小由文档数量决定），每条彩色路径则描绘出一条跨时间延展的故事链。链接宽度表示 kNN 重叠强度：更粗的链接意味着更多采样文档落入目标集群。每条链都使用统一颜色，因此从左到右的一条同色路径就代表一个故事的发展过程。</p><p>例如，乌克兰－俄罗斯链（作为较长路径之一清晰可见）从 2 月初一直延续到第三周；其链接始终较粗，表明该主题在不同日期之间具有很强的连续性。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8c243e0c5773440/6a17093fa6c2b98c86e7968c/100a60a7fb85da8ab3813fd071a82c93f2c3f318-1300x650.png" alt="贯穿 2025 年 2 月的时间故事链" /><p><em>时间故事链贯穿 2025 年 2 月。每条彩色路径都代表一个跨天延续的故事；连线宽度表示 kNN 重叠强度。</em></p><h2>这种方法的成果</h2><p>本文完整介绍了基于 Elasticsearch 构建的无监督文档集群管道：</p><ol><li><p><strong>集群嵌入</strong>：Jina v5 的任务专用适配器可生成针对主题分组优化的嵌入，而不仅仅是用于查询-文档匹配。</p></li><li><p><strong>全局发现式集群</strong>：在一个索引中对整个月的数据进行集群，可最大限度地发掘跨日主题。</p></li><li><p><strong>密度探测质心分类</strong>：取样 5%，通过 <code>msearch</code> kNN 探测密度，选择不同的高密度种子，再根据这些质心对所有文档进行分类。Elasticsearch 负责处理大部分计算任务；客户端仅负责耗时极短（约 0.01 秒）的种子选择工作。</p></li><li><p><a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significanttext-aggregation"><strong><code>significant_text</code></strong></a><strong>标签生成</strong>：无需借助 ML 模型或人工标注，显著性检验就能生成有意义的集群标签。无法产生任何显著词项的集群，说明其内部缺乏连贯性，因此会被降为噪声——这也是一种内置的质量控制机制。</p></li><li><p><strong>时间故事链接</strong>：借助每日索引以及跨索引的采样与查询 kNN，追踪故事如何随时间演变。</p></li></ol><p><strong>关键要点：</strong></p><ul><li><p>嵌入任务类型至关重要：集群嵌入能够形成明显更紧密的主题分组。</p></li><li><p>借助 <a href="https://www.elastic.co/docs/solutions/search/vector/knn">kNN 搜索</a>，Elasticsearch 既可以充当存储层，也可以充当集群引擎。</p></li><li><p>密度探测质心分类几乎将所有计算保留在服务器端，并生成由嵌入空间密度决定的自然大小的集群。</p></li><li><p><code>significant_text</code> 该方法速度快、可解释性强，在自动标注和质量门控方面同样十分有效。</p></li></ul><p><strong>这种方法适用的场景：</strong></p><ul><li><p>您拥有带有时间戳的文本，且希望在无标注训练数据的情况下进行主题发现。</p></li><li><p>您希望使用同一套技术栈完成存储、向量搜索、标注和时间关联。</p></li></ul><p><strong>还可以进一步探索的扩展方向：</strong></p><ul><li><p>多周期集群（如按周、按月汇总）</p></li><li><p>通过增量集群分配进行实时摄取。</p></li><li><p>以 significant_text 词项为种子生成 LLM 集群摘要。</p></li><li><p>在更大规模下，采样得到的 KMeans 质心可以作为基于密度的集群算法的热启动种子，从而降低探测阶段的成本。</p></li></ul><h2>亲自试用</h2><p>您可以将其替换为自己的带时间戳文档语料库；任何包含日期信息的文本集合都适用于这一管道。完整的笔记本和支持代码可在 <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/unsupervised-document-clustering-elasticsearch-jina-embeddings">配套仓库</a>中找到。</p><ul><li><p><a href="https://cloud.elastic.co/registration?onboarding_token=vectorsearch&amp;cta=cloud-registration&amp;tech=trial&amp;plcmt=article%20content&amp;pg=search-labs"><strong>开始免费试用 Elastic Cloud</strong></a>：几分钟内即可启动一个支持 <code>bbq_disk</code> 的托管集群。</p></li><li><p><a href="https://www.elastic.co/elasticsearch/serverless"><strong>试用 Elasticsearch Serverless</strong></a>：无需管理集群，可自动扩展，并支持本演练涵盖的全部内容。</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/unsupervised-document-clustering-elasticsearch-jina-embeddings</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/unsupervised-document-clustering-elasticsearch-jina-embeddings</guid>
    <category><![CDATA[向量数据库]]></category>
    <category><![CDATA[ML 研究]]></category>
    <category><![CDATA[Jina AI]]></category>
    <dc:creator><![CDATA[Matthew Adams]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4bd7dd10a7cd6dc8/6a17094a14b270581de3c5b6/662c00694c3e0c2fb2128098bdb6813df9e86a72-1280x720.png" length="0" type="image/png"/>
    <pubDate>Fri, 10 Apr 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[在 Streams 中利用机器学习自动化日志解析]]></title>
    <description><![CDATA[了解一种混合 ML 方法如何在 Streams 中结合日志格式指纹开展自动化实验，实现 94% 的日志解析准确率和 91% 的日志分区准确率。]]></description>
    <content:encoded><![CDATA[<p>在现代可观测性技术栈中，将来自不同数据源的非结构化日志摄入 Elasticsearch 等平台仍是一项挑战。依赖人工编写的解析规则会让数据管道变得脆弱 — 即使上游代码只有少量更新，也可能导致解析失败、数据无法建立索引。这种脆弱性还会因可扩展性问题而进一步恶化，在动态的微服务环境中，新服务不断加入，手动维护规则很快就会变成运维噩梦。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte8f5bd0e4986b04c/6a170e6acdacbf612e7d2a9e/9108ec303339dd091faa3c363c7cf5c228155f49-3840x2160.png" alt="" /><p>我们的目标是转向一种自动化、自适应的方法，能够同时处理日志解析（字段提取）和日志分区（来源识别）。我们假设，大语言模型（LLM）凭借对代码语法与语义模式的理解，能够在最少人工干预的情况下自动处理这些任务。</p><p>我们很高兴地宣布，此功能已在 <a href="http://elastic.co/elasticsearch/streams"><u>Streams</u></a> 中正式推出！</p><h2>数据集描述</h2><p>我们选择了<a href="https://github.com/logpai/loghub"><strong>Loghub</strong></a>日志集合用于概念验证。我们的调查从以下关键领域选取了代表性样本：</p><ul><li><p>分布式系统：我们使用了 Hadoop 分布式文件系统 (HDFS) 和 Spark 数据集。这些日志混合了大数据平台典型的信息、调试和错误消息。</p></li><li><p>服务器与 Web 应用：Apache Web 服务器和 OpenSSH 的日志提供了访问、错误以及与安全相关事件的重要信息来源，这对于监控 Web 流量和检测潜在威胁至关重要。</p></li><li><p>操作系统：我们纳入了 Linux 和 Windows 日志。这些数据集代表了运维团队日常处理的常见、半结构化系统级事件。</p></li><li><p>移动系统：为确保模型能处理移动环境日志，我们加入了 Android 数据集。这些日志通常较为冗长，涵盖了移动设备上广泛的应用程序和系统级活动。</p></li><li><p>超级计算机：为测试在高性能计算环境下的表现，我们引入了 BGL 数据集，其特点是包含使用特定领域术语的高度结构化日志。</p></li></ul><p>Loghub 集合的一个关键优势在于，其日志基本未经清洗处理和标注，真实模拟了具有微服务架构的、嘈杂的线上生产环境。</p><p>日志示例：</p>[Sun Dec 04 20:34:21 2005] [notice] jk2_init() Found child 2008 in scoreboard slot 6
[Sun Dec 04 20:34:25 2005] [notice] workerEnv.init() ok /etc/httpd/conf/workers2.properties
[Mon Dec 05 11:06:51 2005] [notice] workerEnv.init() ok /etc/httpd/conf/workers2.properties
17/06/09 20:10:58 INFO output.FileOutputCommitter: Saved output of task 'attempt_201706092018_0024_m_000083_1138' to hdfs://10.10.34.11:9000/pjhe/test/1/_temporary/0/task_201706092018_0024_m_000083
17/06/09 20:10:58 INFO mapred.SparkHadoopMapRedUtil: attempt_201706092018_0024_m_000083_1138: Committed<p>此外，我们还搭建了一个包含典型 Web 应用与数据库的 Kubernetes 集群，用于在最常见的场景中采集更多日志。</p><p>常见日志字段示例：时间戳、日志级别（INFO、WARN、ERROR）、来源、消息内容。</p><h2>使用 LLM 进行少样本日志解析</h2><p>我们的首轮实验聚焦于一个根本问题：<strong>LLM 能否可靠地识别关键字段，并生成一致的解析规则来提取它们？</strong></p><p>我们要求模型分析原始日志样本，并以正则表达式和 <a href="https://www.elastic.co/docs/explore-analyze/scripting/grok">Grok</a> 格式生成解析规则。结果显示，此方法潜力巨大，但也面临显著的实现挑战。</p><h3>高置信度与上下文感知</h3><p>初步结果令人鼓舞。LLM 展现出强大的能力，能高置信度地生成与提供的少数样本相匹配的解析规则。除了简单的模式匹配，模型还展现出对日志的理解能力 — 它能正确识别并命名产生日志的来源服务（例如健康追踪应用、Nginx Web 应用、Mongo 数据库）。</p><h3>输入样本的“恰到好处”困境</h3><p>我们的实验很快暴露出一个明显的鲁棒性问题，即<strong>对输入样本极其敏感</strong>。模型的性能会根据提示中包含的具体日志样本而剧烈波动。我们观察到一个日志相似性难题：样本里的日志需要达到<em>适中的多样性水平</em>，从而避免：</p><ul><li><p>过于同质（过拟合）<strong>：</strong>如果输入日志过于相似，LLM 倾向于<strong>过度具体化</strong>。它会把可变数据（例如堆栈跟踪里的具体 Java 类名）当成模板的固定部分。这导致生成的规则非常脆弱，只能覆盖极少部分日志，并提取出无用的字段。</p></li><li><p>过于异质（困惑）：反之，如果样本包含显著的格式差异（或更糟，包含了“垃圾日志”），模型就难以找到共同模式。它往往会生成复杂但有缺陷的正则表达式，或直接将整行内容过度泛化为一个单一的消息块字段。</p></li></ul><h3>上下文窗口限制</h3><p>我们还遇到了上下文窗口瓶颈。当输入日志较长、异构或包含大量可提取字段时，模型的输出质量常常会下降，变得“混乱”或过长而超出输出上下文窗口。在这种情况下，分块会有所帮助。通过使用基于字符和基于实体的分隔符来分割日志，我们可以帮助模型专注于提取主要字段，而不被噪声淹没。</p><h3>一致性与标准化差距</h3><p>即使模型成功生成规则，我们也注意到一些细微的不一致：</p><ul><li><p>服务命名差异：模型在不同运行中会对同一实体使用不同名称（例如将来源标记为“Spark”“Apache Spark”“Spark Log Analytics”）。</p></li><li><p>字段命名差异：字段名称缺乏标准化（例如，<code>id</code> vs. <code>service.id</code> vs. <code>device.id</code>）。我们使用标准化的 <a href="https://www.elastic.co/docs/reference/ecs/ecs-field-reference">Elastic 字段命名规范</a>对名称进行了统一。</p></li><li><p>解析粒度差异：字段提取的粒度因输入日志之间的相似程度而异。</p></li></ul><h2>日志格式指纹</h2><p>为了解决日志相似性问题，我们引入了一种高性能的启发式方法：<strong>日志格式指纹（LFF）</strong>。</p><p>我们不再将原始、嘈杂的日志直接输入 LLM，而是首先应用一种确定性转换来揭示每条消息的底层结构。这个预处理步骤抽象掉变量数据，生成一个简化的“指纹”，使我们能够对相关日志进行分组。</p><p>映射逻辑很简单，以确保速度和一致性：</p><ol><li><p>数字抽象：任何数字序列（0–9）都会替换为单个“0”。</p></li><li><p>文本抽象：任何由字母字符及其间空白组成的序列都会替换为单个“a”。</p></li><li><p>空白字符规范化：所有空白字符序列被压缩为单个空格。</p></li><li><p>符号保留：标点符号和特殊字符被保留，因为它们通常是日志结构最有力的指示符。</p></li></ol><p>我们引入了日志映射方法。基本映射模式包括以下几种：</p><ul><li><p>任意长度的数字（0–9）→ 替换为单个“0”。</p></li><li><p>任意长度的文本（字母字符及空白）→ 替换为单个“a”。</p></li><li><p>空格、制表符和换行符 → 合并为一个空格。</p></li></ul><p>让我们看一个这种映射如何转换日志的例子。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf91eebab0ad79ccd/6a170e6c67045ba94f45c29c/78fa2887486eb9417804354ee3bf2a4fdb0f6383-846x252.png" alt="" /><p>因此我们得到如下日志“掩码”（指纹）：</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt438d74dcb921578b/6a170e6d1949f74aa0e7aae3/ec439a3d3a25002498b97defcff733ea5ebc6b55-826x94.png" alt="" /><p>请注意前两个日志的指纹。尽管时间戳、来源类名和消息内容不同，但它们的前缀（<code>0/0/0 0:0:0 a a.a:</code>）完全一致。这种结构上的一致性使我们能够自动将这些日志归入同一个聚类。这种结构上的一致性使我们能自动把这些日志分桶到同一个聚类中。</p><p>第三个日志会生成完全不同的指纹（<code>0-0-0...</code>），这使我们能够在调用 LLM 之前就用算法将其与第一组区分开来。这使我们在调用LLM <em>之前</em> ，通过算法将其与第一组分离。</p><h2>奖励部分：使用 ES|QL 进行即时实施</h2><p>在 Discover 中运行这条查询就能做到这一点，非常简单。</p><p><strong>查询解析：</strong></p><p><strong>FROM</strong> loghub：指向包含原始日志数据的索引。</p><p><strong>EVAL</strong> pattern =…：核心映射逻辑。我们通过链式 REPLACE 函数执行抽象化处理（例如将数字替换为“0”、文本替换为“a”等），并将结果保存至“pattern”字段。</p><p><strong>STATS </strong>[column1 =] expression1, …<strong> BY </strong>SUBSTRING(pattern, 0, 15):</p><p>这是一个集群步骤。我们将具有前 15 个字符相同的日志进行分组，并创建聚合字段，例如每组的日志总数、日志数据源列表、模式前缀以及 3 条日志示例。</p><p><strong>SORT</strong> total_count DESC | <strong>LIMIT</strong> 100：显示出现频率最高的前 100 个日志模式</p><p>查询结果的可视化如下所示：</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfa3960cf94ccf331/6a170e6fdc55decfa3e00e7c/b119498f124376c41d242a099bf9081fd6536be8-1600x394.png" alt="LogHub 上的日志解析查询结果。" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2dbcde2a22e06367/6a170e71961e693a18c4cfb6/4dcfc0a5b7fa753497cc5def5ea3cd54449c0481-1600x719.png" alt="" /><p>如可视化所示，这种“无需 LLM”的方法能够以很高的准确率对日志进行分区/归因分组。它（基于 LogHub 标签）在 16 个数据源中有 10 个实现了几乎完全的聚类（&gt;90%），并在 16 个数据源中的 13 个实现了多数聚类（&gt;60%），且无需额外清洗、预处理或微调。</p><p>日志格式指纹为<a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-categorize-text-aggregation">日志模式分析</a>等复杂的 ML 解决方案提供了一种务实、高效的替代与补充方案。它能立即洞察日志间的关系，并有效管理大型日志集群。</p><ul><li><p>作为基础组件的多功能性 </p></li></ul><p>借助 <a href="https://www.elastic.co/blog/getting-started-elasticsearch-query-language">ES|QL</a> 实现，LFF 既可作为独立工具用于快速数据诊断/可视化，也可作为日志分析流水线中的基础构件，支撑高吞吐量场景。 </p><ul><li><p>灵活性</p></li></ul><p>LFF 易于定制和扩展以捕获特定模式，例如十六进制数和 IP 地址。</p><ul><li><p>确定性稳定性</p></li></ul><p>与基于 ML 的聚类算法不同，LFF 逻辑简单且确定。新传入的日志不会追溯性地影响现有的日志聚类。</p><ul><li><p>性能与内存</p></li></ul><p>它需要最少的内存，无需训练或 GPU，非常适合实时高吞吐量环境。</p><h2>结合日志格式指纹与 LLM</h2><p>为了验证所提出的混合架构，每个实验都包含来自每个数据源的日志的随机 20% 子集。此约束模拟了现实世界的生产环境，在该环境中，日志是批量处理的，而不是作为一个整体的历史转储进行处理。</p><p>目标是证明 LFF 能作为有效的压缩层。我们希望证明，即使只用少量经过筛选的样本，也能生成高覆盖率的解析规则，并成功泛化到整个数据集。</p><h2>执行管道</h2><p>我们实现了一个多阶段流程，在数据到达 LLM 之前对其进行过滤、聚类和应用分层抽样。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26635762891b3a41/6a170e73509168eea4e1bb91/b3f46ea471760b406a32fc7d4bc74cc03faaced2-3840x1660.png" alt="" /><p>1. 两阶段分层聚类</p><ul><li><p>子类（精确匹配）：通过完全相同的指纹对日志进行聚合。同一子类的每个日志共享完全相同的格式结构。</p></li><li><p>异常值清理：丢弃占总日志量少于 5% 的任何子类，这确保 LLM 聚焦于主要信号，不会被噪声或格式异常的日志带偏。</p></li><li><p>元类（前缀匹配）：剩余的子类通过格式指纹的前 N 个字符匹配分组到元类中。这种分组策略可有效将词汇相似的格式归并到同一个大类下。当数据源未知时，我们选择 N=5 用于日志解析，N=15 用于数据源未知时的日志分区。</p></li></ul><p>2. 分层抽样。一旦分层树构建完成，我们为 LLM 构建日志样本。战略目标是最大化方差覆盖，同时最小化 Token 使用。</p><ul><li><p>我们从更广泛的元类中，为<em>每个</em>有效子类选取具有代表性的日志。</p></li><li><p>为处理子类过多的边缘情况，应用随机下采样以适应目标窗口大小。</p></li></ul><p>3. 规则生成：最后，我们提示 LLM 为每个元类生成一个适用于所提供样本中所有日志的正则表达式解析规则。在概念验证中，我们使用了 GPT-4o mini 模型。</p><h2>实验结果与观察</h2><p>我们在 Loghub 数据集上实现了 94% 的解析准确率和 91% 的分区准确率。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1b896b41b3b70e7e/6a170e757d8d67601a70e7d9/49b2b6a1401dd1f33951da68e5a3fac37d0b5aaa-1600x1506.png" alt="Loghub 数据集的解析准确率为 94%，分区准确率为 91%。" /><p>混淆矩阵展示了日志分区结果。垂直轴代表实际数据源，水平轴代表预测的数据源。热图颜色深浅对应日志量，颜色越浅表示数量越多。对角线排列显示了模型在来源归因上的高保真度，且分散极少。</p><h2>我们的性能基准测试洞察：</h2><ul><li><p><strong>最佳基线：</strong>每个类别 <strong>30–40 条日志样本</strong>的上下文窗口被证明是“最佳区间”，能稳定生成稳健的 Regex 与 Grok 解析模式。</p></li><li><p><strong>输入最小化：</strong>我们将每个类别的输入大小推至 10 个日志（用于正则表达式模式），仅观察到解析性能下降 2%，这证实了基于多样性的抽样比原始数量更为关键。</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/log-parsing-partitioning-automation-experiments-streams</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/log-parsing-partitioning-automation-experiments-streams</guid>
    <category><![CDATA[ML 研究]]></category>
    <category><![CDATA[AI]]></category>
    <dc:creator><![CDATA[Nastia Havriushenko]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc1df5a7cae463d59/6a170e76a6c2b907d7e797ab/965c58f19742361160593c38fcaa8b2f4b0d6cc5-3838x2159.png" length="0" type="image/png"/>
    <pubDate>Fri, 02 Jan 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[使用 ML 生成过滤器和切面]]></title>
    <description><![CDATA[探索在搜索体验中使用 ML 模型自动创建过滤器和切面与传统硬编码方法的利弊。]]></description>
    <content:encoded><![CDATA[<p>过滤器和切面是用于完善搜索结果的机制，可帮助用户更快地找到相关内容或产品。在传统方法中，规则是人工定义的。例如，在电影目录中，流派等属性是预定义的，可用于筛选器和切面。另一方面，通过人工智能模型，可以自动从电影特征中提取新的属性，使整个过程更加动态和个性化。在本博客中，我们将探讨每种方法的优缺点，重点介绍它们的应用和挑战。</p><h2>筛选器与分面</h2><p>在开始之前，我们先来定义一下什么是过滤器和切面。<strong>过滤器</strong>是用于限制结果集的预定义属性。例如，在市场中，甚至在进行搜索之前就可以使用筛选器。用户可以先选择一个类别，如<strong>"Video games"</strong> ，然后再搜索<strong>"PS5"</strong> ，将搜索范围缩小到更具体的子集，而不是整个数据库。这大大增加了获得更多相关结果的机会。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0a77b38aae238938/6a170b821949f72a52e7aa51/5ed8868fa5017d034e1273e35c884a5430afdf3c-1600x937.png" alt="筛选" /><p><strong>面板的</strong>工作原理与筛选器类似，但只有在执行搜索后才可用。换句话说，搜索会返回结果，并根据这些结果生成新的细化选项列表。例如，在搜索 PS5 游戏机时，可以显示<strong>存储容量</strong>、<strong>运输成本</strong>和<strong>颜色</strong>等信息，帮助用户选择理想的产品。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt166e356b80d423ef/6a170b840e2e494ca341a10f/c5633fcc5b6fbb916110faf32144d8d43572e33a-1600x937.png" alt="面面观 " /><p>既然我们已经定义了过滤器和切面，下面我们就来讨论经典方法和基于机器学习 (ML) 的方法对其实施和使用的影响。每种方法都有影响搜索效率的优势和挑战。</p><h2>过滤器和分面的经典方法</h2><p>在这种方法中，过滤器和切面是根据预定义规则手动定义的。这意味着，考虑到目录结构和用户需求，可用于细化搜索的属性是固定的，并事先进行了规划。</p><p>例如，在市场中，"Electronics" 或"Fashion" 等类别可能有特定的筛选条件，如品牌、格式和价格范围。这些规则是静态创建的，可确保搜索体验的一致性，但每当出现新的产品或类别时，就需要进行手动调整。</p><p>虽然这种方法提供了对所显示过滤器和面的可预测性和控制，但当出现需要动态改进的新趋势时，这种方法就会受到限制。</p><p><strong>优点</strong></p><ul><li><p><strong>可预测性和控制：</strong>由于筛选器和切面是手动定义的，因此管理变得更加容易。</p></li><li><p><strong>低复杂性：</strong>无需训练模型。</p></li><li><p><strong>易于维护：</strong>由于规则是预定义的，因此可以快速进行调整和修正。</p></li></ul><p><strong>缺点</strong></p><ul><li><p><strong>新过滤器需要重新索引：</strong>每当需要使用新属性作为筛选器时，就必须对整个数据集重新索引，以确保文档包含该信息。</p></li><li><p><strong>缺乏动态适应性：</strong>过滤器是静态的，不能根据用户行为的变化自动调整。</p></li></ul><h3>滤波器/滤面的实现 - 经典方法</h3><p>在<strong>开发工具 Kibana</strong> 中，我们将使用<strong>经典方法</strong>创建过滤器/面板演示。</p><p>首先，我们定义映射来构建索引：</p>PUT videogames
{
  "mappings": {
    "properties": {
      "name": { "type": "text" },
      "brand": { "type": "keyword" },
      "storage": { "type": "keyword" },
      "price": { "type": "float" },
      "description": { "type": "text" }
    }
  }
}<p><strong>品牌</strong>和<strong>存储</strong> <strong>字段</strong>被设置为关键字，可直接用于聚合<strong>（面</strong>）。<strong>价格</strong>字段为<strong>浮动</strong>类型，可以创建<strong>价格范围</strong>。</p><p>下一步，将对产品数据编制索引：</p>POST videogames/_bulk
{ "index": { "_id": 1 } }
{ "name": "Play Station 5", "brand": "Sony", "storage": "1TB", "price": 499.99, "description": "Stunning Gaming: Marvel at stunning graphics and experience the features of the new PS5. Breathtaking Immersion: Discover a deeper gaming experience with support for haptic feedback, adaptive triggers, and 3D Audio technology. Slim Design: With the PS5 Digital Edition, gamers get powerful gaming technology in a sleek, compact design. 1TB of Storage: Have your favorite games ready and waiting for you to play with 1TB of built-in SSD storage. Backward Compatibility and Game Boost: The PS5 console can play over 4,000 PS4 games. With Game Boost, you can even enjoy faster, smoother frame rates in some of the best PS4 console games." }
{ "index": { "_id": 2 } }
{ "name": "Xbox Series X", "brand": "Microsoft", "storage": "1TB", "price": 499.99, "description": "Fastest, most powerful Xbox console ever. Play thousands of titles: Every game looks and plays better on Xbox Series X. At the heart of Series X is the Xbox Velocity. Architecture, which combines a custom SSD and built-in software to significantly reduce load times in and out of game. Switch between multiple games in an instant with Quick Resume. Explore new worlds and experience the action like never before with an unparalleled 12 teraflops of graphics processing power. Enjoy 4K gaming at up to 120 frames per second, premium advanced 3D sound, and more. 4K at 120 FPS: requires compatible content and display X version - with disc drive" }
{ "index": { "_id": 3 } }
{ "name": "Nintendo Switch", "brand": "Nintendo", "storage": "512GB", "price": 299.99, "description": "SHARPER, VIBRANT VISUALS. The new 7-inch screen on the Nintendo Switch OLED takes your gaming to the next level: vibrant colors with sharp contrasts for every moment. INTEGRATED GAMEPLAY. Enjoy the console's many multiplayer modes and connect with other players. Online or locally, the fun on the Nintendo Switch is guaranteed. ENJOY IMMERSION FOR LONGER. In addition to delivering an unparalleled experience, thanks to its improved audio, the Nintendo Switch has a rechargeable battery while you play. From 4.5 hours to 9 hours of battery life. INCLUDES SUPER MARIO BROS. WONDER. Transform your world with the phenomenal flowers in this new Mario game, full of amazing adventures, power-ups and new abilities. NINTENDO SWITCH ONLINE SUBSCRIPTION. Access online games, play with friends and enjoy the exclusive benefits of the Nintendo Switch Online subscription." }
{ "index": { "_id": 4 } }
{ "name": "Steam Deck", "brand": "Valve", "storage": "512GB", "price": 399.99, "description": "You can save games, apps, photos and videos without worrying about space. High-Level Performance: The 4-core processor and graphics ensure a dynamic experience and fast responses. High-Definition Images: Smooth transitions and sharp images provide complete immersion in the game. Wireless Connectivity: Wi-Fi technology allows you to play wherever you want, without wires or cables limiting your fun" }
{ "index": { "_id": 5 } }
{ "name": "Nintendo Switch Lite", "brand": "Nintendo", "storage": "512GB", "price": 299.99, "description": "MADE TO BE PORTABLE. Nintendo Switch Lite is designed specifically for portable gaming. The console lets you jump into your favorite games wherever you are. COMPACT AND LIGHTWEIGHT. With its sleek, lightweight design, this console is ready to hit the road wherever you are. COMPATIBLE GAMES. The Nintendo Switch Lite system plays the library of Nintendo Switch games that work in handheld mode. A WORLD OF COLOR TO CHOOSE FROM. Available in a variety of vibrant and unique colors, Nintendo Switch Lite lets you bring even more personality wherever you go." }<p>现在，让我们按照品牌、存储空间和价格范围对结果进行分组，从而检索出经典的面孔。在查询中，定义了 size:0。在这种情况下，目标是只检索聚合结果，而不包括与查询相对应的文档。</p>POST videogames/_search
{
  "size": 0,
  "aggs": {
    "brands": {
      "terms": { "field": "brand" }
    },
    "storage_sizes": {
      "terms": { "field": "storage" }
    },
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 300 },   
          { "from": 300, "to": 500 },  
          { "from": 500 }  
        ]
      }
    }
  }
}<p>回复将包括<strong>品牌</strong>、<strong>存储</strong>和<strong>价格的</strong>计数，有助于创建筛选器和面。</p>"aggregations": {
   "brands": {
     "doc_count_error_upper_bound": 0,
     "sum_other_doc_count": 0,
     "buckets": [
       {
         "key": "Microsoft",
         "doc_count": 1
       },
       {
         "key": "Nintendo",
         "doc_count": 1
       },
       {
         "key": "Sony",
         "doc_count": 1
       },
       {
         "key": "Valve",
         "doc_count": 1
       }
     ]
   },
   "storage_sizes": {
     "doc_count_error_upper_bound": 0,
     "sum_other_doc_count": 0,
     "buckets": [
       {
         "key": "1TB",
         "doc_count": 2
       },
       {
         "key": "512GB",
         "doc_count": 2
       }
     ]
   },
   "price_ranges": {
     "buckets": [
       {
         "key": "*-300.0",
         "to": 300,
         "doc_count": 1
       },
       {
         "key": "300.0-500.0",
         "from": 300,
         "to": 500,
         "doc_count": 3
       },
       {
         "key": "500.0-*",
         "from": 500,
         "doc_count": 0
       }
     ]
   }
 }<h2>基于机器学习/人工智能的筛选器和分面方法</h2><p>在这种方法中，机器学习（ML）模型（包括人工智能（AI）技术）分析数据属性，生成相关的过滤器和面。ML/AI 不依赖预定义规则，而是利用索引数据特征。这样就能动态发现新的切面和过滤器。</p><p><strong>优点</strong></p><ul><li><p><strong>自动更新：</strong>自动生成新的过滤器和切面，无需手动调整。</p></li><li><p><strong>发现新属性：</strong>它可以将<strong>以前未考虑过的 </strong>数据特征识别为过滤器，从而丰富搜索体验。</p></li><li><p><strong>减少人工操作：</strong>当人工智能从可用数据中学习时，团队无需不断定义和更新过滤规则。</p></li></ul><p><strong>缺点</strong></p><ul><li><p><strong>维护复杂性：</strong>使用模型可能需要预先验证，以确保生成的过滤器的一致性。</p></li><li><p><strong>需要 ML 和 AI 专业知识：</strong>该解决方案需要合格的专业人员来微调和监控模型性能。</p></li><li><p><strong>无关过滤器的风险：</strong>如果模型没有得到很好的校准，可能会生成对用户无用的切面。</p></li><li><p><strong>成本：</strong>使用 ML 和 AI 可能需要第三方服务，从而增加运营成本。</p></li></ul><p>值得注意的是，即使有了校准良好的模型和精心制作的提示，生成的切面仍应经过审查步骤。这种验证可以是手动的，也可以基于审核规则，以确保内容的适当性和安全性。虽然这不一定是一个缺点，但这是一个重要的考虑因素，以确保在提供给用户之前，面的质量和适用性。</p><h3>实施过滤器/面板--人工智能方法</h3><p>在本演示中，我们将使用一个人工智能模型来自动分析产品特性并提出相关属性建议。有了结构良好的提示，我们就能从目录中提取信息，并将其转化为过滤器和切面。下面，我们将介绍这一过程的每个步骤。</p><p>最初，我们将使用<strong>推理 API</strong>注册一个端点，以便与 ML 服务集成。以下是与<strong>OpenAI 服务</strong>集成的示例。</p>PUT _inference/completion/generate_filter_ia
{
   "service": "openai",
   "service_settings": {
       "api_key": "your-key",
       "model_id": "gpt-4o-mini"
   }
}<p>现在，我们定义一个管道来执行提示并获取模型生成的新过滤器。</p>PUT /_ingest/pipeline/generate_filter_ai
{
   "processors": [
     {
       "script": {
         "source": """ctx.prompt = "You are an expert in data organization for search and product categorization. Your task is to analyze the following product and identify the best dynamic facets that can be used in an e-commerce search experience. Product: " + ctx.name + "description: " + ctx.description + "Instructions: - Analyze the product name and description. - Extract only the dynamic facets (technological features or product characteristics that can be inferred from the description, try to create max 3 facets by characteristics found). Put the values into an array. Using key and value, e.g. dynamic_facets: [{ \"name\": \"Gaming Experience\", \"value\": \"Haptic Feedback\" },{ \"name\": \"Gaming Experience\", \"value\": \"Adaptive Triggers\" } - Return only a JSON."
         """
       }
     },
     {
       "inference": {
         "model_id": "generate_filter_ia",
         "input_output": {
           "input_field": "prompt",
           "output_field": "result"
         }
       }
     },
     {
       "gsub": {
         "field": "result",
         "pattern": "```json",
         "replacement": ""
       }
     },
     {
       "json" : {
         "field" : "result",
         "strict_json_parsing": false,
         "add_to_root" : true
       }
     },
     {
       "remove": {
         "field": "result"
       }
     },
     {
       "remove": {
         "field": "prompt"
       }
     }
   ]
}<p>为"PlayStation 5" 产品运行该流水线的模拟，说明如下：</p><p><em>令人惊叹的游戏：惊叹于令人惊叹的画面，体验全新 PS5 的功能。</em></p><p><em>令人惊叹的沉浸感：支持触觉反馈、自适应触发器和 3D 音频技术，探索更深层次的游戏体验。</em></p><p><em>超薄设计：通过 PS5 数字版，玩家可以在时尚、紧凑的设计中获得强大的游戏技术。</em></p><p><em>1TB 存储空间：内置 1TB SSD 存储空间，让您随时随地畅玩最喜爱的游戏。</em></p><p><em>向后兼容和游戏提升：PS5 游戏机可播放 4,000 多款 PS4 游戏。有了 Game Boost，您甚至可以在一些最好的 PS4 游戏机游戏中享受更快、更流畅的帧率。</em></p><p>让我们观察一下这次模拟产生的提示输出。</p>{
 "docs": [
   {
     "doc": {
       "_index": "index",
       "_version": "-3",
       "_id": "1",
       "_source": {
         "name": "Play Station 5",
         "result": """```json
{
 "dynamic_facets": [
   { "name": "Storage Capacity", "value": "1TB SSD" },
   { "name": "Graphics Technology", "value": "Stunning Graphics" },
   { "name": "Audio Technology", "value": "3D Audio" }
 ]
}
```""",
         "description": "Stunning Gaming: Marvel at stunning graphics and experience the features of the new PS5. Breathtaking Immersion: Discover a deeper gaming experience with support for haptic feedback, adaptive triggers, and 3D Audio technology. Slim Design: With the PS5 Digital Edition, gamers get powerful gaming technology in a sleek, compact design. 1TB of Storage: Have your favorite games ready and waiting for you to play with 1TB of built-in SSD storage. Backward Compatibility and Game Boost: The PS5 console can play over 4,000 PS4 games. With Game Boost, you can even enjoy faster, smoother frame rates in some of the best PS4 console games.",
         "model_id": "generate_filter_ia",
         "prompt": """You are an expert in data organization for search and product categorization. Your task is to analyze the following product and identify the best dynamic facets that can be used in an e-commerce search experience. Product: Play Station 5description: Stunning Gaming: Marvel at stunning graphics and experience the features of the new PS5. Breathtaking Immersion: Discover a deeper gaming experience with support for haptic feedback, adaptive triggers, and 3D Audio technology. Slim Design: With the PS5 Digital Edition, gamers get powerful gaming technology in a sleek, compact design. 1TB of Storage: Have your favorite games ready and waiting for you to play with 1TB of built-in SSD storage. Backward Compatibility and Game Boost: The PS5 console can play over 4,000 PS4 games. With Game Boost, you can even enjoy faster, smoother frame rates in some of the best PS4 console games.Instructions: - Analyze the product name and description. - Extract only the dynamic facets (technological features or product characteristics that can be inferred from the description, try create max 3 facets by characteristics found). Put the values like arrays. Using key and value, e.g. dynamic_facets: [{ "name": "Gaming Experience", "value": "Haptic Feedback" },{ "name": "Gaming Experience", "value": "Adaptive Triggers" } - Return only a JSON."""
       },
       "_ingest": {
         "timestamp": "2025-03-19T22:14:32.0161803Z"
       }
     }
   }
 ]
}<p>现在，新索引中将添加一个新字段<strong>dynamic_facets</strong>，用于存储人工智能生成的面。</p>PUT videogames_1
{
 "mappings": {
   "properties": {
     "name": { "type": "text" },
     "brand": { "type": "keyword" },
     "storage": { "type": "keyword" },
     "price": { "type": "float" },
     "description": { "type": "text" },
     "dynamic_facets": { "type": "nested",
     "properties": { "name": { "type": "keyword" },
                     "value": { "type": "keyword" } } }
   }
 }
}<p>我们将使用<strong>Reindex API</strong> 将<strong>videogames</strong>索引重新编入<strong>videogames_1</strong>，并在此过程中应用<strong>generate_filter_ai</strong>管道。该管道将在索引编制过程中自动生成动态切面。</p>POST _reindex?wait_for_completion=false
{
 "source": {
   "index": "videogames"
 },
 "dest": {
   "index": "videogames_1",
   "pipeline": "generate_filter_ai"
 }
}<p>现在，我们将运行搜索并获得新的筛选器：</p>GET videogames_1/_search
{
 "size": 0,
 "query": {
   "match": {
     "name": "nintendo"
   }
 },
 "aggs": {
   "dynamic_facets": {
     "nested": {
       "path": "dynamic_facets"
     },
     "aggs": {
       "facets": {
         "terms": {
           "field": "dynamic_facets.name"
         },
         "aggs": {
           "facets": {
             "terms": {
               "field": "dynamic_facets.value"
             }
           }
         }
       }
     }
   }
 }
}<p>结果</p>"aggregations": {
   "dynamic_facets": {
     "doc_count": 3,
     "facets": {
       "doc_count_error_upper_bound": 0,
       "sum_other_doc_count": 0,
       "buckets": [
         {
           "key": "Frame Rate",
           "doc_count": 1,
           "facets": {
             "doc_count_error_upper_bound": 0,
             "sum_other_doc_count": 0,
             "buckets": [
               {
                 "key": "120 FPS",
                 "doc_count": 1
               }
             ]
           }
         },
         {
           "key": "Gaming Resolution",
           "doc_count": 1,
           "facets": {
             "doc_count_error_upper_bound": 0,
             "sum_other_doc_count": 0,
             "buckets": [
               {
                 "key": "4K",
                 "doc_count": 1
               }
             ]
           }
         },
         {
           "key": "Graphics Processing Power",
           "doc_count": 1,
           "facets": {
             "doc_count_error_upper_bound": 0,
             "sum_other_doc_count": 0,
             "buckets": [
               {
                 "key": "12 Teraflops",
                 "doc_count": 1
               }
             ]
           }
         }
       ]
     }
   }
 }<p>下面是一个简单的前端，以表示面的实现：</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb0d6aa40caf7a91a/6a170b86ab7f0839afdb9eb6/12b6d9d4f4d0985848d92841545fd22b7253ae6d-1600x1288.png" alt="执行方面" /><p><a href="https://gist.github.com/andreluiz1987/06d9ec1b381e942e9def0e969bd811a0">这里</a>提供了用户界面代码。</p><h2>结论</h2><p>这两种创建过滤器和切面的方法各有利弊。基于手动规则的传统方法可提供控制并降低成本，但需要不断更新，且无法动态适应新产品或新功能。</p><p>另一方面，基于人工智能和机器学习的方法可以自动提取切面，使搜索更加灵活，并且无需人工干预即可发现新的属性。不过，这种方法的实施和维护可能更为复杂，需要进行校准以确保结果的一致性。</p><p>在传统方法和基于人工智能的方法之间做出选择，取决于企业的需求和复杂程度。对于数据属性稳定且可预测的简单场景，传统方法可以更高效、更易于维护，从而避免基础设施和人工智能模型的不必要成本。另一方面，使用 ML/AI 提取切面可以大大增加价值，改善搜索体验，使过滤更加智能。</p><p>重要的是要评估自动化是否值得投资，或者更传统的解决方案是否已能有效满足业务需求。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/filters-facets-using-ml</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/filters-facets-using-ml</guid>
    <category><![CDATA[相关性]]></category>
    <category><![CDATA[ML 研究]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4084864dcdaa25d3/6a170b880c485781f901aaa9/6f196643d573614fe5124705c7e4db9bfce004b0-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 03 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[评估搜索相关性第一部分 —— BEIR 基准测试]]></title>
    <description><![CDATA[学习在深入理解 BEIR 基准测试的背景下评估您的搜索系统，并掌握提升搜索评估流程的技巧与方法。]]></description>
    <content:encoded><![CDATA[<p>这是系列博客文章的第一篇，探讨如何在更好地理解 BEIR 基准测试的背景下，评估您自己的搜索系统。我们将介绍具体的技巧与方法，帮助您在深入理解 BEIR 的背景下改进搜索评估流程。我们还将指出常见的陷阱，这些陷阱会降低评估的可靠性。最后，我们注意到，LLM 为搜索工程师提供了一种强大的新工具，我们将通过示例展示如何利用它们来协助搜索评估。</p><h2>理解搜索相关性评估中的 BEIR 基准测试</h2><p>要改进任何系统，您需要能够衡量其表现。在搜索领域，<a href="https://arxiv.org/abs/2104.08663">BEIR</a>（或等效 <a href="https://huggingface.co/spaces/mteb/leaderboard">MTEB</a> 排行榜的检索部分）被认为是信息检索社区的“圣杯”，这并不令人意外。它是一个结构非常完善的基准测试，涵盖了不同任务的多样化数据集。更具体地说，它涵盖了以下领域：</p><ul><li><p>参数检索 (ArguAna, Touche2020)</p></li><li><p>开放领域问答 (HotpotQA, Natural Questions, FiQA)</p></li><li><p>段落检索（MSMARCO）</p></li><li><p>重复问题检索（Quora，CQADupstack）</p></li><li><p>事实核查（FEVER, Climate-FEVER, Scifact）</p></li><li><p>生物医学信息检索（TREC-COVID、NFCorpus、BioASQ）</p></li><li><p>实体检索 (DBPedia)</p></li><li><p>引文预测 (SCIDOCS)</p></li></ul><p>它提供了一个单一的统计信息 nDCG@10，用于衡量系统在其返回的顶部结果中，为每个任务样例匹配最相关文档的程度。对于人机交互的搜索系统来说，顶部结果的相关性至关重要。然而，评估搜索效果有很多细微差别，而单一的汇总统计数据无法涵盖这些差别。</p><h2>BEIR 数据集的结构</h2><p>每个基准测试包含三个组成部分：</p><ul><li><p>要检索的语料库或文档</p></li><li><p>查询</p></li><li><p>查询的相关性判断（也称为 <code>qrels</code>）。</p></li></ul><p>相关性判断以零或更高的分数表示。非零分数表示文档与查询有一定的相关性。</p><p>数据集</p><p>语料库大小</p><p>#测试集中的查询数量</p><p>#qrels 中正向标注的数量</p><p>#qrels 等于零</p><p>#语料库中的重复项数量</p><p>Arguana</p><p>8,674</p><p>1,406</p><p>1,406</p><p>0</p><p>96</p><p>Climate-FEVER</p><p>5,416,593</p><p>1,535</p><p>4,681</p><p>0</p><p>0</p><p>DBPedia</p><p>4,635,922</p><p>400</p><p>15,286</p><p>28,229</p><p>0</p><p>FEVER</p><p>5,416,568</p><p>6,666</p><p>7,937</p><p>0</p><p>0</p><p>FIQA-2018</p><p>57,638</p><p>648</p><p>1,706</p><p>0</p><p>0</p><p>HotpotQA</p><p>5,233,329</p><p>7,405</p><p>14,810</p><p>0</p><p>0</p><p>Natural Questions</p><p>2,681,468</p><p>3,452</p><p>4,021</p><p>0</p><p>16,781</p><p>NFCorpus</p><p>3,633</p><p>323</p><p>12,334</p><p>0</p><p>80</p><p>Quora</p><p>522,931</p><p>10,000</p><p>15,675</p><p>0</p><p>1,092</p><p>SCIDOCS</p><p>25,657</p><p>1,000</p><p>4,928</p><p>25,000</p><p>2</p><p>Scifact</p><p>5,183</p><p>300</p><p>339</p><p>0</p><p>0</p><p>Touche2020</p><p>382,545</p><p>49</p><p>932</p><p>1,982</p><p>5,357</p><p>TREC-COVID</p><p>171,332</p><p>50</p><p>24,763</p><p>41,663</p><p>0</p><p>MSMARCO</p><p>8,841,823</p><p>6,980</p><p>7,437</p><p>0</p><p>324</p><p>CQADupstack (sum)</p><p>457,199</p><p>13,145</p><p>23,703</p><p>0</p><p>0</p><p><strong>表 1</strong>：数据集统计信息。这些数字是在数据集的测试部分计算得出的（<code>MSMARCO</code> 的 <code>dev</code>）。</p><p><strong>表 1</strong> 列出了构成 <code>BEIR</code> 基准的数据集的一些统计数据，如语料库中的文档数量、测试数据集中的查询数量以及 <code>qrels</code> 文件中的正/负（查询、文档）对数量。通过快速查看数据，我们可以立即推断出以下几点：</p><ul><li><p>大多数数据集在 <code>qrels</code> 文件中不包含任何负面关系，即零分，这会明确地将文档标记为与给定查询无关。</p></li><li><p>每个查询的平均文档关联数（<code>#qrels</code>/<code>#queries</code>）从 <code>ArguAna</code> 的 1.0 到 493.5（<code>TREC-COVID</code>）不等，但大多数情况下的值为 <code>&lt;</code> 5。</p></li><li><p>一些数据集的语料库中存在重复文档，在某些情况下可能导致评估不准确，例如，当一个文档被认为与查询相关但其重复文档却不相关时。例如，在 <code>ArguAna</code> 中，我们识别出 96 个重复文档对案例，每对中只有一个文档被标记为与查询相关。通过将初始 qrels 列表“扩展”以包含重复文档，我们观察到 <code>nDCG@10</code> 分数平均相对提高了约 1%。</p></li></ul>{
  "_id": "test-economy-epiasghbf-pro02b",
  "title": "economic policy international africa society gender house believes feminisation",
  "text": "Again employment needs to be contextualised with …",
  "metadata": {}
}
{
  "_id": "test-society-epiasghbf-pro02b",
  "title": "economic policy international africa society gender house believes feminisation",
  "text": "Again employment needs to be contextualised with …",
  "metadata": {}
}
<p><strong>ArguAna 中的重复对示例。在 qrels 文件中，只有第一个文档显示为与查询（“test-economy-epiasghbf-pro02a”）相关（作为反方论点）</strong></p><p>在 MTEB 排行榜上比较模型时，人们很容易将重点放在平均检索质量上。这虽然是模型整体质量的一个良好代理指标，但并不一定能说明它在您特定场景下的表现。由于结果按数据集报告，因此值得了解不同数据集与您的搜索任务的关联程度，并仅使用最相关的数据集重新评估模型。如果您想深入研究，还可以检查各数据语料库的主题重叠情况。按主题对质量指标进行分层，可以更精细地评估模型的具体优势与劣势。</p><p>这里需要特别注意，当文档未在 <code>qrels</code> 文件中标注时，默认情况下它被视为与查询不相关。我们对此领域进行了更深入的探究，并收集了一些证据，以更清晰地阐明以下问题：“评估者面对没有真实标注信息的（查询，文档）对的频率有多高？”。这一点之所以重要，是因为当只有浅层标注可用时（即并非每个相关文档都被标记），一个信息检索系统可能仅仅因为它“选择”呈现了不同的相关（但未标记）文档，而被判定为比另一个系统更差。这是创建高质量评估集时的常见陷阱，尤其是对于大型数据集。为了可行，人工标注通常会关注当前系统返回的顶部结果，因此可能会遗漏其盲区中的相关文档。因此，通常更可取的做法是将更多资源集中在少数查询的更完整标注上，而不是广泛的浅层标注。</p><h2>利用 BEIR 基准测试进行搜索相关性评估</h2><p>为了启动分析，我们实施了以下场景（见<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/evaluating-search-relevance-part-1/retrieve-and-rerank.ipynb">笔记本</a>）：</p><ol><li><p>首先，我们将每个数据集的语料库加载到 Elasticsearch 索引中。</p></li><li><p>对于测试集中的每个查询，我们使用 BM25 检索前 100 个文档。</p></li><li><p>我们使用多种 SOTA 重排序模型对检索到的文档进行重新排序。</p></li><li><p>最后，我们报告第 2 步（检索后）和第 3 步（重新排序后）得出的前 10 名文档的 "评判率"。换句话说，我们计算的是 <code>qrels</code> 文件中得分排名前 10 的文档的平均百分比。</p></li></ol><p>我们使用的模型重新排序列表如下：</p><ul><li><p><a href="https://docs.cohere.com/reference/rerank">Cohere 的</a> <code>rerank-english-v2.0</code> 和 <code>rerank-english-v3.0</code></p></li><li><p><a href="https://huggingface.co/BAAI/bge-reranker-base">BGE-base</a></p></li><li><p><a href="https://huggingface.co/mixedbread-ai/mxbai-rerank-xsmall-v1">mxbai-rerank-xsmall-v1</a></p></li><li><p><a href="https://huggingface.co/cross-encoder/ms-marco-MiniLM-L-6-v2">MiniLM-L-6-v2</a></p></li></ul><p></p><p>检索</p><p>重排序</p><p></p><p></p><p></p><p></p><p>数据集</p><p>BM25（%）</p><p>Cohere Rerank v2 (%)</p><p>Cohere Rerank v3 (%)</p><p>BGE-base (%)</p><p>mxbai-rerank-xsmall-v1 (%)</p><p>MiniLM-L-6-v2 (%)</p><p>Arguana</p><p>7.54</p><p>4.87</p><p>7.87</p><p>4.52</p><p>4.53</p><p>6.84</p><p>Climate-FEVER</p><p>5.75</p><p>6.24</p><p>8.15</p><p>9.36</p><p>7.79</p><p>7.58</p><p>DBPedia</p><p>61.18</p><p>60.78</p><p>64.15</p><p>63.9</p><p>63.5</p><p>67.62</p><p>FEVER</p><p>8.89</p><p>9.97</p><p>10.08</p><p>10.19</p><p>9.88</p><p>9.88</p><p>FiQa-2018</p><p>7.02</p><p>11.02</p><p>10.77</p><p>8.43</p><p>9.1</p><p>9.44</p><p>HotpotQA</p><p>12.59</p><p>14.5</p><p>14.76</p><p>15.1</p><p>14.02</p><p>14.42</p><p>Natural Questions</p><p>5.94</p><p>8.84</p><p>8.71</p><p>8.37</p><p>8.14</p><p>8.34</p><p>NFCorpus</p><p>31.67</p><p>32.9</p><p>33.91</p><p>30.63</p><p>32.77</p><p>32.45</p><p>Quora</p><p>12.2</p><p>10.46</p><p>13.04</p><p>11.26</p><p>12.58</p><p>12.78</p><p>SCIDOCS</p><p>8.62</p><p>9.41</p><p>9.71</p><p>8.04</p><p>8.79</p><p>8.52</p><p>Scifact</p><p>9.07</p><p>9.57</p><p>9.77</p><p>9.3</p><p>9.1</p><p>9.17</p><p>Touche2020</p><p>38.78</p><p>30.41</p><p>32.24</p><p>33.06</p><p>37.96</p><p>33.67</p><p>TREC-COVID</p><p>92.4</p><p>98.4</p><p>98.2</p><p>93.8</p><p>99.6</p><p>97.4</p><p>MSMARCO</p><p>3.97</p><p>6.00</p><p>6.03</p><p>6.07</p><p>5.47</p><p>6.11</p><p>CQADupstack（平均）</p><p>5.47</p><p>6.32</p><p>6.87</p><p>5.89</p><p>6.22</p><p>6.16</p><p><strong>表 2</strong>：在检索/重新排序的前 10 个文档上计算的（数据集、重排序器）对的评判率</p><p>从 <strong>表 2</strong> 可以看出，除了 <code>TREC-COVID</code>（覆盖率&gt;90%）、<code>DBPedia</code>（~65%）、<code>Touche2020</code> 和 <code>nfcorpus</code>（~35%）之外，大多数数据集在检索或重新排序后的标注率介于 5% 到略高于 10% 之间。这并不意味着所有这些未标注文档都是相关的，但其中可能有一个子集——特别是那些排在靠前位置的——可能是正例。</p><p>随着通用指令调优语言模型的出现，我们拥有了一种新的强大工具，它有可能自动化判断相关性。这些方法的计算成本通常太高，不适合在线搜索，但我们这里关注的是离线评估。在下文中，我们将使用它们来探究一些 BEIR 数据集可能存在浅层标注问题的证据。</p><p>为了进一步验证这一假设，我们决定专注于 MSMARCO 数据集，选择 100 个查询及其前 5 个经重排序（使用 Cohere v2）且当前未被标记为相关的文档。我们遵循了两种不同的评估路径：首先，我们使用精心调优的提示（后续文章中将详述）引导最近发布的 <a href="https://huggingface.co/microsoft/Phi-3-mini-4k-instruct">Phi-3-mini-4k</a> 模型来预测文档与查询的相关性（或不相关性）。与此同时，这些案例也进行了人工标注，以评估 LLM 输出与人工判断之间的一致性率。总体而言，我们可以得出以下两个结论：</p><ul><li><p>LLM 响应与人工标注之间的一致性率接近 80%，作为该方向的起点，这似乎足够好。</p></li><li><p>在 57.6% 的情况下（基于人工判断），返回的文档被判定为实际上与查询相关。换一种说法：对于 100 个查询，我们有 107 个文档被判定为相关，但至少还有 0.576 × 5 × 100 = 288 个额外文档实际上是相关的！</p></li></ul><p>以下是一些从 <code>MSMARCO</code>/<code>dev</code> 数据集中提取的示例，其中包含查询、注释的正例文档（来自 <code>qrels</code>）一个由于标注不全导致的假负例文档：</p><p>示例 1：</p>{
  "query":
    {
        "_id": 155234,
        "text": "do bigger tires affect gas mileage"
    },
  "positive_doc":
    {
        "_id": 502713,
        "text": "Tire Width versus Gas Mileage. Tire width is one of the only tire size factors that can influence gas mileage in a positive way. For example, a narrow tire will have less wind resistance, rolling resistance, and weight; thus increasing gas mileage.",
    },
    "negative_doc":
    {
        "_id": 7073658,
        "text": "Tire Size and Width Influences Gas Mileage. There are two things to consider when thinking about tires and their effect on gas mileage; one is wind resistance, and the other is rolling resistance. When a car is driving at higher speeds, it experiences higher wind resistance; this means lower fuel economy."
    }
}
<p>示例 2：</p>{
  "query":
    {
        "_id": 300674,
        "text": "how many years did william bradford serve as governor of plymouth colony?"
    },
  "positive_doc":
    {
        "_id": 7067032,
        "text": "http://en.wikipedia.org/wiki/William_Bradford_(Plymouth_Colony_governor) William Bradford (c.1590 \u00e2\u0080\u0093 1657) was an English Separatist leader in Leiden, Holland and in Plymouth Colony was a signatory to the Mayflower Compact. He served as Plymouth Colony Governor five times covering about thirty years between 1621 and 1657."
    },
    "negative_doc":
    {
        "_id": 2495763,
        "text": "William Bradford was the governor of Plymouth Colony for 30 years. The colony was founded by people called Puritans. They were some of the first people from England to settle in what is now the United States. Bradford helped make Plymouth the first lasting colony in New England."
    }
}
<p>人工评估此类特定查询，是理解搜索质量的一种普遍有用的技术，它是对 nDCG@10 等定量指标的补充。如果您有一组代表性的查询集，在每次修改搜索时都运行它们，这将为您提供关于性能如何变化的重要定性信息，而这些信息在统计数据中是看不见的。例如，它为您提供了更多关于搜索返回的错误结果的见解：它可以帮助您发现检索结果中的明显错误，相关错误类别，如误解特定领域术语等等。</p><p>我们的结果与围绕 <code>MSMARCO</code> 评估的相关研究一致。例如，<a href="https://arxiv.org/pdf/2109.00062">Arabzadeh 等人</a> 遵循类似的流程，他们雇用众包工人进行偏好判断：除其他发现外，他们表明在许多情况下，重新排序模块返回的文档比 MSMARCO <code>qrels</code> 文件中的文档更受青睐。另一项证据来自 <a href="https://arxiv.org/pdf/2010.08191">RocketQA</a> 重新排序器的作者，他们报告称，经过人工检查，超过 70% 的重排序文档被判定为相关。</p><p> 更新 - 2023 年 9 月 9 日：在对数据集进行仔细重新评估后，我们识别出另外 15 个相关文档案例，使其总数从 273 个增加到 288 个。</p><h2>主要要点和后续步骤</h2><ul><li><p>对更高质量真实标注的追求永无止境，因为它对于基准测试和模型比较至关重要。如果谨慎使用并配以适当的指令调优，LLM 可以在某些评估领域提供协助</p></li><li><p>更普遍地说，鉴于基准测试永远不会完美，从单纯的分数比较转向捕捉统计显著性差异的更稳健技术可能更可取。<a href="https://arxiv.org/pdf/2109.00062">Arabzadeh 等人</a>等人的工作提供了一个很好的例子，他们基于研究结果构建了 95% 置信区间，以表明不同运行之间是否存在显著（或不显著）差异。在随附的<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/evaluating-search-relevance-part-1/retrieve-and-rerank.ipynb">笔记本</a>中，我们提供了使用<a href="https://en.wikipedia.org/wiki/Bootstrapping_(statistics)">自助法</a>实现置信区间的方法。</p></li><li><p>从最终用户的角度来看，在阅读基准测试结果时，考虑任务对齐性是有益的。例如，对于构建 RAG 管道的 AI 工程师来说，如果知道最典型的用例涉及从不同来源汇集多条信息，那么在 HotpotQA 等多跳问答数据集上评估其检索模型的性能，会比在整个 BEIR 基准测试的全局平均分更有意义</p></li></ul><p>在<a href="https://www.elastic.co/search-labs/blog/evaluating-search-relevance-part-2">下一篇博客文章</a>中，我们将更深入地探讨如何使用 Phi-3 作为 LLM 评判工具，以及调优它以预测相关性的过程。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/evaluating-search-relevance-part-1</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/evaluating-search-relevance-part-1</guid>
    <category><![CDATA[ML 研究]]></category>
    <category><![CDATA[Python]]></category>
    <dc:creator><![CDATA[Thanos Papaoikonomou,Thomas Veasey]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9d9912c8d4187096/6a1704f5b0367d30e672bc17/54a6e5197f5721b36fc65f27387d29803ed35589-721x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 16 Jul 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[了解 Lucene 中的标量量化]]></title>
    <description><![CDATA[探索 Elastic 如何将标量量化引入 Lucene，包括自动字节量化、按段量化&amp; 性能见解。]]></description>
    <content:encoded><![CDATA[<h2>Lucene 中的自动字节量化</h2><p>虽然 HNSW 是一种强大而灵活的矢量存储和搜索方式，但要快速运行，它确实需要大量内存。例如，查询 1MM float32 向量维）大约需要1,000,000 * 4 * (768 + 12) = 3120000000 字节（约 3GB内存）。一旦开始搜索大量向量，成本就会变得很高。减少使用约内存的一种方法是通过字节量化。Lucene 以及 Elasticsearch 支持矢量索引已有一段时间，但建立这些矢量一直是用户的责任。这种情况即将改变，因为我们在 Lucene 中引入了标量量化。</p><h2>标量量化 101</h2><p>所有量化技术都被视为原始数据的有损转换。这意味着，为了节省篇幅，有些信息会丢失。有关标量量化的深入解释，请参阅：<a href="https://www.elastic.co/search-labs/scalar-quantization-101">标量量化 101</a>在高层次上，标量量化是一种有损压缩技术。通过一些简单的计算，可以节省大量空间，而对召回的影响却很小。</p><h2>探索建筑</h2><p>习惯于使用 Elasticsearch 的人可能已经熟悉了这些概念，但这里还是要简要介绍一下搜索文档的分布情况。</p><p>每个 Elasticsearch 索引都由<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/size-your-shards.html#size-your-shards">多个分片</a>组成。虽然每个分片只能分配给一个节点，但每个索引有多个分片，可以跨节点并行计算。</p><p>每个分区都由一个<a href="https://lucene.apache.org/core/9_8_0/core/org/apache/lucene/index/package-summary.html">Lucene 索引</a>组成。Lucene 索引由多个只读段组成。在索引过程中，文件会被缓冲并定期刷新到只读段中。当满足某些条件时，这些片段可以在后台合并成一个更大的片段。所有这些都是可配置的，也有其自身的复杂性。但是，当我们谈到分段和合并时，我们指的是只读的 Lucene 分段以及这些分段的自动定期合并。<a href="https://www.elastic.co/search-labs/vector-search-elasticsearch-rationale">下面我们将深入探讨</a>分段合并和设计决策。</p><h2>Lucene 中每个分段的量化</h2><p>Lucene 中的每个分段都存储了以下内容：单个向量、HNSW 图表指数、量化向量和计算出的量化值。为简洁起见，我们将重点讨论 Lucene 如何存储量化向量和原始向量。对于每个片段，我们在文件中记录原始矢量，在 文件中记录量化矢量和单个校正乘法浮点，在文件中记录量化的元数据。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1861d0af970fd096/6a17d9887f6f15a45dc099c0/507a4d578f8a5d2225b11d16ac1fc0b7dd39eaa1-1207x228.png" alt=".vec文件" /><p>图 1：原始矢量存储文件的简化布局。由于 数值为 4 字节，因此占用由于我们正在进行量化，因此在 HNSW 搜索时不会加载这些数据。只有在特别要求时才会使用（例如或在段落合并时<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/filter-search-results.html#query-rescorer">重新</a>量化。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8c52b51939357280/6a17d9897b54f9130f8b3761/ffc6e8bffefc5cd36f14aae315184c89e04a6587-1440x207.png" alt=".veq 文件" /><p>图 2：的简化布局锉刀占用空间，并将在搜索过程中加载到内存中。字节用于计算校正乘数浮动，以调整评分，提高准确性和召回率。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt28e007988f81e5c0/6a17d98b25daabe23208a0d9/555cc92d7d179d8c9711cefbaaac3e0b815d2e42-1440x182.png" alt=".vemq 文件" /><p>图 3：元数据文件的简化布局。在这里，我们将跟踪量化和矢量配置，以及计算出的该分段的量化值。</p><p>因此，对于每个片段，我们不仅要存储量化向量，还要存储用于制作这些量化向量和原始向量的量化值。但是，我们为什么还要保留原始矢量呢？</p><h2>与您一起成长的量化</h2><p>由于 Lucene 会定期刷新到只读分段，因此每个分段只能看到所有数据的一部分。这意味着计算出的量化值仅直接适用于整个数据的样本集。如果样本能充分代表整个语料库，这并不是什么大问题。但 Lucene 允许您以各种方式对索引进行排序。因此，您可以对数据进行索引排序，从而增加每个分段量化计算的偏差。此外，您还可以随时刷新数据！您的样本集可能很小，甚至只有一个矢量。另一个扳手是，您可以控制合并发生的时间。虽然 Elasticsearch 已配置了默认值和定期合并，但你可以通过<a href="https://www.elastic.co/guide/en/elasticsearch/reference/8.10/indices-forcemerge.html">_force_merge</a>API 随时要求合并。那么，我们如何在提供良好的量化效果的同时，还能保证所有这些灵活性？</p><p>Lucene 的向量量化会随时间自动调整。由于 Lucene 采用的是只读分段架构，因此我们可以保证每个分段中的数据没有变化，并在代码中明确规定何时可以更新。这意味着在分段合并过程中，我们可以根据需要调整量化值，并可能重新量化向量。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0d9a2390958c3e82/6a17d98cbe6086e4fd0045d5/646baa8279719d06c05c1a4fdb80a0c060e0dd94-1440x446.png" alt="多个分段量化" /><p>图 4：具有不同量级的三个示例片段。</p><p>但重新量化不是很贵吗？它确实有一些开销，但 Lucene 会智能地处理量化，只在必要时进行完全量化。让我们以图 4 中的片段为例。让我们给段和段各提供，段只提供。Lucene 会对量化值进行加权平均，如果合并后的量化值与数据段的原始量化值足够接近，我们就不必重新量化该数据段，而会使用新合并的量化值。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte2596c10ee616cf3/6a17d98eec0f8903b85a6497/58fa20d60dc337ca7108eb01e84a07c330e87ee6-1440x447.png" alt="合并的量化值" /><p>图 5：段和段有，而段只有 份文件的合并量化示例。</p><p>在图 5 所示的情况中，我们可以看到合并后的量化值与和 中的原始量化值非常相似。 段，似乎偏差太大。因此，中的向量将根据新合并的量化值重新量化。</p><p>在一些极端情况下，合并后的量化值与任何原始量化值的差异都非常大。在这种情况下，我们将从每个分段中抽取一个样本，然后重新计算量化值。</p><h2>量化性能&amp; 数字</h2><p>那么，它的速度快吗？以下是在<code>c3-standard-8</code> GCP 实例上运行实验收集到的数据。为了确保与进行公平的比较，我们使用了一个足够大的实例来在内存中保存原始向量。我们使用最大内积法索引了 <a href="https://huggingface.co/datasets/Cohere/wikipedia-22-12-simple-embeddings">Cohere Wiki</a>向量。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfa48e3724ad97fed/6a17d98f445de96aca4cff88/81958f99b8a1397f669db48de00f264cacc6b49f-576x455.png" alt="量化召回" /><p>图 6：量化矢量与原始矢量的 Recall@10。量化矢量的搜索性能明显快于原始矢量，只需再收集 5 个矢量就能迅速恢复召回率； 可见一斑。</p><p>图 6 展示了这个故事。虽然在召回方面存在差异，这是意料之中的，但差异并不大。而且，只要再收集 5 个矢量，召回率的差异就会消失。所有这一切，段合并速度快，内存仅为向量的 1/4。</p><h2>结论</h2><p>Lucene 为难题提供了独特的解决方案。量化不需要 "训练 "或 "优化 "步骤。在 Lucene 中，它可以正常工作。如果数据发生变化，也不必担心需要 "重新训练 "矢量索引。Lucene 会检测重大变化，并在数据生命周期内自动处理这些变化。期待我们将这一功能引入 Elasticsearch！</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/scalar-quantization-in-lucene</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/scalar-quantization-in-lucene</guid>
    <category><![CDATA[Lucene]]></category>
    <category><![CDATA[ML 研究]]></category>
    <dc:creator><![CDATA[Benjamin Trent]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb382d99ffac9992c/6a17d991b1e113640179f12c/dc07f16d347a68476bded5df9adb831452f61278-1024x1024.jpg" length="0" type="image/jpeg"/>
    <pubDate>Sat, 11 Nov 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[开源 sysgrok - 用于分析、理解和优化系统的人工智能助手]]></title>
    <description><![CDATA[Sysgrok 是一个实验性的概念验证，旨在展示如何使用 LLM 来帮助 SWE 和 SRE 了解系统、调试问题和优化性能。]]></description>
    <content:encoded><![CDATA[<p>在这篇文章中，我将介绍 sysgrok，这是一个研究原型，我们正在研究如何将 OpenAI 的 GPT 模型等大型语言模型 (LLM) 应用于性能优化、根本原因分析和系统工程等领域的问题。您可以在<a href="https://github.com/elastic/perf-copilot">GitHub</a> 上找到它。</p><h2>sysgrok 是做什么的？</h2><p>sysgrok 的功能包括</p><ul><li><p>提取剖析器识别出的最昂贵的函数和进程，解释每个函数和进程提供的功能，并提出优化建议</p></li><li><p>获取一台主机和该主机遇到的问题描述，自动调试问题并提出补救措施和进一步行动建议</p></li><li><p>使用剖析器注释过的源代码，解释热点路径，并提出提高代码性能的方法</p></li></ul><p>sysgrok 的功能主要针对三大类解决方案：</p><ol><li><p><strong>作为性能、可靠性和其他系统相关数据的分析引擎。</strong>在这种模式下，LLM 接收工程师使用的其他工具（如 Linux 命令行工具、剖析器或 Observability 平台）的输出。sysgrok 的目标是使用 LLM 对系统状态进行解释、总结并形成假设。然后，它还可能提出优化或补救建议。</p></li><li><p><strong>作为特定性能和可靠性相关任务的重点自动化解决方案。</strong>在性能工程和 SRE 工作中，有些任务会反复出现。对于这些问题，我们可以建立重点突出的自动化助手，工程师可以直接使用，sysgrok 本身也可以在解决其他问题时使用。例如，在性能工程中，回答这样的问题"："这个库是否有更快的、具有同等功能的版本？" "是很常见的。sysgrok 可直接支持该功能。</p></li><li><p><strong>作为性能和可靠性问题的自动根本原因分析工具。</strong>前两类解决方案是数据分析、解释、搜索和总结的混合体。最重要的是，它们都是以一种有针对性的方式应用于工程师自己收集的数据。在 sysgrok 中，我们还在研究利用 LLM 解决问题的第三种方法，即 LLM 与其他工具相结合，自主执行根本原因分析并解决给定问题。在这种方法中，LLM 会得到一个问题描述（如"网络服务器出现高延迟" ），并告诉它有哪些功能可用（如"ssh 到主机，" " 执行任意 Linux 命令行工具" ）。然后，要求当地联络机制利用现有能力采取行动，对问题进行分流。这些操作由 sysgrok 执行，并要求 LLM 分析结果、分流问题、提出补救措施和下一步建议。</p></li></ol><p>sysgrok 还处于早期阶段，但我们发布它是因为它已经在各种任务中发挥了作用--我们希望它能为其他人进行类似实验提供方便。如果您有任何想法，请随时向我们发送 PR 或<a href="https://github.com/elastic/sysgrok">在 GitHub 上</a>打开问题！</p><h2>分析 LLM 的性能问题</h2><p>在过去的几个月里，LLM（如 OpenAI 的 GPT 模型）大受欢迎，它为各种产品（从客户助理聊天机器人到数据处理助手，再到编码助手）提供了自然语言接口和核心引擎。这一趋势的一个有趣方面是，基本上所有这些应用都使用了未经专门训练或微调的通用模型。相反，它们是在整个互联网的大范围内训练出来的，因此适用于各种任务。</p><p>那么，我们能否利用这些模型来帮助进行性能分析、调试和优化呢？调查性能问题、找出根本原因并提出优化方案的方法<a href="https://www.brendangregg.com/methodology.html">多种多样</a>。不过，任何性能分析工作的核心都是查看各种工具（如 Linux 命令行工具或可观测性平台）的输出，并对输出进行解释，从而形成有关系统状态的假设。在对 GPT 模型进行培训的材料中，有涵盖软件工程、调试、基础设施分析、操作系统内部、Kubernetes、Linux 命令及其用法以及性能分析方法的资料。因此，这些模型可用于总结、解释和假设性能工程师日常遇到的数据和问题，从而加快工程师完成分析的速度。</p><p>不过，我们还可以更进一步，在工程师自己的调查过程中，不仅仅将 LLM 用于数据分析和问题解答。正如我们稍后将在本篇文章中展示的，在某些情况下，LLM 本身可用于驱动流程，由 LLM 决定运行哪些命令或查看哪些数据源来调试问题。</p><h2>演示</h2><p>有关 sysgrok 支持的全部功能，请查看 GitHub<a href="https://github.com/elastic/sysgrok">代码库</a>。从广义上讲，它支持三种解决问题的方法：</p><h3>方法 1：作为性能、可靠性和其他系统相关数据的分析引擎</h3><p>在这种模式下，LLM 会收到工程师正在使用的另一个工具的输出，如 Linux 命令行工具、剖析器或可观测性平台。sysgrok 的目标是解释、总结并提出补救建议。</p><p>例如，<em>topn</em>子命令会获取剖析器报告的最昂贵函数，解释输出结果，然后提出优化系统的建议。</p><p>这段视频还展示了 sysgrok 提供的聊天功能。当提供 -chat 参数时，sysgrok 将在 LLM 每次回复后进入聊天会话。</p><p>这一功能也可通用于 Linux 命令行工具的输出。例如，在《<a href="https://www.brendangregg.com/Articles/Netflix_Linux_Perf_Analysis_60s.pdf">60 秒内完成 Linux 性能分析》（Linux Performance Analysis in 60 seconds）</a>一文中，Brendan Gregg 概述了 SRE 首次连接到出现性能或稳定性问题的主机时应运行的 10 条命令。<em>analyzecmd</em>子命令将要连接的主机和要执行的命令作为输入，然后为用户分析和汇总命令的输出。我们可以用它来自动完成 Gregg 所描述的过程，为用户提供 10 条命令生成的所有数据的一段式摘要，省去用户逐条查看命令输出的麻烦。</p><h3>方法 2：作为特定性能和可靠性相关任务的重点自动化解决方案</h3><p>在性能工程和 SRE 工作中，有些任务会反复出现。对于这些问题，我们可以建立有针对性的自动化助手，工程师可以直接使用，sysgrok 本身也可以在解决其他问题时使用。</p><p>例如，<em>finfaster</em>子命令将库或程序的名称作为输入，并使用 LLM 查找更快的等效替代库或程序。这是性能工程中非常常见的一项任务。</p><p>这种方法在 sysgrok 中的另一个例子是<em>explainfunction</em>子命令。该子命令使用一个库的名称和该库中的一个函数。它解释了该库的作用及其常见用例，然后解释了其功能。最后，如果该库和函数占用了大量 CPU 资源，它还会提出可能的优化建议。</p><h3>方法 3：作为性能和可靠性问题的自动根本原因分析工具</h3><p>LLM 的使用不仅限于集中问题解答、摘要和类似任务。它也不局限于一次性使用，即向他们提出一个单一的、孤立的问题。sysgrok<em>debughost</em>子命令演示了如何将 LLM 用作"大脑" ，以实现自动解决问题的目标。在这种模式下，LLM 被嵌入到一个进程中，该进程使用 LLM 来决定如何调试特定问题，并赋予它连接主机、执行命令和访问其他数据源的能力。</p><p>debughost 命令可能是 sysgrok 目前最具实验性的部分。它展示了在实现性能分析自动代理的道路上迈出的一步，但要达到这一目标还需要大量的研究&amp;D。</p><h2>结论</h2><p>在这篇文章中，我介绍了 sysgrok，这是一款全新的开源人工智能助手，用于分析、理解和优化系统。我们还讨论了 sysgrok 实现的三大类方法：</p><ol><li><p>性能、可靠性和其他系统相关数据的分析引擎：请参阅 topn、stacktrace、analyzecmd 和 code 子命令。</p></li><li><p>针对特定性能和可靠性相关任务的自动化解决方案：请参阅 explainprocess、explaintfunction 和 findfaster 子命令。</p></li><li><p>自动分析性能和可靠性问题的根本原因：参见 debughost 子命令。</p></li></ol><p>你可以<a href="https://github.com/elastic/sysgrok">在 GitHub 上</a>找到 sysgrok 项目。请随时创建公关和问题，如果您想讨论项目或法律硕士的一般应用，也可以直接通过<a href="mailto:sean.heelan@elastic.co">sean.heelan@elastic.co</a>联系我。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/open-sourcing-sysgrok-ai-assistant</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/open-sourcing-sysgrok-ai-assistant</guid>
    <category><![CDATA[ML 研究]]></category>
    <dc:creator><![CDATA[Sean Heelan]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltff8f9a2d63790904/6a170bbbcdacbf61eb7d2a26/86f6f563d9f1ee6929ce4afc9005dfacd93f2990-720x420.png" length="0" type="image/png"/>
    <pubDate>Wed, 28 Jun 2023 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[无状态--使用 Elasticsearch 查找的新状态]]></title>
    <description><![CDATA[了解 Elasticsearch 无状态，探索无状态架构，从而提高性能并降低成本。]]></description>
    <content:encoded><![CDATA[<p>通过无状态 Elasticsearch，我们正在投资建设一个全新的完全云本地架构，以推动规模和速度的发展。在本博客中，我们将探讨我们的起点、引入无状态架构后 Elasticsearch 的未来以及该架构的细节。</p><h2>我们的起点</h2><p><a href="https://www.elastic.co/what-is/elasticsearch">Elasticsearch</a>的第一个版本于 2010 年发布，它是一个分布式可扩展搜索引擎，允许用户快速搜索并浮现关键见解。十二年过去了，Elasticsearch 的提交次数已超过 65,000 次，它将继续为用户提供久经考验的解决方案，以解决各种搜索问题。在包括数百名 Elastic 全职员工在内的 1,500 多名贡献者的努力下，Elasticsearch 不断发展，以应对搜索领域出现的新挑战。</p><p>在 Elasticsearch 诞生之初，当数据丢失的问题被提出时，Elastic 团队经过<a href="https://www.elastic.co/blog/a-new-era-for-cluster-coordination-in-elasticsearch">多年的努力</a>，重写了集群协调系统，以确保确认的数据得到安全存储。当发现在大型集群中管理索引是一件麻烦事时，团队开始实施广泛的<a href="https://www.elastic.co/blog/elasticsearch-data-lifecycle-management-with-data-tiers">ILM 解决方案</a>，通过允许用户预先定义索引模式和生命周期操作来实现这项工作的自动化。由于用户发现需要存储大量的度量和时间序列数据，因此增加了各种功能，如更好的压缩功能，以减少数据量。由于搜索大量冷数据的存储成本越来越高，我们投资创建了<a href="https://www.elastic.co/blog/introducing-elasticsearch-searchable-snapshots">可搜索快照</a>，作为在低成本对象存储上直接搜索用户数据的一种方式。</p><p>这些投资为 Elasticsearch 的下一步发展奠定了基础。随着云原生服务和新协调系统的发展，我们决定是时候对 Elasticsearch 进行进化，以改善使用云原生系统时的体验。我们相信，这些变化为在 Elastic<a href="https://www.elastic.co/cloud/"> Cloud 上运行</a> Elasticsearch 带来了改进运行、性能和成本的机会。</p><h2>我们的目标--采用无状态架构</h2><p>运行或协调 Elasticsearch 时面临的主要挑战之一是，它依赖于大量持久状态，因此是一个有状态的系统。这三个主要部分是 translog、索引存储和集群元数据。这种状态意味着存储必须是持久的，不会在节点重启或更换时丢失。</p><p>Elastic Cloud 上现有的 Elasticsearch 架构必须在多个可用性区域内重复索引，以便在发生故障时提供冗余。我们打算将这些数据的持久性从本地磁盘转移到对象存储，如 AWS S3。通过依靠外部服务来存储这些数据，我们将不再需要进行索引复制，从而大大减少了与摄取相关的硬件。由于 AWS S3、GCP Cloud Storage 和 Azure Blob Storage 等云对象存储跨可用区复制数据的方式，这种架构还能提供非常高的耐用性保证。</p><p>将索引存储卸载到外部服务中还能让我们通过分离索引和搜索职责来重新构建 Elasticsearch。我们打算建立一个索引层和一个搜索层，而不是让主实例和副本实例同时处理这两种工作负载。将这些工作负载分开，可以使它们独立扩展，并使硬件选择更有针对性，以满足各自的使用情况。它还有助于解决一个长期存在的难题，即搜索和索引负载会相互影响。</p><p>经过为期数月的概念验证和实验阶段，我们确信这些对象存储服务能够满足我们对索引存储和集群元数据的要求。我们的测试和基准测试表明，这些存储服务可以满足我们在 Elastic Cloud 中看到的最大集群的高索引需求。此外，将数据备份到对象存储区可降低索引成本，并可对搜索性能进行简单调整。为了搜索数据，Elasticsearch 将使用久经考验的可搜索快照（Searchable Snapshots）模型，在该模型中，数据永久保存在云原生对象存储中，而本地磁盘则用作频繁访问数据的缓存。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf17ddc7c69dc6e76/6a17d9f563baff2cc5741b02/e1d7b7b36bd1bbf906d50c3b873bfe2e1acd7fb3-1440x805.png" alt="" /><p>为了帮助区分，我们将现有模型描述为"节点对节点" 复制。在该模型的热层中，主分片和副本分片都承担着处理摄取和提供搜索请求的重任。这些节点是"有状态的" ，因为它们依靠本地磁盘安全地持久化所托管分片的数据。此外，主分片和副本分片不断进行通信，以保持同步。它们的做法是将主分区上执行的操作复制到副本分区上，这意味着这些操作的成本（主要是 CPU 成本）会在指定的每个副本上产生。同样的分片和节点在为收录工作提供服务的同时，也在为搜索请求提供服务，因此在进行配置和扩展时必须考虑到这两种工作负载。</p><p>除了搜索和摄取，节点到节点复制模型中的分片还负责处理其他密集型任务，如合并 Lucene 片段。虽然这种设计有其优点，但根据我们多年来从客户那里了解到的情况以及更广泛的云生态系统的演变，我们看到了很多机会。</p><p>新架构可实现许多直接和未来的改进，包括</p><ol><li><p>在相同的硬件上，你可以大幅提高摄取吞吐量，或者换个角度看，在相同的摄取工作负载下，大幅提高效率。这一增长来自于消除了每个副本的重复索引操作。CPU 密集型的索引操作只需在索引层上进行一次，然后将生成的段传送到对象存储区。这样，搜索层就可以按原样使用数据了。</p></li><li><p>您可以将计算与存储分开，以简化集群拓扑结构。如今，Elasticsearch 拥有多个数据层（内容层、热层、温层、冷层和冻结层），可将数据与硬件配置文件相匹配。热层用于近实时搜索，冷冻层用于搜索频率较低的数据。这些层级在提供价值的同时，也增加了复杂性。在新架构中，不再需要数据层，从而简化了 Elasticsearch 的配置和操作。我们还将索引与搜索分离开来，这进一步降低了复杂性，并使我们能够独立扩展这两种工作负载。</p></li><li><p>通过减少必须存储在本地磁盘上的数据量，索引层的存储成本可以得到改善。目前，Elasticsearch 必须在热节点（主节点和副本节点）上存储完整的分片副本，以便编制索引。采用无状态方法，直接在对象存储区建立索引，只需要部分本地数据。对于只进行追加的用例，只需存储某些元数据以编制索引。这将大大减少索引所需的本地存储空间。</p></li><li><p>您可以降低与搜索查询相关的存储成本。通过将 "可搜索快照 "模式作为搜索数据的本机模式，与搜索查询相关的存储成本将大大降低。根据用户对搜索延迟的需求，Elasticsearch 将允许对频繁请求的数据进行调整，以增加本地缓存。</p></li></ol><h2>基准测试 - 75% 索引吞吐量改进</h2><p>为了验证这种方法，我们实施了一个广泛的概念验证，其中数据仅在单个节点上编制索引，并通过云对象存储实现复制。我们发现，通过消除对索引复制专用硬件的需求，我们可以将索引<strong>吞吐量提高 75% </strong>。此外，仅从对象存储中提取数据所需的 CPU 成本远低于编制数据索引和本地写入数据的成本，而这正是目前热层所必需的。这意味着搜索节点可以将其 CPU 全部用于搜索。</p><p>这些性能测试是在一个双节点集群上针对三大公共云提供商（AWS、GCP 和 Azure）进行的。我们打算在实现无状态生产的过程中，继续建立更大的基准。</p><p><strong>索引吞吐量</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4a44b141e077a8cf/6a17d9f7445de982084cffa9/2c3c94b38a5c816a720112851b4a497b4176c285-593x270.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8dfd035e67eaf0a8/6a17d9f9e3179127802d56d5/ee236cd455e8fa8f4af62a0f8557a5e907deffbf-596x270.png" alt="" /><p><strong>CPU 使用率</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt13df63861f1149a6/6a17d9fa414c643b05945026/76632a9211a4762e3559ab498beb5381b7d441d2-547x329.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfd352e4ebd0a1417/6a17d9fcbe60863c0c0045e0/62dd9063a05d5841e196a5abf39db7e9c990fb01-547x326.png" alt="" /><h2>我们无国籍，你们有储蓄</h2><p>Elastic Cloud 上的无状态架构可让您减少索引开销，独立扩展摄取和搜索，简化数据层管理，并加快扩展或升级等操作。这是实现弹性云平台实质性现代化的第一个里程碑。</p><h2>成为 Elasticsearch 无状态愿景的一部分</h2><p>有兴趣抢先尝试这种解决方案吗？您可以在<a href="https://discuss.elastic.co/">讨论区</a>或我们的<a href="https://ela.st/slack">社区休闲频道</a>与我们联系。我们希望您能提供反馈意见，帮助我们确定新架构的方向。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/stateless-your-new-state-of-find-with-elasticsearch</guid>
    <category><![CDATA[ML 研究]]></category>
    <category><![CDATA[Elastic Cloud Serverless]]></category>
    <dc:creator><![CDATA[Leaf Lin,Tim Brooks,Quin Hoxie]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcc6aaa7d1d08f8d5/6a17d9c94b055d1ca0432084/dd0e2f3d452a288a185558102c705c60fdf77ad9-1440x840.png" length="0" type="image/png"/>
    <pubDate>Thu, 06 Oct 2022 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[实施学术论文：从 Elasticsearch 和 Lucene 中汲取的经验教训]]></title>
    <description><![CDATA[借鉴我们使用 Elasticsearch 和 Lucene 的经验，了解将研究论文纳入软件应用程序的策略。]]></description>
    <content:encoded><![CDATA[<p>本帖分享在软件应用程序中实施学术论文的策略。它借鉴了 Elasticsearch 和 Lucene 的示例，希望能帮助其他工程师学习我们的经验。读到这些策略，你可能会想："但这只是软件开发啊！"事实的确如此：作为工程师，我们已经掌握了正确的方法和工具，只是需要加以调整，以适应新的挑战。</p><h2>背景</h2><p>在开发 Elasticsearch 的过程中，我们偶尔会遇到一个重要问题，但没有简单或既定的解决方法。人们自然会问："嗯，有没有学术论文论述过这个问题？"其他时候，学术工作是灵感的源泉。我们会遇到一篇提出新算法或数据结构的论文，然后想："这一定很有用！"以下是 Elasticsearch 和 Apache Lucene 如何结合学术工作的几个例子：</p><ul><li><p>用于<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.15/search-aggregations-metrics-cardinality-aggregation.html"> 万有引力聚合 的</a><a href="https://research.google/pubs/pub40671/"> HyperLogLog++</a></p></li><li><p>用于<a href="https://www.elastic.co/blog/improving-response-latency-in-elasticsearch-with-adaptive-replica-selection"> 自适应复制选择</a><a href="https://www.usenix.org/system/files/conference/nsdi15/nsdi15-paper-suresh.pdf"> 的 C3 算法</a></p></li><li><p>用于 Lucene 中最近向量搜索的<a href="https://arxiv.org/abs/1603.09320">层次导航小世界图 (HNSW)</a></p></li><li><p><a href="https://github.com/elastic/ml-cpp/pull/488">改进机器学习分类的</a> <a href="https://jmlr.csail.mit.edu/papers/volume17/15-308/15-308.pdf">MIC 统计</a></p></li><li><p><a href="http://engineering.nyu.edu/~suel/papers/bmw.pdf">块最大 WAND</a>，用于<a href="https://www.elastic.co/blog/faster-retrieval-of-top-hits-in-elasticsearch-with-block-max-wand">在 Lucene 中更快地检索热门话题</a></p></li><li><p>......以及<a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.15/query-dsl-combined-fields-query.html"> </a><a href="https://github.com/elastic/elasticsearch/blob/b2a9328890b23e7ccf6c66a3b13d6d65e453a3dd/server/src/main/java/org/elasticsearch/search/sort/BucketedSort.java#L302-L323">更多</a></p></li></ul><p>学术论文是工程师开发数据密集型系统的宝贵资源。但是，实施这些算法可能会让人望而生畏，而且容易出错--算法描述往往很复杂，重要的实际细节被省略了。测试是一项真正的挑战：例如，我们如何才能彻底测试输出结果与数据集密切相关的机器学习算法？</p><h2>像评估软件依赖性一样评估论文</h2><p>添加一个新的软件依赖关系需要仔细评估：如果其他软件包不正确、速度慢或不安全，我们的项目也可能如此。在引入依赖关系之前，开发人员一定要对其质量进行评估。</p><p>这同样适用于您正在考虑实施的学术论文。也许有人会认为，论文中发表了一种算法，它就一定是正确的、性能良好的。但是，即使通过了评审程序，学术论文也可能存在问题。也许正确性证明所依赖的假设并不现实。或者，"实验 "部分显示的性能比基线高得多，但这只在特定的数据集上成立。即使论文质量很高，其方法也可能不适合您的项目。</p><p>在考虑是否对学术论文采取 "依赖 "态度时，不妨像对待软件包一样提出同样的问题：</p><ul><li><p>图书馆是否被广泛使用并经过 "实战检验"？→ 其他软件包是否实施了本文，效果如何？</p></li><li><p>是否有性能基准？这些看起来准确和公平吗？→ 论文是否包含现实的实验？它们设计得好吗？</p></li><li><p>性能的提升是否足以证明复杂性的合理性？→ 论文是否与强有力的基线方法相比较？它比基准线高出多少？</p></li><li><p>这种方法能与我们的系统很好地整合吗？→ 算法的假设和权衡是否符合我们的使用情况？</p></li></ul><p>不知为什么，当一个软件包发布与竞争对手的性能比较时，该软件包总是最快的！如果由第三方设计基准，可能会更加平衡。同样的现象也适用于学术论文。如果一种算法不仅在原始论文中表现出色，而且还在其他论文中作为强有力的基线出现，那么它就很有可能是可靠的。</p><h2>创造性地进行测试</h2><p>学术论文中的算法通常比我们日常遇到的算法类型具有更复杂的行为。也许这是一种近似算法，用精确度来换取更快的速度。也可能是一种机器学习方法，它能接收大量数据集，并产生（有时是意想不到的）输出结果。如果我们不能简单地描述这些算法的行为特征，又如何为它们编写测试程序呢？</p><h3>关注不变式</h3><p>在设计单元测试时，我们通常会从示例的角度来思考：如果我们给算法这个示例输入，它就应该有这样的输出。遗憾的是，对于大多数数学算法来说，基于示例的测试并不能充分涵盖它们的行为。</p><p>让我们来看看 C3 算法，Elasticsearch 使用它来确定哪个节点应该处理搜索请求。它使用一个微妙的公式对每个节点进行排名，该公式结合了节点以前的服务和响应时间以及队列大小。测试几个例子并不能真正验证我们对公式的理解是否正确。退一步思考测试不变式：如果服务时间增加，节点的等级是否会降低？如果队列规模为 0，排名是否如论文所说由响应时间决定？</p><p>关注不变式可以帮助解决一些常见问题：</p><ul><li><p>这种方法是否应该与顺序无关？如果是这样，以不同的顺序传递输入数据应该会得到相同的输出结果。</p></li><li><p>算法中的某个步骤会产生类别概率吗？如果是这样，这些概率的总和应为 1。</p></li><li><p>函数是否围绕原点对称？如果是这样，翻转输入的符号应该只是翻转输出的符号。</p></li></ul><p>我们最初实施 C3 时，公式中出现了一个错误，不小心用响应时间的倒数代替了响应时间。这意味着速度较慢的节点可以排名靠前！在修复该问题时，我们<a href="https://github.com/elastic/elasticsearch/pull/70283">确保添加了不变量检查</a>，以防止将来出现错误。</p><h3>与参考实施比较</h3><p>在发表论文的同时，作者还发布了该算法的实施方案。(如果论文中包含实验，这种情况尤其可能发生，因为许多期刊都要求作者发布用于重现结果的代码）。您可以根据该参考实现测试自己的方法，确保没有遗漏算法的重要细节。</p><p>在开发用于最近邻搜索的 Lucene HNSW 实现时，我们<a href="https://issues.apache.org/jira/browse/LUCENE-9937"> 根据</a> 论文作者的 参考库进行了测试 。我们针对相同的数据集运行了 Lucene 和库，比较了其结果的准确性和计算次数。当这些数字紧密匹配时，我们就知道 Lucene 忠实地实现了算法。</p><p>在将算法集成到系统中时，通常需要进行修改或扩展，例如将其扩展到多个内核，或添加启发式算法以提高性能。最好先实施"vanilla" 版本，对照参考进行测试，然后再逐步修改。这样，您就可以确信在进行定制之前已经捕捉到了所有关键部分。</p><h3>与现有算法对决</h3><p>最后一节提出了测试不变式的另一个想法：将算法输出与更简单、更易理解的算法输出进行比较。举例来说，Lucene 中的 block-max WAND 算法可以跳过那些无法出现在顶部结果中的文档，从而加快文档检索速度。我们很难准确描述 block-max WAND 在每种情况下的表现，但我们知道，应用它不应该改变最高结果！因此，我们的测试可以生成多个随机搜索查询，然后在<a href="https://github.com/apache/lucene/blob/main/lucene/core/src/test/org/apache/lucene/search/TestWANDScorer.java#L669"> 使用和不使用 WAND 优化的情况下运行这些</a> 查询，并检查 它们 的结果是否始终一致。</p><p>这些测试的一个重要方面是，它们会<a href="https://www.elastic.co/blog/elasticsearch-testing-qa-increasing-coverage-randomizing-test-runs"> 生成</a> 用于进行比较的 随机输入 。这可以帮助解决你想不到的情况，并使意想不到的问题浮出水面。例如，Lucene 的 BM25F 评分随机比较测试有助于<a href="https://issues.apache.org/jira/browse/LUCENE-10039">捕捉细微边缘情况下的错误</a>。向算法提供随机输入的想法与<a href="https://en.wikipedia.org/wiki/Fuzzing"> 模糊（fuzzing</a> ）的概念密切相关， 模糊 是计算机安全领域的一种常用测试技术。</p><p>Elasticsearch 和 Lucene 经常使用这种测试方法。如果你看到一个测试提到两个算法之间的"决斗" （TestDuelingAnalyzers、testDuelTermsQuery......），那么你就知道这个策略正在发挥作用。</p><h2>使用论文术语</h2><p>当其他开发人员使用您的代码时，他们需要查阅该文件以了解其细节。<a href="https://github.com/elastic/elasticsearch/blob/4f22f437ee50cacb94b37b457be1da0b8ba0e8ce/server/src/main/java/org/elasticsearch/search/aggregations/metrics/HyperLogLogPlusPlus.java#L24-L39">关于 Elasticsearch 的 HyperLogLog++ 实现的评论说</a>得很好："在没有读过论文的情况下就试图理解这个类的作用，是一种冒险"。这种方法的评论也树立了一个好榜样。其中包括学术论文的链接，并重点介绍了对最初描述的算法所做的修改。</p><p>由于开发人员会根据论文来理解代码，因此使用完全相同的术语会很有帮助。由于数学符号是简洁的，这可能导致一些通常不被认为是 "好风格 "的名称，但在论文中却非常清晰。在 Elasticsearch 中，学术论文中的公式是你为数不多能遇到的神秘变量名，如<a href="https://github.com/elastic/elasticsearch/blob/4f22f437ee50cacb94b37b457be1da0b8ba0e8ce/server/src/main/java/org/elasticsearch/node/ResponseCollectorService.java#L151">rS 和 muBarSInverse</a>。</p><p>
<em>作者推荐的阅读论文方式：喝大杯咖啡。</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt12d81453c706f7cb/6a17d80e0b0bede6badd3424/d03a8e2a50e173b15a4ec3732810c63ff53321f6-1440x1081.jpg" alt="elastic-blog-academicpaper.jpg" /><h2>您可以给作者发送电子邮件</h2><p>在完成一篇难度很大的论文时，你可能会花几个小时来琢磨一个公式，不知道是自己理解错了，还是只是有一个错别字。如果这是一个开源项目，你可以在 GitHub 或 StackOverflow 上提问。但是，您能从哪里获得学术论文呢？作者看起来很忙，可能会因为你的邮件而感到厌烦。</p><p>相反，许多学者喜欢听到他们的想法被付诸实践的消息，并乐于通过电子邮件回答问题。如果您从事的是他们熟悉的产品，他们甚至可能会在网站上列出您的应用！</p><p>学术界使用软件开发中的许多相同工具公开讨论论文的趋势也在不断增长。如果论文附带软件包，您可以<a href="https://github.com/facebookresearch/faiss/issues/1928"> 在 Github 上 找到</a> 常见问题的 答案。Stack Exchange 社区（如 "理论计算机科学 "和 "交叉验证"）也包含<a href="https://cstheory.stackexchange.com/questions/49296/problem-in-the-paper-stable-minimum-space-partitioning-in-linear-time">有关热门论文的详细讨论</a>。一些会议已开始在网上发表所有论文的评论。这些评论包含了与作者<a href="https://openreview.net/forum?id=H1eA7AEtvS">的来回讨论</a>，这些讨论能让人对写作方法产生有益的见解。</p><h2>待续</h2><p>本篇文章主要介绍选择学术论文的基本知识，以及 </p><p>但并不包括实际部署算法的所有方面。例如，如果算法只是复杂系统中的一个组件，我们如何确保对该组件的更改能带来端到端的改进？如果整合算法需要进行大量修改或扩展，而原始论文又没有涵盖这些内容，该怎么办？这些都是我们希望在今后的文章中与大家分享的重要话题。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/implementing-academic-papers-lessons-learned-from-elasticsearch-and-lucene</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/implementing-academic-papers-lessons-learned-from-elasticsearch-and-lucene</guid>
    <category><![CDATA[ML 研究]]></category>
    <category><![CDATA[Lucene]]></category>
    <dc:creator><![CDATA[Julie Tibshirani]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbd7e961f594005e7/6a17d80f033c8d981f6bb009/d240bfef29e9d432069059b312dd044eb76eec6c-1440x840.png" length="0" type="image/png"/>
    <pubDate>Wed, 29 Sep 2021 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>