Generatiivisesta tekoälystä eli GenAI:sta puhutaan joka paikassa. Jos olet kuullut tämän termin, niin olet todennäköisesti käyttänyt ChatGPT:tä, MS Copilotia ja vastaavia GenAI-tuotteita, mutta miten GenAI:n päälle rakennetaan räätälöityjä ratkaisuja?

Tässä artikkelissa on muutama näkökulma aiheeseen Luodon asiakasprojekteista sekä sisäisistä kokeiluista keräämiemme kokemusten pohjalta. Käymme läpi suurten kielimallien (Large Language Models, LLMs) peruskäsitteitä, miten niitä ohjeistetaan, mitä tekemistä datalla on asian kanssa, sekä miten ohjeista ja datasta lähdetään rakentamaan prototyyppiä ja lopulta sovellusta.

Suuri kielimalli on isolla määrällä dataa koulutettu neuroverkko, joka on rakennettu käyttäen ns. Transformer-arkkitehtuuria. Tässä kirjoituksessa termillä kielimalli viitataan tällaisiin neuroverkkoihin, ja tarkastellaan malleja, jotka prosessoivat pelkkää tekstiä.

Mitä haluat rakentaa?

Tällä hetkellä paine hyödyntää AI:ta mahdollisimman laajasti on kova. Mieti kuitenkin ensin, minkälaisia ongelmia haluat GenAI:n avulla ratkoa. GenAI on työkalu muiden joukossa, ja perinteisemmätkin menetelmät ovat edelleen käyttökelpoisia ja monissa tapauksissa selvästi kustannustehokkaampia.

Yleinen käyttötapaus on botti, joka hyödyntää vastaustensa muodostamisessa dokumentaatiota, ohjeistusta, verkkosivuja ja vastaavaa materiaalia. Kyseessä voi olla myös taustapalvelu joka tuottaa sanallisia raportteja tai yhteenvetoja vaikkapa asiakaspalautteesta analysoiden palautteen sävyä, tai GenAI:ta hyödyntävien ominaisuuksien integroiminen osaksi olemassa olevaa tuotetta.

Kielimalli tarvitsee dataa

Kun on tiedossa, mitä GenAI:n avulla halutaan saada aikaiseksi, pitää miettiä, mitä dataa sovellus tarvitsee. Datalla ja sen laadulla on väliä, koska jos kielimallille antaa sillisalaattia, se on erittäin kyvykäs tuottamaan siitä lisää sillisalaattia. 

Usein sanotaan, että kielimalli ‘hallusinoi’. Tämä on kuitenkin enemmän ominaisuus kuin bugi. Koska kielimallin ainoa tehtävä on katsoa tekstinpätkää ja ennustaa, mikä sanan palanen todennäköisimmin tulee seuraavaksi, ‘hallusinoinnin’ määrä riippuu paljolti siitä, mitä mallille annetussa syötteessä on. Tämän vuoksi kielimalleihin ei myöskään kannata suhtautua totuuskoneina vaan tilastollisina koneina, jotka ovat taitavia nappaamaan kiinni datassa olevista rakenteista ja noudattamaan niitä uuden tuottamisessa.

Eli mitä paremmin mallille annettu syöte istuu rakennettavaan käyttötapaukseen, sitä todennäköisemmin tulokset vastaavat odotuksia. Syöte yleensä sisältää toimintaohjeet (=prompt) sekä käyttötapaukseen liittyvää dataa.

Esimerkkejä:

  • Käyttäjälle ohjeita antava botti tarvitsee dokumentteja, ohjeistusta, linkkejä, ja vastaavaa lähdemateriaalia
  • Asiakaspalautetta prosessoiva taustapalvelu tarvitsee säännöllisesti uudet asiakaspalautteet
  • Teollisuusprosessin analyysin kanssa auttava AI tarvitsee prosessiin liittyvää dataa kuvauksineen sekä toimialaan liittyviä ohjeita

Dataksi voidaan laskea myös työkalujen käyttö. Kielimallille voidaan kertoa: ”tässä on metodi, jota kutsumalla saat haettua tietoa aiheesta X”, esimerkiksi ”tällä metodilla voit hakea päivään liittyvät kalenterimerkinnät”. Työkaluiksi voidaan pukea mikä tahansa toiminto, esimerkiksi REST-rajapinnan kutsuminen tai jopa koodin tuottaminen ja ajaminen (tätä esim GPT:n käyttämä Code Interpreter tekee).

Kielimallin valinta

Kirjoitushetkellä tunnetuimmat kielimallit ovat OpenAI:n GPT:t (3.5, 4, 4o), Anthropicin Claude (Opus, Sonnet, Haiku), sekä Googlen Gemini. Suljettujen kielimallien lisäksi on olemassa iso liuta avoimia malleja, joista mainittakoon Metan Llama-variantit ja Microsoftin Phi-3.

Kielimalleja voi ajaa paikallisesti tai hyödyntää erilaisten pilvipalveluiden kautta. Nämä eroavat hieman niin hinnoittelun kuin tekniikan suhteen. Integraatio tapahtuu tyypillisesti REST-rajapintojen avulla. Etenkin yritysmaailman datalla on turvallisempaa hyödyntää niitä pilvipalveluiden kautta: Azure OpenAI Service GPT:ille, Amazon Bedrock Claudelle sekä Google Cloud Geminille.

Prototyyppi

Kun on valittu käytettävä kielimalli sekä relevantti data, voidaan alkaa hahmotella itse ratkaisua. Voidaan esimerkiksi ottaa Azure OpenAI Servicestä käyttöön GPT-4, antaa sille toimintaohjeet sekä pieni määrä dataa ja pyrkiä iteroimalla löytämään ohje, joka tuottaa näiden pohjalta suurin piirtein halutun kaltaisia lopputuloksia.

Hahmotteluun useimmiten riittää yksinkertainen pätkä koodia, joka kutsuu OpenAI:n rajapintaa ja tulostaa vastauksen. Tällä tavalla voidaan lyhyessä ajassa kokeilla monia eri lähestymistapoja, ja usein jo muutamassa päivässä saadaan hahmoteltua perusrunko, jonka päälle voi lähteä rakentamaan varsinaista sovellusta. Tai voidaan todeta, että GenAI ei nyt ole tähän toimivin ratkaisu – arvokasta tietoa sekin.

Promptaus eli kielimallin ohjeistaminen

Promptaus tarkoittaa sitä, että kielimallille kirjoitetaan ohjeet siitä, miten sen tulee toimia. Ohjeiden kirjoitus on vähintään yhtä paljon taidetta kuin tiedettä. Hyvä perusohje on ilmaista selkeästi ja yksikäsitteisesti miten haluaa mallin toimivan. Kielenä tulee yleensä käytettyä englantia, sillä siitä kielimalleilla on eniten tietoa jo valmiiksi. Englanninkielisestä promptista huolimatta kielimalli osaa vastata millä tahansa tuntemallaan kielellä.

Kielimallin saama ohje voi näyttää esimerkiksi tältä:
You are a friendly bot answering to questions from employees of Foobar company. The questions are related to company internal processes and vary from holiday rules to collective bargaining agreement and payment processes. Please keep your answers short and concise.

The user wants to know:
Mitä työehtosopimus sanoo arkipyhistä?

Datan ja kielimallin yhdistäminen

Yllä oleva esimerkkiohje saa kielimallin vastaamaan, mutta vastaukset ovat varmasti puutaheinää, koska sillä ei ole yhtään faktoja, joihin nojata. Yksinkertaisin tapa tuoda kuvaan mukaan dataa on laittaa se mukaan promptiin.

Edellinen ohje datalla höystettynä voisi näyttää tältä:
You are a friendly bot answering to questions from employees of Foobar company. The questions are related to company internal processes and vary from holiday rules to collective bargaining agreement and payment processes. Please keep your answers short and concise.

#Company holiday rules
Employees are entitled to 25 vacation days per year, which can be taken with prior approval from their manager. National holidays are also observed.

# Company payment process

Salaries are processed on the last working day of each month and are directly deposited into employees’ bank accounts

The user wants to know:
Milloin on palkkapäivä?



Yllä oleva osaisi todennäköisesti jo hieman enemmän. Mutta entä sitten kun dataa on paljon? Usein dataa on lukemattomista eri aiheista ja lähteistä niin iso määrä, että se ei kerralla mahdu promptiin. Siinä ei myöskään olisi järkeä, koska mieluiten haluttaisiin ohjeita, jotka jollain tavalla liittyvät kysymykseen johon ollaan vastaamassa. Järkevämpää on, että ensin haetaan relevanttia dataa ja laitetaan vain oleellinen mukaan promptiin. Tästä tavasta, jossa ensin haetaan dataa ja sitten laitetaan sitä promptiin, käytetään nimeä RAG (Retrieval-Augmented Generation).

Vektorihaku

Joissain tapauksissa esimerkiksi perinteinen relaatiokanta riittää tiedon hakemiseen. Jos halutaan tehokkaasti etsiä vastauksia isosta tekstimassasta, tarvitaan vektorikantoja ja vektorihakua.

Vektorihaku toimii ns. vektoriupotusten (vector embedding) avulla. Upotuksilla on koneoppimisen ja etenkin NLP:n yhteydessä pitkä historia, mutta tässä yhteydessä keskitytään suurten kielimallien kanssa käytettäviin upotuksiin. Vektoriupotus on pala tekstiä, joka on muunnettu pitkäksi jonoksi numeroita eli vektoriksi. Jokainen jonon numeroista on koordinaatti vektoriavaruudessa. 3-ulotteisessa vektorissa on 3 koordinaattia, vektoriupotuksessa yleensä satoja tai tuhansia. Vektoriupotuksen ideana on saada keskenään samanlaiset käsitteet lähekkäin koordinaatistossa.

Upotukset luodaan käyttämällä siihen erikoistuneita neuroverkkoja, jotka ottavat sisään tekstiä ja tuottavat vektoreita. Näistä pienempiä malleja voi ajaa lokaalisti tai isompia, kuten esimerkiksi OpenAI:n upotusmalleja, käyttää rajapintojen kautta.

Data tallennetaan vektorikantaan siten, että indeksoitavat dokumentit pilkotaan palasiin. Jokaiselle palaselle lasketaan vektoriupotus, jonka jälkeen tekstinpala, upotus sekä niihin liittyvä metadata (sivunumero, linkki, tagit, mitä vain) viedään vektorikantaan. Esimerkkejä vektorihakua tukevista tietokannoista ovat Azure AI Search, Pinecone, ChromaDB , AWS OpenSearch sekä PostgreSQL pgvector-lisäosalla.

Kun ollaan hakemassa dataa hakusanalla tai kysymyksellä, kysymys muunnetaan ensin vektoriupotukseksi. Tämän jälkeen tehdään vektorihaku, eli etsitään N kpl vektoreita, jotka ovat koordinaatistossa lähimpänä vektoroitua kysymystä. Lähimpänä olevat vektorit etsitään sopivalla metriikalla, kuten kosinietäisyydellä.

Kun hakutulokset ovat tiedossa, ne voidaan antaa kielimallille osana promptia, jonka jälkeen kielimalli pystyy vastaamaan kysyttyyn aiheeseen huomattavasti paremmin. Aiemmin esitetty esimerkki voisi vektorihaun tulosten kanssa näyttää tältä (3 osuvinta hakutulosta mukana promptissa):
You are a friendly bot answering to questions from employees of Foobar company. The questions are related to company internal processes and vary from holiday rules to collective bargaining agreement and payment processes. Please keep your answers short and concise.

# Context
– Employees are entitled to paid leave on all national public holidays.

– If a public holiday falls on a weekend, employees will receive an additional day off during the same month.

– Work on a public holiday is compensated at double the regular hourly rate.


The user wants to know:
Mitä työehtosopimus sanoo arkipyhistä?

Kielimallin hienosäätö eli finetuning

Useimmiten ohjeiden ja datan yhdistelmällä saadaan riittävän hyviä tuloksia, mutta joskus se ei riitä. Syitä tähän voivat esimerkiksi olla:
– sovellusalue saattaa olla niin spesifi (lähtien käytetyistä termeistä ja niiden merkityksistä) että yleinen kielimalli ei selviä riittävän hyvin
– halutaan säätää kielimallin käyttämää tyyliä/sävyä tarkasti ja niin, että se käyttää sitä aina riippumatta promptista ja datasta

Promptien ja datan käyttö eivät muuta itse kielimallin rakennetta, mutta mallin hienosäätö muuttaa. Hienosäädön ideana on ottaa joukko dataa, esimerkiksi kysymys-vastauspareja, ja niiden avulla säätää itse mallin parametreja. Hienosäädössä voidaan päivittää joko kaikkia mallin parametreja (vie enemmän aikaa ja resursseja) tai käyttää menetelmiä, jotka päivittävät vain osaa mallin parametreista.

Hienosäädön kustannus riippuu mm. koulutukseen käytetyn datan määrästä ja mallin koosta. Myös hienosäädetyn mallin ylläpitäminen pilvessä maksaa yleensä huomattavasti enemmän kuin perusmallin, koska silloin malli on käytössä vain yhdellä toimijalla. Tässäkin hinnoittelu vaihtelee eri palveluntarjoajien välillä.

Protosta sovellukseksi

Kun protosta päätetään rakentaa varsinainen sovellus, alkaa työ muistuttaa enemmän perinteistä sovelluskehitystä, jonka yksityiskohdat riippuvat ympäristöstä, johon sovellusta rakennetaan. Kielimallit itsessään eivät rajoita käytettäviä teknologioita, koska REST-rajapintaa voi käyttää mistä tahansa, mutta kirjastotuki on kattavinta Python- ja Javascript/Typescript -maailmoissa.

Yleisimpiä kysymyksiä ovat ainakin: 

  • Ketkä sovellusta tulevat käyttämään? Miten autentikointi ja autorisointi hoidetaan?
  • Mitä teknologioita käytetään?
  • Miten sovellus sovitetaan olemassaolevaan arkkitehtuuriin ja infraan?
  • Mitä resursseja sovellus tarvitsee toimiakseen?
  • Mihin se integroidaan?
  • Miten sovelluksen tarvitsemaa dataa päivitetään?
  • Miten sovellusta monitoroidaan?

Sovellustakin rakentaessa nopea iterointi ja pienissä palasissa eteneminen on eduksi. Varsinkin jos ollaan rakentamassa bottia, puolivalmiiden kirjastojen ja komponenttien hyödyntäminen kannattaa ehdottomasti, esimerkkeinä vaikkapa Pythonille Chainlit ja Javascript-maailmaan BotUI. Jos teknisempi kuvaus ja koodi kiinnostaa, perustason botin rakennukseen voit tutustua myös viime syksynä julkaisemamme tutoriaalin avulla.

Luoto ja GenAI-ratkaisut

Luoto ja ekosysteemiyhtiöt ovat tunnettuja luotettuina ja osaavina kumppaneina ohjelmistohankkeiden eri osa-alueilla. Olemme panostaneet voimakkaasti myös GenAI-kyvykkyytemme kehittämiseen. Teemme sekä sisäisiä GenAI-kehitysprojekteja oman liiketoiminnan tarpeisiin että rakennamme ratkaisuja useissa eri asiakasympäristöissä.

Olemme mukana ensimmäisistä ideoinneista monimutkaisten kokonaisuuksien toteuttamiseen. Roolimme voi olla valmentava, tai voimme huolehtia koko toteutuksesta.

Mietitäänkö teillä, miten GenAI:ta voisi hyödyntää? Ota yhteyttä ja jutellaan lisää.