Blog JSystems - uwalniamy wiedzę!
Blog JSystems - uwalniamy wiedzę!

Ollama to narzędzie, które pozwala uruchamiać modele językowe (LLM) na własnym komputerze lub serwerze - bez wysyłania danych do chmury. Instalację, API i podstawy opisaliśmy w osobnym tutorialu Ollama. Tutaj zajmiemy się czymś innym: doborem modelu do zadania.
„Model na Ollamie” to nie jeden byt. W bibliotece są setki modeli, a każdy ma inny charakter - jeden świetnie rozmawia, drugi pisze kod, trzeci rozumie obrazy, a jeszcze inny zamienia tekst na wektory do wyszukiwania. Wybranie złego modelu do zadania to zmarnowany czas i pamięć. Pokażemy sześć modeli, które naszym zdaniem najlepiej oddają tę różnorodność - po jednym na typowe zastosowanie.
Zanim przejdziemy do modeli - krótko o mechanice. Ty wysyłasz pytanie (prompt) do Ollamy, ona ładuje wybrany model do pamięci i zwraca odpowiedź. Wszystko dzieje się na Twoim sprzęcie: żadne dane nie opuszczają maszyny. To kluczowa różnica wobec usług w chmurze - i powód, dla którego firmy stawiają modele lokalnie.

Na nasz serwer pobraliśmy sześć modeli. Tak wygląda lista po pobraniu - i od razu widać, jak bardzo różnią się rozmiarem:

Każdy z tych modeli pobraliśmy jedną komendą ollama pull - model ściąga się raz, a potem działa w pełni offline. Tak wyglądało pobieranie na naszym hoście:

ollama pull: manifest, pobranie pliku modelu, weryfikacja sumy kontrolnej i „success". Potem model działa bez internetu.Komplet komend, którymi pobraliśmy całą szóstkę - możesz je skopiować i uruchomić u siebie:
ollama pull llama3.1:8b
ollama pull hf.co/speakleash/Bielik-11B-v2.3-Instruct-GGUF:Q4_K_M
ollama pull qwen2.5-coder:7b
ollama pull llava:7b
ollama pull gemma2:2b
ollama pull bge-m3Najbardziej uniwersalny wybór. Model ogólnego przeznaczenia poradzi sobie z rozmową, streszczaniem, pisaniem e-maili i prostym rozumowaniem. To dobry punkt startowy, jeśli nie masz jednego, wąsko określonego zadania. Poprosiliśmy go o streszczenie reklamacji klienta, ocenę emocji i propozycję odpowiedzi:

Taki model jest „dobry we wszystkim, mistrzem w niczym”. Jeśli zależy Ci na konkretnej specjalizacji - kodzie, polszczyźnie czy obrazach - lepiej sięgnąć po model wyspecjalizowany, o czym za chwilę.
Bielik to rodzina modeli trenowanych przez polską społeczność (SpeakLeash) z myślą o naszym języku. Modele ogólne radzą sobie po polsku coraz lepiej, ale model trenowany na polszczyźnie zwykle naturalniej odmienia, lepiej trzyma kontekst i rzadziej „kaleczy” język. Poprosiliśmy Bielika o wyjaśnienie różnicy między fakturą VAT a proformą:
Faktura VAT i faktura proforma to dwa różne dokumenty, które służą do różnych celów w obrocie handlowym.
Faktura VAT to oficjalny dokument wystawiany przez sprzedawcę po dokonaniu transakcji. Zawiera ona szczegółowe informacje o produktach lub usługach, kwotach netto i brutto oraz naliczonym podatku VAT. Faktura VAT jest wymagana przez prawo i stanowi podstawę do odliczenia VAT przez kupującego.
Faktura proforma natomiast to dokument wystawiany przed dokonaniem transakcji, często na życzenie klienta. Służy on jako oferta cenowa lub potwierdzenie zamówienia i nie ma mocy prawnej w sensie podatkowym.
Oto dwa przykłady sytuacji, kiedy używa się każdej z tych faktur:
1. Faktura VAT:
- Kupujesz nowy komputer w sklepie stacjonarnym. Sprzedawca wystawia Ci fakturę VAT po dokonaniu transakcji, którą możesz wykorzystać do odliczenia podatku VAT, jeśli prowadzisz działalność gospodarczą.
[...]

Jeśli generujesz dużo treści po polsku - opisy, odpowiedzi do klientów, podsumowania dokumentów - rodzimy model bywa wyraźnie lepszym wyborem niż model ogólny tej samej wielkości.
Do programowania istnieją modele trenowane głównie na kodzie. Przy tym samym rozmiarze biją model ogólny: lepiej rozumieją składnię, rzadziej zmyślają nieistniejące funkcje i trzymają się konwencji. Poprosiliśmy taki model o napisanie funkcji walidującej polski NIP (z cyfrą kontrolną). Oto jak wykonał to zlecenie w terminalu:

A oto ta sama funkcja, wyciągnięta z odpowiedzi modelu i gotowa do skopiowania:
def waliduj_nip(nip: str) -> bool:
"""
Funkcja walidująca polski NIP (Numer Identyfikacyjny Podatkowy).
:param nip: Ciąg znaków reprezentujący NIP do walidacji.
:return: True jeśli NIP jest poprawny, False w przeciwnym razie.
"""
# Usuń spacje i myślniki z wejścia
nip = nip.replace(' ', '').replace('-', '')
# Jeśli wynik nie ma dokładnie 10 cyfr (same cyfry) -> zwróć False
if len(nip) != 10 or not nip.isdigit():
return False
# Wagi dla pierwszych 9 cyfr: [6,5,7,2,3,4,5,6,7]
wagi = [6, 5, 7, 2, 3, 4, 5, 6, 7]
# Oblicz sumę
suma = sum(int(nip[i]) * wagi[i] for i in range(9))
# Oblicz kontrolną cyfrę
kontrolna = suma % 11
# Jeśli kontrolna == 10 -> zwróć False (NIP niepoprawny)
if kontrolna == 10:
return False
# Zwróć True wtedy i tylko wtedy, gdy kontrolna == dziesiąta cyfra NIP
return int(nip[9]) == kontrolna
Nie wierzymy modelowi na słowo - uruchomiliśmy tę funkcję na prawdziwych numerach NIP. Liczy cyfrę kontrolną poprawnie: akceptuje poprawny numer, odrzuca błędny:

Część modeli rozumie nie tylko tekst, ale i obraz. Model wizyjny (multimodalny - przyjmuje obraz na wejściu) opisze zdjęcie, odczyta tekst z paragonu czy zrzutu ekranu. Daliśmy mu prawdziwe zdjęcie i poprosiliśmy o opis po polsku. Oto obraz wejściowy:

A tak model opisał to zdjęcie - sam, na podstawie pikseli:
Na tym obrazku widzimy kotka w śniegu. Kotka jest brązowym z wyraźnymi pędzami, a jej oczy są ciemne. Wokół kotki znajduje się śnieg i nieco trudna rzeźba terenu.

Rdzeń opisu jest trafny: model sam rozpoznał kota, śnieg, brązową sierść i ciemne oczy - bez żadnej podpowiedzi tekstowej. Ale polszczyzna mu się sypie: „z wyraźnymi pędzami" czy „trudna rzeźba terenu" to językowe potknięcia mniejszego modelu wizyjnego. To typowe - świetnie nadają się do wstępnej analizy obrazu, ale ich opisy warto traktować jak podpowiedź, nie pewnik.
Nie każde zadanie wymaga dużego modelu. Do klasyfikacji, prostych odpowiedzi czy pracy na słabszym sprzęcie świetnie sprawdza się mały model (rzędu 2 miliardów parametrów). Zmieści się nawet na laptopie bez wydajnej karty graficznej i odpowiada błyskawicznie. Poprosiliśmy go o zaklasyfikowanie wiadomości od klienta do jednej kategorii:

Mały model nie poprowadzi głębokiego rozumowania, ale do prostych, powtarzalnych zadań - segregowania zgłoszeń, tagowania, krótkich odpowiedzi - jest idealny. Działa też tam, gdzie duży model po prostu się nie zmieści.
Ostatni model jest inny niż pozostałe - nie rozmawia. Model embeddingowy zamienia tekst na wektor liczb (embedding - lista liczb opisująca znaczenie tekstu), tak że fragmenty o podobnym sensie mają zbliżone wektory. To podstawa wyszukiwania semantycznego (po znaczeniu, nie po słowach kluczowych) i systemów RAG, czyli odpowiadania na pytania na podstawie własnych dokumentów. Do polskich tekstów wybraliśmy model wielojęzyczny bge-m3 - radzi sobie z polszczyzną wyraźnie lepiej niż popularne modele anglojęzyczne. Zadaliśmy pytanie i kazaliśmy modelowi dopasować najlepszy fragment z bazy wiedzy sklepu:
| Dopasowanie | Dokument z bazy wiedzy |
|---|---|
| 0.670 | Zwrotu można dokonać w ciągu 30 dni od otrzymania przesyłki, bez podania przyczyny. |
| 0.579 | Reklamacje rozpatrujemy do 14 dni; o decyzji informujemy mailowo. |
| 0.470 | Akceptujemy płatności kartą, BLIK oraz przelewem tradycyjnym. |
| 0.464 | Nasz sklep czynny jest od poniedziałku do piątku w godzinach 9-17. |
| 0.459 | Czas dostawy kurierem to zwykle 1-2 dni robocze na terenie kraju. |
Zapytanie: „Jak mogę zwrócić kupiony produkt?” - model porównał je z 5 dokumentami (wektory o 1024 wymiarach) i wskazał najlepiej pasujący.

Ciekawostka z pomiarów: dla pojedynczego, krótkiego zapytania embeddingi liczą się na CPU równie szybko co na GPU (u nas nawet odrobinę szybciej) - narzut przesłania danych na kartę nie zwraca się przy tak małej pracy. Karta zaczyna się opłacać dopiero przy masowym indeksowaniu tysięcy dokumentów naraz.
Zebraliśmy wszystkie modele w jednej tabeli - każdy zmierzony dwa razy: na CPU i na karcie graficznej. Widać dwie zależności. Po pierwsze: im mniejszy model, tym szybciej generuje. Po drugie: karta graficzna (u nas NVIDIA GeForce RTX 3060) przyspiesza generację około 5-8× - im większy model, tym większa różnica. Wyjątkiem są embeddingi, gdzie przy jednym krótkim zapytaniu GPU nie daje przewagi.

A jeśli zaczynasz od zadania (a tak należy robić) - ta ściąga podpowie, w którą stronę patrzeć:

Po zainstalowaniu Ollamy pobranie i uruchomienie modelu to dwie komendy. Na przykład dla małego, szybkiego modelu:
ollama pull gemma2:2b
ollama run gemma2:2bPełną instalację, konfigurację API i integrację z Pythonem opisaliśmy w tutorialu Ollama od zera.
Nie potrzebujesz dedykowanej, mocnej karty - modele policzą się na samym procesorze (CPU), tylko wolniej. Taka karta bardzo jednak pomaga: na NVIDIA GeForce RTX 3060 te same modele generowały 5-8× szybciej niż na CPU (pełne porównanie wyżej). Mniejsze modele (2B) są płynne nawet na słabszym sprzęcie; większe (7-11B) też ruszą, tylko wolniej.
Nie ma jednego najlepszego - jest najlepszy do konkretnego zadania. Do kodu wybierz model do kodu, do polszczyzny Bielika, do obrazów model wizyjny, do wyszukiwania model embeddingowy. Dlatego warto mieć pobranych kilka i przełączać się między nimi.
Tak - w tym tkwi siła rozwiązania lokalnego. Model działa na Twoim sprzęcie, a zapytania i dokumenty nie wychodzą na zewnątrz. To częsty powód, dla którego firmy wybierają modele lokalne zamiast usług w chmurze.
Od kilkuset megabajtów (model embeddingowy) przez około 1,6 GB (mały model 2B) po 5-7 GB (modele 7-8B). Pobierasz je raz; potem działają w pełni offline.
Pokazujemy na szkoleniach, jak z lokalnych i chmurowych modeli złożyć realne rozwiązania - agentów, automatyzacje i wyszukiwanie po własnych dokumentach.
Szkolenie: Tworzenie agentów AI -->
Budujesz wyszukiwanie po dokumentach? Zobacz też szkolenie z budowy systemów RAG.
Komentarze (0)
Brak komentarzy...