Clone
14
K2 Search
midnight edited this page 2024-10-29 12:22:05 +01:00

Feldolgozás

Jogszabályok feldolgozása és a chunkok előállítása

Jegyzetes:

  • Eredeti jogszabály XML -> Köztes fa
    • Az eredeti jogszabály lineáris és helyenként hierarchikus XML-ből áll
    • Eredmény: szövegi részek tisztán hierarchikus szerkezetben
  • A köztes fa előállítása visitorokkal történik:
    • feldolgozzák a specifikus XML elemeket (tartalom, attribútumok)
    • pl.: táblázatból szöveges vagy markdown formátum
  • Minden elem tartalmazhat:
    • Context
      • minden olyan információ ami az adott content könnyebb megértéséhez és megtalálásához szükséges lehet
      • pl.: a törvénynek a címe, a preambulum, a fejezet címe
    • Content
      • A content pedig minden olyan tartalom ami a keresések megválaszolásához szükséges információkat tartalmazzák
      • pl.: egy paragrafus tartalma, egy táblázat szövege
  • A fa bejárása során jönnek létre a chunkok
    • Minden context összefűzve addig, amíg nem nem jutunk contentig
    • Eredmény:
      • Egybefüggő szöveg a szerkezet szerint a kontextusban minden, a tartalomig vezető információval
      • Kereshető rész
      • HTML/XML elemek eltávolítva
  • A chunkokhoz a legközelebbi jhId van hozzárendelve
    • Fában való felfelé kereséssel van meghatározva

Szöveges:

A jogszabályok xml formátumából lineáris és helyenként hierarchikus szerkezetéből építünk egy egységes köztes fa szerkezetet. Ebben a fában a jogszabály szövegének részei találhatóak tisztán hierarchikus szerkezetben.

Példa:
norma -> dokumentum -> könyv -> rész -> fejezet -> bekezdés -> szakasz

Ezek előállításához visitorok-ba szervezett feldolgozók segítenek amelyek képesek feldolgozni specifikus xml elemeket, azoknak tartalmát és attributumait (pl: táblázatok-ból tudunk előállítani szöveges formátumot, vagy markdown-os szerkezetet).

Minden eleme az általunk épített fának tartalmazhat egy Context-et vagy egy Content-et. A contextben található minden olyan információ ami az adott content könnyebb megértéséhez és megtalálásához szükséges lehet (pl: a törvénynek a címe, a preambulum, a fejezet címe). A content pedig minden olyan tartalom ami a keresések megválaszolásához szükséges információkat tartalmazzák (pl: egy paragrafus tartalma, egy táblázat szövege).

A chunkok ebből a fa szerkezetből épülnek fel, ahogy bejárjuk a fát minden context-et összefűzünk egészen addig amíg nem érkezünk egy olyan levélhez ami content-et tartalmaz. Ezáltal a végén kapunk egy olyan egybefüggő szöveget amiben szerkezet szerint a kontextusban szerepel minden content-ig vezető információ, és a contentben összefűzve az kereshető rész áll elő. A legvégén pedig eltávolítunk minden HMTL/XML elemet a szövegből.

A jhId (NJT-n való anchor linkek előállításához szükséges) hozzárendelése a chunkokhoz egyszerűen a fában való felfele kereséssel lett megoldva, így a chunkhoz legközelebbi jhId-t tudjuk meghatározni.

Keresési találatok szövegkiemelése

A beérkező kérést feldaraboljuk szavakra és eltávolítunk belőle minden nem a magyar ABC-ben szereplő karaktert. Ezeknek a szavaknak megkeressük a szótöveit a Hunspell nevű könyvtárral, majd ezeknek az összegyűjtött szavaknak és szótöveknek megkeressük a szinonimáit egy Thesaurus nevű könyvtárral és ezeket is belerakjuk a lehetséges kiemelendő szavak közé.

A kiemelt szavakat szűrjük egy előre megírt listával ami tartalmazza a kötőszavakat/kérdőszavakat és egyéb szavakat amit nem szeretnénk semmilyen formában látni a kiemelés során.

A folyamat végén pedig megkeressük a szavakat a keresési eredmények között és a szövegben megtalált szavakat kiegészítjük hogy teljes szavakat emeljük ki. (pl adat -> adatok, adatai)

Metadatás keresés évszámos és sorszámos keresések

A keresés több stratégiával is működik, ha a beérkező kérést felismerjük valamilyen minta szerint akkor tudunk a törvények meta-adatai között is keresni. Jelenleg az alábbi stratégiák támogatottak.

Évszámos és Sorszámos keresés

Évszámot és sorszámot is akkor tudunk így is keresni különböző formátumokban.

  • A következő formátumok támogatottak:
    • 2016. évi XXXIII. törvény
    • 2016 / 33
    • 2016. 33.
    • 2016. XXXIII.
    • 2016 33
    • a fentieknek akár fordított formában is, pl: 33 2016.

Ha nem sikerül jól beazonosítani hogy melyik rész az évszám vagy a sorszám, akkor mindkét verzióban megpróbáljuk.

Évszámos keresés

Ha évszámot adunk meg akkor a jogszabályok évszámában keresünk.

Sorszámos keresés

Ha számot vagy római számot kapunk, akkor a jogszabályok sorszámaiban keresünk.

Keresési kifejezés/kérdés kiegészítése

Lehetőségünk van arra hogy mielőtt a beérkező keresést módosítsuk a jobb találtok érdekében, ez a beérkező kérés elején egy előre meghatározott gyűjteményből tudunk szöveget kicserélni. Így képesek vagyunk olyan kereséseket is finomhangolni ami nem feltétlenül szerepel a jogszabályban és nehezen lenne kereshető. (pl: Mi a chipsadó? -> Mi a Népegészségügyi termékadó?)

Továbbá a chunk építés során gyűjtünk egy listát ami alias-okat tartalmaz, ezt a "továbbiakban" különböző variációinak felismeréséből építjük fel. (pl. NEBEK -> Nemzetközi Bűnügyi Együttműködési Központ)

Keresés

Embedding

Az embedding során egy adott modellel előállítjuk egy chunk szemantikai vektoros reprezentációját, amit később felhasználunk a kereséshez.

Embedding Backendek

Ollama

  • hivatalos Docker image
  • CPU/GPU support
  • GGUF formátum
  • egyedi modellarchitektúrák konvertálása alkalom adtán nehézkes lehet (gemma, nv-embed)

Egyedi (SentenceTransformer)

  • python alapú szerver, docker konténerben
  • egyszerű REST API
  • CPU/GPU support
  • HF/Transformers modell formátum, a legtöbb modell alapra ebben készül

Spring ONNX integráció

  • alkalmazásszerverbe épül be
  • CPU/GPU support
  • ONNX formátum szükséges, csak támogatott architektúrákkal megy

Embedding Modellek

A vektorok előállításához használt modellek nagyban befolyásolják a keresési találatok minőségét. Jellemzően a kevesebb paraméteres, de specifikusan embedding célra tanított modellek jobban teljesítenek, mint a komplexebb modellek. További előny, ha a modell tanító adathalmaza a célnyelvnek megfelelő szöveget tartalmazott.

Llama 3.2 72B

  • Backend: Ollama
  • Tapasztalat: Az egyes embeddingek vektorai túl hasonlóak, ezért nem alkalmasak keresésre

gte-Qwen2-7B-instruct

  • Backend: Ollama
  • A töbnyelvű embedding rangsorban 2. helyezett jelenleg
  • Tapasztalat: Ez a modell specifikusan embedding célokra van tanítva, ezért a generált vektorok között nagyobb a távolság, jól kereshető. A kisebb paraméterszám ellenére is jobb találatokat ad, mint a Llama3.2 modell. Ezen felül sokkal gyorsabb a vektorok generálása, az előzetes embedding generálás és a felhasználó keresések során egyaránt.

bge-multilingual-gemma2

  • Backend: egyedi (SentenceTransformer)
  • A töbnyelvű embedding rangsorban 1. helyezett jelenleg
  • Tapasztalat: A Qwen embedding modellhez hasonlóan szintén jól összehasonlítható vektorokat generál.

nv-embed-v2

  • Backend: egyedi (SentenceTransformer)
  • Új modell (2024. 09.)
  • Az embedding modell rangsor élén áll jelenleg
  • Tapasztalat:
    • Nem generál megfelelő vektorokat 16bit precízió mellett GPU-n, 32bites módban nincs elég VRAM
    • Érdemes visszatérni hozzá, amennyiben elterjedtebb lesz és rendelkezésre áll megfelelő tooling, vagy nagyobb hardverkapacitás

Vektoros keresés

A korábban elkészített embedding vektorokat a felhasználó által keresett kifejezésből, hasonlóan képzett vektorokkal hasonlítja össze. A vektorok irányát és/vagy távolságát kiszámítva megállapítható, hogy mely chunk-ok relevánsak a kereséshez.

  • Vektor adatbázis: Qdrant
    • nagyobb méretű vektorok támogatása
    • webes kezelőfelület
  • csak az embedding vektort és a szükséges metaadatokat tárolja
    • egyéb adatok a normál adatbázisban
  • hivatalos Docker image
  • Search Score: a beállított algoritmusnak megfelelő, nem biztos, hogy távolság

Reranking

A vektoros keresés eredményeként kapott találatok gyakran az összes relevánsnak tűnő dokumentumot tartalmazzák, de nem relevancia szerinti sorrendben.
A reranking során egy erre tanított modellel az egyes találatokat relevancia szerint súlyozzuk, majd ennek megfelelően rendezzük.

  • Egyedi reranker service (FlagReranker)
    • python alapú szerver, docker konténerben
    • egyszerű REST API
    • CPU/GPU support
    • HF/Transformers modell formátum, a legtöbb modell alapra ebben készül
  • bge-reranker-v2-m3 modell
    • a bge-gemma2 és gte-Qwen2 modellekkel jól tud együttműködni

Válaszgenerálás

A keresési találatok alapján LLM segítségével megpróbálunk egy választ adni a felhasználó kérdésére.
Ehhez fontos, hogy a modell rendelkezésére bocsássuk a kérdés megválaszolásához az összes releváns információt. A találatokhoz tartozó metaadatok segítségével a válasz pontos referenciákat tartalmazhat.

  • OpenAI API GPT4-en keresztül generált
  • A prompt felépítése:
    • instrukciók
    • relevánsnak ítélt kontextus
    • user query
  • Az első két keresési találat chunkjait (és a hozzájuk tartozó contextet) tartalmazza a kérés kontextje
  • A kérés REST API-n történik, a válasz egyben van megvárva (nincsen streamelve)
  • A felhasználó számára egy elkülönített szövegdobozban jelenik meg