Jezična borba s velikim jezičnim modelima: kako spriječiti da LLM piše srpski umjesto hrvatskog
Kad prvi put pošaljete prompt velikom jezičnom modelu i dobijete odgovor na srpskom, shvatite da ste upravo dotakli jedan od najpodcijenjenijih problema u implementaciji generativne umjetne inteligencije za male jezike. To nije greška u kodu, već strukturalni problem s kojim se suočava svaki inženjer koji pokušava prisiliti model da proizvodi tekst na jeziku koji nije engleski, njemački ili francuski. LLM-ovi su trenirani na gigantskim korpusima gdje srpski, kao južnoslavenski jezik s većom zastupljenošću na internetu, dominira nad hrvatskim u omjeru koji se kreće negdje između tri prema jedan i pet prema jedan. Kad model ne dobije eksplicitne instrukcije, njegova statistička priroda ga gura prema onome što je češće vidio. Rezultat je tekst koji zvuči kao da ga je pisao netko tko je odrastao u Beogradu, a ne u Zagrebu. Ovdje počinje inženjerski problem koji nema veze s lingvistikom, već s arhitekturom sustava.
Prva linija obrane je output filter. Ne mislim na softverski dodatak koji će povremeno ispraviti pokoju riječ, već na sustav koji se izvršava nakon svakog generiranog tokena i prije nego što tekst uopće napusti memoriju. Mi smo implementirali set od osamdesetak pattern replace pravila koja se primjenjuju sekvencijalno. Svako pravilo cilja specifičnu zamjenu: registriran umjesto registrovan, općina umjesto opština, nijednom umjesto nijem. Zvuči jednostavno, ali ključ je u redoslijedu i hijerarhiji. Ako pravilo za nijem pokreneš prije pravila za nijedan, dobit ćeš nijemput umjesto nijednomput. Zato smo definirali dependency graph među pravilima, gdje svako pravilo ima svoj priority score. Ona s višim prioritetom se izvršavaju prva i mogu generirati nove uzorke za niža pravila. To je iterativni proces koji se ponavlja dok se ne postigne stabilno stanje bez novih zamjena.
Output filter, međutim, ima fundamentalno ograničenje. On ne može ispraviti stvari koje nisu pokrivene patternima. Ako model generira cijelu rečenicu na srpskom koja ne sadrži ni jednu od osamdeset ciljanih riječi, filter će je propustiti. Zato smo uveli schema-level BEFORE INSERT trigger na bazi podataka. Svaki generirani tekst koji se sprema u produkcijsku bazu prolazi kroz dodatnu provjeru prije nego što se insertira. Trigger analizira cijeli tekst na prisutnost ćiriličnih znakova i CJK (kineski, japanski, korejski) karaktera. Ako ih detektira, cijeli tekst se odbacuje i generira se novi prompt. Ovo zvuči agresivno, ali u praksi se događa u manje od jedan posto slučajeva. Bitnije je da trigger provjerava i konzistentnost jezičnog uzorka kroz cijeli dokument. Koristimo statistički model koji uspoređuje frekvenciju specifičnih hrvatskih i srpskih konstrukcija. Ako omjer padne ispod definiranog praga, tekst se vraća na ponovnu generaciju s dodatnim jezičnim uputama.
Zašto generic LLM-ovi failaju za male jezike? Zato što su trenirani na podacima gdje mali jezici čine zanemariv postotak. Kad model ima tristo milijardi parametara i beskončno mnogo tokena, on optimizira za najčešće obrasce. Hrvatski jezik, s otprilike pet milijuna govornika i relativno malom digitalnom prisutnošću, jednostavno nema dovoljno signala da bi model razvio stabilne jezične reprezentacije. To nije zlonamjerno, već je posljedica zakona velikih brojeva. Kad model vidi riječ opština u tisuću konteksta i riječ općina u samo dvjesto, njegova internalna distribucija će favorizirati prvu. Problem postaje još izraženiji kad model generira tekst od više paragrafa, jer se greške akumuliraju i multipliciraju kroz autoregresivni proces. Jedna pogrešna riječ u prvom paragrafu može pokrenuti lančanu reakciju koja cijeli tekst odvuče u krivom jezičnom smjeru.
Arhitektura koju smo izgradili za forsing kvalitete počinje s prompt engineeringom koji nije puko dodavanje instrukcije piši na hrvatskom. To je najčešća greška koju vidim u industriji. Prompt mora sadržavati eksplicitne primjere hrvatskog teksta koji su relevantni za domenu. Ako generiraš pravni dokument, prompt treba sadržavati tri do pet primjera stvarnih hrvatskih zakonskih članaka. Ako generiraš tehnički članak, prompt treba sadržavati primjere iz hrvatskih tehničkih publikacija. Ključ je u domeni. Generic hrvatski primjeri iz novina neće pomoći kad model treba generirati tekst o mrežnoj infrastrukturi. Mi smo definirali desetak domain-specific templatea, svaki sa setom od pet do deset primjera koji pokrivaju specifične jezične obrasce. Uz to, svaki prompt sadrži i negativne primjere, odnosno tekstove na srpskom koje model ne smije oponašati. To je tehnika koja se zove contrastive learning u kontekstu prompta i značajno poboljšava konzistentnost.
Gradimo ovo svaki dan. Ako tvoja institucija troši mjesece na taj problem — razgovaraj s nama.
Output filter mora biti pametan, a ne samo mehanički. Pattern replace pravila su korisna, ali ne rješavaju problem fleksibilnosti jezika. Hrvatski i srpski dijele velik dio vokabulara, ali se razlikuju u sufiksima, prefiksima i sintaktičkim konstrukcijama. Na primjer, srpski koristi konstrukciju treba da uradiš dok hrvatski preferira trebaš napraviti. Razlika je suptilna, ali konzistentna. Zato smo implementirali drugi sloj filtera koji koristi lightweight NLP model treniran na paralelnim korpusima hrvatskog i srpskog. Taj model analizira svaku rečenicu i označava je kao hrvatsku, srpsku ili mješovitu. Ako je oznaka mješovita, filter pokreće dodatnu provjeru i eventualno zamjenu cijele rečenice. Ovaj pristup je skuplji u smislu latencije, ali je jedini način da se uhvate greške koje nisu na razini pojedinačnih riječi. U produkciji smo izmjerili prosječno povećanje latencije od 150 milisekundi po generiranom tekstu, što je prihvatljivo za većinu use caseova.
Schema-level BEFORE INSERT trigger je posljednja linija obrane i ona mora biti nepropusna. Ne možemo dopustiti da ijedan tekst koji nije konzistentno hrvatski uđe u produkcijsku bazu. Trigger radi na principu tri nezavisne provjere. Prva provjera je leksička, koristi rječnik od 50 tisuća najčešćih hrvatskih riječi i provjerava pokrivenost teksta. Druga provjera je sintaktička, koristi parser koji detektira specifične hrvatske gramatičke konstrukcije poput aorista i imperfekta. Treća provjera je statistička, uspoređuje distribuciju n-grama s referentnim korpusom hrvatskog jezika. Tekst mora proći sve tri provjere da bi bio prihvaćen. Ako padne na bilo kojoj, trigger pokreće automatsku ponovnu generaciju s dodatnim jezičnim instrukcijama koje su specifične za ono što je palo. Ovo je iterativni proces koji se ponavlja maksimalno tri puta prije nego što se generira error i obavijesti inženjerski tim.
Implementacija ovakvog sustava zahtijeva razumijevanje da jezična čistoća nije luksuz, već funkcionalni zahtjev. Kad korisnik dobije tekst na srpskom, on gubi povjerenje u sustav. To nije pitanje estetike, već pouzdanosti. U reguliranim industrijama poput prava, financija ili zdravstva, jezična greška može imati ozbiljne posljedice. Zato smo output filter i schema trigger implementirali kao dva nezavisna sustava koji se međusobno nadopunjuju. Filter radi na razini tokena i rečenica, trigger na razini cijelog dokumenta. Kombinacija daje redundantnost koja je ključna za produkcijske sustave. Mjerimo stopu prolaznosti kroz oba sloja. Trenutno je na 97,3 posto, što znači da manje od tri posto generiranih tekstova zahtijeva ponovnu generaciju. To je prihvatljivo za većinu use caseova, ali radimo na smanjenju tog postotka.
Cijeli pristup je evoluirao iz frustracije s generičkim rješenjima. Kad smo prvi put implementirali jednostavan filter s desetak pravila, mislili smo da je problem riješen. Nakon tjedan dana produkcije, otkrili smo da model i dalje generira tekstove koji su na 80 posto hrvatski i 20 posto srpski. Problem nije bio u pojedinačnim riječima, već u sintaksi i frazeologiji. Model je koristio srpske konstrukcije poput u vezi sa umjesto u vezi s ili s obzirom na to da umjesto s s obzirom na to da. Ove razlike su suptilne, ali konzistentne i štetne za percepciju kvalitete. Zato smo proširili filter na osamdesetak pravila i dodali NLP sloj. Danas je sustav robustan, ali ne i savršen. Svaki mjesec dodajemo nova pravila na temelju analize grešaka iz produkcije. To je kontinuirani proces koji nikad neće završiti jer se jezik mijenja, a modeli se ažuriraju.
Ono što me najviše iznenađuje je koliko malo timova u industriji ozbiljno shvaća ovaj problem. Čujem priče o implementacijama gdje su zadovoljni s 70 posto točnosti jer je to dovoljno dobro za prototip. U produkciji, 70 posto znači da svaki treći tekst treba ručnu korekciju. To nije skalabilno. Ako imate tisuću generiranih tekstova dnevno, to je tristo tekstova koji zahtijevaju ljudsku intervenciju. Trošak je ogroman, a korisničko iskustvo je loše. Zato smo uložili vrijeme u izgradnju sustava koji je dizajniran za produkciju od prvog d
Ovo gradimo svaki dan na RiNET-u.
Ako tvoja institucija, banka, osiguranje ili infrastrukturna firma rješava taj tip problema — zakaži razgovor. Pokazat ćemo ti arhitekturu, ne marketing.
Zanima vas ovakva AI tehnologija?
RiNET gradi sovereign AI rjesenja za javni sektor i poduzeca - od civic intelligence do automatizacije nabave.
Kontaktirajte nas →
Komentari