
Modele embeddingów po polsku - bge-m3, multilingual-e5 czy PolDense? Test na 900 pytaniach
Model embeddingów zamienia tekst na wektor liczb, dzięki czemu RAG, chatbot czy wyszukiwarka znajdują fragmenty podobne znaczeniowo do pytania, a nie tylko te z tymi samymi słowami. Który wybrać do polskich tekstów? Reguła z mojego testu na 900 prawdziwych pytaniach klientów: jeśli licencja Gemma Ci odpowiada, weź PolDense-150M (81,3 NDCG@10, 149 mln parametrów, działa na zwykłym CPU). Jeśli potrzebujesz licencji MIT lub Apache, weź multilingual-e5-large (80,7) albo bge-m3 (79,7, najodporniejszy na pytania bez polskich znaków i z literówkami). Do ok. 1 mln fragmentów wystarczy serwer z CPU, powyżej potrzebujesz GPU albo API. Cokolwiek wybierzesz, dodaj prefiks zapytania, którego wymaga model - bez niego PolDense traci prawie 30 punktów.
Który model embeddingów wybrać do polskiego RAG? Przetestowałem 10 modeli i BM25 na 900 prawdziwych pytaniach klientów: wyniki, odporność na brak polskich znaków i literówki, prefiks, który zabiera 30 punktów, ranking PIRB, ceny API, koszt przy dwóch skalach, licencje i kod.
/// WPIS W SKRÓCIE
W tym wpisie pokazuję wyniki mojego testu 10 modeli i BM25 na polskich pytaniach klientów, co się dzieje, gdy ktoś pisze bez polskich znaków albo z literówką, jak jeden zapomniany prefiks psuje wyniki, co mówi oficjalny polski benchmark PIRB, ile kosztują modele przez API i lokalnie przy dwóch skalach, jakie licencje pozwalają na użycie w firmie i jak przetestować modele na własnych danych - z kodem.
Czy w ogóle potrzebujesz modelu embeddingów - pierwsza decyzja
Najprostsza alternatywa to wyszukiwanie po słowach kluczowych (BM25), które masz za darmo w Postgresie czy Elasticsearchu. W moim teście BM25 osiągnęło 47,7 NDCG@10, a najlepszy model embeddingów 82,7. Na pierwszym miejscu właściwy fragment był w 33% przypadków przy BM25 i w 67% przy najlepszym modelu. Powód jest prosty: klient pyta „jak oddać towar”, a w dokumentacji jest „procedura zwrotu”, a polska odmiana sprawia, że „zwrot”, „zwrotu” i „zwrocie” to dla BM25 trzy różne słowa.
| Sytuacja | Co wystarczy |
|---|---|
| Wyszukiwanie po numerach, kodach produktów, nazwach własnych | BM25 albo filtr w bazie |
| Pytania w języku naturalnym do dokumentacji, FAQ, procedur | Model embeddingów |
| Oba rodzaje pytań w jednym systemie | Wyszukiwanie hybrydowe: embeddingi + BM25 |
Mój test: 10 modeli na 900 pytaniach klientów
Jak testowałem: zbiór Allegro FAQ z konkursu PolEval 2022 - 900 prawdziwych pytań klientów i 921 fragmentów odpowiedzi (średnio 50 słów). Dla każdego pytania znane są poprawne fragmenty. Każdy model zamieniał na wektory wszystkie fragmenty i pytania, a ja sprawdzałem, czy właściwy fragment trafia na górę listy. Wszystko na 4-rdzeniowym procesorze Intel Xeon, bez GPU, z prefiksami zalecanymi przez autorów modeli (październik 2026).
| Model | NDCG@10 | Trafienie na 1. miejscu | Właściwy fragment w top 10 | Parametry | Wymiar wektora | Fragmenty na sekundę (CPU) | Licencja |
|---|---|---|---|---|---|---|---|
| OPI-PIB/PolDense-400M | 82,7 | 67,4% | 96,9% | 395 mln | 1024 | 2,4 | Gemma |
| OPI-PIB/PolDense-150M | 81,3 | 65,0% | 96,5% | 149 mln | 768 | 6,7 | Gemma |
| intfloat/multilingual-e5-large | 80,7 | 65,9% | 94,9% | 560 mln | 1024 | 4,8 | MIT |
| BAAI/bge-m3 | 79,7 | 64,8% | 94,1% | 568 mln | 1024 | 4,6 | MIT |
| OPI-PIB/PolDense-68M | 79,1 | 62,3% | 94,8% | 68 mln | 512 | 15,6 | Gemma |
| sdadas/mmlw-retrieval-roberta-large | 76,9 | 60,9% | 92,3% | 435 mln | 1024 | 6,2 | Apache 2.0 |
| intfloat/multilingual-e5-base | 76,0 | 59,8% | 91,5% | 278 mln | 768 | 16,2 | MIT |
| sdadas/mmlw-retrieval-roberta-base | 74,6 | 58,1% | 90,7% | 124 mln | 768 | 18,4 | Apache 2.0 |
| Qwen/Qwen3-Embedding-0.6B | 72,6 | 56,2% | 89,2% | 596 mln | 1024 | 8,2 | Apache 2.0 |
| intfloat/multilingual-e5-small | 72,2 | 54,8% | 90,8% | 118 mln | 384 | 45,6 | MIT |
| BM25 (słowa kluczowe) | 47,7 | 32,6% | 64,7% | - | - | - | - |
Co z tego wynika:
- Polskie modele wygrywają w swojej wadze. PolDense-68M z 68 mln parametrów wypada lepiej niż wielojęzyczne modele ośmiokrotnie większe (mmlw-large, Qwen3-0.6B) i niemal równo z bge-m3.
- Popularny model to nie znaczy dobry po polsku. Qwen3-Embedding-0.6B, chętnie polecany w zagranicznych rankingach, zajął przedostatnie miejsce wśród modeli - na poziomie najmniejszego e5.
- Liczba parametrów nie mówi o szybkości. PolDense-68M jest mniejszy od mmlw-base, ale na CPU wolniejszy, bo obsługuje teksty do 8192 tokenów i bez specjalnych bibliotek przyspieszających (dostępnych głównie na GPU) liczy wolniej.
- Różnica między pierwszym a piątym modelem to 3,6 punktu. Wybór między nimi powinien wynikać z licencji, szybkości i odporności na błędy w pytaniach, a nie z samego rankingu.
Polskie znaki i literówki - test, którego nikt nie robi
Klienci często piszą „jak zwrocic towar” zamiast „jak zwrócić towar”. Sprawdziłem więc, co się dzieje, gdy z tych samych pytań usunę polskie znaki (dotyczyło to 92% pytań) albo wstawię jedną literówkę w dłuższym słowie:
| Model | Pytania poprawne | Bez polskich znaków | Z literówką |
|---|---|---|---|
| PolDense-400M | 82,7 | 81,4 (-1,3) | 78,6 (-4,1) |
| PolDense-150M | 81,3 | 77,8 (-3,5) | 75,5 (-5,8) |
| multilingual-e5-large | 80,7 | 76,8 (-3,9) | 76,0 (-4,7) |
| bge-m3 | 79,7 | 78,5 (-1,2) | 77,2 (-2,5) |
| PolDense-68M | 79,1 | 76,3 (-2,8) | 72,8 (-6,3) |
| mmlw-retrieval-roberta-large | 76,9 | 76,0 (-0,9) | 70,9 (-6,0) |
| multilingual-e5-base | 76,0 | 71,4 (-4,6) | 69,8 (-6,2) |
| multilingual-e5-small | 72,2 | 66,2 (-6,0) | 67,4 (-4,8) |
| BM25 | 47,7 | 38,3 (-9,4) | 41,8 (-5,9) |
Wnioski: bge-m3 jest najbardziej odporny - przy pytaniach bez polskich znaków i z literówkami traci najmniej, więc w wyszukiwarce dla klientów indywidualnych bywa pewniejszym wyborem niż model z wyższym wynikiem na czystych danych. Najbardziej cierpi BM25 i najmniejsze modele. Nie usuwaj polskich znaków z dokumentów „na wszelki wypadek” - modele uczono na poprawnym polskim i tylko pogorszysz wyniki.
Prefiks, o którym wszyscy zapominają
Wiele modeli wymaga, żeby przed pytaniem dopisać krótki prefiks: „query: ” w e5, „zapytanie: ” w mmlw, „[query]: ” w PolDense. To nie jest kosmetyka. Policzyłem, co się dzieje, gdy go pominiesz:
| Model | Z prefiksem | Bez prefiksu | Różnica |
|---|---|---|---|
| PolDense-150M | 81,3 | 51,4 | -29,9 |
| PolDense-68M | 79,1 | 51,0 | -28,1 |
| PolDense-400M | 82,7 | 56,0 | -26,7 |
| mmlw-retrieval-roberta-base | 74,6 | 67,7 | -6,9 |
| mmlw-retrieval-roberta-large | 76,9 | 71,7 | -5,2 |
| multilingual-e5-large | 80,7 | 78,1 | -2,6 |
| bge-m3 | 79,7 | nie wymaga | - |
Bez prefiksu najlepszy model w teście spada niemal do poziomu prostego wyszukiwania po słowach. Taki błąd nie wywala aplikacji ani nie pokazuje komunikatu - wyniki są po prostu gorsze i nikt nie wie dlaczego. Dlatego prefiks trzymaj w jednym miejscu w kodzie razem z nazwą modelu i dodawaj go tylko do pytań, nie do dokumentów (chyba że model wymaga też prefiksu dokumentu, jak e5 z „passage: ”).
from sentence_transformers import SentenceTransformerMODEL = "OPI-PIB/PolDense-150M"QUERY_PREFIX = "[query]: " # zmieniasz model? zmień też prefiksmodel = SentenceTransformer(MODEL, device="cpu")def embed_documents(texts: list[str]): return model.encode(texts, batch_size=16, normalize_embeddings=True)def embed_query(text: str): return model.encode(QUERY_PREFIX + text, normalize_embeddings=True)docs = ["Zwrot towaru możesz zgłosić w ciągu 14 dni w zakładce Moje zakupy.", "Fakturę VAT pobierzesz po zaksięgowaniu płatności."]D = embed_documents(docs)q = embed_query("jak oddac towar ktory mi nie pasuje")print(docs[int((D @ q).argmax())])
Ranking PIRB - szerszy obraz na 41 zadaniach
Mój test to jeden typ danych: krótkie odpowiedzi FAQ. Szerszy obraz daje Polish Information Retrieval Benchmark (PIRB), który utrzymuje Ośrodek Przetwarzania Informacji: 41 zadań, od prawa i medycyny po pytania z portali internetowych. Wybrane wyniki (średnie NDCG@10, stan na 9 października 2026):
| Model | PIRB NDCG@10 | Parametry | Licencja |
|---|---|---|---|
| PolDense-1B | 64,11 | 1,0 mld | Gemma |
| llama-embed-nemotron-8b | 63,73 | 7,5 mld | tylko niekomercyjnie |
| bge-multilingual-gemma2 | 63,26 | 9,2 mld | Gemma |
| PolDense-400M | 63,21 | 395 mln | Gemma |
| PolDense-150M | 61,07 | 149 mln | Gemma |
| Qwen3-Embedding-8B | 60,93 | 7,6 mld | Apache 2.0 |
| PolDense-68M | 59,01 | 68 mln | Gemma |
| mmlw-retrieval-roberta-large | 58,46 | 435 mln | Apache 2.0 |
| multilingual-e5-large | 57,29 | 560 mln | MIT |
| bge-m3 | 55,98 | 568 mln | MIT |
| multilingual-e5-base | 53,12 | 278 mln | MIT |
| Qwen3-Embedding-0.6B | 50,71 | 596 mln | Apache 2.0 |
| BM25 | 41,85 | - | - |
Kolejność w PIRB jest podobna do mojej: polskie modele PolDense na górze, e5-large przed bge-m3, a Qwen3-0.6B daleko w tyle. Różnica jest w skali wyników - PIRB zawiera dużo trudniejszych zadań (np. prawo), więc średnie są niższe. Ciekawostka z PIRB: wariant hybrydowy bge-m3 (55,75) wypadł minimalnie gorzej niż sam wariant gęsty (55,98), więc „hybryda zawsze pomaga” to mit - trzeba ją sprawdzić na swoich danych.
Modele przez API - OpenAI, Gemini, Voyage
Modele przez API nie są w PIRB, a bez kluczy nie mogłem ich uczciwie przetestować, więc nie podaję dla nich wyników po polsku. Ceny (październik 2026):
| Model | Cena za mln tokenów | Uwagi |
|---|---|---|
| OpenAI text-embedding-3-small | 0,02 USD | 1536 wymiarów, można skracać |
| OpenAI text-embedding-3-large | 0,13 USD | 3072 wymiary, można skracać |
| Google Gemini Embedding 2 | 0,20 USD (0,10 USD w trybie wsadowym) | Darmowy w planie bezpłatnym |
| Voyage voyage-4-lite | 0,02 USD | 200 mln tokenów za darmo |
| Voyage voyage-4 | 0,06 USD | 200 mln tokenów za darmo |
| Voyage voyage-4-large | 0,12 USD | 200 mln tokenów za darmo |
API ma sens, gdy nie chcesz utrzymywać serwera, a dane mogą trafić do dostawcy na warunkach biznesowych. Przed wyborem przepuść przez nie ten sam test, który pokazuję niżej - koszt testu na 1 000 fragmentów to ułamki centa.
Ile to kosztuje przy dwóch skalach
Założenie: fragmenty po ok. 300 tokenów, a pytania po ok. 20 tokenów.
| Skala | API (text-embedding-3-small) | API (Gemini Embedding 2) | Lokalnie na CPU (PolDense-68M) | Pamięć na wektory |
|---|---|---|---|---|
| 50 tys. fragmentów, 30 tys. pytań miesięcznie | ok. 0,30 USD jednorazowo + grosze miesięcznie | ok. 3 USD + ok. 0,12 USD miesięcznie | ok. 1 godzina liczenia na serwerze, który już masz | ok. 0,1-0,3 GB |
| 10 mln fragmentów, 3 mln pytań miesięcznie | ok. 60 USD + ok. 1,2 USD miesięcznie | ok. 300-600 USD + ok. 12 USD miesięcznie | ok. 7 dni na 4 rdzeniach CPU - potrzebne GPU | 20-123 GB zależnie od wymiaru |
Najważniejszy wniosek: samo liczenie embeddingów przez API jest tanie. Prawdziwe koszty są gdzie indziej:
- Pamięć bazy wektorowej. 10 mln wektorów o wymiarze 3072 (text-embedding-3-large) to ok. 123 GB, o wymiarze 512 (PolDense-68M) ok. 20 GB. To różnica w rachunku za bazę co miesiąc. Więcej o kosztach baz w porównaniu baz wektorowych.
- Zmiana modelu. Wektory z różnych modeli są niekompatybilne, więc zmiana modelu oznacza przeliczenie całego indeksu. Przechowuj teksty źródłowe i zaplanuj to z góry - piszę o tym w tekście o vendor lock-in w AI.
- Prywatność. Model lokalny nie wysyła dokumentów nigdzie, co przy danych osobowych upraszcza zgodność z RODO.
Licencje - co wolno w firmie
| Licencja | Modele | Użycie komercyjne |
|---|---|---|
| MIT | multilingual-e5, bge-m3 | Tak, bez dodatkowych warunków poza zachowaniem informacji o licencji |
| Apache 2.0 | mmlw-retrieval, Qwen3-Embedding | Tak, z zachowaniem informacji o licencji i zmianach |
| Gemma Terms of Use | PolDense, bge-multilingual-gemma2 | Tak, ale obowiązuje polityka zakazanych zastosowań Google, a przy dystrybucji modelu trzeba przekazać warunki dalej |
| Niekomercyjna | llama-embed-nemotron-8b | Nie |
Jeśli dział prawny woli najprostszą licencję, wybierz e5-large albo bge-m3 - tracisz 1-2 punkty względem PolDense-150M, ale masz MIT.
Jak przetestować modele na własnych danych
Ranking to punkt wyjścia, a nie decyzja. Zbierz 50-200 prawdziwych pytań i dla każdego wskaż fragment, który powinien się znaleźć. Potem uruchom dla 2-3 kandydatów taki skrypt:
from sentence_transformers import SentenceTransformerCANDIDATES = {"OPI-PIB/PolDense-150M": "[query]: ", "BAAI/bge-m3": "", "intfloat/multilingual-e5-large": "query: "}DOC_PREFIX = {"intfloat/multilingual-e5-large": "passage: "}def evaluate(name, qprefix, docs, questions, correct): m = SentenceTransformer(name, device="cpu") D = m.encode([DOC_PREFIX.get(name, "") + d for d in docs], normalize_embeddings=True) Q = m.encode([qprefix + q for q in questions], normalize_embeddings=True) top10 = (Q @ D.T).argsort(axis=1)[:, ::-1][:, :10] hit1 = sum(top[0] == c for top, c in zip(top10, correct)) / len(correct) hit10 = sum(c in top for top, c in zip(top10, correct)) / len(correct) return round(100 * hit1, 1), round(100 * hit10, 1)# docs: lista fragmentów, questions: lista pytań, correct: indeks właściwego fragmentu dla każdego pytania# for name, prefix in CANDIDATES.items(): print(name, evaluate(name, prefix, docs, questions, correct))
Dodaj do zestawu pytania bez polskich znaków i z literówkami - tak, jak piszą Twoi użytkownicy. Wynik „właściwy fragment w top 10” mówi, czy RAG ma szansę odpowiedzieć dobrze, bo model językowy dostaje zwykle kilka najlepszych fragmentów, a nie tylko pierwszy.
Najczęstsze błędy
- Brak prefiksu zapytania - w moim teście do 30 punktów straty, bez żadnego komunikatu o błędzie.
- Wybór modelu z angielskiego rankingu. MTEB i rankingi zagraniczne nie mówią, jak model radzi sobie po polsku.
- Usuwanie polskich znaków z dokumentów. Modele uczono na poprawnym tekście, więc tylko pogarszasz wyniki.
- Mieszanie wektorów z dwóch modeli w jednym indeksie. Po zmianie modelu przelicz wszystko od nowa.
- Za długie fragmenty dla modeli z limitem 512 tokenów. e5 i mmlw obcinają dłuższy tekst bez ostrzeżenia, więc koniec dokumentu w ogóle nie trafia do wektora. Dziel teksty na krótsze fragmenty albo wybierz model z dłuższym limitem (bge-m3, PolDense - do 8192 tokenów).
---
Pomagam firmom budować wyszukiwanie i RAG na polskich dokumentach - od wyboru modelu embeddingów i testu na własnych danych po bazę wektorową i wdrożenie. Robię to w ramach budowy aplikacji AI i automatyzacji z AI. Napisz do mnie - zacznę od testu 2-3 modeli na próbce Twoich pytań.
Warto przeczytać:
/// RELATED_SERVICES
Potrzebujesz wdrożenia tych koncepcji? Zobacz usługi powiązane z tym tematem.
Budowa Aplikacji AI
Dedykowane oprogramowanie AI i aplikacje webowe z silnikiem AI — MVP, full stack development, programowanie systemów AI od zera do produkcji.
Zobacz usługęUsługaAI & Automatyzacja
Agenci AI 24/7, automatyzacja procesów z n8n i Make, chatboty, RAG z Twoimi danymi i custom LLM. Buduję systemy AI, które redukują ręczną pracę i zwiększają efektywność.
Zobacz usługę/// ŹRÓDŁA
- 01Dane do mojego testu: PolEval 2022 Allegro FAQ, 900 pytań
- 02PIRB - Polish Information Retrieval Benchmark (leaderboard)
- 03Dadas et al. (2024) - PIRB: A Comprehensive Benchmark of Polish Dense and Hybrid Text Retrieval Methods
- 04PL-MTEB: Polish Massive Text Embedding Benchmark (ACL 2026 Findings)
- 05OPI-PIB - PolDense-150M (model card)
- 06sdadas - mmlw-retrieval-roberta-base (model card)
- 07BAAI - bge-m3 (model card)
- 08Wang et al. (2024) - Multilingual E5 Text Embeddings: A Technical Report
- 09OpenAI - API pricing (embeddings)
- 10Google - Gemini API pricing (Gemini Embedding 2)
- 11Voyage AI - Pricing
- 12Google - Gemma Terms of Use
/// RELATED_RECORDS
Adopcja AI w zespole - dlaczego licencje leżą nieużywane i jak przekonać ludzi do AI
Według Gartnera tylko 5% firm po pilotażu Copilota planowało szersze wdrożenie, a z AI codziennie korzysta 8% pracowników. Pięć oporów i co na nie działa, rola menedżerów, program liderów AI, pomiar adopcji na trzech poziomach i plan na 90 dni.
Jak wybrać wykonawcę wdrożenia AI - 15 pytań, sygnały ostrzegawcze i zapisy w umowie
Według MIT NANDA 95% pilotaży AI nie daje efektu finansowego, ale wdrożenia z partnerami udają się w 67% przypadków. Zespół wewnętrzny, partner czy hybryda, 15 pytań do wykonawcy, sygnały ostrzegawcze, zapisy w umowie i pilotaż z kryteriami sukcesu.
Human-in-the-loop w praktyce - jak zaprojektować nadzór człowieka nad agentami AI
Za mało nadzoru kończy się incydentem jak skasowana baza w Replit, za dużo - klikaniem bez czytania: użytkownicy Claude Code zatwierdzają 93% próśb agenta. Cztery poziomy autonomii, macierz ryzyka i odwracalności, karta zatwierdzenia, eskalacje i art. 14 AI Act w architekturze.
Signal received?
Przerwij
Ciszę
Zainicjuj protokół. Nawiąż połączenie. Zbudujmy coś głośnego.
