Lokalny model do kodowania: test 7 modeli na RTX 3090
Siedem otwartych modeli, jedna karta graficzna i to samo zadanie: zbudować stronę firmową z gotowego tekstu. Każdy model dostał je sześć razy, w dwóch seriach. Zmierzyliśmy prędkość, sprawdziliśmy 42 wyniki w przeglądarce i publikujemy je wszystkie.
Po co lokalny model do kodu
Kod firmy to często jej najcenniejsza własność intelektualna. Do tego dochodzą klucze w plikach konfiguracyjnych, dane testowe z produkcji i logika, której nie chcesz pokazywać na zewnątrz. Asystent programisty w chmurze widzi to wszystko.
Model uruchomiony na własnym serwerze rozwiązuje ten problem tak samo jak przy dokumentach: kod nie wychodzi z firmowej sieci. Zostaje pytanie, czy otwarte modele, które mieszczą się na jednej karcie graficznej, piszą kod nadający się do użycia i jak szybko. Sprawdziliśmy to na konkretnym zadaniu i konkretnym sprzęcie. O doborze sprzętu piszemy w artykule Jaki serwer do lokalnego LLM.
Jak testowaliśmy
Każdy model dostał polecenie „Create a new landing page based on this text”, a pod nim pełny tekst naszej strony firmowej, około 5,6 tysiąca znaków. Bez szablonu i bez wskazówek co do wyglądu. To dobrze oddaje codzienną pracę z asystentem: dużo treści do przeniesienia, kilkanaście sekcji, układ na komputer i telefon, trochę JavaScriptu.
- Sprzęt: jedna karta NVIDIA GeForce RTX 3090 z 24 GB pamięci, limit mocy 350 W.
- Oprogramowanie: Ollama 0.35, wszystkie modele w kwantyzacji Q4_K_M, kontekst 32 768 tokenów, limit odpowiedzi 32 768 tokenów.
- Ustawienia próbkowania: domyślne z pliku Modelfile każdego modelu, czyli zalecane przez wydawcę. Modele z trybem rozumowania miały go włączonego.
- Dwie serie po trzy podejścia na model. Seria 1 z poleceniem jak wyżej. W serii 2 dopisaliśmy jedno zdanie: „Odpowiedz jednym kompletnym plikiem HTML (CSS i JS w środku), bez opisu i bez Markdownu.”
Każdą stronę otworzyliśmy w przeglądarce Edge w oknie komputera (1440 px) i telefonu (około 500 px), przewinęliśmy do końca i sprawdziliśmy automatycznie:
- kompletność: ile z 34 kluczowych fraz tekstu, po jednej z każdego fragmentu, widać na stronie,
- telefon: czy menu da się otworzyć i czy strona nie jest szersza od ekranu,
- kontakt: czy e-mail i telefon są klikalnymi linkami
mailto:itel:, - poprawność: błędy w konsoli, uszkodzone znaczniki, zaślepki typu
alert(), - zależności: czy strona ściąga cokolwiek z zewnętrznych serwerów.
Zrzuty ekranu przejrzeliśmy dodatkowo ręcznie, bo automat potrafi się pomylić. Prędkość podajemy z Ollamy: liczbę wygenerowanych tokenów na sekundę i czas całej odpowiedzi.
Testowane modele
Wszystkie modele mieszczą się w 24 GB pamięci karty. Część z nich to modele MoE (mixture of experts): mają dużo parametrów, ale przy każdym tokenie liczą tylko ich mały fragment, więc generują szybciej.
| Model | Parametry | Licencja | Wynik od twórców* |
|---|---|---|---|
| Qwen3.6-27B | 27 mld (gęsty) | Apache 2.0 | SWE-bench Verified 77,2% |
| Qwen3.6-35B-A3B | 35 mld, 3 mld aktywnych | Apache 2.0 | SWE-bench Verified 73,4% |
| Qwen3.8-27B | 27 mld (gęsty, MTP) | Apache 2.0 | SWE-bench Pro 61,7% |
| GLM-4.7-Flash | 31 mld, 3 mld aktywnych | MIT | SWE-bench Verified 59,2% |
| Devstral Small 2 | 24 mld (gęsty) | Apache 2.0 | SWE-bench Verified 68,0% |
| Gemma 4 26B A4B | 25,2 mld, 3,8 mld aktywnych | Apache 2.0 | LiveCodeBench v6 77,1% |
| Mistral Small 3.2 | 24 mld (gęsty) | Apache 2.0 | HumanEval Plus 92,9% (pass@5) |
* Wyniki deklarowane przez twórców na kartach modeli w Hugging Face. To różne benchmarki, więc nie da się ich porównać wprost. SWE-bench mierzy, ile prawdziwych zgłoszeń z repozytoriów GitHub model naprawi samodzielnie. Mistral Small 3.2 to model ogólny, nie wyspecjalizowany w kodzie. MTP oznacza przewidywanie kilku tokenów naraz, o czym niżej.
Seria 1: kod czy opis?
Pierwsza seria sprawdziła coś, czego nie planowaliśmy: czy model w ogóle zrozumie, że ma napisać kod. Polecenie „stwórz stronę na podstawie tekstu” nie mówi wprost, w jakiej formie oddać wynik.
| Model | Oddał plik HTML | Co oddał zamiast tego |
|---|---|---|
| Qwen3.6-27B | 3 z 3 | |
| Qwen3.6-35B-A3B | 3 z 3 | |
| Qwen3.8-27B | 3 z 3 | |
| GLM-4.7-Flash | 3 z 3 | Za każdym razem z polskim wstępem „Oto kompletny…” przed kodem |
| Devstral Small 2 | 1 z 3 | Dwa razy opis układu strony w Markdownie |
| Gemma 4 26B A4B | 0 z 3 | Projekt strony: koncepcja, sekcje, kolory |
| Mistral Small 3.2 | 0 z 3 | Tekst strony sformatowany w Markdownie |
Devstral, model zaprojektowany do programowania, w dwóch podejściach napisał wprost, że to koncepcja i do wdrożenia potrzebny będzie programista. Gemma za każdym razem oddawała starannie opisany projekt: nazwę koncepcji, paletę kolorów i układ sekcji, ale bez kodu.
W rozmowie z asystentem to drobiazg, bo dopytasz. W automatycznym procesie, gdzie odpowiedź od razu trafia do pliku, model „gadatliwy” albo „projektujący” po prostu nie zadziała. Dlatego w serii 2 dopisaliśmy jedno zdanie o formie odpowiedzi. Wtedy wszystkie siedem modeli oddało kompletny plik HTML w każdym z trzech podejść, bez wstępów.
Seria 2: jakość stron
Druga seria pokazuje, jak modele radzą sobie, kiedy wiedzą, czego od nich chcemy. Liczby w tabeli to wyniki z trzech podejść. Numery w pierwszej kolumnie prowadzą do stron dokładnie w takiej postaci, w jakiej oddał je model. Dodaliśmy tylko znacznik, który wyłącza je z wyszukiwarek.
| Model i strony | Kompletność | Menu na telefonie | Mieści się na telefonie | Klikalny kontakt | Uwagi |
|---|---|---|---|---|---|
| Qwen3.8-27B 1 2 3 | 100% | 1 z 3 | 3 z 3 | 2 z 3 | Pełna treść za każdym razem. Na telefonie menu najczęściej po prostu znika. |
| Qwen3.6-35B-A3B 1 2 3 | 97% | 1 z 3 | 2 z 3 | 1 z 3 | W jednej stronie zaślepka alert(). |
| Qwen3.6-27B 1 2 3 | 96% | 2 z 3 | 3 z 3 | 3 z 3 | Najmniej usterek. Bez zewnętrznych zależności. |
| Mistral Small 3.2 1 2 3 | 96% | 0 z 3 | 2 z 3 | 1 z 3 | Proste strony. Obrazki z niedziałającego serwisu. |
| Devstral Small 2 1 2 3 | 93% | 0 z 3 | 0 z 3 | 3 z 3 | Menu nie mieści się na ekranie telefonu. |
| Gemma 4 26B A4B 1 2 3 | 83% | 0 z 3 | 3 z 3 | 1 z 3 | Uszkodzony kod w każdej stronie. Biblioteki z zewnętrznych CDN. |
| GLM-4.7-Flash 1 2 3 | 77% | 2 z 3 | 2 z 3 | 1 z 3 | Pomija całe fragmenty tekstu. |
Kompletność to średni odsetek kluczowych fraz z tekstu, które widać na stronie. Żadna strona nie miała błędów JavaScriptu, poza odwołaniami do brakujących zasobów. Na komputerze prawie wszystkie wyglądają profesjonalnie. Różnice wychodzą dopiero przy czytaniu treści i na telefonie.
Prędkość na RTX 3090
Prędkość generowania podajemy z serii 1. Wtedy na karcie nie działało nic innego, a wyniki trzech podejść różniły się najwyżej o kilka procent. Liczbę tokenów i czas na stronę bierzemy z serii 2, bo dopiero w niej wszystkie modele pisały kod. Podczas serii 2 na tym samym serwerze działały inne usługi, więc te czasy mogą być zawyżone o kilka procent.
| Model | Typ | Tokeny na sekundę | Tokeny na stronę | Czas na stronę |
|---|---|---|---|---|
| Gemma 4 26B A4B | MoE | 117 | 9 400 | 1 min 32 s |
| GLM-4.7-Flash | MoE | 108 | 10 500 | 1 min 44 s |
| Qwen3.6-35B-A3B | MoE | 96 | 13 200 | 2 min 39 s |
| Qwen3.8-27B | gęsty + MTP | 84 | 12 400 | 2 min 32 s |
| Mistral Small 3.2 | gęsty | 51 | 4 200 | 1 min 33 s |
| Devstral Small 2 | gęsty | 49 | 6 600 | 2 min 26 s |
| Qwen3.6-27B | gęsty | 39 | 11 700 | 5 min 29 s |
Mediany z trzech podejść. Tokeny na stronę obejmują też rozumowanie modelu przed odpowiedzią, dlatego GLM i Gemma, które dużo „myślą”, generują więcej, niż widać w samym pliku.
Trzy rzeczy z tej tabeli warto zapamiętać:
- MoE jest 2 do 3 razy szybsze od modelu gęstego. Przy każdym tokenie karta czyta z pamięci tylko aktywne parametry, czyli 3 do 4 mld zamiast 24 do 27 mld. Na sprzęcie z wolniejszą pamięcią, takim jak NVIDIA DGX Spark, ta różnica ma jeszcze większe znaczenie.
- Qwen3.8-27B jest gęsty, a mimo to ponad 2 razy szybszy od Qwen3.6-27B. Model ma wbudowane przewidywanie kilku tokenów naraz (MTP, multi-token prediction). Ollama zgaduje kilka kolejnych tokenów i sprawdza je w jednym przebiegu. Do tego oddaje krótszą odpowiedź, więc gotowa strona powstaje ponad 2 razy szybciej.
- Liczy się czas na stronę, nie same tokeny na sekundę. Mistral generuje wolno, ale pisze krótko, więc kończy w półtorej minuty. Jego strony są też najprostsze.
Qwen3.6-35B-A3B przy kontekście 32 tys. tokenów nie zmieścił się w całości w 24 GB: około 5% modelu trafiło do pamięci RAM. Mimo to generował 96 tokenów na sekundę.
Błędy, które warto znać
Najważniejsza lekcja z testu: kodu z modelu nie oceniasz po zrzucie ekranu. Na pierwszy rzut oka prawie wszystkie strony wyglądają dobrze. Problemy wychodzą przy czytaniu, klikaniu i na telefonie.
Brak menu na telefonie
To najczęstsza wada. Działające menu miało tylko 6 z 21 stron drugiej serii. Zwykle model chował linki na wąskim ekranie i nie dodawał przycisku, który je pokazuje. Czasem przycisk był, ale nic nie robił. W jednej stronie od Qwen3.6-35B-A3B zamiast funkcji była zaślepka alert(). Jeśli strona ma działać na telefonie, trzeba to napisać w poleceniu.
Uszkodzony kod u Gemmy
We wszystkich trzech stronach Gemmy z drugiej serii w kodzie pojawiły się surowe tokeny bajtowe, na przykład bg-purple-50<0xC2>0/20 w nazwie klasy albo <<0xC2>="feature-icon"> zamiast znacznika <div class="feature-icon">. Taki fragment psuje wygląd albo całą sekcję. W jednej stronie model wpisał nieistniejący adres fonts.googleapislongrightarrow.googleapis.com, więc czcionki się nie wczytały. Nie wiemy, czy to wina samego modelu, kwantyzacji czy Ollamy. Wiemy, że powtarzało się w każdym podejściu.
Tytuł w kolorze tła
Mistral Small 3.2 w pierwszej stronie ustawił kolor nagłówków #2c3e50, czyli dokładnie taki sam jak tło nagłówka strony. Tytuł „AI Transformation” jest w kodzie, ale nie widać go na ekranie. Automat uznał tytuł za obecny, bo jest w kodzie. Błąd wyłapał dopiero człowiek patrzący na zrzut.
Strona szersza od telefonu
Devstral we wszystkich trzech stronach ustawił menu w jednym rzędzie, bez wersji na telefon. Linki wychodzą poza ekran, a cała strona robi się o około 260 px szersza od telefonu i przewija się na boki.
Obrazki z cudzych serwerów
Modele chętnie wstawiają obrazki zastępcze z zewnętrznych serwisów. Mistral w dwóch stronach użył via.placeholder.com, który już nie działa, więc w miejscu obrazków są puste pola i błędy w konsoli. GLM sięgał po losowe zdjęcia z picsum.photos. Wszystkie strony Gemmy ściągają biblioteki albo czcionki z zewnętrznych CDN, a dwie z nich cały Tailwind. Strona działa, ale każda wizyta odpytuje cudze serwery. W firmie, która wybiera lokalne AI z powodu prywatności, to raczej wada.
Pominięta i zmieniona treść
GLM-4.7-Flash pomijał średnio prawie co czwartą kluczową frazę, na przykład całe sekcje „Pełna Elastyczność Wdrożenia” czy „Prompt & Context Engineering”. W jednej stronie zamienił też nazwę firmy w logo na nazwę produktu, CerebrOS. Model nie informuje o takich skrótach. Dowiesz się dopiero, porównując stronę z tekstem.
Który model wybrać
Do pisania kodu na jednej karcie z 24 GB pamięci wygrywa rodzina Qwen. Między wersjami wybierasz według tego, co ważniejsze:
- Qwen3.8-27B to najlepszy kompromis. Pełna treść w każdej stronie i 2,5 minuty na stronę. Jego słabością było menu na telefonie, więc warto o nie poprosić wprost.
- Qwen3.6-27B jest najstaranniejszy: najmniej usterek, wszystkie kontakty klikalne, zero zewnętrznych zależności. Kosztem jest czas: ponad 5 minut na stronę.
- Qwen3.6-35B-A3B jest szybki jak MoE i dobrze przenosi treść, ale zostawia więcej drobnych błędów. To rozsądny wybór na sprzęt z dużą, ale wolniejszą pamięcią.
GLM-4.7-Flash i Gemma 4 są najszybsze, ale pierwszy gubi treść, a druga psuje kod. Devstral Small 2 ma przyzwoity wynik w SWE-bench, a Mistral projektował go pod pracę agentową w repozytorium. W naszym zadaniu poradził sobie dopiero po doprecyzowaniu polecenia i nie zrobił wersji na telefon. To przypomnienie, że jeden benchmark nie mówi wszystkiego. Model najlepiej sprawdzić na własnych zadaniach.
Ograniczenia testu. Jeden typ zadania: strona z gotowego tekstu, bez poprawek i bez pracy na istniejącym kodzie. Trzy podejścia na model w każdej serii, kwantyzacja Q4_K_M i ustawienia domyślne Ollamy. W innej kwantyzacji albo innym serwerze modeli wyniki, zwłaszcza Gemmy, mogą wyglądać inaczej. Nowe wersje modeli wychodzą co kilka miesięcy, więc ranking szybko się starzeje.
Model do kodu nie musi działać osobno. Przez Enterprise AI Gateway programiści korzystają z lokalnego modelu do codziennej pracy na firmowym kodzie, a do trudnych zadań bez poufnych danych możesz dopuścić model chmurowy. Więcej o doborze modeli znajdziesz w przewodniku Lokalne AI w firmie.
Pytania i odpowiedzi
Jaki jest najlepszy lokalny model do programowania na jedną kartę graficzną?
W naszym teście na RTX 3090 najlepiej wypadła rodzina Qwen. Qwen3.8-27B najwierniej przeniósł treść i dzięki przewidywaniu wielu tokenów naraz generował ponad dwa razy szybciej niż Qwen3.6-27B. Qwen3.6-27B dał najrówniejsze wyniki: działające kontakty we wszystkich sześciu stronach, zero zewnętrznych zależności i żadnej strony szerszej od ekranu telefonu.
Ile tokenów na sekundę daje RTX 3090 przy lokalnym modelu do kodu?
Przy kwantyzacji Q4_K_M i Ollamie 0.35 zmierzyliśmy od 38,7 tokena na sekundę dla gęstego Qwen3.6-27B do 117 dla Gemmy 4 26B A4B. Modele MoE, które przy każdym tokenie liczą tylko 3 do 4 mld parametrów, są 2 do 3 razy szybsze od modeli gęstych. Qwen3.8-27B osiąga 84 tokeny na sekundę dzięki przewidywaniu wielu tokenów naraz.
Dlaczego model zamiast kodu oddał opis strony?
Polecenie „stwórz stronę na podstawie tekstu” można zrozumieć jako prośbę o projekt. Gemma 4, Mistral Small 3.2 i w dwóch podejściach Devstral oddały opis w Markdownie, a Devstral dopisał, że do wdrożenia potrzebny jest programista. Po dopisaniu jednego zdania, że odpowiedź ma być jednym plikiem HTML, wszystkie modele oddały kod w każdym podejściu.
Czy kodu z lokalnego modelu można używać bez sprawdzania?
Nie. W 21 stronach z drugiej serii tylko 6 miało działające menu na telefonie. Zdarzały się zaślepki zamiast funkcji, nagłówki w kolorze tła, obrazki z nieistniejących serwisów i uszkodzone znaczniki. Wynik trzeba otworzyć w przeglądarce, także na telefonie, i przeklikać.
Źródła i dane
Dane z testu:
- Wyniki wszystkich 42 podejść (CSV): prędkość, czas, kompletność i wyniki sprawdzeń
- Polecenia: seria 1 i seria 2
- Odpowiedzi z serii 1, w których model nie oddał kodu, publikujemy jako pliki tekstowe, na przykład Gemma 4, podejście 1 i Devstral Small 2, podejście 1. Pełna lista plików jest w CSV.
Karty modeli i benchmarki:
- Qwen3.6-27B, karta modelu (Hugging Face)
- Qwen3.6-35B-A3B, karta modelu (Hugging Face)
- Qwen3.8-27B, karta modelu (Hugging Face)
- GLM-4.7-Flash, karta modelu (Hugging Face)
- Devstral Small 2, karta modelu (Hugging Face)
- Gemma 4 26B A4B, karta modelu (Hugging Face)
- Mistral Small 3.2, karta modelu (Hugging Face)
- Qwen3.6-27B w LLM Stats
- SWE-bench: opis benchmarku i tabele wyników