Nästa gen AI och WebGPU · 8 min läsning · Uppdaterad 16 augusti 2026

Så fungerar lokal AI i webbläsaren med WebGPU och React

Lokalt läge i NorthernGo laddar in en kvantiserad språkmodell i webbläsaren med @mlc-ai/web-llm och kör den på ditt eget grafikkort via WebGPU. Modellen laddas ner en gång, mellan ungefär 2,2 GB och 5,5 GB beroende på vilken du väljer, och sparas i webbläsarens cache. Din prompt och den genererade koden lämnar aldrig datorn, och lokal generering drar inte av dina molnkrediter.

Vad som faktiskt körs på din maskin

Uttrycket "lokal AI" används tillräckligt löst för att det är värt att vara exakt med vilken programvara som körs var.

Modellen körs i byggverktyget — React-applikationen på northerngo.com som du skriver din prompt i. När du slår på Lokal AI laddas en kvantiserad språkmodell ner till din webbläsare och körs på ditt grafikkort. Bygg-agenten som skriver appens kod är den modellen. Ingenting av din prompt eller den färdiga källkoden skickas någonstans.

Appen du genererar är en annan sak. Genererade appar är ett enda HTML-dokument som använder Tailwind via CDN, med NorthernGos SDK injicerad i en script-tagg. De bär inte med sig någon egen språkmodell. Anropar en genererad app window.NorthernGoAI.generate(prompt) går den förfrågan över nätet till plattformens modellproxy, precis som från vilken annan webbsida som helst. Lokalt läge ändrar hur din app byggs, inte hur den körs för dina användare.

Den skillnaden spelar roll av precis det skäl folk brukar fråga om lokal AI: sekretessen kring koden och uppdraget, inte kring slutanvändarnas data. Är det kontroll över var dina användares data hamnar du behöver är det en annan fråga, som besvaras i guiden om att bygga GDPR-säkra appar inom EU.

Kontrollen som avgör om något av det här är möjligt

WebGPU är det webbläsar-API som exponerar grafikkortet för allmänna beräkningar. Allt annat hänger på att det finns:

if (!navigator.gpu) {
  // Inget WebGPU: lokalt läge kan inte startas alls.
  visaMeddelande('Din webbläsare eller dator saknar stöd för WebGPU.');
  return;
}

I praktiken betyder det en Chromium-baserad webbläsare på dator — Chrome eller Edge. Stödet i Safari och Firefox har rört sig under 2025 och 2026, men byggverktyget utgår från Chromium på dator och säger det rakt ut i felmeddelandet när en generering misslyckas. Ett dedikerat grafikkort krävs inte strikt, men integrerad grafik med lite tillgängligt minne blir så långsam att molnvägen är det bättre valet.

Mobil är tekniskt möjligt och avrådes medvetet. Gränssnittet visar en varning innan det drar igång en nedladdning på flera gigabyte över mobilnätet, och en gång till innan en cachad modell aktiveras på en telefon, eftersom kostnaden i minne och batteri är verklig.

De fem modellerna

Lokalt läge är inte en enda modell. Du väljer en i dialogen Välj AI-modell, och valet är en genuin avvägning mellan nedladdningsstorlek, hastighet och hur väl modellen följer instruktioner.

Nedladdningen sker en gång. Därefter ligger vikterna i webbläsarens cache och aktiveringen tar sekunder. Byggverktyget kommer ihåg vilken modell du senast använde, så nästa session hoppar över modellvalet helt och startar den direkt.

Gratis- och Premium-konton får Qwen 3.5 (4B) utan tak på hur många gånger du genererar, och det är den delen som är värd att ta till sig: den månatliga krediten på 5, 25 eller 50 genereringar gäller enbart molngenerering. Lokal generering mäts inte, eftersom den inte kostar plattformen något.

Att koppla in en flergigabytesmotor i en React-app

Bygger du något liknande själv är två implementationsdetaljer värda att stjäla, eftersom båda var buggar innan de blev mönster.

Importera motorn dynamiskt. web-llm-paketet ska aldrig ligga i det initiala bygget — en besökare som aldrig rör lokalt läge ska aldrig ladda ner det:

const { initLocalAI, generateLocalCode } = await import('../utils/localAI');

Håll motorns tillstånd utanför komponentträdet. Reglaget för att aktivera finns på två ställen i NorthernGo — en knapp i navigeringsraden och en kontroll i promptrutan — och båda är monterade samtidigt. När var och en höll sitt eget isLoading visade den ena fortfarande motorn som avstängd när du startade den i den andra, och en snabb dubbelklickning kunde dra igång samma nedladdning på 5 GB två gånger. Lösningen är en store på modulnivå med ett enda pågående löfte: ett andra anrop för samma modell får tillbaka löftet som redan körs, och ett anrop för en annan modell under pågående nedladdning avvisas rakt av i stället för att köas.

Själva laddningen rapporterar framsteg via en callback, och det är den som driver procentsatsen i gränssnittet:

import { CreateMLCEngine } from '@mlc-ai/web-llm';

const motor = await CreateMLCEngine('Qwen3.5-4B-q4f16_1-MLC', {
  initProgressCallback: (rapport) => {
    setProgress(Math.round(rapport.progress * 100));
    setStatusText(rapport.text);
  }
});

En sak till som är lätt att missa: att byta modell kräver att den föregående avlastas först. Två uppsättningar vikter får inte plats i grafikminnet samtidigt, och den andra laddningen misslyckas på ett svårläst sätt.

await motor.unload();

Strömningen, och varför temperaturen är så låg

Genereringen använder ett chat completion-API i OpenAI-form, vilket gör att koden du skriver mot den ser ut som vanlig modellkod:

const delar = await motor.chat.completions.create({
  messages: [
    { role: 'system', content: systemkontext },
    { role: 'user', content: prompt }
  ],
  temperature: 0.1,
  stream: true
});

let helText = '';
for await (const del of delar) {
  helText += del.choices[0]?.delta?.content || '';
  onStream(helText);
}

Temperaturen är 0,1 i stället för mer sedvanliga 0,7 av ett specifikt skäl. Det här är små modeller som ombeds följa en lång och stelbent formatspecifikation — skriv bara ut de inre HTML-elementen, inget dokumentskal, använd Tailwinds klasser. Kreativitet i det steget ger löpande text, ursäkter och halvfärdig markdown snarare än bättre design. Designbesluten kommer från prompten, inte från slumpen i samplingen.

Tal och bilder använder en separat stack. Text-till-tal och transkribering går via pipelines i @huggingface/transformers med device: 'webgpu', i Web Workers så att huvudtråden förblir responsiv, och de initieras i bakgrunden parallellt med textmodellen.

Vad som ändå rör nätet i lokalt läge

Att vara exakt här spelar större roll än säljformuleringen, så: lokalt läge är inte samma sak som offline.

Vid ett nybygge på Premium eller Pro anropas molnet först i Arkitekt-steget för att skissa appens struktur, och den ritningen lämnas sedan till den lokala modellen. På Gratis-planen hoppas det steget över helt. När du ändrar en befintlig app i stället för att bygga en ny hoppas Arkitekt-anropet över för alla — den lokala modellen får den nuvarande sidkroppen och producerar en riktad diff i stället.

Det finns ingen LLM-granskare som skriver om koden på den lokala vägen. En syntaxkontroll stoppar JavaScript som inte går att tolka; den lagar inte logik, och det är inte en tur och retur till molnet.

Alltså: på Gratis är genereringen helt lokal. På Premium och Pro skickas en beskrivning av det du bad om till molnet en gång per nybygge, om inte Arkitekt-anropet misslyckas, för då fortsätter byggverktyget utan det. Behöver du en garanti för att ingenting lämnar maskinen är Ollama för lokala modeller eller Gratis-planen de ärliga svaren. Den bredare avvägningen finns i jämförelsen mellan lokal och molnbaserad AI i appbyggare.

Där lokal generering är genuint sämre

Felsökning

"Lokal generering misslyckades" direkt, innan någon nedladdning. WebGPU är inte tillgängligt. Använd Chrome eller Edge på dator och kontrollera att hårdvaruacceleration är påslagen i webbläsarens inställningar.

Nedladdningen börjar om varje gång. Modellen cachas i webbläsarens lagring. Privata fönster, hård cacherensning och vissa företagspolicyer slänger den. Byggverktyget sparar dessutom vald modell i localStorage — är lagringen helt blockerad fungerar aktiveringen ändå, men modellvalet dyker upp varje session.

Genereringen dör mitt i med ett minnesfel. Grafikminnet tog slut. Byt till en mindre modell, stäng andra grafiktunga flikar och starta om webbläsaren för att frigöra vikter som inte avlastades rent.

"En annan modell laddas redan ner." Precis vad det står: en nedladdning av en annan modell pågår. Vänta tills den är klar i stället för att ladda om sidan, vilket bara börjar om.

Resultatet är en sida som beskriver reglerna i stället för din app. En liten modell har läst instruktionsblocket som själva specifikationen. Ett omförsök med en kortare och mer konkret prompt brukar räcka; det gör även ett byte till Qwen 2.5 Coder, som är märkbart bättre på att hålla fast vid ett format.

Vanliga frågor

Behöver jag en speldator för att köra lokal AI i webbläsaren?

Nej, men du behöver en webbläsare på dator med stöd för WebGPU, i praktiken Chrome eller Edge, och tillräckligt med grafikminne för modellen du väljer. Qwen 3.5 (4B) på ungefär 3 GB går att köra på vanliga bärbara datorer. De större modellerna på 5 GB vill ha ett dedikerat grafikkort för att vara användbara och inte bara möjliga.

Drar lokalt läge av mina månatliga AI-krediter?

Nej. Den månatliga tilldelningen på 5 genereringar för Gratis, 25 för Premium och 50 för Pro gäller bara molngenerering. Lokal generering på ditt eget grafikkort är obegränsad i alla planer, eftersom den inte kostar plattformen något.

Skickas något till en server när jag använder lokalt läge?

På Gratis-planen, nej. På Premium och Pro skickas din förfrågan vid ett nybygge först till Arkitekt-steget i molnet, som returnerar en strukturskiss som den lokala modellen sedan bygger utifrån. Ändringar i en befintlig app hoppar över det steget helt, och granskningen körs alltid på den lokala modellen.

Kommer appen jag bygger med lokal AI också att fungera offline för mina användare?

Inte automatiskt, och inte tack vare lokalt läge. Genererade appar innehåller ingen språkmodell; varje AI-funktion i dem anropar plattformen över nätet. Publicerade appar får däremot en service worker som cachar gränssnittet för offline-bruk, men databasanrop och AI-anrop kräver alltid uppkoppling.

Varför skriver den lokala modellen ibland om hela min app i stället för den del jag frågade om?

Små modeller har ett begränsat kontextfönster och tappar ibland bort diff-formatet de ombads använda. Byggverktyget upptäcker det och kör ett omförsök med striktare instruktioner. Händer det upprepade gånger: använd en kortare och mer specifik prompt, eller byt till Qwen 2.5 Coder som håller fast vid ett givet utdataformat bättre än allroundmodellerna.

Bygg det själv

NorthernGo förvandlar en beskrivning i ren text till en fungerande webbapp med databas, inloggning och en live-adress. Lokal AI-generering körs på ditt eget grafikkort, är obegränsad och ingår gratis i alla prisplaner.

Börja bygga gratis