<?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[Thomas Veasey - 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[Thomas Veasey - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/de/search-labs/author/thomas-veasey</link>
    </image>
    <link>https://www.elastic.co/de/search-labs/author/thomas-veasey</link>
    <atom:link href="https://www.elastic.co/de/search-labs/rss/author/thomas-veasey.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[de]]></language>
    <lastBuildDate>Tue, 29 Sep 2026 07:01:43 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Beschleunigung der Zusammenführung von HNSW-Diagrammen]]></title>
    <description><![CDATA[Informieren Sie sich über unsere Arbeit zur Reduzierung des Aufwands beim Erstellen mehrerer HNSW-Diagramme, insbesondere zur Reduzierung der Kosten für das Zusammenführen von Diagrammen.]]></description>
    <content:encoded><![CDATA[<p>In der Vergangenheit <a href="https://www.elastic.co/de/search-labs/blog/multi-graph-vector-search">haben wir einige der Herausforderungen erörtert</a> , die mit der Suche in mehreren <a href="https://www.elastic.co/de/search-labs/blog/hnsw-graph">HNSW-Graphen</a> einhergehen, und wie wir diese bewältigen konnten. Damals deuteten wir einige weitere Verbesserungen an, die wir geplant hatten. Dieser Beitrag ist der Höhepunkt dieser Arbeit.</p><p>Sie fragen sich vielleicht, warum Sie überhaupt mehrere Diagramme verwenden? Dies ist ein Nebeneffekt einer Architekturentscheidung in Lucene: unveränderliche Segmente. Wie bei den meisten architektonischen Entscheidungen gibt es Vor- und Nachteile. Beispielsweise haben wir vor Kurzem Serverless Elasticsearch allgemein zugänglich gemacht. In diesem Zusammenhang haben wir durch unveränderliche Segmente erhebliche Vorteile erzielt, darunter eine effiziente Indexreplikation und die Möglichkeit, die Index- und Abfrageberechnung zu entkoppeln und unabhängig voneinander automatisch zu skalieren. Bei der Vektorquantisierung bieten uns Segmentzusammenführungen die Möglichkeit, Parameter zu aktualisieren, um sie an die Dateneigenschaften anzupassen. In diesem Sinne sind wir der Meinung, dass die Möglichkeit, Datenmerkmale zu messen und Indexierungsentscheidungen zu überprüfen, noch weitere Vorteile mit sich bringt.</p><p>In diesem Beitrag besprechen wir die Arbeit, die wir geleistet haben, um den Aufwand für die Erstellung mehrerer HNSW-Diagramme deutlich zu reduzieren und insbesondere die Kosten für das Zusammenführen von Diagrammen zu senken.</p><h3>Hintergrund</h3><p>Um eine überschaubare Anzahl von Segmenten beizubehalten, prüft Lucene regelmäßig, ob Segmente zusammengeführt werden sollen. Dies läuft darauf hinaus, zu prüfen, ob die aktuelle Segmentanzahl eine Zielsegmentanzahl überschreitet, die durch die Basissegmentgröße und die Zusammenführungsrichtlinie bestimmt wird. Wenn die Anzahl überschritten wird, führt Lucene Segmentgruppen zusammen, während die Einschränkung verletzt wird. Dieser Vorgang wurde <a href="https://blog.mikemccandless.com/2011/02/visualizing-lucenes-segment-merges.html">an anderer Stelle</a> ausführlich beschrieben.</p><p>Lucene entscheidet sich für die Zusammenführung ähnlich großer Segmente, da dadurch ein logarithmisches Wachstum der Schreibverstärkung erreicht wird. Im Fall eines Vektorindex ist die Schreibverstärkung die Anzahl der Male, die ein Vektor in ein Diagramm eingefügt wird. Lucene versucht, Segmente in Gruppen von etwa 10 zusammenzuführen. Folglich werden Vektoren in einen Graphen eingefügt, der ungefähr beträgt.mal, wobei  die Anzahl der Indexvektoren und  die erwartete Anzahl der Basissegmentvektoren ist. Aufgrund des logarithmischen Wachstums liegt die Schreibverstärkung selbst bei großen Indizes im einstelligen Bereich. Die Gesamtzeit, die zum Zusammenführen von Graphen benötigt wird, ist jedoch linear proportional zur Schreibverstärkung.</p><p>Beim Zusammenführen von HNSW-Graphen nehmen wir bereits eine kleine Optimierung vor: Wir behalten den Graphen für das größte Segment bei und fügen Vektoren aus den anderen Segmenten darin ein. Dies ist der Grund für den oben genannten 9/10-Faktor. Im Folgenden zeigen wir, wie wir durch die Verwendung von Informationen aus allen Diagrammen, die wir zusammenführen, deutlich bessere Ergebnisse erzielen können.</p><h3>HNSW-Graphzusammenführung</h3><p>Bisher haben wir den größten Graphen beibehalten und Vektoren aus den anderen eingefügt, wobei wir die Graphen, die sie enthalten, ignoriert haben. Die zentrale Erkenntnis, die wir im Folgenden nutzen, ist, dass jeder HNSW-Graph, den wir verwerfen, wichtige Näheinformationen über die darin enthaltenen Vektoren enthält. Wir möchten diese Informationen nutzen, um das Einfügen zumindest einiger Vektoren zu beschleunigen.</p><p>Wir konzentrieren uns auf das Problem des Einfügens eines kleineren Graphen  in einen größeren Graphen , da dies eine atomare Operation ist, die wir zum Erstellen beliebiger Zusammenführungsrichtlinien verwenden können.</p><p>Die Strategie besteht darin, eine Teilmenge von Eckpunkten von  zu finden, die in den großen Graphen eingefügt werden soll. Wir verwenden dann die Konnektivität dieser Knoten im kleinen Graphen, um das Einfügen der verbleibenden Knoten  zu beschleunigen. Im Folgenden verwenden wir  und  um die Nachbarn eines Knotens  im kleinen bzw. großen Graphen zu bezeichnen. Schematisch ist der Ablauf wie folgt.</p><p><code>MERGE-HNSW</code></p><p><code>Inputs </code><code> and </code></p><p><code>1</code><code>Find </code><code> to insert into </code><code> using COMPUTE-JOIN-SET</code>
<code>2</code><code>Insert each vertex </code><code> into </code>
<code>3</code><code>for </code><code> do</code>
<code>4</code>
<code>5</code>
<code>6</code><code>FAST-SEARCH-LAYER</code>
<code>7</code><code>SELECT-NEIGHBORS-HEURISTIC</code>
<code>8</code></p><p>Wir berechnen die Menge  mithilfe eines Verfahrens, das wir unten besprechen (Zeile 1). Dann fügen wir jeden Knoten in  mithilfe des Standard-HNSW-Einfügeverfahrens in den großen Graphen ein (Zeile 2). Für jeden Knoten, den wir nicht eingefügt haben, finden wir seine Nachbarn, die wir eingefügt haben, und deren Nachbarn im großen Graphen (Zeilen 4 und 5). Wir verwenden ein mit diesem Set (Zeile 6) gesätes <code>FAST-SEARCH-LAYER</code> -Verfahren, um die Kandidaten für <code>SELECT-NEIGHBORS-HEURISTIC</code> aus dem HNSW- <a href="https://arxiv.org/pdf/1603.09320">Papier</a> (Zeile 7) zu finden. Tatsächlich ersetzen wir <code>SEARCH-LAYER</code> , um den Kandidatensatz in der Methode <code>INSERT</code> (Algorithmus 1 aus dem Dokument) zu finden, die ansonsten unverändert bleibt. Schließlich fügen wir den Scheitelpunkt hinzu, den wir gerade in  eingefügt haben (Zeile 8).</p><p>Damit dies funktioniert, ist klar, dass jeder Scheitelpunkt in  mindestens einen Nachbarn in  haben muss. Tatsächlich verlangen wir, dass für jeden Scheitelpunkt in   für ein gewisses , die maximale Schichtkonnektivität, gilt. Wir beobachten, dass in realen HNSW-Diagrammen eine ziemliche Streuung der Scheitelpunktgrade zu sehen ist. Die folgende Abbildung zeigt eine typische kumulative Dichtefunktion des Scheitelpunktgrads für die unterste Ebene eines Lucene HNSW-Diagramms.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc815e1a9c3bb0d06/6a17e178ec0f89308a5a6564/44f001b3a1bc6627e172fed5c52a02cfdcb4cd66-1324x898.png" alt="HNSW-Graph: Beispielhafte Knotengradverteilung" /><p>Wir haben die Verwendung eines festen Werts für  sowie die Möglichkeit untersucht, ihn zu einer Funktion des Scheitelpunktgrads zu machen. Diese zweite Wahl führt zu größeren Beschleunigungen bei minimalen Auswirkungen auf die Grafikqualität, daher habe ich mich für Folgendes entschieden</p><p>Beachten Sie, dass | per Definition gleich dem Grad des Scheitelpunkts  im kleinen Graphen ist. Eine Untergrenze von zwei bedeutet, dass wir jeden Scheitelpunkt einfügen, dessen Grad kleiner als zwei ist.</p><p>Ein einfaches Zählargument legt nahe, dass wir bei sorgfältiger Wahl von  nur etwa  direkt in  einfügen müssen. Konkret färben wir eine Kante des Graphen, wenn wir genau einen ihrer Endknoten in  einfügen. Dann wissen wir, dass wir für jeden Knoten in  mindestens  Kanten einfärben müssen, um mindestens  Nachbarn in  Darüber hinaus erwarten wir, dass</p><p>Dabei ist  der durchschnittliche Knotengrad im kleinen Graphen. Für jeden Knoten  färben wir höchstens  Kanten. Daher beträgt die Gesamtzahl der Kanten, die wir voraussichtlich einfärben werden, höchstens . Wir hoffen, dass wir durch sorgfältige Wahl von  annähernd diese Anzahl von Kanten einfärben können. Um alle Eckpunkte abzudecken, muss  folgende Bedingung erfüllen:</p><p>Dies impliziert, dass .</p><p>Vorausgesetzt, <code>SEARCH-LAYER</code> dominiert die Laufzeit, lässt dies darauf schließen, dass wir eine bis zu  Beschleunigung der Zusammenführungszeit erreichen könnten. Angesichts des logarithmischen Wachstums der Schreibverstärkung bedeutet dies, dass wir selbst bei sehr großen Indizes die Erstellungszeit im Vergleich zum Erstellen eines Diagramms normalerweise nur verdoppeln würden.</p><p>Das Risiko bei dieser Strategie besteht darin, dass wir die Grafikqualität beeinträchtigen. Wir haben es zunächst mit einem No-Op <code>FAST-SEARCH-LAYER</code> versucht. Wir haben festgestellt, dass dies die Qualität des Diagramms in dem Maße verschlechtert, dass die Rückrufrate als Funktion der Latenz beeinträchtigt wird, insbesondere beim Zusammenführen auf ein einzelnes Segment. Anschließend haben wir mithilfe einer eingeschränkten Suche im Diagramm verschiedene Alternativen untersucht. Am Ende war die effektivste Wahl die einfachste. Verwenden Sie <code>SEARCH-LAYER</code> , aber mit einem niedrigen <code>ef_construction</code>. Mit dieser Parametrisierung konnten wir Grafiken von hervorragender Qualität erzielen und die Zusammenführungszeit dennoch durchschnittlich um etwas mehr als 30 % verkürzen.</p><h3>Berechnung der Join-Menge</h3><p>Die Suche nach einer guten Join-Menge kann als HNSW-Graphüberdeckungsproblem formuliert werden. Eine Greedy-Heuristik ist eine einfache und effektive Heuristik zur Annäherung an optimale Graphüberdeckungen. Bei unserem Ansatz werden die Knotenpunkte nacheinander in absteigender Reihenfolge der Verstärkung zu  hinzugefügt. Der Gewinn ist wie folgt definiert:</p><p>Dabei bezeichnet  die Anzahl der Nachbarn eines Vektors  in  und  ist die Indikatorfunktion. Der Gewinn beinhaltet die Änderung der Anzahl der Scheitelpunkte, die wir zu  hinzugefügt haben, also , da wir unserem Ziel durch das Hinzufügen eines weniger abgedeckten Scheitelpunkts näher kommen. Die Gewinnberechnung wird in der folgenden Abbildung für den zentralen orangefarbenen Scheitelpunkt veranschaulicht.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7a353d56fa09af5f/6a17e17a2f4a5c33f7fa8825/fe11cd55a7d94d9e0b0f4d47ea309a99075c355d-540x474.png" alt="Knotengewinn, der der Join-Menge J im HNSW-Graphen hinzugefügt werden soll" /><p>Wir behalten für jeden Knoten  den folgenden Zustand bei:</p><ol><li><p>Ob es abgestanden ist,</p></li><li><p>Sein Gewinn ,</p></li><li><p>Die Anzahl der benachbarten Eckpunkte in  wird  bezeichnet,</p></li><li><p>Eine Zufallszahl im Bereich [0,1], die zum Auflösen eines Gleichstands verwendet wird.</p></li></ol><p>Der Pseudocode zum Berechnen des Join-Sets lautet wie folgt.</p><p><code>COMPUTE-JOIN-SET</code></p><p><code>Inputs </code></p><p><code>1</code>
<code>2</code>
<code>3</code><code>for </code><code> do</code>
<code>4</code>
<code>5</code>
<code>6</code>
<code>7</code><code>while </code><code> do
8</code><code> maximum gain vertex in </code>
<code>9</code><code>Remove the state for </code><code> from </code>
<code>10</code><code>if </code><code> is not stale then</code>
<code>11</code>
<code>12</code>
<code>13</code><code>for </code><code> do</code>
<code>14</code><code>mark </code><code> as stale if </code>
<code>15</code><code>mark neighbors of </code><code> stale if </code><code>
16</code><code>
17</code><code>else
18</code><code>
19</code><code>if </code><code> then
20</code><code>
21</code><code>return </code></p><p>Wir initialisieren zunächst den Status in den Zeilen 1-5.</p><p>In jeder Iteration der Hauptschleife extrahieren wir zunächst den Scheitelpunkt mit der maximalen Verstärkung (Zeile 8) und lösen Gleichstände nach dem Zufallsprinzip auf. Bevor wir Änderungen vornehmen, müssen wir prüfen, ob die Verstärkung des Scheitelpunkts veraltet ist. Insbesondere beeinflussen wir jedes Mal, wenn wir einen Scheitelpunkt zu  hinzufügen, den Gewinn anderer Scheitelpunkte:</p><ol><li><p>Da alle seine Nachbarn einen zusätzlichen Nachbarn in  haben, können sich ihre Gewinne ändern (Zeile 14).</p></li><li><p>Wenn einer seiner Nachbarn jetzt vollständig gedeckt ist, können sich die Gewinne aller seiner Nachbarn ändern (Zeilen 14-16).</p></li></ol><p>Wir berechnen die Gewinne auf verzögerte Weise neu, d. h. wir berechnen den Gewinn eines Scheitelpunkts nur dann neu, wenn wir ihn in  einfügen möchten (Zeilen 18–20). Da die Gewinne immer nur abnehmen, können wir nie einen Scheitelpunkt verpassen, den wir einfügen sollten.</p><p>Beachten Sie, dass wir lediglich den Gesamtgewinn der zu  hinzugefügten Scheitelpunkte im Auge behalten müssen, um zu bestimmen, wann wir aussteigen müssen. Darüber hinaus wird, obwohl  mindestens ein Scheitelpunkt einen von Null verschiedenen Gewinn aufweisen, sodass wir immer Fortschritte machen.</p><h3>Ergebnisse</h3><p>Wir haben Experimente mit vier Datensätzen durchgeführt, die zusammen unsere drei unterstützten Distanzmetriken (euklidisch, Kosinus und inneres Produkt) abdecken:</p><ol><li><p>quora-E5-small: 522931 Dokumente, 384 Dimensionen und verwendet Kosinusähnlichkeit,</p></li><li><p>cohere-wikipedia-v2: 1 Million Dokumente, 768 Dimensionen und verwendet Kosinusähnlichkeit,</p></li><li><p>Kern: 1 Million Dokumente, 960 Dimensionen und verwendet euklidische Distanz und</p></li><li><p>cohere-wikipedia-v3: 1 Mio. Dokumente, 1024 Dimensionen und verwendet das maximale innere Produkt.</p></li></ol><p>Für jeden Datensatz bewerten wir zwei Quantisierungsstufen:</p><ol><li><p>int8 – verwendet eine 1-Byte-Ganzzahl pro Dimension und</p></li><li><p>BBQ – das ein einzelnes Bit pro Dimension verwendet.</p></li></ol><p>Schließlich haben wir für jedes Experiment die Suchqualität bei zwei Abruftiefen bewertet und nach dem Erstellen des Index und anschließend nach der erzwungenen Zusammenführung zu einem einzelnen Segment untersucht.</p><p>Zusammenfassend lässt sich sagen, dass wir durchgängig erhebliche Beschleunigungen bei der Indizierung und Zusammenführung erzielen und dabei in allen Fällen die Grafikqualität und damit die Suchleistung beibehalten.</p><h4>Experiment 1: int8-Quantisierung</h4><p>Die durchschnittlichen Beschleunigungen von der Basislinie bis zum Kandidaten, die vorgeschlagenen Änderungen, sind:</p><p>Beschleunigung der Indexzeit: <strong>1,28</strong></p><p>Beschleunigung der Force Merge: <strong>1,72</strong></p><p>Dies entspricht folgender Laufzeitaufteilung</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8422be122ef1a9c9/6a17e17bbe6086522e00467d/5f9f6d487b4c74c4998aa47465912c1a9743e928-734x479.png" alt="Index- und Zusammenführungszeiten für die Baseline- und Kandidatenzusammenführungsstrategien" /><p>Der Vollständigkeit halber sind die genauen Zeiten</p><p></p><p>Index</p><p></p><p>Verschmelzen</p><p></p><p>Datensatz</p><p>Basislinie</p><p>Kandidat</p><p>Entwickeln</p><p>Kandidat</p><p>Quora-E5-klein</p><p>112,41 s</p><p>81,55 s</p><p>113,81 s</p><p>70,87 s</p><p>wiki-cohere-v2</p><p>158,1 s</p><p>122,95 s</p><p>425,20 s</p><p>239,28 s</p><p>Kern</p><p>141,82 s</p><p>119,26 s</p><p>536,07 s</p><p>279,05 s</p><p>wiki-cohere-v3</p><p>211,86 s</p><p>168,22 s</p><p>654,97 s</p><p>414,12 s</p><p>Unten zeigen wir die Diagramme „Rückruf vs. Latenz“, die den Kandidaten (gestrichelte Linien) mit der Basislinie bei zwei Abruftiefen vergleichen: Rückruf@10 und Rückruf@100 für Indizes mit mehreren Segmenten (das Endergebnis unserer Standard-Zusammenführungsstrategie nach der Indizierung aller Vektoren) und nach der erzwungenen Zusammenführung zu einem einzelnen Segment. Eine Kurve, die höher und weiter links liegt, ist besser, da sie eine höhere Rückrufrate bei geringerer Latenz bedeutet.</p><p>Wie Sie sehen, ist der Kandidat für mehrere Segmentindizes für den Cohere v3-Datensatz besser und für alle anderen Datensätze etwas schlechter, aber fast vergleichbar. Nach der Zusammenführung zu einem einzigen Segment sind die Erinnerungskurven in allen Fällen nahezu identisch.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf674622469bf6a90/6a17e17dfbc5f874a84919c9/9195297f19f90b172d832ba56bdada7b0d8a768b-985x392.png" alt="Rückruf @10 und @100 im Vergleich zur Latenz nach dem Erstellen des Index" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltde89f7e94ac823f4/6a17e17fe9ea876429a9c507/c866f32d579ae2b841e92ca733dd29c0e214ac6b-986x386.png" alt="Rückruf @10 und @100 im Vergleich zur Latenz nach der Zusammenführung zu einem einzelnen Segment" /><h4>Experiment 2: BBQ-Quantisierung</h4><p>Die durchschnittlichen Beschleunigungen von der Basislinie zum Kandidaten sind:</p><p>Beschleunigung der Indexzeit: <strong>1,33</strong></p><p>Beschleunigung der Force Merge: <strong>1,34</strong></p><p>Dies entspricht folgender Laufzeitaufteilung</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5b0eb305222fa5c2/6a17e18125daab514f08a18c/11be0cf6b63480dc703409329357ea4847b55051-740x415.png" alt="Index- und Zusammenführungszeit für die Baseline- und Kandidatenzusammenführungsstrategien" /><p>Der Vollständigkeit halber sind die genauen Zeiten</p><p></p><p>Index</p><p></p><p>Verschmelzen</p><p></p><p>Datensatz</p><p>Basislinie</p><p>Kandidat</p><p>Entwickeln</p><p>Kandidat</p><p>Quora-E5-klein</p><p>70,71 s</p><p>58,25 s</p><p>59,38 s</p><p>40,15 s</p><p>wiki-cohere-v2</p><p>203,08 s</p><p>142,27 s</p><p>107,27 s</p><p>85,68 s</p><p>Kern</p><p>110,35 s</p><p>105,52 s</p><p>323,66 s</p><p>202,2 s</p><p>wiki-cohere-v3</p><p>313,43 s</p><p>190,63 s</p><p>165,98 s</p><p>159,95 s</p><p>Bei Indizes mit mehreren Segmenten ist der Kandidat für fast alle Datensätze besser, mit Ausnahme von Cohere v2, wo die Basislinie etwas besser ist. Für die einzelnen Segmentindizes sind die Recall-Kurven in allen Fällen nahezu identisch.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb12174abeadbcdd1/6a17e1822f4a5c4cc2fa8829/7da1be27bab5a7f5f9c9a1882ea35761a4a0ba5c-973x383.png" alt="Rückruf @10 und @100 im Vergleich zur Latenz nach dem Erstellen des Index" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf1b88d4f7fec9905/6a17e184414c64a8de9450b4/a26af30a56c55a12addee7e4fb7e8f606f366668-979x386.png" alt="Erinnern Sie sich an @10 und @100 im Vergleich zur Latenz nach der Zusammenführung zu einem einzigen Segment" /><h3>Fazit</h3><p>Der in diesem Blog besprochene Algorithmus wird im kommenden Lucene 10.2 und in der darauf basierenden Elasticsearch-Version verfügbar sein. Benutzer können in diesen neuen Versionen von der verbesserten Zusammenführungsleistung und der verkürzten Indexerstellungszeit profitieren. Diese Änderung ist Teil unserer kontinuierlichen Bemühungen, Lucene und Elasticsearch für die Vektor- und Hybridsuche schnell und effizient zu machen.</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/hnsw-graphs-speed-up-merging</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/hnsw-graphs-speed-up-merging</guid>
    <category><![CDATA[Vektordatenbank]]></category>
    <category><![CDATA[Lucene]]></category>
    <dc:creator><![CDATA[Thomas Veasey,Mayya Sharipova]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9fca6a01d0541cfb/6a17e187033c8d46486bb0e1/49a6c880f5dedd0fa502ece5be124824ee218cc0-1792x1024.png" length="0" type="image/png"/>
    <pubDate>Mon, 07 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Bewertung der Suchrelevanz Teil 1 – Der BEIR-Benchmark]]></title>
    <description><![CDATA[Lernen Sie, Ihr Suchsystem im Zusammenhang mit einem besseren Verständnis des BEIR-Benchmarks zu bewerten, mit Tipps und Techniken zur Verbesserung Ihrer Suchbewertungsprozesse.]]></description>
    <content:encoded><![CDATA[<p>Dies ist der erste Beitrag einer Reihe von Blogbeiträgen, in denen wir uns damit befassen, wie Sie Ihre eigenen Suchsysteme im Zusammenhang mit einem besseren Verständnis des BEIR-Benchmarks bewerten können. Wir stellen Ihnen spezielle Tipps und Techniken vor, mit denen Sie Ihre Suchbewertungsprozesse im Zusammenhang mit dem besseren Verständnis von BEIR verbessern können. Wir stellen Ihnen auch die häufigsten Fallstricke vor, die eine Bewertung weniger zuverlässig machen. Abschließend möchten wir darauf hinweisen, dass LLMs ein leistungsstarkes neues Tool für Suchingenieure darstellen. Anhand eines Beispiels zeigen wir, wie Sie diese zur Bewertung der Suche einsetzen können.</p><h2>Den BEIR-Benchmark bei der Bewertung der Suchrelevanz verstehen</h2><p>Für die Verbesserung eines Systems müssen Sie messen können, wie gut es funktioniert. Im Zusammenhang mit der Suche <a href="https://arxiv.org/abs/2104.08663">BEIR</a> (oder gleichwertig der Abschnitt „Retrieval” der Bestenliste <a href="https://huggingface.co/spaces/mteb/leaderboard">MTEB</a>) gilt als der „heilige Gral” für die Informationsabruf-Community, was nicht weiter verwunderlich ist. Es handelt sich um einen sehr gut strukturierten Benchmark mit vielfältigen Datensätzen für unterschiedliche Aufgaben. Genauer gesagt werden folgende Bereiche abgedeckt:</p><ul><li><p>Abrufen von Argumenten (ArguAna, Touche2020)</p></li><li><p>Open-Domain-QA (HotpotQA, Natural Questions, FiQA)</p></li><li><p>Passagenabruf (MSMARCO)</p></li><li><p>Abrufen doppelter Fragen (Quora, CQADupstack)</p></li><li><p>Faktenprüfung (FEVER, Climate-FEVER, Scifact)</p></li><li><p>Biomedizinische Informationsabfrage (TREC-COVID, NFCorpus, BioASQ)</p></li><li><p>Abrufen von Entitäten (DBPedia)</p></li><li><p>Zitationsvorhersage (SCIDOCS)</p></li></ul><p>Es liefert eine einzige Statistik, nDCG@10, die angibt, wie gut ein System die relevantesten Dokumente für jedes Aufgabenbeispiel in den von ihm zurückgegebenen besten Ergebnissen abgleicht. Für ein Suchsystem, mit dem ein Mensch interagiert, ist die Relevanz der betsen Ergebnisse entscheidend. Allerdings gibt es bei der Bewertung von Suchvorgängen viele Nuancen, die durch eine einzelne zusammenfassende Statistik nicht erfasst werden.</p><h2>Struktur eines BEIR-Datensatzes</h2><p>Jeder Benchmark hat drei Artefakte:</p><ul><li><p>der Korpus oder die Dokumente, die abgerufen werden sollen</p></li><li><p>Die Abfragen</p></li><li><p>die Relevanzbewertungen für die Abfragen (auch bekannt als <code>qrels</code>).</p></li></ul><p>Relevanzbewertungen werden als Wert zwischen null und größer angegeben. Werte ungleich Null zeigen an, dass das Dokument in gewisser Weise mit der Abfrage in Zusammenhang steht.</p><p>Datensatz</p><p>Korpusgröße</p><p>#Abfragen im Testset</p><p>#qrels positiv gekennzeichnet</p><p>#qrels gleich Null</p><p>#duplicates im Korpus</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>Natürliche Fragen</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 (Summe)</p><p>457.199</p><p>13.145</p><p>23.703</p><p>0</p><p>0</p><p><strong>Tabelle 1</strong>: Datensatzstatistiken. Die Zahlen wurden auf dem Testabschnitt der Datensätze berechnet (<code>dev</code> für <code>MSMARCO</code>).</p><p><strong>Tabelle 1</strong> enthält einige Statistiken zu den Datensätzen, aus denen der <code>BEIR</code>-Benchmark besteht, wie zum Beispiel die Anzahl der Dokumente im Korpus, die Anzahl der Abfragen im Testdatensatz und die Anzahl der positiven/negativen Paare (Abfrage, Dokument) in der <code>qrels</code>-Datei. Ein kurzer Blick auf die Daten lässt uns sofort Folgendes ableiten:</p><ul><li><p>Die meisten Datensätze enthalten keine negativen Beziehungen in der <code>qrels</code>-Datei, d. h. null Werte, was Dokumente ausdrücklich als irrelevant für die jeweilige Abfrage kennzeichnen würde.</p></li><li><p>Die durchschnittliche Anzahl von Dokumentbeziehungen pro Abfrage (<code>#qrels</code> / <code>#queries</code>) variiert von 1,0 im Ticket von <code>ArguAna</code> bis 493,5 (<code>TREC-COVID</code>), jedoch mit einem Wert von <code>&lt;</code>5 für die Mehrheit der Tickets.</p></li><li><p>Bei einigen Datensätzen gibt es doppelte Dokumente im Korpus, was in einigen Fällen zu einer falschen Auswertung führen kann, z. B. wenn ein Dokument als relevant für eine Abfrage angesehen wird, sein Duplikat jedoch nicht. Zum Beispiel haben wir in <code>ArguAna</code> 96 Tickets von doppelten Dokumentpaaren identifiziert, wobei pro Paar nur ein Dokument als relevant für eine Abfrage markiert wurde. Durch die „Erweiterung“ der ursprünglichen Qrels-Liste um die Duplikate haben wir einen relativen Anstieg des <code>nDCG@10</code>-Wertes um durchschnittlich ~1 % festgestellt.</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>Beispiel für duplizierte Paare in ArguAna. In der qrels-Datei scheint nur der erste Eintrag (als Gegenargument) für die Abfrage („test-economy-epiasghbf-pro02a“) relevant zu sein.</strong></p><p>Beim Vergleich von Modellen in der MTEB-Rangliste ist es naheliegend, sich auf die durchschnittliche Retrieval-Qualität zu konzentrieren. Dies ist ein guter Indikator für die Gesamtqualität des Modells, sagt jedoch nicht unbedingt etwas darüber aus, wie es für Sie funktionieren wird. Da die Ergebnisse pro Datensatz gemeldet werden, ist es sinnvoll zu verstehen, wie eng die verschiedenen Datensätze mit Ihrer Suchaufgabe zusammenhängen, und die Modelle nur anhand der relevantesten Datensätze neu zu bewerten. Wenn Sie noch tiefer eintauchen möchten, können Sie zusätzlich überprüfen, ob es Überschneidungen zwischen den Themen der verschiedenen Datensätze gibt. Die Stratifizierung von Qualitätsmaßen nach Themen ermöglicht eine viel differenziertere Bewertung ihrer spezifischen Stärken und Schwächen.</p><p>Wichtig ist hierbei, dass ein Dokument, das nicht in der <code>qrels</code>-Datei markiert ist, standardmäßig als für die Abfrage irrelevant angesehen wird. Wir befassen uns etwas eingehender mit diesem Bereich und sammeln einige Nachweise, um mehr Licht in die folgende Frage zu bringen: „Wie oft werden einem Evaluator Paare (Abfrage, Dokument) vorgelegt, für die es keine Ground-Truth-Informationen gibt?“. Der Grund dafür ist, dass bei nur verfügbaren oberflächlichen Markups (sodass nicht jedes relevante Dokument als solches gekennzeichnet ist) ein Informationsabrufsystem schlechter bewertet werden kann als ein anderes, nur weil es sich dafür „entscheidet“, andere relevante (aber nicht markierte) Dokumente anzuzeigen. Das ist ein häufiger Fehler bei der Erstellung qualitativ hochwertiger Evaluierungsdatensätze, insbesondere bei großen Datensätzen. Aus praktischen Gründen konzentriert sich die manuelle Kennzeichnung in der Regel auf die besten Ergebnisse, die vom aktuellen System zurückgegeben werden, sodass relevante Dokumente in den blinden Flecken möglicherweise übersehen werden. Daher ist es in der Regel vorzuziehen, mehr Ressourcen auf ein umfassenderes Markup weniger Abfragen als auf ein breites, oberflächliches Markup zu konzentrieren.</p><h2>Nutzung des BEIR-Benchmarks zur Bewertung der Suchrelevanz</h2><p>Um unsere Analyse zu beginnen, implementieren wir das folgende Szenario (siehe <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/evaluating-search-relevance-part-1/retrieve-and-rerank.ipynb">Notizbuch</a>):</p><ol><li><p>Zuerst laden wir den Korpus jedes Datensatzes in einen Elasticsearch-Index.</p></li><li><p>Für jede Abfrage im Testsatz rufen wir die 100 besten Dokumente mit BM25 ab.</p></li><li><p>Wir ordnen die abgerufenen Dokumente mithilfe verschiedener SOTA-Reranking-Modelle neu an.</p></li><li><p>Abschließend geben wir die „Bewertungsrate“ für die 10 besten Dokumente aus Schritt 2 (nach dem Abrufen) und Schritt 3 (nach dem Reranking) an. Mit anderen Worten: Wir berechnen den durchschnittlichen Prozentsatz der 10 besten Dokumente mit einer Bewertung in der <code>qrels</code>-Datei.</p></li></ol><p>Die Liste der von uns verwendeten Reranking-Modelle lautet wie folgt:</p><ul><li><p><a href="https://docs.cohere.com/reference/rerank">Coheres</a> <code>rerank-english-v2.0</code> und <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>Abruf</p><p>Reranking</p><p></p><p></p><p></p><p></p><p>Datensatz</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>Natürliche Fragen</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 (Durchschnitt)</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>Tabelle 2</strong>: Bewertungsrate pro Paare (Datensatz, Reranker), berechnet anhand der 10 am häufigsten abgerufenen/neu geordneten Dokumente</p><p><strong>Aus Tabelle 2</strong> sehen wir, mit Ausnahme von <code>TREC-COVID</code> (&gt;90 % Abdeckung), <code>DBPedia</code> (~65 %), <code>Touche2020</code> und <code>nfcorpus</code> (~35 %), dass die Mehrheit der Datensätze eine Labeling-Rate zwischen 5 % und etwas mehr als 10 % nach dem Abrufen oder Reranking aufweist. Das heißt nicht, dass alle diese unmarkierten Dokumente relevant sind, aber es könnte ein Teilbereich davon geben, insbesondere diejenigen, die an oberster Stelle stehen, die positiv sein könnten.</p><p>Mit dem Aufkommen von auf allgemeine Anweisungen abgestimmten Sprachmodellen haben wir ein neues leistungsfähiges Tool, das die Beurteilung der Relevanz potenziell automatisieren kann. Diese Methoden sind in der Regel viel zu rechenaufwändig, um online für die Suche verwendet zu werden, aber hier geht es uns um die Offline-Auswertung. Im Folgenden verwenden wir sie, um die Hinweise darauf zu untersuchen, dass einige der BEIR-Datensätze unter oberflächlichen Markups leiden.</p><p>Zur weiteren Untersuchung dieser Hypothese haben wir uns entschlossen, uns auf MSMARCO zu konzentrieren und einen Teilbereich von 100 Abfragen zusammen mit den fünf (mit Cohere v2) höchsten Reranking-Dokumenten auszuwählen, die derzeit nicht als relevant markiert sind. Wir haben zwei verschiedene Bewertungsansätze verfolgt: Zunächst haben wir einen sorgfältig abgestimmten Prompt (mehr dazu in einem späteren Beitrag) verwendet, um das kürzlich veröffentlichte <a href="https://huggingface.co/microsoft/Phi-3-mini-4k-instruct">Phi-3-mini-4k-Modell</a> darauf vorzubereiten, die Relevanz (oder Nicht-Relevanz) eines Dokuments für die Abfrage vorherzusagen. Parallel dazu wurden diese Tickets auch manuell gekennzeichnet, um auch die Übereinstimmungsrate zwischen dem LLM-Ausgang und der menschlichen Bewertung zu ermitteln. Insgesamt können wir die folgenden beiden Schlüsse ziehen:</p><ul><li><p>Die Übereinstimmungsrate zwischen den LLM-Reaktionen und den menschlichen Beurteilungen lag bei knapp 80 %, was als Ausgangspunkt in diese Richtung durchaus gut erscheint.</p></li><li><p>In 57,6 % der Fälle (nach menschlicher Beurteilung) erwiesen sich die zurückgegebenen Dokumente tatsächlich als relevant für die Abfrage. Anders ausgedrückt: Bei 100 Abfragen werden 107 Dokumente als relevant eingestuft, aber es gibt mindestens 0,576 x 5 x 100 = 288 zusätzliche Dokumente, die tatsächlich relevant sind!</p></li></ul><p>Hier einige Beispiele aus dem Datensatz <code>MSMARCO</code>/<code>dev</code>, die die Abfrage, das annotierte positive Dokument (aus <code>qrels</code>) und ein falsch negatives Dokument aufgrund unvollständiger Auszeichnung enthalten:</p><p>Beispiel 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>Beispiel 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>Die manuelle Auswertung solcher spezifischer Abfragen ist eine allgemein nützliche Methode, um die Suchqualität zu verstehen und quantitative Messgrößen wie nDCG@10 zu ergänzen. Bei einem repräsentativen Abfrageset, das Sie immer ausführen, wenn Sie Änderungen an der Suche vornehmen, erhalten Sie wichtige qualitative Informationen darüber, wie sich die Leistung verändert, die in den Statistiken nicht sichtbar sind. Beispielsweise erhalten Sie viel mehr Einblick in die falschen Ergebnisse Ihrer Suche: Sie erkennen offensichtliche Fehler in den Suchergebnissen, Kategorien verwandter Fehler, wie z. B. die Fehlinterpretation fachspezifischer Terminologie und so weiter.</p><p>Unser Ergebnis stimmt mit einschlägigen Studien zur <code>MSMARCO</code> Bewertung der Suchrelevanz überein. Zum Beispiel folgen <a href="https://arxiv.org/pdf/2109.00062">Arabzadeh et al.</a> einem ähnlichen Verfahren, bei dem sie Crowdsourcing-Mitarbeiter für Präferenzurteile einsetzen: Sie zeigen unter anderem, dass in vielen Fällen die von den Reranking-Modulen zurückgegebenen Dokumente im Vergleich zu den Dokumenten in der MSMARCO- <code>qrels</code>-Datei bevorzugt werden. Ein weiterer Nachweis stammt von den Autoren des <a href="https://arxiv.org/pdf/2010.08191">RocketQA</a>-Rerankers, die berichten, dass mehr als 70 % der Reranking-Dokumente nach einer manuellen Überprüfung als relevant eingestuft wurden.</p><p> Aktualisierung – 9. September: Nach einer genauen Neubewertung des Datensatzes haben wir 15 weitere Fälle relevanter Dokumente identifiziert, wodurch sich die Gesamtzahl von 273 auf 288 erhöht hat</p><h2>Wichtigste Erkenntnisse und nächste Schritte</h2><ul><li><p>Das Streben nach besseren Referenzwerten ist ein nie endender Prozess, da diese für Benchmarking und Modellvergleiche von entscheidender Bedeutung sind. LLMs können in einigen Bewertungsbereichen helfen, wenn sie mit Vorsicht angewendet und mit den richtigen Anweisungen abgestimmt werden.</p></li><li><p>Allgemeiner gesagt: Da Benchmarks niemals perfekt sein werden, könnte es vorteilhaft sein, von einem reinen Wertevergleich zu robusteren Methoden überzugehen, die statistisch signifikante Unterschiede erfassen. Die Arbeit von <a href="https://arxiv.org/pdf/2109.00062">Arabzadeh et al.</a> liefert hierfür ein gutes Beispiel, da auf Grundlage der Ergebnisse 95-prozentige Konfidenzintervalle erstellt wurden, die signifikante (oder nicht signifikante) Unterschiede zwischen den verschiedenen Durchläufen aufzeigen Im beigefügten <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/evaluating-search-relevance-part-1/retrieve-and-rerank.ipynb">Notizbuch</a> stellen wir eine Implementierung von Konfidenzintervallen unter Verwendung von <a href="https://en.wikipedia.org/wiki/Bootstrapping_(statistics)">Bootstrapping</a> zur Verfügung.</p></li><li><p>Aus der Perspektive des Endnutzers ist es sinnvoll, bei der Betrachtung von Benchmark-Ergebnissen über die Aufgabenausrichtung nachzudenken. Für einen KI-Ingenieur, der beispielsweise eine RAG-Pipeline entwickelt und weiß, dass der typische Anwendungsfall das Zusammenführen mehrerer Informationen aus verschiedenen Quellen beinhaltet, wäre es sinnvoller, die Leistung seines Retrieval-Modells anhand von Multi-Hop-QA-Datensätzen wie HotpotQA zu bewerten, anstatt den globalen Durchschnitt des gesamten BEIR-Benchmarks zu verwenden.</p></li></ul><p>Im <a href="https://www.elastic.co/search-labs/blog/evaluating-search-relevance-part-2">nächsten Blogbeitrag</a> werden wir uns eingehender mit der Verwendung von Phi-3 als LLM-as-a-Judge und der Optimierung zur Vorhersage der Relevanz befassen.</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-Forschung]]></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>
  </channel>
</rss>