Zagadkowe embeddingi

Ci, którzy wcześniej nie zetknęli się z technicznymi szczegółami dotyczącymi Modeli Językowych, szybko natrafią na pojęcie embeddingów. Jeden z pierwszych istotnych elementów składających się na maszynerię Modeli Językowych - Embedding to siłacz, który obok Mechanizmu Uwagi stoi za oszałamiającymi sukcesami AI!

Przyjrzyjmy się im od strony praktycznej. Czy można w domu, na małym laptopie z linuxem użyć tych embeddingów do czegokolwiek sensownego? Przynajmniej po to, żeby zobaczyć – jak działają?

Takie intencje przyświecały mi podczas pierwszych eksperymentów, które chcę tu opisać. Zobaczymy jak można użyć embeddingów z API genai lub z ollama do trenowania i inferencji za pomocą regresorów i klasyfikatorów ze scikit-learn. To pouczające i inspirujące doświadczenie, które prowadzi do stu kolejnych pomysłów, z moim wykluwającym się pomysłem na „Transformer Dla Ubogich” na czele (o którym napiszę w przyszłości).

Skąd brać embeddingi?

Na laptopie z linuksem mamy co najmniej dwie proste ścieżki otrzymania embeddingów, zarówno na poziomie wyrazów, jak i dla całych wypowiedzi:

Gdy eksperymentujemy, warto sprawdzać różne modele. Niektóre z nich są szybsze, z kolei inne „znają” język polski.

Stolice Państw – minimalne zadanie. Proof Of Concept

Co można z tym zrobić? Prostym pomysłem, który wpadł mi do głowy, było połączenie embeddingów z „Machine Learning” w lekkiej formie, czyli ze scikit-learn! Wymyśliłem, że sprawdzę wiedzę geograficzną, jaka jest wdrukowana w embeddingi.

Przygotowałem kilka przykładów zdań na temat stolic:

Zdanie Wartość
Praga jest stolicą Włoch. 0
Rzym jest stolicą Włoch. 1
Grecja jest stolicą Hagi. 0
Warszawa jest stolicą Polski. 1

Był to mikro-korpus, który następnie przedstawiłem Modelowi Językowemu z prośbą o rozszerzenie do wielkości ok 100. Dostałem w ten sposób mini-korpus, który zamieniłem na embeddingi, a następnie, po podzieleniu na zbiór treningowy i testowy w stosunku 60:40, pokazałem „wyjętemu z pudełka” (czyli bez parametrów, bez tuningu) klasyfikatorowi ze scikit-learn. Próbowałem LogisticRegression, a potem SVC.

Najpierw wyniki były słabe: 60% trafności.

Przyjrzałem się jednak bliżej i zauważyłem, że pierwszy model embeddingowy, którego użyłem nie był polskojęzyczny! Wynikało to z dokumentacji.

Po przejściu na model bg3-m3 (wielojęzyczny) i skupieniu się na SVC dostałem 100% na zbiorze testowym.

Radość w obozie zwycięzców panowała do samego rana. – To działa! Jeszcze nawet zanim to „rano” nadeszło, pojawiły się nowe pomysły!

Jak trenować systemy dla większych zadań? KLEJ!

Zapytałem AI o dostępność benchmarków modeli językowych dla języka polskiego, dowiedziałem się o Kompleksowej Liście Ewaluacji Językowych stworzonej przez ludzi z Allegro i AGH (nazwa jest tak dobrana, żeby akronim mógł być odpowiednikiem GLUE, co z kolei oznacza General Language Understanding Evaluation).

Szybko zorientowałem się, że KLEJ składa się z dziewięciu dobrze określonych zadań, dane treningowe i – częściowo – testowe są dostępne do pobrania i – co dla mnie bardzo ważne – są małe! Kilka tysięcy przykładów na każde zadanie. W sumie - nieco ponad 65000 tekstów. Od razu zrozumiałem że to liczba całkowicie wygodna z punktu widzenia mojego laptopa.

Rzeczywiście - obliczenie embeddingów dla tych wszystkich tekstów zajęło kilkanaście minut za pomocą modeli embedding-001 z genai. Więcej mi zajęło napisanie kodu, który w wygodny sposób cache-uje te embeddingi!

Druga rzecz, również bardzo ważna - rodzaj tych zadań całkowicie odpowiada moim potrzebom. Są to zadania klasyfikacji (dwie lub kilka etykiet), niektóre tylko wymagają regresji, a większość w sensowny sposób może być do regresji sprowadzona, bo etykiety można uporządkować.

Last but not least, autorzy KLEJ precyzyjnie określili sposób obliczania metryk, jaki stosują przy budowaniu leaderboardu, a więc - moje wyniki mogę bezpośrednio porównywać z „wielkimi”, a z drugiej strony (może to ważniejsze) – z „baseline”.

Wyniki

Policzywszy to wszystko, porównałem swoje wyniki do dwóch wybranych modeli z leaderboardu KLEJ.:

Zadanie Polish RoBERTa-v2 HerBERT - KLEJ embedding-001/SVR metrics
NKJP-NER 95.8 92.7 68.53 Accuracy
CDSC-E 94.3 92.5 76.30 Spearman corr.
CDSC-R 95.1 91.9 44.44 Accuracy
CBD 74.3 50.3 48.97 F1
PolEmo2.0-IN 93.1 89.2 79.25 Accuracy
PolEmo2.0-OUT 84.0 76.3 46.36 Accuracy
DYK 75.4 52.1 54.91 F1
PSC 98.8 95.3 85.70 F1
AR 89.2 84.5 79.76 1 - wMAE
Średnia 88.89 80.53 64.91

Autorzy zaprojektowali metryki w ten sposób, że można wziąć z nich średnią, bo 100 oznacza “geniusza”, 0 oznacza “antygeniusza”, a 25 oznacza np. “losowy wybór 1 z 4”, czyli – wszystkie skale są podobne, co wynika z zaprojektowania metryk.

Moja średnia jest dużo niższa niż tamtych modeli, ale i tak jest niezła, jak na „składak” wykonany z publicznie dostępnych elementów, policzony na laptopie.

Wnioski

  1. Całkiem dużo da się zrobić w domu, istnieje wiele ciekawych ścieżek dalszych prób!
  2. KLEJ jest świetnym narzędziem mierzenia jakości własnych rozwiązań, jeśli dotyczą języka polskiego.

Eksplozja pomysłów. Co dalej…

W przyszłości myślę o tym, żeby czymś własnym zastąpić embeddingi. Mam kilka ścieżek pomysłów, generalnie polegają na tym, żeby embeddingi dla pojedynczych słów języka polskiego stabelaryzować, a potem jakoś je składać, korzystając ze spaCy, Morfeusz2 itp, szukać możliwości kodowania formy gramatycznej zamiast pozycji w zdaniu, co pozwoliłoby wykorzystać specyfikę języka polskiego. Albo - może - trenować podmodele, które za pomocą embeddingów słów będą jakoś konstruować embeddingi fraz.

Może cechy języka polskiego, które utrudniają nieco bezpośrednie stosowanie algorytmów powstających w głównym nurcie NLP – są szansą dla nas, żeby zbudować coś specyficznego, ciekawego, nowatorskiego?

W kolejnych odcinkach będę pisać – co udało się zrobić. Zachęcam wszystkich do samodzielnych eksperymentów – to niesamowicie satysfakcjonująca, nowa, obiecująca – i superciekawa dziedzina! A w domu można wiele uzyskać!.