Ollama context deadline exceeded: jak naprawić błąd
Błąd context deadline exceeded w Ollama oznacza przekroczenie limitu czasu oczekiwania. Sprawdź konfigurację klienta HTTP, parametry keep_alive oraz limity serwera Nginx.
Co faktycznie oznacza błąd "context deadline exceeded"
Błąd Ollama o treści context deadline exceeded to informacja o przekroczeniu limitu czasu. Fragment kodu w języku Go ustalił termin wykonania żądania, model nie zakończył pracy w tym czasie i termin upłynął. Żaden proces nie uległ awarii, a pliki nie są uszkodzone. Zadanie nadal trwało, gdy zegar odliczył czas.
Sformułowanie to pochodzi ze standardowego pakietu context języka Go, co samo w sobie stanowi istotną wskazówkę. Klient napisany w Pythonie, oparty na httpx, zgłasza zamiast tego httpx.ReadTimeout. Przeglądarka wyświetla zwykły błąd sieciowy. Jeśli widzisz dokładnie ten komunikat, oznacza to, że program w języku Go przestał czekać: narzędzie wiersza poleceń Ollama, sam serwer Ollama lub aplikacja w języku Go wywołująca API (application programming interface).
Limit ten może zostać ustawiony na pięciu poziomach. Zawodzą one w różnych punktach i każdy wymaga innego rozwiązania, dlatego kluczowe jest ustalenie, który z nich zadziałał.
- Twój klient HTTP, który nadał żądaniu sztywny limit czasowy.
- Limit czasu ładowania modelu przez serwer Ollama, który aktywuje się, gdy duży model jest odczytywany z dysku po raz pierwszy.
keep_alive, który zwalnia model z pamięci między żądaniami, przez co każde kolejne wywołanie ponownie obciążone jest kosztem ładowania.num_ctxo rozmiarze na tyle dużym, że samo przetwarzanie promptu trwa minuty na maszynie bez akceleracji GPU.- Reverse proxy, takie jak nginx lub Traefik, zrywające połączenie, zanim Ollama zdąży odpowiedzieć.
Przeanalizuj tę listę w podanej kolejności. Każdy poniższy krok eliminuje jedną warstwę, co pozwala uniknąć zgadywania.
Odtworzenie żądania do API w celu wykluczenia proxy
Wykonaj żądanie bezpośrednio na serwerze, kierując je prosto do Ollama, z pominięciem proxy.
time curl -s http://127.0.0.1:11434/api/generate -d '{
"model": "llama3.1:8b",
"prompt": "Why is the sky blue?",
"stream": false
}' | head -c 400curl nie narzuca własnego limitu czasowego dla całego połączenia, a jedynie limit czasu nawiązania połączenia, dlatego to polecenie oczekuje tak długo, jak wymaga tego Ollama. Pozwala to na podział problemu na dwie części. Jeśli otrzymasz odpowiedź w formacie JSON, oznacza to, że Ollama udzieliła odpowiedzi, a limit czasu jest narzucany przez komponent znajdujący się przed nią. Jeśli to wywołanie zawiesza się na kilka minut, opóźnienie występuje wewnątrz Ollama, a proxy jest niewinne.
Teraz wyślij to samo żądanie przez publiczny adres URL i zmierz czas jego trwania.
curl -s -o /dev/null -w '%{http_code} %{time_total}\n' \
-X POST https://llm.example.com/api/generate \
-d '{"model": "llama3.1:8b", "prompt": "hi", "stream": false}'Status 504 wyświetlony po podejrzanie równej liczbie sekund, na przykład 60.0 lub 30.0, oznacza przekroczenie limitu czasu przez proxy. Proxy korzystają z domyślnych, zaokrąglonych wartości. Model nie kończy pracy dokładnie po 60.000 sekundach dwa razy z rzędu. Jeśli bezpośrednie wywołanie zostaje natychmiast odrzucone, zamiast działać powoli, problemem jest nasłuchiwanie, a nie limit czasu; przypadek ten opisuje na jakim adresie Ollama nasłuchuje na porcie 11434.
Monitorowanie dziennika serwera podczas wykonywania żądania
Otwórz drugą sesję i śledź dziennik usługi, a następnie wyślij żądanie ponownie.
journalctl -u ollama --no-pager --follow --pager-endPoprawny zimny start loguje ładowanie modelu, uruchomienie modułu wykonawczego (runner), a następnie obsługę żądania. Nieudane ładowanie wygląda inaczej; poniższy ciąg znaków identyfikuje przekroczenie czasu ładowania serwera:
Error: timed out waiting for llama runner to start - progress 0.00 -Ten komunikat oznacza, że proces modelu nie zakończył uruchamiania w wyznaczonym czasie. Wartość postępu wskazuje na stopień zaawansowania operacji. Wartość 0.00 oznacza, że moduł wykonawczy nie zgłosił żadnych danych przed upływem terminu, co zazwyczaj wskazuje na trwający odczyt pliku lub użycie pamięci swap przez maszynę. Aby uzyskać więcej szczegółów podczas ładowania, zrestartuj usługę z ustawioną zmienną OLLAMA_DEBUG=1 i powtórz operację.
Pomiar, czy opóźnienie wynika z ładowania, czy generowania
Ollama raportuje własne czasy wykonania, więc nie ma potrzeby zgadywania w tym zakresie.
ollama run --verbose llama3.1:8b "Why is the sky blue?"Po udzieleniu odpowiedzi wyświetlane są wartości total duration, load duration, prompt eval count, prompt eval rate, eval count oraz eval rate. Uruchom polecenie dwukrotnie. Przy drugim uruchomieniu wartość load duration powinna spaść niemal do zera, ponieważ model znajduje się już w pamięci. Jeśli wartość ta nie spada, oznacza to, że model jest usuwany z pamięci między uruchomieniami, co odpowiada przypadkowi keep_alive opisanemu poniżej.
Te same liczby są zwracane przez API w końcowym obiekcie JSON jako load_duration, prompt_eval_duration oraz eval_duration. Dokumentacja wskazuje, że wszystkie czasy trwania są zwracane w nanosekundach, więc należy podzielić je przez 10^9, aby uzyskać wynik w sekundach.
curl -s http://127.0.0.1:11434/api/generate -d '{
"model": "llama3.1:8b",
"prompt": "Why is the sky blue?",
"stream": false
}' | python3 -c 'import json,sys; d=json.load(sys.stdin); print({k: round(v/1e9, 2) for k, v in d.items() if k.endswith("_duration")})'Zidentyfikuj największą wartość. Jeśli dominuje load_duration, występuje problem z ładowaniem modelu; przejdź do dwóch kolejnych sekcji. Jeśli dominuje prompt_eval_duration, kosztem jest przetwarzanie promptu; przejdź do sekcji num_ctx. Jeśli dominuje eval_duration, model generuje dane zbyt wolno na danym sprzęcie i żadne ustawienie limitu czasu tego nie zmieni. Skróć wynik za pomocą num_predict lub przejdź na mniejszy model.
Zwiększenie wartości OLLAMA_LOAD_TIMEOUT po sprawdzeniu wersji
Zmienna serwerowa określająca czas oczekiwania na uruchomienie modelu to OLLAMA_LOAD_TIMEOUT. Jej wartość domyślna zmieniała się pomiędzy wydaniami, dlatego należy sprawdzić ją dla konkretnej wersji, zamiast polegać na zewnętrznych artykułach, w tym niniejszym. Najpierw należy wyświetlić wersję.
ollama --versionNastępnie należy otworzyć kod źródłowy dla odpowiedniego tagu, https://github.com/ollama/ollama/blob/<your version>/envconfig/config.go, i wyszukać OLLAMA_LOAD_TIMEOUT. Wartość znajdująca się w tym pliku jest wartością domyślną skompilowaną w pliku binarnym. Własną wartość należy ustawić za pomocą pliku typu drop-in dla systemd.
sudo systemctl edit ollama.serviceZmienne należy dodać w sekcji [Service], co jest metodą zalecaną przez dokumentację Ollama dla systemu Linux:
[Service]
Environment="OLLAMA_LOAD_TIMEOUT=15m"
Environment="OLLAMA_KEEP_ALIVE=-1"sudo systemctl daemon-reload
sudo systemctl restart ollama
systemctl show ollama --property=EnvironmentOstatnie polecenie wyświetla środowisko, które faktycznie otrzymała usługa. Pusty wynik oznacza, że plik drop-in został zapisany poza znacznikami edytora lub w niewłaściwej sekcji, przez co ustawienia nie weszły w życie. Należy mieć świadomość celu tego działania: wydłużenie czasu oczekiwania zapobiega przedwczesnemu przerwaniu procesu przez serwer, ale nie przyspiesza ładowania. Jeśli model nie mieści się w pamięci RAM, system zacznie korzystać ze swapu, ładowanie drastycznie zwolni, a wyższa wartość jedynie odsunie moment wystąpienia błędu w czasie.
Dlaczego pierwsze żądanie po przerwie jest powolne
Ollama zwalnia nieużywany model z pamięci, aby odzyskać zasoby. Ustawienie keep_alive decyduje o momencie tego działania. Dokumentacja Ollama określa wartość domyślną na 5 minut (stan na wrzesień 2026). W rezultacie aplikacja czatowa używana raz na godzinę przeładowuje model przy każdej wiadomości, co powoduje, że każde zapytanie obarczone jest kosztem "zimnego startu". Żądanie, które przekracza limit czasu, to pierwsze zapytanie po okresie bezczynności, co odpowiada wzorcowi opisywanemu przez użytkowników jako losowe problemy.
Sprawdź, co aktualnie znajduje się w pamięci:
ollama ps
curl -s http://127.0.0.1:11434/api/psPusta lista lub krótki czas do wygaśnięcia potwierdzają ten stan. Parametr keep_alive przyjmuje ciąg określający czas, taki jak "10m" lub "24h", liczbę sekund, 0 dla natychmiastowego zwolnienia pamięci lub liczbę ujemną, aby utrzymać model w pamięci na stałe. Ustawienie można zdefiniować dla pojedynczego żądania lub poprzez zmienną OLLAMA_KEEP_ALIVE w usłudze dla wszystkich zapytań.
curl -s http://127.0.0.1:11434/api/generate -d '{
"model": "llama3.1:8b",
"keep_alive": -1
}'Żądanie zawierające nazwę modelu bez promptu ładuje model i kończy działanie. Jest to udokumentowany sposób na rozgrzanie serwera po restarcie. Warto umieścić go w niewielkiej jednostce systemd, aby wyeliminować oczekiwanie na zimny start. Koszt jest przewidywalny: przypięty model zajmuje pamięć na stałe, więc na małym serwerze można przypiąć jeden model, a nie cztery. Utrzymywanie modelu w pamięci między żądaniami zawiera obliczenia dotyczące pamięci oraz opis jednostki rozgrzewającej.
Dlaczego duża wartość num_ctx powoduje przekroczenie limitu czasu przed wygenerowaniem pierwszego tokena
Zanim model rozpocznie generowanie tekstu, musi odczytać cały prompt. Ten etap to prefill i to właśnie go mierzy prompt eval. Parametr num_ctx określa długość kontekstu, co wykonuje dwie operacje jednocześnie. Ogranicza liczbę tokenów, które model może uwzględnić, oraz ustala rozmiar pamięci podręcznej KV (key value cache), którą serwer rezerwuje z wyprzedzeniem. Oba te czynniki zwiększają nakład pracy.
Na serwerze działającym wyłącznie na CPU proces prefill jest powolny, a jego czas trwania rośnie liniowo wraz z liczbą tokenów w prompcie. Długi dokument wklejony do czatu może wymagać minut przetwarzania prefill, podczas gdy klient nie otrzymuje żadnych danych, ponieważ strumieniowanie jeszcze się nie rozpoczęło. Klient osiąga swój limit czasu i zgłasza błąd przekroczenia limitu kontekstu, mimo że serwer przez cały ten czas pracował. Można to zweryfikować za pomocą liczb z poprzedniej sekcji: należy uruchomić ten sam prompt z użyciem "options": {"num_ctx": 2048}, a następnie 32768 i porównać wyniki prompt_eval_duration.
Wartość domyślna serwera pochodzi z OLLAMA_CONTEXT_LENGTH, a parametr num_ctx w obiekcie options nadpisuje ją dla pojedynczego żądania. Częstym błędem jest zwiększanie tej wartości do maksimum deklarowanego przez model tylko dlatego, że takie maksimum istnieje. Alokacja pamięci podręcznej KV może spowodować, że model przekroczy dostępną pamięć RAM, co zmieni poprawnie działającą konfigurację w taką, która korzysta ze stronicowania pamięci (swapping). Szczegóły dotyczące doboru rozmiaru znajdują się w Dobieranie num_ctx do rzeczywistej pamięci.
Dlaczego nginx zwraca błąd 504 Gateway Time-out
Dokumentacja nginx definiuje proxy_read_timeout z wartością domyślną 60s, a dziennik błędów wprost wskazuje przyczynę niepowodzenia:
upstream timed out (110: Connection timed out) while reading response header from upstreamIstotny szczegół zawarty w dokumentacji nginx brzmi: limit czasu „jest ustawiany tylko pomiędzy dwiema kolejnymi operacjami odczytu, a nie dla transmisji całej odpowiedzi”. Odpowiedź strumieniowa resetuje licznik przy każdym fragmencie danych, dlatego czaty strumieniowe działają poprawnie. Żądanie z parametrem "stream": false nie wysyła żadnych danych do momentu zakończenia generowania odpowiedzi, więc cały proces musi zmieścić się w tym jednym oknie czasowym. Z tego powodu ten sam model działa w oknie czatu, a kończy się błędem przy wywołaniu ze skryptu.
location / {
proxy_pass http://127.0.0.1:11434;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
proxy_buffering off;
}sudo nginx -t && sudo systemctl reload nginxParametr proxy_buffering off ma znaczenie dla strumieniowania. Przy włączonym buforowaniu nginx może gromadzić odpowiedź i przekazać ją dopiero po zakończeniu, przez co tokeny przestają pojawiać się pojedynczo, a działający strumień sprawia wrażenie zawieszonego.
Traefik stosuje analogiczną kontrolę w obiekcie ServersTransport, z którego korzysta router.
http:
serversTransports:
ollama:
forwardingTimeouts:
dialTimeout: "30s"
responseHeaderTimeout: "0s"
idleConnTimeout: "60s"Parametr responseHeaderTimeout określa czas oczekiwania na nagłówki odpowiedzi po wysłaniu żądania, a wartość zero oznacza brak limitu czasu. Usługa musi odwoływać się do transportu za pomocą nazwy przy użyciu serversTransport: ollama; w przeciwnym razie edytowana konfiguracja nie będzie używana przez żaden element systemu.
Mniejsza kwantyzacja przyspiesza ładowanie ze względu na mniejszą ilość danych do odczytu
Kwantyzacja określa precyzję, z jaką przechowywane są wagi modelu. Niższa precyzja oznacza mniejszy plik, a proces ładowania modelu polega głównie na odczycie tego pliku z dysku do pamięci operacyjnej.
The data behind this chart
[
{
"label": "q4_K_M",
"download_size_gb": 4.9
},
{
"label": "q8_0",
"download_size_gb": 8.5
},
{
"label": "fp16",
"download_size_gb": 16
}
]Podane wartości to rozmiary opublikowane na stronie modelu, a nie pomiary z serwera testowego. Domyślna wersja 8B zajmuje 4.9 GB. Wersja tego samego modelu o pełnej precyzji zajmuje 16 GB, co oznacza ponad trzykrotnie większą liczbę bajtów do odczytania oraz ponad trzykrotnie większe zapotrzebowanie na pamięć. Na wynajmowanym serwerze ze współdzieloną pamięcią masową ta różnica decyduje o tym, czy ładowanie zakończy się powodzeniem, czy przekroczy limit czasu. Ustalenie, który model mieści się w pamięci RAM to weryfikacja, którą należy przeprowadzić przed pobraniem jakichkolwiek dużych plików.
Co zmienić na wynajętym serwerze
Wprowadzaj te zmiany w kolejności wskazanej przez pomiary, jedną po drugiej, i po każdej z nich ponownie uruchamiaj polecenie pomiarowe.
- Przypnij model za pomocą
OLLAMA_KEEP_ALIVE=-1lub rozgrzej go podczas startu systemu, aby żadne żądanie użytkownika nie obciążało procesu ładowania. - Zmniejsz
num_ctxdo wartości faktycznie wymaganej przez Twoje prompty; skróci to fazę prefill i zwolni pamięć zajmowaną przez KV cache. - Wybierz mniejszą kwantyzację, aby podczas ładowania odczytywać mniej bajtów i pozostawić miejsce na cache.
- Zwiększ
proxy_read_timeoutw Nginx lubresponseHeaderTimeoutw Traefik i wyłącz buforowanie, aby strumieniowane tokeny docierały bezpośrednio do klienta. - Zwiększ limit czasu (timeout) w swoim kliencie, ponieważ program w Go lub Pythonie z limitem 30 sekund zakończy się błędem przy każdym modelu, który "myśli" dłużej.
Za wszystkimi tymi przyczynami kryje się jeszcze jedna. Ollama obsługuje ograniczoną liczbę żądań jednocześnie, a pozostałe ustawia w kolejce. W efekcie drugi użytkownik może czekać w kolejce tak długo, aż upłynie jego własny limit czasu, mimo że sam model wcale nie działa wolno. Dziennik serwera wykaże, że żądanie zostało obsłużone z opóźnieniem, a nie że wystąpił błąd. Co się dzieje, gdy kilka osób korzysta z jednego serwera Ollama omawia ustawienia równoległości, a podstawowa instalacja na VPS opisuje konfigurację usługi, na której opierają się te zmiany.
FAQ
Co oznacza komunikat "context deadline exceeded" w Ollama?
Oznacza to, że limit czasu dla żądania upłynął, zanim model udzielił odpowiedzi. Fraza ta pochodzi z pakietu context języka Go, więc została wygenerowana przez program napisany w tym języku: narzędzie wiersza poleceń Ollama, serwer Ollama lub aplikację korzystającą z API. Jest to przekroczenie czasu oczekiwania (timeout), co nie oznacza uszkodzenia danych ani awarii systemu. Kolejnym krokiem jest ustalenie, która warstwa narzuciła ten limit, ponieważ klient, proces ładowania modelu, keep_alive, num_ctx oraz reverse proxy posiadają własne ustawienia limitów.
Czy należy zwiększyć limit czasu klienta, czy limit czasu Ollama?
Najpierw wykonaj pomiary. Wyślij żądanie za pomocą curl bezpośrednio na serwerze, kierując je do http://127.0.0.1:11434, ponieważ curl nie narzuca żadnego ogólnego limitu czasowego. Jeśli to wywołanie zwróci odpowiedź w formacie JSON, oznacza to, że Ollama działa poprawnie, a limit czasu został przekroczony przez klienta lub proxy – w takim przypadku należy zwiększyć limit w tych komponentach. Jeśli to wywołanie również zawiesza się, opóźnienie występuje wewnątrz Ollama, a pola load_duration oraz prompt_eval_duration w odpowiedzi wskażą, czy model jest w trakcie ładowania, czy przetwarzania promptu.
Dlaczego pierwsze żądanie kończy się błędem, a kolejne działają?
Ollama zwalnia nieaktywny model z pamięci zgodnie z harmonogramem określonym przez keep_alive. Dokumentowana wartość domyślna to 5 minut (stan na wrzesień 2026). Pierwsze żądanie po okresie bezczynności powoduje ponowne załadowanie modelu z dysku i wiąże się z pełnym czasem "zimnego startu", podczas gdy żądanie wysłane zaraz po nim zastaje model w pamięci i zwraca odpowiedź szybko. Uruchom ollama ps, aby sprawdzić, co jest załadowane i kiedy wygasa. Ustaw OLLAMA_KEEP_ALIVE=-1, aby utrzymać model w pamięci, akceptując fakt, że zajmuje on zasoby RAM.
Dlaczego błąd występuje tylko przy korzystaniu z nginx?
Dokumentacja nginx definiuje proxy_read_timeout z wartością domyślną 60s; limit ten dotyczy czasu między dwoma kolejnymi odczytami, a nie całego czasu odpowiedzi. Odpowiedź strumieniowa resetuje ten licznik przy każdym fragmencie danych, podczas gdy żądanie wysłane z "stream": false musi zakończyć się w ramach jednego okna czasowego. Dlatego okno czatu działa, a skrypt kończy się błędem. Wyszukaj upstream timed out (110: Connection timed out) while reading response header from upstream w dzienniku błędów nginx, a następnie zwiększ proxy_read_timeout i ustaw proxy_buffering off.
Czy zwiększenie OLLAMA_LOAD_TIMEOUT przyspiesza ładowanie?
Nie. Zmienia to jedynie czas, przez jaki serwer oczekuje, zanim przerwie operację i zarejestruje timed out waiting for llama runner to start. Jeśli model nie mieści się w pamięci, maszyna korzysta ze swapu, ładowanie drastycznie zwalnia, a zwiększenie limitu jedynie przesuwa moment wystąpienia błędu, nie rozwiązując przyczyny. Sprawdź wartość domyślną dla swojej kompilacji, uruchamiając ollama --version i czytając envconfig/config.go dla danej wersji; jeśli ładowanie trwa minuty, należy rozważyć użycie modelu o mniejszej kwantyzacji.