Fine-tuning 13 listopada 2026 9 min czytania

Fine-tuning OCR po polsku: jak nauczyłem lokalny model czytać „ł”, „ą” i „ę” na laptopie z 8 GB VRAM

Mariusz Kałmuk
Mariusz Kałmuk Specjalista ds. automatyzacji i Agentów AI / Web Designer

Gotowy model OCR czytał polskie dokumenty jak turysta bez polskiej klawiatury: „ł” zamieniał na „l”, „ą” na „a”, a „łódź” wychodziła z niego jako „lodz”. Dostroiłem go lokalnie metodą LoRA, na danych syntetycznych i laptopie z kartą 8 GB. Pokazuję wyniki, porównanie z Tesseractem i PP-OCRv6 oraz miejsca, w których ten model się nie sprawdza.

Fine-tuning modelu OCR do polskich znaków: skan dokumentu z literami ł, ą, ę odczytywany lokalnie na laptopie

W skrócie

  • Model MiniCPM-OCR 1.0 (OpenBMB, 1,3 mld parametrów) czytał polski tekst, ale gubił ogonki: zachowywał tylko ok. 69% polskich liter.
  • Dostroiłem go metodą LoRA wyłącznie na danych syntetycznych, na laptopie z kartą 8 GB, w dwóch rundach po niecałej godzinie.
  • Efekt: 69% → 94% zachowanych polskich liter na obrazach testowych i 82% → 96% na prawdziwych skanach. Błąd znakowy (CER) spadł ponad dwukrotnie.
  • Uczciwie: na czytelnym druku Tesseract i PP-OCRv6 są co najmniej tak dobre, a lżejsze i szybsze. Mój model wygrywa na zdjęciach i trudnych obrazach i zwraca strukturę tabel.
  • Nie czyta pisma odręcznego. Na rozmytym skanie z rękopisem zaczyna zmyślać tekst.
  • Model jest publiczny na Hugging Face i działa w pełni lokalnie.

Problem: OCR, który „prawie” czyta po polsku

Nowoczesne modele OCR czytają dokumenty znacznie lepiej niż klasyczne silniki: rozumieją układ strony, tabele, czasem wzory. Ale większość z nich trenowano głównie na angielskim i chińskim. Po polsku widać to od razu, bo model po cichu zamienia polskie litery na łacińskie odpowiedniki.

# Ilustracja problemu (przykład, nie cytat z testu): „łódź” → „lodz” „błędną” → „bledna” „świadczenie” → „swiadczenie”

Dla człowieka to drobiazg, coś jak SMS pisany w biegu bez polskich znaków. Dla wyszukiwarki, systemu księgowego albo kontroli umowy to po prostu inne słowo. A wynik wygląda przekonująco, więc błąd łatwo przeoczyć.

Zmierzyłem to na bazowym modelu: z tekstów testowych zachowywał ok. 69% polskich liter. Najgorzej było z „ę”, „ą”, „ł” i wielkimi literami.

Dlaczego fine-tuning, a nie lepszy prompt

Zanim cokolwiek trenowałem, sprawdziłem najprostszą hipotezę: może obraz jest za mały. Powiększyłem go, zmieniłem rozdzielczość. Wynik się nie zmienił. To nie jest kwestia jakości obrazu, tylko nawyk modelu językowego: tam, gdzie widzi „ł”, wolałby napisać „l”, bo tak najczęściej wyglądał jego trening.

„Model nie miał wady wzroku. Miał złe przyzwyczajenie. Okulary tu nie pomogą, trzeba poprawić nawyk.”

— Wniosek z pierwszego dnia testów

Takiego nawyku nie naprawi prompt ani RAG. Trzeba go zmienić w wagach, a najtańszy sposób to LoRA: dokładam do modelu niewielki adapter i uczę tylko jego, nie cały model. Trochę jak karteczka z poprawkami doklejona do grubego podręcznika zamiast drukowania go od nowa.

Jak to zrobiłem

1. Dane syntetyczne, bez Twoich dokumentów

Teksty po polsku napisał lokalnie Bielik 11B. Wyrenderowałem je różnymi czcionkami, z degradacjami: skan, zdjęcie z perspektywą, niska rozdzielczość, wyjustowany tekst. Czcionki treningowe i testowe są rozłączne, żeby model nie mógł się „nauczyć na pamięć”. Dodałem linie z rzadkimi literami i końcówkami typu „-ć”.

2. LoRA tylko na części językowej

Enkoder wizyjny i projektor zostały zamrożone. Rank 16, ok. 1,3 tys. próbek w pierwszej rundzie, ok. 1,8 tys. w drugiej, po dwie epoki. Cały trening zmieścił się na laptopie z RTX 5060 8 GB i trwał 43 oraz 54 minuty. Czyli krócej niż niejeden firmowy status.

3. Eksport do formatu lokalnego

Adapter scaliłem z modelem i skonwertowałem do GGUF w kwantyzacji Q8_0 (0,8 GB), tak żeby działał w Ollamie.

Dwie pułapki, które kosztowały mnie czas, a mogą zaoszczędzić Tobie

Pamięć: słownik 248 tys. tokenów plus ok. tysiąca tokenów obrazu na próbkę kończy się brakiem pamięci na 8 GB. Pomogło ograniczenie rozmiaru wycinków. (O tym, czemu rozmiar pliku to nie zużycie pamięci, pisałem przy okazji modeli na 32 GB VRAM.)

Szablon czatu: własny eksport z domyślnym szablonem sprawiał, że Ollama wpisywała odpowiedź w pole „thinking” i zwracała puste wyniki. Trzeba użyć szablonu z oficjalnego GGUF.

Co osiągnąłem

Testowałem na obrazach z czcionkami, których model nie widział, oraz na wycinkach prawdziwych skanów dokumentów (nie wchodziły do treningu).

Zbiór Model Polskie litery zachowane Błąd znakowy (CER) Słowa z błędem
84 obrazy syntetyczne bazowy 68,9% 2,63% 14,1%
84 obrazy syntetyczne po fine-tuningu 94,0% 1,08% 4,8%
11 prawdziwych skanów bazowy 81,5% 1,40% 10,1%
11 prawdziwych skanów po fine-tuningu 96,4% 0,55% 2,5%

Przy okazji sprawdziłem, czy model nie zapomniał innych języków: angielski, chiński, niemiecki, francuski i czeski czytał tak samo dobrze jak przed treningiem (CER 0,21% → 0,18%).

Zastrzeżenie: 11 wycinków z czterech dokumentów to mała próbka. Kierunek jest jednoznaczny, ale dokładne liczby traktuj jako orientacyjne.

Czym się różni od Tesseracta i PP-OCR

Porównałem go na tych samych danych z Tesseractem (język polski) i PP-OCRv6, bez żadnej obróbki obrazu.

Silnik Skany (CER / polskie litery) Obrazy syntetyczne (CER / polskie litery)
MiniCPM-OCR bazowy 1,40% / 81,5% 2,63% / 68,9%
MiniCPM-OCR po fine-tuningu 0,55% / 96,4% 1,08% / 94,0%
Tesseract (pol) 0,25% / 100% 14,16% / 86,3%
PP-OCRv6 (pl) 0,32% / 96,4% 1,61% / 88,3%

Co z tego wynika, bez ściemy:

  • Na czytelnych skanach druku Tesseract i PP-OCRv6 wygrywają lub remisują, są lżejsze i znacznie szybsze (Tesseract: pół sekundy na CPU). Jeśli masz czyste dokumenty, nie ma powodu sięgać po duży model.
  • Na zdjęciach i obrazach z perspektywą Tesseract bez obróbki wstępnej się sypie (CER ok. 37%), a mój model trzyma stały poziom ok. 1%. PP-OCRv6 radzi sobie ze zdjęciami równie dobrze.
  • Przewaga mojego modelu to struktura, nie liczba poprawnych liter: potrafi zwrócić tabelę jako tabelę, a nie luźne słowa. Tego w porównaniu nie mierzyłem, więc nie będę udawał, że mam liczby.
  • Prywatność: wszystko działa lokalnie, na własnym sprzęcie. Czas: ok. 3 s na akapit na GPU albo ok. 15 s na samym CPU.

Mój wniosek: Tesseract albo PP-OCRv6 jako domyślny silnik, a model LLM-owy jako drugi krok tam, gdzie klasyczny OCR sobie nie radzi (tabele, zdjęcia, złożony układ). Wyniki obu silników można porównywać i rozbieżności kierować do ręcznej weryfikacji. Jak w przychodni: najpierw lekarz rodzinny, specjalista dopiero wtedy, gdy trzeba.

Czego ten model nie potrafi

To część, o której rzadko się pisze.

  • Pismo odręczne. Sprawdziłem na archiwalnym skanie z rękopisem (rozmyty mikrofilm). Z ok. 340 słów wzorca model odnalazł 8. Przy dwóch stronach zmyślił płynny angielski i łaciński tekst, którego tam nie było. Do rękopisów użyj innego narzędzia, np. Transkribus.
  • Halucynacje na słabych skanach. Przy bardzo kiepskiej jakości wynik wygląda wiarygodnie, a jest błędny. Klasyczny silnik zwróciłby błąd rozpoznania, który łatwiej zauważyć.
  • Wciąż słabsze litery: „ł” i „Ą” (ok. 86–87% na zbiorze syntetycznym).
  • Do dokumentów, w których liczy się kwota, data lub nazwisko, zawsze weryfikuj z oryginałem albo drugim silnikiem.

Gdzie pobrać

Model jest publiczny na Hugging Face: huggingface.co/OtoroSI/MiniCPM-OCR-1.0-PL-otoro-si-Q8_0

To modyfikacja modelu OpenBMB na licencji Apache 2.0, nie oficjalne wydanie. Karta modelu zawiera instrukcję dla Ollamy, wszystkie wyniki i ograniczenia. Uruchomisz go na własnym komputerze, bez wysyłania dokumentów do chmury.

FAQ

Czy mogę użyć tego do faktur i umów?

Do czytelnych skanów druku tak, ale zawsze z weryfikacją kwot, dat i nazwisk. Dla prostych, czystych dokumentów szybszy i tańszy w utrzymaniu będzie Tesseract.

Czy potrzebuję mocnej karty graficznej?

Niekoniecznie. Na GPU z 8 GB działa wygodnie (ok. 3 s na akapit), na samym CPU ok. 15 s. Model waży 0,8 GB plus 0,9 GB projektora wizyjnego.

Czy moje dokumenty trafiły do treningu?

Nie. Trening opierał się wyłącznie na danych syntetycznych, a prawdziwych skanów używałem tylko do testów.

Czy to zadziała na rękopisach?

Nie. To jedno z ograniczeń opisanych wyżej.

Chcesz sprawdzić, czy lokalny OCR ma sens w Twojej firmie?

Zanim zainwestujesz w duży model, warto zmierzyć, jak radzą sobie Twoje dokumenty: czy wystarczy Tesseract, czy potrzebujesz modelu rozumiejącego tabele i układ, i gdzie trzeba dodać weryfikację. Przeanalizuję próbkę Twoich skanów i powiem uczciwie, co się opłaca.

Umów darmowy audyt →

Źródła naukowe i branżowe (EN):