Viktiga begrepp och överväganden för utvecklare som skapar generativa AI-lösningar
Stora språkmodeller (LLM) är fantastiska, men även de har sina begränsningar. Utvecklare måste förstå dessa begränsningar, vilka LLM:er som kan "out of the box" och hur du justerar dem för att få bästa resultat för de generativa AI-lösningar som de skapar. Den här artikeln identifierar flera utmaningar och begränsande faktorer och förklarar vanliga sätt att övervinna dessa utmaningar och ta kontroll över processen för innehållsgenerering oavsett vilken typ av generativa AI-funktioner du skapar i ditt program.
Tekniska utmaningar när du arbetar med LLM:er
De viktigaste utmaningarna eller begränsningarna att vara medveten om när du arbetar med LLM:er:
Kunskapsavgränsning – På grund av den höga kostnaden för att träna en LLM är deras kunskapskropp begränsad till vad de tränades på vid en viss tidpunkt. Utan plugin-program eller andra boenden har de ingen åtkomst till realtidsinformation och har inte heller tillgång till privata data.
Hallucination – En LLM använder statistiska sannolikheter och lite slumpmässighet för att generera information. Det finns mekanismer för att hålla genererade svar anpassade till människans avsikt i de frågor som ställs och den information som de har tränats på, men det är möjligt att de skapar svar som inte är korrekta.
Transparens – Återigen, på grund av hur modellerna tränas har de inte längre tillgång till den grundläggande kunskap som de har tränats på. Och även om de gjorde det, finns det ingen garanti för att informationen var sanningsenlig och grundad från början. Dessutom finns det inget verifieringssteg för att säkerställa att det genererade svaret är korrekt.
Ingen domänspecifik kunskap – På liknande sätt som "kunskapsavstängning, om du har privat information som företagsdokument endast internt, har LLM inte tränats på den här informationen och har därför ingen domänspecifik kunskap.
Vad kan du göra för att minimera eventuella utmaningar eller problem med LLM:er och få bästa möjliga resultat för att hjälpa dina användare och din organisation? Börja med att förstå hur du kan komplettera var LLM hämtar sina data från.
Förstå var LLM:er får sin information
En bra utgångspunkt för att få bästa resultat från en LLM är att förstå var eller hur LLM får sin information. Följande kategorier representerar olika metoder för hur LLM:er interagerar med olika informationskällor för att generera svar.
Hämtning av generation (ROG) – Det här är det sätt på vilket llm:er fungerar på traditionellt sätt, där modellen genererar svar enbart baserat på den kunskap som den har tränats på, utan att komma åt eller hämta någon extern information under genereringsprocessen. Modellens kunskaper är statiska, begränsade till vad som ingick i dess träningsdata fram till slutdatumet. Förutom kreativt skrivande kan den svara på frågor om information som är lättillgänglig på internet.
RAG (Retrieval-Augmented Generation) – Kombinerar de generativa funktionerna i LLMs med möjligheten att hämta information från externa databaser eller dokument i realtid. Modellen frågar en extern källa för att hitta relevant information, som den sedan använder för att informera sitt svar. Den här metoden gör det möjligt för modellen att tillhandahålla mer exakt och uppdaterad information än vad den kunde från sin förtränade kunskap ensam. Användningsfall inkluderar faktakontroll, svar på frågor baserat på realtidsdata eller privata, domänspecifika data.
Hämtningscentrerad generation (RCG) – Lägger ännu större vikt vid det externt hämtade innehållet, vilket ofta strukturerar svar kring den information som hämtas från externa källor. Modellen kan direkt införliva stora segment av hämtad text i sina utdata, redigera eller kommentera dem för att passa användarens fråga. Den här metoden kan ses som en hybrid mellan hämtningsbaserade och generativa metoder, där balansen i hög grad kan gynna den information som hämtas framför modellens egna generativa funktioner. Användningsfall omfattar sammanfattning av ett längre dokument, forskningshjälp för att tillhandahålla jämförelser och tematiska utforskningar i flera liknande dokument samt kompilering eller sortering av olika materialkällor i en kombinerad utdata.
Ett bra exempel på ROG (Retrieval Off Generation) är ChatGPT. Vid behov utökar Däremot Copilot (via Bing) LLM genom att använda externa källor från nyhetskällor (och tillhandahålla länkar till dessa källor).
Vid första anblicken låter RAG (Retrieval-Augmented Generation) och Retrieval-Centric Generation (RCG) liknande eftersom båda omfattar integrering av extern information i språkgenereringsprocessen. De skiljer sig dock åt i hur de prioriterar och använder den hämtade informationen inom genereringsprocessen.
I RAG-system används den externa datahämtningen för att utöka generativa funktioner i en förtränad språkmodell. Den hämtade informationen ger mer kontext eller specifika data som modellen använder för att informera sina svar. Här är den generativa aspekten av språkmodellen fortfarande central för svaret, medan hämtade data fungerar som ett stödjande element för att förbättra noggrannheten eller djupet.
RCG-system å andra sidan lägger större vikt vid själva den hämtade informationen. I dessa system är hämtade data ofta i centrum för svaret, där generativmodellens roll främst är att förfina, formatera eller förbättra den hämtade texten något. Den här metoden används särskilt när informationens noggrannhet och direkta relevans är av största vikt och mindre kreativ syntes eller extrapolering krävs.
Mekanismerna för extern hämtning av data som driver både RAG och RCG beskrivs i artiklar om lagring av vektoriserade inbäddningar av dokument jämfört med finjustering av en LLM, de två vanliga metoderna för att komplettera den kunskap som är tillgänglig för LLM baserat på den inledande utbildningen.
Att förstå skillnaderna mellan hämtningsmodeller kan hjälpa dig att välja rätt metod för specifika program, balansera behovet av kreativ syntes jämfört med behovet av noggrannhet och återgivning till källmaterial.
Förstå faktorer som påverkar hur slutsatsdragning fungerar
Eftersom du förmodligen är bekant med ChatGPT:s webbaserade användargränssnitt kan förståelse för hur det fungerar för att besvara frågor hjälpa dig att förstå begrepp som är viktiga när du skapar generativa AI-funktioner i dina egna program.
När en användare chattar med ChatGPT ger designen av användargränssnittet en illusion av en långvarig chattsession som upprätthåller tillståndet under flera fram och tillbaka-utbyten mellan dig och LLM. För en viss chattsession skickas i själva verket alla uppmaningar och alla LLM:s svar (även kallade slutföranden) med varje ny uppmaning. I takt med att konversationen växer skickar du allt mer text till LLM för att bearbeta – alla tidigare frågor och slutföranden. ChatGPT använder hela chattsessionens kontext – inte bara den aktuella prompten – när du skapar ett svar på din aktuella fråga. Hela chattsessionen kallas för kontextfönstret.
Det finns en längdgräns för kontextfönster beroende på vilken version av ChatGPT du arbetar med. Alla delar av chattkonversationen som överskrider längdgränsen för kontextfönstret ignoreras när du skapar ett svar på din senaste fråga.
Långa konversationer kan verka som en bra idé i början, men långa kontextfönster kan påverka hur mycket beräkning som krävs för att bearbeta prompten och skapa en slutförande. Detta påverkar svarstiden och hur mycket det kostar för OpenAI att bearbeta begäran.
Vad är ChatGPT:s kontextfönstergräns? Eller snarare, hur många ord kan ChatGPT arbeta med? Begränsningen för kontextfönstret beror på vilken LLM-modell, version och utgåva du arbetar med. Dessutom mäts kontextlängder i token, inte i ord. Token är de minsta textenheterna som modellen kan förstå och generera. Dessa enheter kan vara ord, delar av ord (t.ex. stavelser eller stjälkar) eller till och med enskilda tecken. Token står i centrum för bearbetning av naturligt språk (NLP).
Användningen av token påverkar två viktiga överväganden för utvecklare:
- Gräns för maximalt antal kontextfönster
- Priset per prompt och slutförande
Vad är tokenisering?
"Tokenisering" är processen för att konvertera text till token. Det är ett viktigt steg i att förbereda data för träning eller slutsatsdragning (processen för att skapa slutföranden baserat på frågor) med en LLM. Processen omfattar flera steg, bland annat att dela upp komplex text i hanterbara delar (token) som modellen sedan kan bearbeta. Den här processen kan vara enkel, till exempel att dela upp text efter blanksteg och skiljetecken, eller mer komplex, med avancerade algoritmer för att hantera olika språk, morfologier (ordstrukturen) och syntaxer (ordordningen). LLM-forskare och utvecklare bestämmer sig för tokeniseringsmetoden baserat på vad de försöker åstadkomma. OpenAI har en användbar sida som förklarar mer om tokenisering och har till och med en kalkylator som illustrerar hur en mening eller ett stycke delas upp i token.
Som anteckningen längst ned på sidan OpenAI Tokenizer anger att i typiska engelska texter motsvarar en token cirka fyra tecken. Det innebär att i genomsnitt är 100 token ungefär lika med 75 ord eller tre fjärdedelar av ett ord per token.
Sidan OpenAI Tokenizer talar också om tiktoken, ett paket för Python och JavaScript som gör att du programmatiskt kan uppskatta hur många token du ska använda för en viss fråga som skickas till OpenAI API.
Tokenanvändning påverkar fakturering
Varje Azure OpenAI-API har olika faktureringsmetoder. För bearbetning och generering av text med API:et för chattslutsättning debiteras du baserat på antalet token som du skickar som en uppmaning och antalet token som genereras som ett resultat (slutförande).
Varje LLM-modell (t.ex. gpt-3.5, gpt-3.5-turbo, gpt-4 osv.) har vanligtvis ett annat pris, vilket återspeglar den mängd beräkningar som krävs för att bearbeta och generera token. Många gånger visas priset som "pris per 1 000 tokens" eller "pris per en miljon token".
Den här prismodellen har en betydande inverkan på hur du utformar användarinteraktioner och mängden för- och efterbearbetning som du lägger till.
Frågor om system och användare
Fram tills nu har diskussionen enbart fokuserat på "användarfrågor" – de uppmaningar som utgör utbytet mellan en användare och ChatGPT.
OpenAI introducerade "systemprompten" (kallas även "anpassade instruktioner"), som är en övervalv uppsättning instruktioner som du definierar och läggs till i alla dina chattkonversationer. Tänk på det som en uppsättning metainstruktioner som du vill att LLM alltid ska observera varje gång du startar en ny chattsession. Du kan till exempel ställa in systemprompten på "svara alltid i poetisk form av haiku". Från och med då resulterar varje ny uppmaning till ChatGPT i en haiku som innehåller svaret.
Även om "svara i haiku-formulär" inte är ett användbart exempel, illustrerar det tanken att du kan påverka en LLM-slutförande till din uppmaning genom att ändra själva prompten.
Varför skulle du vilja ändra användarens uppmaning? Om du skapar en generativ AI-funktion eller ett program för en professionell målgrupp, som kan omfatta företagsanställda, kunder och partner, vill du utan tvekan lägga till skydd för att begränsa omfattningen av ämnen eller domäner som det får svara på.
Men att ändra användarens uppmaning är bara en metod för att förbättra textgenereringsupplevelsen för användare.
Metoder för att förbättra textgenereringsupplevelsen för användare i ChatGPT
För att förbättra textgenereringsresultaten är utvecklarna begränsade till att helt enkelt förbättra uppmaningen, och det finns många tekniska tekniker som kan vara till hjälp. Men om du skapar ett eget generativt AI-program finns det flera sätt att förbättra textgenereringsupplevelsen för användare, och du kanske vill experimentera med att implementera alla:
- Ändra användarprompterna programmatiskt
- Implementera en slutsatsdragningspipeline
- Hämtningsförhöjd generation (beskrivs i andra artiklar)
- Finjustering (beskrivs i andra artiklar)
Programmatiskt ändra användarprompter
Ur ett programmatiskt perspektiv finns det inget särskilt API för att lägga till en systemprompt i användarnas konversationer. Du lägger bara till instruktioner i prompten efter behov. Det finns dock några metoder för att förbättra användarfrågor:
- Kontextuell priming: Skapa systemuppmaningar som uttryckligen anger kontexten för konversationen i din önskade domän. Det handlar om att tillhandahålla en kort beskrivning eller en uppsättning instruktioner i början av varje interaktion, som vägleder AI:n för att hålla sig inom problemdomänen.
- Exempelbaserad vägledning: Ta med exempel på de typer av frågor och svar som är relevanta för din domän i den första prompten. Detta hjälper AI:n att förstå vilken typ av svar som förväntas.
Dessutom kan alla tekniker för prompt-engineering användas. Om du kan göra detta programmatiskt på något sätt kan du förbättra användarens uppmaning för deras räkning.
Förbehållet för den här metoden är att ju längre prompten är, desto dyrare blir varje anrop till LLM. Trots detta är detta sannolikt den mest billiga av de metoder som kommer att diskuteras.
Implementera en slutsatsdragningspipeline
Nästa steg utöver att ändra användarens uppmaning programmatiskt är att skapa en hel slutsatsdragningspipeline.
En slutsatsdragningspipeline är processen från slutpunkt till slutpunkt som tar råa indata (till exempel text eller bilder) och "rensar upp den" innan du använder den för att utföra din primära uppmaning (förbearbetning) eller för att kontrollera slutförandet för att säkerställa att den uppfyller användarens behov innan den visas för användaren (efterbearbetning).
Förbearbetning kan omfatta nyckelordskontroll, relevansbedömning eller transformering av frågan för att bättre passa det förväntade domänspråket. Du kan till exempel analysera den första uppmaningen som skickats av användaren och börja med att fråga LLM om uppmaningen är meningsfull, om den ligger inom gränserna för vad du är villig att acceptera, om den baseras på en felaktig lokal eller behöver skrivas om för att undvika vissa fördomar. Om LLM analyserar prompten och hittar problem kan du gå ett steg längre: be LLM att formulera om uppmaningen för att eventuellt förbättra svaret.
Efterbearbetning kan innebära att verifiera svarets relevans och lämplighet för domänen. Det kan vara att ta bort eller flagga svar som inte passar domänkraven. Du kanske till exempel vill inspektera slutförandet som tillhandahålls av LLM för att säkerställa att det uppfyller dina kvalitets- och säkerhetskrav. Du kan be LLM att utvärdera svaret för att se om det verkligen uppfyller de krav som du bad den att följa. Om den inte gör det kan du be LLM att ändra slutförandet och upprepa detta tills du har ett tillfredsställande resultat.
Det finns en varning för att lägga till förbearbetningssteg: varje gång du lägger till ett anrop till en LLM i din slutsatsdragningspipeline ökar du den totala svarstiden (tid att svara) och kostnaden för varje interaktion med användaren. Som erfaren programutvecklare är du förmodligen redan medveten om den här typen av kompromisser som måste göras av ledningen som påverkar programvarusystemets budget, prestanda och effektivitet.
Artikeln Building advanced Retrieval-Augmented Generation systems dives deep into specific steps of building an inference pipeline.
Andra faktorer som påverkar slutföranden
Förutom att programmatiskt ändra prompten, skapa en slutsatsdragningspipeline och andra tekniker beskrivs ytterligare information i Utöka en stor språkmodell med hämtningsförhöjd generation och finjustering. Dessutom finns det parametrar som kan ändras när du gör anrop till Azure OpenAI-API:et.
Dokumentationen för chattens slutpunkt innehåller obligatoriska och valfria parametrar som kan påverka olika aspekter av slutförandet. Om du använder ett SDK i stället kan du läsa SDK-dokumentationen för det språk du väljer. Om du vill experimentera med parametrarna kan du göra det i Playground.
Temperatur: Kontrollera slumpmässigheten i utdata som genereras av modellen. Vid noll blir modellen deterministisk och väljer konsekvent den mest sannolika nästa token från sina träningsdata. Vid en temperatur på 1 balanserar modellen mellan att välja token med hög sannolikhet och att införa slumpmässighet i utdata.
Maxtoken: Styr den maximala längden på svaret. Om du anger en högre eller lägre gräns kan det påverka detaljerna och omfånget för det innehåll som genereras.
Top P (Nucleus Sampling): Används med temperaturen för att kontrollera slumpmässigheten i svaret. Top P begränsar AI:n till att endast ta hänsyn till den högsta P-procenten av sannolikhetsmassan när varje token genereras. Lägre värden leder till mer fokuserad och förutsägbar text, medan högre värden ger mer mångfald.
Frekvensstraff: Minskar sannolikheten för att modellen upprepar samma rad eller fras. Om du ökar det här värdet kan du undvika redundans i den genererade texten.
Närvarostraff: Uppmuntrar modellen att introducera nya begrepp och termer i slutförandet. Närvarostraff är användbart för att generera mer mångsidiga och kreativa utdata.
Stoppsekvenser: Du kan ange en eller flera sekvenser för att instruera API:et att sluta generera ytterligare token. Lagringssekvenser är användbara för att styra strukturen för utdata, till exempel att avsluta ett slutförande i slutet av en mening eller ett stycke.
Logit Bias: Gör att du kan ändra sannolikheten för att angivna token visas i slutförandet. Logit Bias kan användas för att vägleda slutförandet i en viss riktning eller för att förhindra oönstrade innehåll.
Förstå Microsoft OpenAI-skydd
Förutom att hålla LLM:s svar bundna till specifika ämnen eller domäner, kommer du sannolikt också att oroa dig för de typer av frågor som användarna ställer om LLM. Det är viktigt att tänka på vilka typer av svar det genererar.
Först filtrerar API-anrop till Microsoft OpenAI Services automatiskt innehåll som kan vara stötande och rapporterar tillbaka det till dig i många filtreringskategorier.
Du kan använda OpenAI:s modererings-API direkt för att uttryckligen kontrollera innehåll om det finns potentiellt skadligt innehåll.
För det andra kan du använda Azure AI Content Safety för att hjälpa till med textmoderering, bildmoderering, riskidentifiering av jailbreak och identifiering av skyddat material. Detta kombinerar en portalkonfiguration, konfiguration och rapportering med kod som du kan lägga till i ditt program för att identifiera skadligt innehåll.
Slutliga överväganden som kan påverka dina beslut om programdesign
Att förstå tokenisering, prissättning, kontextfönster och implementering av programmässiga förbättringar för att förbättra användarnas textgenerering påverkar hur du utformar ditt generativa AI-system. Här är en kort lista över saker att tänka på och andra lärdomar från den här artikeln som påverkar dina beslut om programdesign:
- Utvärdera nödvändigheten av att använda den senaste AI-modellen mot kostnadsöverväganden. Billigare modeller kan räcka för programmets behov och balansera prestanda med budgetbegränsningar.
- Överväg att optimera längden på kontextfönstret för att hantera kostnader utan att avsevärt påverka användarupplevelsen. Att trimma onödiga delar av konversationen kan minska bearbetningsavgifterna samtidigt som kvalitetsinteraktioner upprätthålls.
- Utvärdera hur tokenisering och kornigheten för dina indata och utdata påverkar prestandan. Att förstå hur din valda LLM hanterar tokenisering kan hjälpa dig att optimera effektiviteten för dina API-anrop, vilket kan minska kostnaderna och förbättra svarstiderna.
Om du vill börja experimentera med att skapa en generativ AI-lösning omedelbart rekommenderar vi att du tar en titt på Kom igång med chatten med ditt eget dataexempel för Python. Det finns även versioner av självstudien i .NET, Java och JavaScript.