Szybka odpowiedź

Mały model otwarty dotrenowany metodą LoRA wygrywa z dużym modelem sterowanym promptem wtedy, gdy zadanie jest wąskie, powtarzalne i masywne: ta sama klasyfikacja tysiące razy dziennie, stały zestaw klas, odpowiedź w ściśle określonym formacie. Zyskujesz niższe opóźnienie i koszt zapytania, krótszy prompt, stabilny JSON i możliwość uruchomienia modelu na własnym serwerze. Duży model z promptem jest lepszy, gdy masz mało przykładów, definicje klas często się zmieniają albo zadanie wymaga szerokiej wiedzy. Rozstrzyga jeden test: oba warianty na tym samym odłożonym zbiorze danych, którego żaden z nich nie widział.

Przykład, który przejdziemy: klasyfikator zapytań

Weźmy typowe zadanie z działu obsługi klienta. Do skrzynki trafiają wiadomości z formularza, e-maila i czatu. Każdą trzeba przypisać do jednej z ośmiu kategorii (reklamacja, faktura i płatność, zmiana danych, awaria, pytanie o ofertę, rezygnacja, skarga na obsługę, inne) i nadać priorytet. Wynik idzie do systemu zgłoszeń, więc musi być maszynowo czytelny:

{"category": "faktura_i_platnosc", "priority": "normal", "confidence": 0.93}

Wariant A to duży model przez API z promptem, który opisuje kategorie i podaje kilka przykładów. Wariant B to model otwarty klasy 1-8B parametrów, dotrenowany adapterem LoRA na historycznych zgłoszeniach z poprawnymi etykietami. Poniżej przechodzimy przez decyzję i budowę wariantu B krok po kroku.

Kiedy mały model z LoRA wygrywa

Opóźnienie. Generowanie tokenów w modelach językowych ogranicza głównie przepustowość pamięci: przy każdym kolejnym tokenie GPU musi odczytać wagi modelu. Model kilka razy mniejszy odczytuje kilka razy mniej danych na token. Do tego dotrenowany model nie potrzebuje długiego promptu z definicjami klas i przykładami, bo nauczył się ich z danych. Krótszy prompt to krótsze przetwarzanie wejścia przed pierwszym tokenem odpowiedzi.

Koszt zapytania. Przy API płacisz za tokeny wejścia i wyjścia. Prompt z opisem ośmiu kategorii i kilkunastoma przykładami bywa dłuższy niż sama klasyfikowana wiadomość, a płacisz za niego przy każdym zapytaniu. Mały model na własnym GPU ma koszt głównie stały (sprzęt, prąd, utrzymanie), więc opłaca się przy dużym, przewidywalnym wolumenie.

Stabilny format. Model dotrenowany na tysiącach par „wiadomość, poprawny JSON” bardzo rzadko zmienia nazwy pól czy wymyśla nową kategorię. Warto jednak wiedzieć, że stabilność formatu da się wymusić także bez fine-tuningu: vLLM ma structured outputs, które ograniczają dekodowanie do listy wartości (choice), wyrażenia regularnego albo schematu JSON. Fine-tuning poprawia trafność wyboru klasy, a dekodowanie ze schematem gwarantuje poprawną składnię. W produkcji najlepiej używać obu.

Prywatność i kontrola. Treść zgłoszeń często zawiera dane osobowe. Mały model działa na Twoim serwerze albo w Twojej chmurze, więc dane nie wychodzą do zewnętrznego dostawcy. Masz też kontrolę nad wersją: model nie zmieni się bez Twojej decyzji, a wynik z ubiegłego miesiąca da się odtworzyć.

Są też dane z badań. W raporcie LoRA Land (Predibase, 2024) 310 modeli dotrenowanych 4-bitową LoRA na 31 zadaniach wypadło średnio o 34 punkty lepiej niż modele bazowe i o 10 punktów lepiej niż GPT-4. Bucher i Martini (2024) pokazali, że mniejsze dotrenowane modele w klasyfikacji tekstu (sentyment, emocje, stanowiska) konsekwentnie i istotnie wygrywają z dużymi modelami użytymi bez przykładów (zero-shot), w tym GPT-4 i Claude Opus. To wyniki z konkretnych zadań, a nie gwarancja dla Twojego, więc i tak trzeba to zmierzyć na własnych danych.

Kiedy fine-tuning się nie opłaca

Masz kilkadziesiąt przykładów. Le Scao i Rush (2021) policzyli, że w klasyfikacji dobry prompt jest wart średnio setki przykładów treningowych. Przy małej liczbie danych duży model z dobrym promptem zwykle wygra. OpenAI w dokumentacji fine-tuningu pisze wprost: jeśli 50 dobrych przykładów nic nie daje, przemyśl zadanie albo prompt, zanim dołożysz danych.

Zadanie często się zmienia. Jeśli co tydzień dochodzi nowa kategoria albo zmienia się definicja istniejącej, każda zmiana oznacza nowe etykiety, trening i ewaluację. Prompt zmienisz w minutę.

Potrzebna jest szeroka wiedza. Mały model ma mniej wiedzy o świecie. Jeśli do poprawnej klasyfikacji trzeba rozumieć przepisy, specyfikę wielu branż albo rzadkie nazwy produktów, duży model ma przewagę. Wiedzę, która się zmienia, np. aktualny cennik, lepiej podawać w kontekście (RAG) niż wtrenowywać w wagi.

Wolumen jest mały. Przy kilkuset zapytaniach dziennie koszt API jest niski, a własny model oznacza utrzymanie: serwer, monitoring, aktualizacje, ponowny trening. Szerzej o tym rachunku piszemy w artykule budować czy kupić AI.

Porównanie w jednej tabeli

KryteriumDuży model z promptemMały model + LoRA
Startgodziny: prompt i kilka przykładówdni lub tygodnie: etykiety, trening, ewaluacja
Potrzebne danekilka do kilkunastu przykładów w prompciesetki do tysięcy oznaczonych przykładów
Opóźnieniewyższe: duży model i długi promptniższe: mały model i krótki prompt
Koszt zapytaniarośnie liniowo z wolumenem i długością promptugłównie stały koszt GPU, niski koszt krańcowy
Stabilność formatudobra ze schematem, zależna od wersji modelubardzo dobra, wersja pod Twoją kontrolą
Zmiana definicji klasedycja promptunowe etykiety i ponowny trening
Szeroka wiedzadużaograniczona do tego, co ma model bazowy
Dane poza firmątak, chyba że model jest hostowany u Ciebienie, model działa na Twojej infrastrukturze

Krok 1: dane, czyli etykiety, jakość i zbiór testowy

Ile przykładów. OpenAI zaleca start od 50 starannie przygotowanych przykładów i pisze, że poprawę widać zwykle przy 50-100. Autorzy LIMA (2023) dostroili model do zachowania asystenta na 1000 starannie wybranych przykładów. Dla klasyfikatora rozsądniej liczyć per klasa: zacznij od kilkudziesięciu przykładów na każdą kategorię, a potem dokładaj tam, gdzie macierz pomyłek pokazuje błędy. Rzadkie klasy (np. skarga na obsługę) potrzebują celowego dobierania przykładów, bo w losowej próbce będzie ich za mało.

Jakość ważniejsza od liczby. Model nauczy się Twoich niekonsekwencji. Jeśli dwie osoby oznaczają podobne zgłoszenia różnie, model będzie zgadywał. Przed treningiem:

  • spisz definicję każdej klasy z przykładami granicznymi;
  • daj tę samą próbkę dwóm osobom i sprawdź zgodność; tam, gdzie się różnią, popraw definicje;
  • usuń duplikaty i prawie duplikaty (te same szablony maili), bo zawyżają wynik;
  • sprawdź, czy przykłady przypominają to, co model dostanie w produkcji: te same kanały, długości, błędy pisowni.

Odłożony zbiór testowy. Zanim zaczniesz trenować, odłóż 10-20% danych i nie zaglądaj do nich przy strojeniu. Najlepiej odłożyć najnowsze dane (np. ostatni miesiąc), bo tak sprawdzisz, jak model poradzi sobie z przyszłymi zgłoszeniami. Prawie duplikaty muszą trafić w całości po jednej stronie podziału. Osobno wydziel mały zbiór walidacyjny do wyboru hiperparametrów i kalibracji. Dane syntetyczne wygenerowane przez duży model mogą uzupełnić rzadkie klasy w treningu, ale nigdy nie powinny trafiać do zbioru testowego.

Krok 2: punkt odniesienia z dużym modelem

Zanim cokolwiek wytrenujesz, zmierz wariant A na tym samym zbiorze testowym. Napisz najlepszy prompt, na jaki Cię stać, z definicjami klas i przykładami, i włącz dekodowanie ze schematem JSON. To jest poprzeczka. Fine-tuning ma sens tylko wtedy, gdy mały model ją przeskoczy albo zbliży się do niej przy wyraźnie niższym koszcie i opóźnieniu. Bez tego punktu odniesienia nie wiesz, czy trening coś dał.

Krok 3: LoRA, QLoRA czy pełny fine-tuning

LoRA (Hu i in., 2021) zamraża wagi modelu i trenuje tylko małe macierze niskiego rzędu dołożone do wybranych warstw. Autorzy podają, że dla GPT-3 175B zmniejsza to liczbę trenowanych parametrów 10 000 razy, a zapotrzebowanie na pamięć GPU 3 razy, bez dodatkowego opóźnienia przy inferencji po scaleniu wag. QLoRA (Dettmers i in., 2023) idzie dalej: zamrożony model bazowy trzyma w 4 bitach (NF4), co pozwoliło dotrenować model 65B na jednym GPU 48 GB.

Pełny fine-tuningLoRAQLoRA
Co się trenujewszystkie wagiadaptery niskiego rzędu, baza zamrożona w BF16adaptery, baza zamrożona w 4 bitach
Pamięć na wagi i optymalizatorok. 16 bajtów na parametr przy Adamie w mieszanej precyzji (ok. 64 GB dla modelu 4B, bez aktywacji)ok. 2 bajty na parametr bazy plus mały adapter (ok. 8 GB dla 4B)ok. 0,5 bajta na parametr bazy plus adapter (ok. 2-3 GB dla 4B)
Czasnajdłuższy, często wiele GPUkrótki, zwykle jedno GPUpodobny do LoRA, z narzutem na dekwantyzację
Jakość w wąskim zadaniupunkt odniesieniazwykle porównywalna, gdy LoRA obejmuje wszystkie warstwyblisko LoRA
Artefaktpełna kopia modeluadapter o rozmiarze rzędu megabajtów do setek MBadapter

Wartości pamięci to wagi i stan optymalizatora, bez aktywacji, które rosną z długością sekwencji i rozmiarem partii. 16 bajtów na parametr dla Adama w mieszanej precyzji pochodzi z analizy ZeRO (Rajbhandari i in., 2019).

Co mówią nowsze badania o jakości:

  • LoRA na wszystkich warstwach. „LoRA Without Regret” (Thinking Machines, 2025) pokazuje, że LoRA nałożona także na warstwy MLP uczy się z tą samą efektywnością co pełny fine-tuning, dopóki zbiór danych nie przekracza pojemności adaptera. LoRA tylko na warstwach uwagi wypada słabiej, nawet przy tej samej liczbie trenowanych parametrów. W bibliotece PEFT odpowiada temu target_modules="all-linear".
  • Learning rate. Ta sama analiza wskazuje, że optymalny learning rate dla LoRA jest ok. 10 razy wyższy niż dla pełnego fine-tuningu.
  • Mniej nauki, mniej zapominania. Biderman i in. (2024) pokazali, że przy dużych zbiorach nowej wiedzy (kod, matematyka) LoRA wyraźnie ustępuje pełnemu fine-tuningowi, ale lepiej zachowuje dotychczasowe umiejętności modelu.

Wniosek dla klasyfikatora: zadanie jest wąskie, danych jest od setek do kilku tysięcy przykładów, więc LoRA na wszystkich warstwach liniowych to rozsądny domyślny wybór. QLoRA wybierz, gdy model w BF16 nie mieści się w pamięci karty. Pełny fine-tuning rzadko jest tu potrzebny.

Krok 4: ewaluacja, czyli coś więcej niż dokładność

Dokładność i macro-F1. Sama dokładność (accuracy) oszukuje przy niezbalansowanych klasach: jeśli 60% zgłoszeń to pytania o fakturę, model, który zawsze odpowiada „faktura”, ma 60%. Macro-F1 liczy F1 osobno dla każdej klasy i uśrednia, więc słaba rzadka klasa obniża wynik.

Macierz pomyłek. Wiersze to prawdziwe klasy, kolumny to przewidywania. Pokazuje, które pary klas model myli, np. „reklamacja” z „skargą na obsługę”. To najlepsza wskazówka, gdzie poprawić definicje albo dołożyć przykładów. Często okazuje się, że mylą się także ludzie, i wtedy problemem jest taksonomia, nie model.

Kalibracja. Jeśli model zwraca pewność, musi ona coś znaczyć. Guo i in. (2017) pokazali, że nowoczesne sieci neuronowe są często zbyt pewne siebie. Sprawdzasz to wykresem niezawodności: dzielisz odpowiedzi na przedziały pewności i w każdym liczysz odsetek trafień. Wśród odpowiedzi z pewnością ok. 0,8 trafnych powinno być ok. 80%. Pewność możesz odczytać z prawdopodobieństw tokenów (logprobs) dla etykiety klasy, zamiast prosić model o wpisanie liczby. Jeśli kalibracja jest zła, skalowanie temperaturą dobrane na zbiorze walidacyjnym to prosta i skuteczna poprawka.

Próg i ścieżka awaryjna. Dobra kalibracja pozwala ustawić próg: poniżej niego zgłoszenie idzie do człowieka albo do dużego modelu. Na zbiorze testowym policz, jaki odsetek zapytań przejdzie automatycznie i jaka będzie wtedy trafność. To zwykle bardziej przekonuje biznes niż jedna liczba accuracy.

MetrykaCo mówiKiedy zwodzi
Accuracyodsetek trafnych odpowiedziprzy niezbalansowanych klasach
Macro-F1średnia jakość po wszystkich klasachgdy klasy mają bardzo różną wagę biznesową
Macierz pomyłekktóre klasy się myląprzy małym zbiorze testowym liczby są zbyt drobne
Wykres niezawodności, ECEczy pewność odpowiada trafnościprzy kilkudziesięciu przykładach przedziały są zbyt puste

Krok 5: serwowanie adapterów

Po treningu masz dwie drogi. Możesz scalić adapter z modelem bazowym (w PEFT merge_and_unload()) i serwować go jak zwykły model, bez narzutu na adapter. Albo możesz zostawić adaptery osobno i serwować wiele z nich na jednym modelu bazowym.

Druga droga ma sens, gdy klasyfikatorów jest kilka, np. osobny dla każdego działu albo języka. vLLM obsługuje to natywnie:

vllm serve <model-bazowy> \
  --enable-lora \
  --lora-modules routing-pl=/adapters/routing-pl routing-en=/adapters/routing-en \
  --max-loras 4 \
  --max-lora-rank 16

Klient wybiera adapter nazwą w polu model, tak jak wybiera się model w API zgodnym z OpenAI. Zapytania do różnych adapterów i do modelu bazowego trafiają do tej samej partii obliczeń. --max-lora-rank ustaw na najwyższy rank Twoich adapterów, bo wyższa wartość marnuje pamięć. Adaptery można też ładować w locie (/v1/load_lora_adapter po ustawieniu VLLM_ALLOW_RUNTIME_LORA_UPDATING), ale dokumentacja vLLM zaleca to tylko w odizolowanym, zaufanym środowisku.

Skala tego podejścia jest dobrze zbadana. S-LoRA (Sheng i in., 2023) serwuje tysiące adapterów na jednym GPU, trzymając je w pamięci RAM i przenosząc do GPU tylko te potrzebne w danej chwili. W LoRA Land 25 dotrenowanych modeli Mistral-7B działało na jednym A100 80 GB. W pimento robimy to na NVIDIA Blackwell, a jak wygląda nasze podejście do modeli i fine-tuningu, opisujemy na stronie filaru.

Do serwowania klasyfikatora dołóż dekodowanie ze schematem (structured_outputs z listą choice albo schematem JSON). Wtedy nawet rzadki błąd modelu nie zepsuje parsera w systemie zgłoszeń.

Lista kontrolna decyzji

Fine-tuning małego modelu z LoRA ma sens, jeśli odpowiadasz „tak” na większość pytań:

  1. Zadanie jest wąskie i ma stały zestaw wyników (klasy, pola, format).
  2. Wolumen to co najmniej tysiące zapytań dziennie albo opóźnienie ma znaczenie dla użytkownika.
  3. Masz albo możesz zdobyć setki dobrze oznaczonych przykładów, z rzadkimi klasami włącznie.
  4. Definicje klas są stabilne przez miesiące, nie tygodnie.
  5. Dane nie powinny opuszczać Twojej infrastruktury albo chcesz kontrolować wersję modelu.
  6. Masz odłożony zbiór testowy i zmierzony punkt odniesienia z dużym modelem.
  7. Ktoś będzie utrzymywał model: monitoring jakości, ponowny trening przy dryfie danych.

Jeśli odpowiadasz „nie” na pytania 3, 4 albo 6, zacznij od dużego modelu z dobrym promptem i schematem JSON. Zbieraj w tym czasie poprawione etykiety z produkcji, bo to one staną się danymi do fine-tuningu, gdy wolumen urośnie.

Źródła