Jak uruchomić lokalny model AI bez wysyłania danych do chmury
Przejdź do treści i przykładów
Aby korzystać z modelu lokalnie, uruchom Ollama z pobranym modelem i kieruj zapytania do adresu 127.0.0.1. Przy odczycie odpowiedzi w Pythonie dodaj "stream": false: domyślnie API zwraca serię obiektów JSON, a nie jeden dokument. Poniższy przykład sprawdzono na Linuxie z Ollama 0.35.1 i qwen3:0.6b.
Zainstaluj Ollama według dokumentacji dla Linuxa lub strony pobierania dla swojego systemu. Pobierz model poleceniem ollama pull qwen3:0.6b. Opis wariantu znajduje się w bibliotece producenta. Do przykładu Python potrzebna jest biblioteka requests; zainstaluj ją w środowisku wirtualnym:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install requests
Środowisko wirtualne izoluje zależności projektu od systemowego Pythona. Dzięki temu przykład nie zmienia pakietów używanych przez inne programy na Twoim komputerze, a całość można usunąć jednym poleceniem, kasując katalog .venv.
W osobnym terminalu uruchom własną instancję serwera, bez kolizji z domyślną usługą:
OLLAMA_NO_CLOUD=1 OLLAMA_HOST=127.0.0.1:11541 ollama serve
Jeżeli program już działa jako usługa, te zmienne dotyczą tylko nowego procesu. Sprawdź log nowej instancji i adres, do którego wysyła zapytania Twój skrypt. Pobrany model musi być dostępny temu samemu użytkownikowi.
Taki układ ma praktyczną zaletę: osobny port pozwala testować konfigurację bez ruszania usługi, z której korzystasz na co dzień. Gdy przykład przestanie być potrzebny, wystarczy zatrzymać proces w terminalu, a domyślna instalacja pozostanie nietknięta.
import requests
response = requests.post(
"http://127.0.0.1:11541/api/generate",
json={
"model": "qwen3:0.6b",
"prompt": "Odpowiedz tylko liczbą: 17 + 26 + 30 =",
"think": False,
"stream": False,
"options": {"temperature": 0, "num_predict": 64},
},
timeout=180,
)
response.raise_for_status()
data = response.json()
print(data["response"])
Wynik próby z 2 października 2026: 17 + 26 + 30 = 73. Obliczenie jest prawidłowe; wymóg samej liczby nie został spełniony. Wynik sprawdzono na CPU, z około 23,5 GiB RAM. Nie jest to pomiar minimalnych wymagań ani ranking jakości modelu.
Kilka parametrów w tym wywołaniu warto rozumieć, zamiast kopiować je na ślepo. Wartość temperature: 0 ogranicza losowość, co ułatwia porównywanie kolejnych uruchomień. Z kolei num_predict: 64 ogranicza długość odpowiedzi w tokenach, więc skrypt nie będzie generował tekstu bez końca. Wywołanie raise_for_status() zamienia kod błędu HTTP, na przykład przy literówce w nazwie modelu, w wyjątek zamiast cichego odczytu błędnej odpowiedzi.
Po pominięciu stream serwer zwrócił NDJSON: kolejne obiekty oddzielone końcem linii. Wywołanie response.json() zgłosiło JSONDecodeError. Ten sam skrypt z stream: false poprawnie odczytał pojedynczy obiekt. Jeżeli potrzebujesz wyświetlać tekst w trakcie generowania, odczytuj i parsuj kolejne linie strumienia zamiast całej odpowiedzi naraz. Kontrakt opisuje dokumentacja /api/generate.
Darmowy webinar na żywo z Janem Gajosem · w najbliższą środę o 19:00
Czytasz o AI, a w pracy dalej robisz wszystko ręcznie? Znam to.
Sam tak robiłem. Na webinarze pokazuję na swoim ekranie, jak oddać AI powtarzalne zadania: maile, proste automatyzacje, asystenta do pracy. Bez programowania i bez teorii. 90 minut, a na końcu pytasz, o co chcesz.
Link do pokoju przyjdzie mailem. Zapisując się, zgadzasz się na wiadomości e-mail zgodnie z polityką prywatności. Wolisz zacząć od lektury? Zobacz e-booki Jana Gajosa
Strumień jest przydatny w aplikacjach interaktywnych, na przykład w prostym czacie w terminalu, gdzie użytkownik nie chce czekać na całą odpowiedź. Poniższy szkic pokazuje, jak parsować każdą linię osobno. To ilustracja zasady, nie część próby opisanej wyżej, więc przed użyciem sprawdź ją na własnej instancji.
import json
import requests
with requests.post(
"http://127.0.0.1:11541/api/generate",
json={
"model": "qwen3:0.6b",
"prompt": "Wymień trzy zalety lokalnego modelu.",
"think": False,
"stream": True,
},
stream=True,
timeout=180,
) as response:
response.raise_for_status()
for line in response.iter_lines():
if not line:
continue
chunk = json.loads(line)
print(chunk.get("response", ""), end="", flush=True)
if chunk.get("done"):
break
print()
Każda linia to samodzielny obiekt JSON z fragmentem tekstu w polu response. Ostatni obiekt ma pole done ustawione na prawdę. Parametr stream=True w requests jest niezależny od pola o tej samej nazwie w JSON: pierwszy dotyczy sposobu czytania odpowiedzi po stronie klienta, drugi decyduje, jak odpowiada serwer.
Gdy skrypt zgłasza błąd połączenia, zacznij od sprawdzenia, czy serwer w ogóle nasłuchuje na oczekiwanym adresie. Pomaga w tym kilka prostych kroków:
curl http://127.0.0.1:11541/api/tags, aby zobaczyć listę modeli widocznych dla tej instancji,OLLAMA_HOST w terminalu klienta nie wskazuje innego portu niż adres w skrypcie.Jeżeli lista modeli jest pusta, najczęstszą przyczyną jest uruchomienie serwera przez innego użytkownika systemu lub z innym katalogiem na modele. Model pobrany na jednym koncie nie jest wtedy widoczny na drugim.
Wariant qwen3:0.6b wybrano do przykładu, bo szybko się pobiera i działa na zwykłym procesorze. Przy tak małym modelu nie oczekuj jakości zbliżonej do dużych modeli chmurowych, takich jak GPT-5 czy Claude Opus 4.7. To dobry wybór do sprawdzenia, czy cała konfiguracja działa, oraz do prostych, krótkich zadań: klasyfikacji krótkich tekstów, wyciągania pojedynczych pól z notatek czy testowania własnych skryptów integrujących API.
Do poważniejszej pracy, na przykład streszczania
Darmowy webinar na żywo z Janem Gajosem · w najbliższą środę o 19:00
Czytasz o AI, a w pracy dalej robisz wszystko ręcznie? Znam to.
Sam tak robiłem. Na webinarze pokazuję na swoim ekranie, jak oddać AI powtarzalne zadania: maile, proste automatyzacje, asystenta do pracy. Bez programowania i bez teorii. 90 minut, a na końcu pytasz, o co chcesz.
Link do pokoju przyjdzie mailem. Zapisując się, zgadzasz się na wiadomości e-mail zgodnie z polityką prywatności. Wolisz zacząć od lektury? Zobacz e-booki Jana Gajosa