Kontexten avgör en kodgranskning. Våra egna modeller läser 524 000 tokens på en gång.

De flesta kodskannrar hyr sin modell av någon annan. Vi tränar våra egna — sträcker ut RoPE förbi modellens ursprungliga räckvidd och handleder mot verkliga anropsgrafer. Uppmätt på 524 000 tokens, dubbelt så mycket som basmodellen klarar från början.

De flesta AI-kodskannrar på marknaden är i praktiken en prompt mot någon annans API. Det är ett fullt rimligt sätt att bygga en produkt — men inte om du lovar att koden aldrig lämnar Europa, och inte om det du säljer bygger på att läsa mer kod i ett svep än någon annan klarar. Vi tränar våra egna modeller, på egen hårdvara. Och vi kan berätta vad de faktiskt presterar.

I den senaste utvärderingen svarade en av dem rätt på frågor som spände över 524 000 tokens kod — dubbelt så mycket som basmodellen klarar från början. Här är varför den siffran betyder mer än den låter som.

Kontexten avgör en källkodsgranskning

Fråga vilken granskare som helst hur arbetet går till. Ingen svarar "en fil i taget". Man bygger först en bild av hela systemet och letar sedan efter ställena där bilden spricker.

Det beror på att de allvarliga sårbarheterna sitter i glappen mellan filerna. En valideringsfunktion som ser vattentät ut — tills du hittar anroparen som hoppar över den. En behörighetskontroll som görs tre moduler bort från där du skulle leta. En sanering som körs på ena vägen in till en sink men inte på den andra. Inget av det syns i filen där buggen till slut smäller.

En skanner som läser en fil i taget har helt enkelt ingen möjlighet att se sådant. Den ser syntax, matchar mönster och producerar brus — det har vi skrivit om tidigare, och det är därför vår skanner läser in hela kluster av sammanhängande kod i stället.

Men "läs hela klustret" är ett löfte du bara kan hålla om modellen rymmer klustret. I verkliga kodbaser landar ett kluster på hundratusentals tokens. Då slutar kontextfönstret vara en siffra i ett datablad och blir taket för hur bra granskningen kan bli.

Varför kontextfönster brister: RoPE

Transformermodeller har ingen inbyggd känsla för position. Moderna modeller får den från RoPE — rotary position embeddings — som kodar var en token står genom att rotera dess query- och key-vektorer med en vinkel som följer positionen. Avstånden mellan tokens uppstår då direkt ur geometrin, vilket är elegant och fungerar utmärkt inom det intervall modellen tränats på.

Utanför det intervallet vittrar det sönder. Positioner bortom träningslängden svarar mot rotationer modellen aldrig har sett, attention blir opålitlig, och det första som försvinner är förmågan att hitta tillbaka — att lokalisera den enda funktionsdefinition som spelar roll, 400 000 tokens bakåt.

Den vanliga lösningen är att skala om positionerna vid körning. YaRN och besläktade interpolationsmetoder klämmer in längre sekvenser i det rotationsintervall modellen redan känner igen. Det är gratis, kräver ingen träning, och varje "1M-kontext"-modell du hittar på Hugging Face gör någon variant av det.

Men metoden har en verklig svaghet: modellen har fortfarande aldrig tränat på de positionerna. Du har ändrat räknesättet, inte vikterna. Precisionen sjunker bortom det ursprungliga fönstret — och det är precis där en kodgranskning behöver den mest. Att hitta rätt på långt avstånd är inget specialfall för oss. Det är själva kärnan i arbetet.

Därför tränar vi igenom utsträckningen i stället för att skala om vid körning. Modellen får se riktigt långa sekvenser vid de omskalade positionerna redan under träningen, så att positionerna blir verkliga i stället för interpolerade. Hur känsligt det här är syns i en observation från forskningen: bfloat16 bryter ned RoPE vid långkontextträning — på långt avstånd räcker avrundningsfelet i bf16 för att på egen hand förstöra den relativa positionen.

Alla delar av en modell är inte lika känsliga. Det är i en delmängd av lagren som precisionen på långt avstånd avgörs, och det är där utsträckningen måste hålla under verklig belastning. Där lägger vi krutet.

Anropsgrafer är ett gratis och verifierbart facit

Det svåra med långkontextträning är inte träningen. Det svåra är att veta om modellen verkligen har förstått något — eller bara gissat bra.

Koden löser det åt oss. En anropsgraf är exakt och maskinellt kontrollerbar: funktion A anropar antingen funktion B eller så gör den det inte. Alltså kan vi ta fram hur många frågor som helst med känt facit, på vilken kontextlängd vi vill, ur riktiga kodbaser — och rätta varenda en automatiskt.

Det är dessutom en fråga som inte går att besvara utan att göra båda sakerna vi bryr oss om samtidigt. För att avgöra om A anropar B över en halv miljon tokens måste modellen både förstå koden och hitta två definitioner som kan ligga i var sin ände av kontexten. En fråga, båda förmågorna, och ett facit som följer med källkoden.

Två detaljer håller det ärligt. Vi tar bort identifierande namn — även i kommentarer och docstrings — så att modellen inte kan gena till svaret via ett talande funktionsnamn. Och vi kräver att den citerar anropsstället, så att ett rätt svar måste vara förankrat och inte bara tur.

Vad den presterar

Utvärderat på kodbaser vi hållit helt utanför träningen, 774 frågor:

Kontextlängd F1
65 000 0,95
131 000 0,91
262 000 0,88
393 000 0,90
524 000 0,81

Vid 524 000 tokens — dubbelt så mycket som basmodellen klarar från början — svarar den fortfarande rätt på fyra av fem frågor.

Ett resultat överraskade oss på riktigt: avståndet spelar nästan ingen roll. Om anroparen och den anropade ligger intill varandra eller i var sin ände av en halv miljon tokens påverkar knappt träffsäkerheten. Det som vittrar först är inte korrektheten utan förankringen — ju längre kontext, desto sämre blir modellen på att peka ut exakt var den hittade svaret, samtidigt som svaret fortsätter vara rätt. Det är ett mer intressant fel än ett rakt stup i träffsäkerhet, och det är där vi arbetar nu.

Vi är medvetet försiktiga med vad vi påstår. Det här är våra siffror från vår egen utvärdering. Den kontrollerade jämförelsen mot den otränade basmodellen kommer med nästa milstolpe. Vi visar hellre kurvan nu och det kontrollerade resultatet när det faktiskt är färdigt.

Varför det här är ovanligt

När vi gick igenom forskningsläget innan vi började hittade vi inte en enda publicerad, tränad utsträckning bortom 262K för den här typen av modell. "1M-kontext"-modellerna på Hugging Face är ompaketerade konfigurationer — interpolation vid körning, ingen träning, inga utvärderingar publicerade. Den enda genuina långkontextmodellen i klassen finns bara bakom ett API, med receptet stängt.

Det är i den luckan vi arbetar. Och det är därför vi publicerar siffror i stället för en specifikation.

Varför vi gör det

Att träna egna modeller är långsammare och dyrare än att anropa ett API. Tre skäl till att det ändå är värt det.

Det är den enda hederliga formen av datasuveränitet. En skanner som skickar din kod till ett amerikanskt API håller den inte kvar i Europa, hur marknadsföringen än låter — och som vi gick igenom i frågan om att skicka källkod till amerikanska AI-tjänster är även de residensalternativ som faktiskt finns avstängda som standard, dyrare, och försedda med dokumenterade luckor. Äger du modellen försvinner frågan i stället för att behöva hanteras.

Vi kan bygga för uppgiften. Inget generellt API är byggt för att hålla ett helt kodkluster i huvudet och resonera om vilken funktion som når vilken. Vi kan träna precis för det, eftersom det är vad produkten gör.

Modeller små nog att äga räcker. Den här kör på hårdvara du kan rackmontera — inget kluster i frontlinjeklass, ingen mätare som tickar per token. Det är ingen kompromiss utan hela tanken bakom bolaget, och skälet till att vår on-prem-appliance är en riktig produkt och inte en punkt i en broschyr.

Vi utgår från öppna vikter. Allt därefter — datan, handledningen, utsträckningen av kontexten — är vårt, körs på vår egen hårdvara och lämnar aldrig Europa. Vilken basmodell, i vilken storlek och exakt hur den tränas går vi gärna igenom under NDA. Det är inget vi lämnar ifrån oss till konkurrenterna i ett blogginlägg.

Härnäst

Större modeller med samma angreppssätt, den kontrollerade jämförelsen mot basmodellen, och att pressa den användbara kontexten längre — för klustren vi verkligen vill granska är större än 524 000 tokens, och vi växer hellre fönstret än går tillbaka till att läsa en fil i taget.

Siffrorna publicerar vi oavsett hur det går. Vill du ha det lästa djupet applicerat på din egen kodbas är det precis det en Codelight-granskning är.

Ämnen: #ai #data-sovereignty #benchmarks