LW IT Solutions
« Blog Overview /Cloud & AI/Tutorials / Tutorial: Sprawdzanie rozmiaru chunku i nakładki na...
This post in other languages:

Tutorial: Sprawdzanie rozmiaru chunku i nakładki na zestawie testowym

Tutorial: Sprawdzanie rozmiaru chunku i nakładki na zestawie testowym
Spis treści
  1. Pytanie, na które musi odpowiedzieć zestaw testowy
  2. Trzydzieści pytań bez pisania trzydziestu pytań
  3. Przeprowadzenie przebiegu
  4. Odczyt krzywej
  5. Czego ta miara nie obejmuje
  6. Źródła

Rozmiar chunku wybiera się na początku przedsięwzięcia, zwykle z przykładu w poradniku, a potem nigdy się go nie rusza. Nie dlatego, że nikt nie przeczuwa jego znaczenia, lecz dlatego, że jego sprawdzenie wygląda na wymagające całego rusztowania oceny.

Potrzeba trzydziestu pytań, jednej miary i pętli. A pętla nie wywołuje żadnego modelu językowego – właśnie to czyni całą rzecz na tyle tanią, by naprawdę ją przeprowadzić.

Wykres liniowy trafności w pierwszych pięciu wynikach dla czterech rozmiarów chunku przy dwóch nakładkach, obok tabela kosztów osadzeń i tokenów kontekstu dla każdego ustawienia
Krzywa wypłaszcza się po 512 tokenach, a nakładka opłaca się tylko na małym końcu. Jedno i drugie dotyczy określonego zbioru – i właśnie dlatego się mierzy, zamiast przepisywać.

Pytanie, na które musi odpowiedzieć zestaw testowy

Wyszukiwanie ma dokładnie jedno zadanie: wprowadzić fragment z odpowiedzią do węższego wyboru trafiającego do modelu. To, czy model napisze potem dobrą odpowiedź, jest pytaniem osobnym o osobnych przyczynach – a mieszanie obu jest tym, co czyni ocenę drogą.

Pomiar da się więc rozdzielić. Zestaw pytań, każde ze znanym miejscem odpowiedzi w materiale źródłowym, oraz miara pytająca, jak często to miejsce pojawia się w pierwszych k wynikach. Nic z tego nie wymaga generowania tekstu, a zatem przebieg po dwunastu ustawieniach kosztuje osadzenia i nic więcej.

Miara nazywa się trafnością w pierwszych k wynikach. Dla k równego pięć: w ilu z trzydziestu pytań właściwy fragment znalazł się wśród pierwszych pięciu trafień. Jej uzupełnieniem jest średnia odwrotność rangi, nagradzająca dodatkowo bycie pierwszym, a nie piątym – użyteczna, gdy trafność przestaje rozdzielać kandydatów.

Trzydzieści pytań bez pisania trzydziestu pytań

Zestaw testowy potrafi wytworzyć model językowy i właśnie tutaj opłaca się ostrożność, bo droga najbardziej oczywista daje zestaw niczego niemierzący.

Wytworzenie pytania z chunku, a potem sprawdzanie, czy ten chunk zostanie znaleziony, jest kołem: pytanie napisano z tego tekstu, dzieli z nim słownictwo i odnajdzie go przy niemal każdym ustawieniu. Test mówi wtedy, że każde ustawienie jest znakomite.

Wyjściem jest wytwarzanie z dokumentu i zapisywanie, gdzie odpowiedź stoi – a nie w który chunk wpadła. Przypisanie do chunku następuje później, dla każdego ustawienia, w chwili oceny.

Polecenie dla generatora, na kazdy dokument zrodlowy:

  Przeczytaj ponizszy dokument. Napisz osiem pytan, na ktore dokument
  odpowiada. Do kazdego pytania przytocz doslownie zdanie zawierajace
  odpowiedz. Bez pytan wymagajacych wiedzy spoza dokumentu. Zmieniaj
  sformulowania tak, by pytanie nie powtarzalo brzmienia swojego
  zdania zrodlowego.

Wynik na kazdy wpis:

  { "frage": "…", "beleg": "doslowne zdanie z dokumentu",
    "dokument": "handbuch-2026.md" }

Następują potem dwie czynności ręczne i kosztują dwadzieścia minut. Przejrzenie pytań i skasowanie tych, których odpowiedź naprawdę nie stoi w przytoczonym zdaniu – kilka takich generator wytwarza. Oraz przepisanie tej garstki, która powtarza zdanie źródłowe niemal dosłownie, bo właśnie ona schlebiałaby każdemu ustawieniu.

Trzydzieści do pięćdziesięciu wpisów to zakres użyteczny. Poniżej mniej więcej dwudziestu pięciu jedno przechylające się pytanie przesuwa wynik o cztery punkty procentowe, a kolejność staje się szumem; powyżej pięćdziesięciu dodatkowa dokładność nie zmienia już tego, które ustawienie wygrywa.

Przeprowadzenie przebiegu

Każde ustawienie oznacza: podzielić zbiór na nowo, osadzić na nowo i przepuścić przez to pytania. Sama ocena jest porównaniem podciągu – właściwym chunkiem jest ten zawierający zapisane zdanie.

import itertools, json

GROESSEN     = [256, 512, 1024, 2048]
UEBERLAPPUNG = [0.0, 0.2]
K            = 5

def treffer(fragen, index, k):
    n = 0
    for f in fragen:
        gefunden = index.suche(f["frage"], k=k)
        if any(f["beleg"] in c.text for c in gefunden):
            n += 1
    return n / len(fragen)

fragen = json.load(open("testsatz.json"))
for groesse, ueberlappung in itertools.product(GROESSEN, UEBERLAPPUNG):
    stuecke = zerlegen(korpus, groesse, int(groesse * ueberlappung))
    index   = einbetten(stuecke)
    print(f"{groesse:5d}  {ueberlappung:.0%}  "
          f"recall@{K} {treffer(fragen, index, K):.2f}  "
          f"Stuecke {len(stuecke):5d}")

Trzy szczegóły czynią przebieg godnym zaufania. Zapisane zdanie trzeba porównywać po tym samym ujednoliceniu, które stosuje dzielnik – inaczej ściągnięty znak końca linii zamienia trafienie w chybienie. Zdanie padające dokładnie na granicę chunku liczy się jako znalezione, gdy zawiera je którykolwiek z dwóch chunków – i właśnie po to jest nakładka. A model osadzeń musi pozostać ten sam przez cały przebieg, bo zamiana zmienia wszystko i porównanie traci znaczenie.

Koszt warto oszacować wcześniej, a nie później. Osiem ustawień na zbiorze dwóch milionów tokenów daje z nakładką około osiemnastu milionów tokenów do osadzenia – od kilku centów do kilku euro zależnie od modelu, a więc na tyle mało, że przebieg wychodzi taniej niż jedno popołudnie dyskusji o nim.

Odczyt krzywej

Wynik takiego przebiegu ma niemal zawsze ten sam kształt, a kształt mówi więcej niż pojedyncze liczby.

Rozmiar chunku bez nakładki 20 % nakładki Tokeny kontekstu na odpowiedź przy k = 5
256 0,71 0,79 1 280
512 0,84 0,88 2 560
1024 0,89 0,90 5 120
2048 0,87 0,87 10 240

Wynikają z tego trzy odczytania. Krzywa rośnie stromo, a potem się wypłaszcza, i to załamanie jest ustawieniem do wzięcia – tutaj 512, bo 1024 kupuje jeden lub dwa punkty za podwójny kontekst w każdej pojedynczej odpowiedzi, i to na stałe.

Nakładka zarabia na siebie na małym końcu, a na dużym traci znaczenie. Wynika to z jej celu: istnieje po to, by odpowiedź przecięta granicą przetrwała, a liczba granic zmniejsza się o połowę przy każdym podwojeniu rozmiaru chunku. Przy 1024 tokenach nakładka jest głównie dwudziestoprocentową dopłatą do rachunku za osadzenia.

A ustawienie największe wypada gorzej niż to poniżej, co za pierwszym razem zaskakuje. Chunk o 2048 tokenach obejmuje kilka tematów, jego osadzenie jest więc średnią po wszystkich i niczego nie trafia ostro. Większe chunki podnoszą prawdopodobieństwo, że odpowiedź leży gdzieś w węższym wyborze, i obniżają prawdopodobieństwo, że właściwy chunk stoi na przedzie.

Do tego samego przebiegu należy jedno porównanie i zwykle je wygrywa: dzielenie po strukturze zamiast po liczbie. Dzielnik przecinający na nagłówkach i zostawiający akapity w całości, z ograniczeniem rozmiaru jako regułą awaryjną, bije przy dokumentach z podziałem niemal każdy stały rozmiar – a przebieg pokazuje, o ile. To argument za włożeniem popołudnia w dzielnik zamiast w rozmiar.

Czego ta miara nie obejmuje

Trafność mierzy jedno ogniwo łańcucha, a trzy rzeczy leżą poza nim.

Pierwszą jest przesortowujący. Tam, gdzie taki działa, wyszukiwanie pobiera szeroki wybór wstępny – pięćdziesiąt, sto – a przesortowujący skraca go do pięciu. Liczy się wtedy trafność w pierwszych pięćdziesięciu, a ta wygląda zupełnie inaczej: jest wysoka niemal wszędzie, a rozmiar chunku przestaje przeważać. Mierzenie trafności w pierwszych pięciu w układzie z przesortowaniem odpowiada na pytanie, którego nikt nie zadał.

Drugą jest jakość odpowiedzi. Znaleziony chunk zawierający zdanie z odpowiedzią, ale nie zdanie je poprzedzające, nadal może dać odpowiedź błędną, bo modelowi brakuje warunku, na którym odpowiedź się opierała. W tej mierze jest to niewidoczne, a najtańszym sposobem zauważenia jest dwadzieścia odpowiedzi przeczytanych ręcznie, gdy ustawienie już stoi.

Trzecią jest czas. Zbiór rośnie, jego słownictwo się przesuwa, a zestaw testowy zbudowany dziś stopniowo przestaje przypominać to, o co się pyta. Powtórzenie przebiegu raz w roku kosztuje godzinę, a pożyteczniejsza część tej godziny polega na dołączeniu pytań rzeczywiście w międzyczasie zadanych – zestaw testowy z prawdziwych zapytań bije wytworzony pod każdym względem prócz szybkości powstania.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

Napisanie komentarza

Adres e-mail nie jest publikowany. Pola obowiązkowe oznaczono gwiazdką.

ALL ARTICLES & CATEGORIES

CCTV

Śledź tę kategorię przez RSS

Cloud & AI

Śledź tę kategorię przez RSS

Data Privacy

Wszystkie artykuły w tej kategorii (12) Śledź tę kategorię przez RSS

Digital Analytics

Wszystkie artykuły w tej kategorii (47) Śledź tę kategorię przez RSS

Digital Marketing

Wszystkie artykuły w tej kategorii (26) Śledź tę kategorię przez RSS

IT & Networks

Wszystkie artykuły w tej kategorii (16) Śledź tę kategorię przez RSS

Music Production

Śledź tę kategorię przez RSS

Raspberry Pi

Śledź tę kategorię przez RSS

Smart Home

Wszystkie artykuły w tej kategorii (17) Śledź tę kategorię przez RSS

Tworzenie stron internetowych

Śledź tę kategorię przez RSS

Wtyczki i triki WordPress

Śledź tę kategorię przez RSS