ABONAMENTE VIDEO REDACȚIA
RO
EN
Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 146
Abonament PDF

Studiu de caz: crearea unei aplicații CookBook ce integrează AI

Timea Fodor
FullStack Developer @ msg systems Romania



PROGRAMARE


Inteligența Artificială revoluționează modul în care interacționăm cu tehnologia. Ușurința de utilizare și accesibilitatea transformă treptat o multitudine de domenii, îmbunătățirea aplicațiilor fiind una dintre direcții. Unele dintre exemple sunt îmbunătățirea experienței clienților și identificarea de inovații în crearea de conținut.

În acest studiu de caz, am încercat să transform o aplicație simplă care prezintă rețete pe baza ingredientelor și a numelui rețetelor dintr-o bază de date PostgreSQL. În acest sens, am integrat o componentă Large Language Model (LLM), Retrieval Augmented Generation (RAG) și un model customizat.

Setări inițiale

Am pornit de la o aplicație creată cu NextJS și care avea o bază de date Supabase. Aplicația în sine este destul de simplă: o pagină ce permite căutarea de rețete pe bază de ingrediente și de nume de rețetă; o pagină ce expune rezultatele, unde fiecare rezultat poate fi accesat ca o nouă pagină ce deschide rețeta și detaliile acesteia.

Am dorit să îmbunătățim funcționalitățile acestei aplicații prin intermediul LLM, astfel încât criteriile de căutare să fie mai largi și personalizate pentru utilizatori. În acest sens, am folosit frameworkul Ollama și RAG, în loc de a face căutare bazată doar pe interogări simple.

Ce este RAG?

În general, componentele LLM sunt potrivite pentru multiple activități de procesare a limbajului natural. Răspunsurile generate de acestea pot fi precise, corecte, cu alte cuvinte exact ceea ce trebuie unui utilizator. Totuși, aceasta nu este o regulă.

Sunt situații când o întrebare adresată către ChatGPT produce un rezultat ce pare incorect sau înșelător, în ciuda nivelului aparent de încredere pe care îl afișează modelul. Verificarea ulterioară a informației arată că LLM-ul a "mințit". Acest fenomen se numește halucinație. Modelele cu utilizare generală sunt pre-antrenate pe volume mari de date din surse variate, dar sunt insuficient de fiabile în cazuri unde este nevoie de informație de ultimă oră, informație specifică unui domeniu, verificare factuală de informații etc.

Retrieval Augmented Generation are drept obiectiv înlăturarea acestei probleme, combinând generarea avansată de text a unui LLM cu o operație de căutare semantică menită să extragă informație precisă și relevantă contextual. Aceasta funcționează astfel:

  1. Utilizatorul scrie și trimite o interogare care este trimisă mai departe unui LLM embedded.

  2. Modelul transformă interogarea într-un "vector embedded" care este comparat cu vectorii altor date de intrare din baza de date cu vectori.

  3. Cele mai relevante rezultate din baza de date cu vectori sunt transmise mai departe unui LLM generativ care le folosește ca parte a promptului pentru a genera rezultatul final.

  4. Acest rezultat ajunge la utilizator.

Pentru a implementa acest algoritm, trebuie să înțelegem ce este un embedding. Componentele embedding sunt reprezentări avansate ale unor vectori. Acești vectori înțeleg sensul unui cuvânt plasând cuvintele într-un spațiu vectorial continuu. Cuvintele cu sensuri similare sunt reprezentate de vectori care sunt apropiați în acest spațiu. Modelele embedding folosesc "componente embedding contextuale" ce țin cont de mecanismul de atenție al arhitecturii unui Transformer pentru a distinge același cuvânt în contexte diferite (în funcție de cuvintele ce se află în jurul unuia și aceluiași cuvânt). Prin urmare, unul și același cuvânt poate avea embeddinguri diferite bazate pe context. Cele mai folosite embeddinguri contextuale sunt ELMo și BERT.

Configurarea unui LLMs

Pentru a descărca un LLM, trebuie să instalăm Ollama, o platformă gratuită ce ne permite să rulăm LLM-uri pe mașini locale. Pentru acest studiu de caz, am folosit modelul embedding all-minilm și modelul llava-llama3 pentru generare de text și interpretare de imagini.

Există mai multe feluri de face acest lucru, dar cel mai simplu poate fi din terminal, rulând:

ollama run all-minilm
ollama run llava-llama3

Dacă modelele nu se află pe mașina locală, Ollama le va aduce pentru noi.

Customizând modelul llava-llama3, putem să îi îmbunătățim performanța. De exemplu, putem seta un mesaj detaliat de sistem:

/set system "You are an expert in food, culinary arts, and gastronomy. Your primary focus is to provide detailed, accurate descriptions of food items…"

Este important de remarcat că, pe măsură ce este mai detaliat mesajul de sistem, pe atât mai bună va fi generarea de text. Rezultatul modelului se poate îmbunătăți semnificativ dacă definim rolul, criteriile generale, studiile de caz concrete, tonul, stilul și câteva scenarii pe post de exemple.

Mai departe, putem salva modelul nostru customizat (numit foodie) cu:

/save foodie

Ajustarea bazei de date

Cel mai important detaliu în selectarea unei baze de date este ca aceasta să ofere suport pentru vectori. Supabase oferă acest lucru prin intermediul pgvector. În plus, trebuie să adăugăm o coloană ce include vectorul embedded pentru fiecare rețetă. Valoarea embedded trebuie să fie cât mai detaliată pe cât posibil.

Implementarea RAG

Din moment ce Ollama nu oferă suport pentru embedding de tip imagine, dacă includem imagini, trebuie să cerem modelului să o descrie și să includă acea descriere alături de elementele căutate.

messageToEmbed = message;
…
if (image) {
  const arrayBuffer = await image.arrayBuffer();
  const uint8Array = new Uint8Array(arrayBuffer);
  const images = [uint8Array];

  const generateResponse = await ollama.generate({
    model: "foodie",
    prompt:
     "Try to guess the food on this image. Do not 
      detail the plating, aesthetics, focus only on 
      the food and what it could be made of.",
      images,
    });
    messageToEmbed += " " + 
      generateResponse.response;
    }

Rezultatul, adică messageToEmbed, va fi inclus de modelul all-minilm:

try {
  const embeddingsResponse = await ollama
   .embeddings({
      model: "all-minilm",
      prompt: messageToEmbed,
    });
const embeddedMessage = embeddingsResponse.embedding;

Căutarea de tip vectorial este efectuată în Supabase, folosindu-se distanța cosine pe post de metrică de similaritate ce va returna primele trei rețete relevante.

Următorul pas este reprezentat de ceea ce diferențiază RAG de căutarea semantică: rezultatul este transformat folosind un model generativ, adăugând exact trei etichete (tags) fiecărei rețete din rezultatul generat de modelul nostru (modelul foodie):

const detailedRecipes = await Promise.all(
  data.map(async (recipe: Recipe) => {
    const generateTags = await ollama.generate({
      model: "foodie",
      prompt: `Generate exactly 3 tags for this 
               recipe: ${JSON.stringify(
      recipe
      )}, separated by comma`,
    });

    const tags = generateTags.response.split(",")
                .map((tag) => tag.trim());

        return { ...recipe, tags };

Generarea creativă de conținut

Implementarea inițială permitea ca detaliile unei rețete să poată fi accesate după efectuarea unei căutări, dând click pe rețetă. Drept urmare, toate informațiile relevante, precum timpul de gătit, ingredientele și pașii apăreau pe ecran, dar le lipsea descrierea în sine a rețetei.

Pentru a îmbunătăți aplicația, putem personaliza informația pe care utilizatorii o văd. Pentru a realiza acest lucru, putem salva descrierea în "messageToEmbed" deja calculat, practic în locul unde atât descrierea imaginii, cât și criteriile de căutare sunt calculate. Dacă utilizatorul dă click pe o rețetă care a fost returnată de RAG, apoi utilizatorul accesează pagina de detalii, putem genera o descriere a rețetei pe baza criteriilor de căutare ale utilizatorului.

const prompt = `In exactly 2 sentences explain why this recipe is exceptional, based on the user's search criteria. Highlight the flavors and experience without listing steps or ingredients. Be persuasive and concise. This is the recipe: ${JSON.stringify(
   recipe
   )}. User's search criteria: ${userInput}`;      

  const generateDescription = await ollama.generate({
    model: "foodie",
    prompt,
  });

  description = generateDescription.response;

  return NextResponse.json({ description });

Considerații finale

După cum s-a arătat mai sus, LLM-urile pot îmbunătăți aplicațiile noastre prin personalizarea rezultatelor și prin extragerea de interpretări ale datelor noastre. Acestea sunt unelte puternice care vor fi, cel mai probabil, utilizate la scară largă. Totuși, când decidem să integrăm LLM-uri în aplicațiile noastre, ar trebui să ținem cont și de alte aspecte.

Unul din cele mai importante aspecte este securitatea datelor. Securitatea datelor reprezintă una din principalele preocupări ale clienților, întrucât păzirea informațiilor sensibile este crucială pentru menținerea încrederii și a conformității cu standardele. Precum s-a arătat în exemplul de mai sus, modelele locale pot fi folosite în locul celebrelor LLM-uri, dar această alegere are nevoie de investigații suplimentare înainte de integrarea unui LLM în aplicațiile voastre.

Un alt aspect de luat în calcul este de a evalua dacă merită introdusă încă o dependință în aplicație, în măsura în care aceasta poate presupune mentenanță suplimentară în viitor.

În ultimul rând, datele de antrenament pot genera prejudecăți care trebuie gestionate pentru a asigura rezultate corecte și fiabile.

Ținând cont de aceste aspecte, putem folosi LLM-urile pentru a îmbunătăți aplicațiile, respectând principiile de securitate și fiabilitate.

Referințe

[1] Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, L., & Polosukhin, I. "Attention is All You Need." 6 Dec. 2017.

[2] Lewis, Patrick, et al. "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks."

[3] Mehul, J. "RAG: Part 3: Embeddings." Medium, https://medium.com/@j13mehul/rag-part-3-embeddings-ff415eb9fed9.

[4] "Explained: Tokens and Embeddings in LLMs." The Research Nest, Medium, https://medium.com/the-research-nest/explained-tokens-and-embeddings-in-llms-69a16ba5db33.

[5] Ollama. GitHub, https://github.com/ollama/ollama/tree/main/docs.

[6] Johnson S., Unsplash, https://unsplash.com/photos/a-computer-circuit-board-with-a-brain-on-it-_0iV9LmPDn0.

LANSAREA NUMĂRULUI 149

Marți, 26 Octombrie, ora 18:00

sediul Cognizant

Facebook Meetup StreamEvent YouTube

NUMĂRUL 147 - Automotive

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects