Mulla on omalla koneella pyörivä kielimalli, jota käytän Open WebUI:n kautta vähän kaikkeen: kirjoittamiseen, tiedonhakuun, suunnitteluun ja välillä myös koodiin. Nykyinen malli on 27 miljardin parametrin Qwen3.6-versio. Se toimii yleismallina yllättävän hyvin, mutta koodauksessa alkoi tulla raja vastaan.
Annoin sille tehtäväksi rakentaa yhden tiedoston Python-sovelluksen DJ-varausten hallintaan. Ei mitään järjettömän monimutkaista. SQLite-tietokanta, lomakkeet, varausten luonti ja muokkaus, hakutoiminto, validointi ja hinnat kokonaisina sentteinä.
Ensimmäinen vastaus katkesi kesken ja sisälsi sisennysvirheen. Nostin mallin vastausrajaa ja annoin uuden yrityksen. Toinen versio oli pidempi, mutta edelleen rikki. Siinä oli syntaksivirhe, puuttuvia metodeja, poistaminen GET-pyynnöllä ja hinta tallennettiin liukulukuna.
Pyysin mallia auditoimaan oman koodinsa. Se löysi osan virheistä, mutta ei huomannut näkyvää syntaksivirhettä eikä puuttuvia metodeja. Pahempaa oli se, että malli alkoi kuvailla sellaisten metodien toimintaa, joita annetussa koodissa ei ollut lainkaan.
Siinä kohtaa päätin lopettaa promptin viilaamisen ja testata, auttaisiko oikea coder-malli.
Testikoneessa on RTX 4070 Ti Super, jossa on 16 gigatavua videomuistia. Tavallista muistia on 32 gigatavua. Se rajaa vaihtoehtoja aika tehokkaasti: valtavat huippumallit eivät mahdu järkevästi, vaikka ne olisi kvantisoitu.
Vertailuun päätyivät nykyinen Qwen3.6 Balanced, Qwen2.5-Coder 14B, Qwen3.6 NEO-CODE, Qwen3-Coder 30B-A3B ja Devstral Small 2 24B.
Rakensin niille viisi testiä. Ensimmäisessä käsiteltiin suomalaisia hintoja täsmällisesti sentteinä. Toisessa validoitiin varaustietoja. Kolmas oli rajattu bugikorjaus. Neljännessä auditoitiin tarkoituksella rikkinäistä lähdekoodia. Viimeisessä piti rakentaa kokonainen HTTP- ja SQLite-pohjainen DJ-varausohjelma.
Mallien tuottama Python ei saanut vain näyttää uskottavalta. Tallensin vastaukset tiedostoiksi, ajoin syntaksitarkistuksen ja suoritin piilotetut testit Bubblewrap-hiekkalaatikossa. Kokonainen sovellus myös käynnistettiin ja sen reittejä testattiin oikeilla HTTP-pyynnöillä.
Ensimmäisen ajon jälkeen nykyinen yleismallini näytti voittajalta 86,53 pisteellä. Qwen3-Coder jäi 78,20 pisteeseen. Tulos näytti selkeältä, mutta siinä oli jotain outoa. Osa sovelluksista oli saanut hyvät pisteet, vaikka ne eivät todellisuudessa toimineet.
Vika löytyi omasta testiharnessistani.
Jos sovellustesti kaatui kesken, saavuttamattomat testit putosivat pois pistelaskun nimittäjästä. Rikkinäinen sovellus saattoi siis saada suhteettoman hyvän tuloksen vain siksi, ettei kaikkia sen virheitä ehditty testata. Lisäksi testi oletti yhden tietokantasarakkeen nimen, jota en ollut määrännyt promptissa.
Korjasin pisteytyksen niin, että saavuttamaton testi on epäonnistunut testi. Määrittelin myös lomakekentät, statusarvot ja suomalaisen hintamuodon yksiselitteisesti. Sen jälkeen ajoin kaikki viisi mallia uudelleen alusta asti.
Tämä oli ehkä koko kokeen opettavaisin kohta. Jos arviointijärjestelmä on rikki, tarkka pisteluku ei tee tuloksesta yhtään luotettavampaa. Benchmark voi näyttää tieteelliseltä ja silti valehdella.
Korjatussa testissä Qwen3-Coder 30B-A3B nousi ykköseksi tuloksella 69,78/100. Qwen3.6 NEO-CODE sai 68,95, Devstral Small 2 sai 63,27, nykyinen Balanced-malli 56,45 ja Qwen2.5-Coder 51,11 pistettä.
Qwen3-Coder oli samalla ylivoimaisesti nopein. Se tuotti keskimäärin noin 152 tokenia sekunnissa. Muut suuret mallit jäivät noin 39–44 tokeniin sekunnissa.
Nopeusero tulee mallin MoE-rakenteesta. Mallissa on yhteensä noin 30 miljardia parametria, mutta jokaista tokenia kohti niistä aktivoituu vain reilut kolme miljardia. Kaikki painot pitää silti saada muistiin, mutta laskentaa tarvitaan vähemmän.
Qwen3-Coder sai täydet pisteet varausvalidoinnista ja bugikorjauksesta. Auditointi onnistui myös hyvin. Hintojen käsittelyssä se teki silti yllättävän typeriä virheitä: negatiivinen arvo pääsi läpi ja yksi regex meni rikki oman merkkijonokäsittelyn takia.
Testi kertoo ennen kaikkea siitä, miten nämä mallit toimivat mun koneella ja mun tehtävissä. Se ei todista, että Qwen3-Coder olisi aina paras paikallinen koodausmalli.
Mallit olivat eri kokoisia ja eri tavoin kvantisoituja, jotta ne mahtuivat 16 gigatavun videomuistiin. Qwen2.5-Coder oli laadukkaana Q6-versiona, kun taas 30 miljardin Qwen3-Coder ajettiin selvästi tiukempana Q3-versiona. Jokaisesta tehtävästä otettiin myös vain yksi vastaus. Jo nykyinen Balanced-malli näytti kahdella ajokerralla, kuinka paljon tulos voi vaihdella: ensimmäisellä kierroksella se hoiti hintatehtävän täydellisesti, toisella se unohti kokonaisen pyydetyn funktion.
Testisarjakin painottaa asioita, joita itse tarvitsen. Mukana oli suomalaista hintamuotoa, Pythonia, SQLitea, HTTP-reittejä ja virheiden käsittelyä. Joku toinen voisi testata TypeScript-repoa, Reactia tai Rustia ja saada eri järjestyksen.
Silti tuloksesta saa käyttökelpoisen suunnan. Qwen3-Coder oli vahva pienissä tehtävissä, nopea ja mahtui koneelle. Siksi se ansaitsi jatkopaikan, vaikka yksittäinen pisteluku ei ole mikään lopullinen totuus.
Tää oli testin karuin tulos.
Qwen3-Coderin pitkä sovellus kääntyi, mutta ei käynnistynyt onnistuneesti. NEO-CODE teki f-stringiin syntaksivirheen. Devstral aloitti vastauksen Markdown-koodiaidalla eikä sulkenut sitä, joten tallennettu tiedosto ei ollut kelvollista Pythonia. Qwen2.5-Coder sai palvelimen käyntiin ja lomakkeen auki, mutta varauksen lähettäminen kaatoi käsittelijän. Nykyinen Balanced-malli kääntyi, mutta sekään ei selvinnyt käynnistystestistä.
Eli viidestä mallista nolla rakensi toimivan sovelluksen yhdellä vastauksella.
Tämä ei tarkoita, että mallit olisivat hyödyttömiä koodauksessa. Ne selviytyivät rajatuista tehtävistä paljon paremmin. Jokainen malli sai täydet pisteet bugikorjauksesta. Useampi osasi tehdä validoinnin täysin oikein. Ongelmat alkoivat, kun samaan vastaukseen piti mahduttaa arkkitehtuuri, tietokanta, HTTP-reitit, lomakkeet, tietoturva, virhetilanteet ja käynnistys.
Pitkä koodi näyttää helposti valmiilta ennen kuin se on valmis. Se on vaarallinen yhdistelmä: vastaus on vakuuttava, mutta kone ei välitä vakuuttavuudesta. Yksi väärä sulje riittää.
Kokeen jälkeen pidän koneella kahta mallia eri töihin.
Qwen3.6 Balanced jää yleismalliksi. Se hoitaa keskustelun, verkkonhaun, kirjoittamisen, ideoinnin ja muun päivittäisen työn. Qwen3-Coderista tulee erillinen NiceCode-malli koodaukseen.
Mutta en aio käyttää sitäkään niin, että pyydän Open WebUIssa kokonaista sovellusta ja kopioin vastauksen suoraan tuotantoon.
Coder-mallin pitää päästä käyttämään tiedostoja ja terminaalia. Sen pitää kirjoittaa koodi, ajaa `py_compile`, käynnistää ohjelma, suorittaa testit, lukea oikea virheilmoitus ja korjata tiedostoa. Sitten sama kierros uudelleen niin monta kertaa, että testit menevät läpi.
Tässä Qwen3-Coderin nopeudella on enemmän merkitystä kuin yhdellä täydellisellä vastauksella. Kun malli tuottaa 152 tokenia sekunnissa, useita korjauskierroksia ehtii ajaa ilman loputonta odottelua.
Seuraava vaihe ei ole uuden leaderboardin rakentaminen. Haluan nähdä, mitä tapahtuu, kun Qwen3-Coder pääsee oikeasti tekemään töitä eikä vain palauttamaan yhtä pitkää vastausta chat-ikkunaan.
Aion käynnistää sen omana NiceCode-mallina ja yhdistää sen coding agenttiin, joka saa lukea projektin tiedostoja, tehdä rajattuja muutoksia ja ajaa testit itse. Silloin kiinnostava mittari ei ole se, syntyykö täydellinen sovellus ensimmäisellä yrityksellä. Kiinnostavaa on, löytääkö malli oman virheensä testituloksesta ja saako se ohjelman toimimaan toisella, kolmannella tai viidennellä kierroksella.
Myös generointiasetuksia pitää testata. Tässä vertailussa Qwen3-Coder käytti sille suositeltua 0,7:n lämpötilaa. Tarkassa tiedostotyössä matalampi lämpötila voi vähentää turhaa vaihtelua, mutta liian alas vedettynä malli saattaa jumiutua huonoon ratkaisuun. Ajan samat tehtävät ainakin muutamalla eri lämpötilalla ja pidän muun testin lukittuna.
Yksi vastaus per tehtävä ei myöskään riitä mittaamaan luotettavuutta. Seuraavassa versiossa jokainen testi ajetaan useamman kerran eri siemenillä. Jos malli onnistuu kerran kolmesta, se on eri asia kuin malli, joka onnistuu joka kerta.
Haluan kokeilla myös kontekstin koon ja kvantisoinnin vaikutusta. Nykyinen Qwen3-Coder on Q3-versio, jotta se mahtuu 16 gigatavun videomuistiin. Laadukkaampi Q4 vaatisi osittaista CPU-offloadia ja olisi hitaampi, mutta voi silti olla parempi, jos syntaksivirheet vähenevät tarpeeksi. Devstral ansaitsee uuden mahdollisuuden oikeassa agenttiympäristössä, ja myöhemmin mukaan voi ottaa uusia malleja sitä mukaa kun llama.cpp-tuki ja järkevän kokoiset quant-versiot valmistuvat.
Lopulta tärkein testi tehdään oikeassa repossa. Pieni bugi, olemassa olevat testit ja selkeä hyväksymisehto kertovat enemmän päivittäisestä hyödystä kuin yksi valtava generointiprompti.
Mä tykkään paikallisissa malleissa siitä, että ne pyörivät omalla koneella. Data ei lähde ulkopuoliselle palvelulle, käyttö ei maksa jokaisesta tokenista ja järjestelmää saa rakentaa omien tarpeiden mukaan.
Mutta paikallisuus ei tee mallista automaattisesti luotettavaa. Eikä coder-nimi mallin perässä tarkoita, että sen kirjoittama ohjelma toimii.
Tämän testin jälkeen en enää kysy ensimmäisenä, mikä malli kirjoittaa näyttävimmän vastauksen. Kysyn, mikä malli toimii parhaiten osana järjestelmää, joka pystyy tarkistamaan sen työn.
Voittajaksi tuli Qwen3-Coder. Silti tärkein osa kokonaisuutta ei ole malli.
Se on testi, joka kertoo milloin malli on väärässä.