Vektorer i databasen
Du kan förbättra resultatet av att använda stora språkmodeller (LLM) genom att ta hjälp av vektordatabaser (exempelvis Qdrant) för något mer kontextmedvetna svar.
Ett relativt vanligt behov när man använder sig av stora språkmodeller är att man behöver svar som inkluderar information som modellen i fråga inte är tränad på.
Detta dilemma går att lösa genom att konvertera sådan information till vektorer och lagra dessa i en databas som har stöd för att indexera och göra sökningar mot just vektorer.
Notera att dessa vektorer, som kallas inbäddningar, fångar den semantiska betydelsen av den data som har bäddats in.
Stora språkmodeller (LLM:er)
För att skapa dessa så kallade inbäddningar använder man sig av modeller specifikt lämpade för detta ändamål.
Om man, som jag, vill kunna köra språkmodellerna lokalt så kan man använda sig av programmet Ollama vilket gör att man får tillgång till ett lokalt API via vilket man kan kommunicera med önskad modell.
Modellerna laddar man ner lokalt, detta görs smidigt via ollama pull <modellnamn>
När jag kollar på Ollamas lista över populäraste modellerna för inbäddning så ligger dessa i toppen:
- nomic-embed-text — A high-performing open embedding model with a large token context window.
- mxbai-embed-large — State-of-the-art large embedding model from mixedbread.ai
- snowflake-arctic-embed — A suite of text embedding models by Snowflake, optimized for performance.
Man kan enkelt använda sig av Ollamas API för att generera vektorer för en given text.
$ export OLLAMA_HOST=localhost:11434
$ curl http://$OLLAMA_HOST/api/embeddings -d '{"model":"snowflake-arctic-embed:22m","prompt":"Athega grundades redan 1996."}'
{"embedding":[-0.18882769346237183,0.2260323464870453,-0.39999955892562866,0.15696017444133759,-0.6100883483886719,-0.2382824420928955,-0.3801445960998535,-1.1961348056793213,0.1434703767299652,-0.0746501088142395,-0.19834569096565247,0.5632953643798828,-0.26520317792892456,-0.32899045944213867,0.345439076423645,-0.18847623467445374,0.12632708251476288,-0.021235350519418716,-1.3690578937530518,0.1002238541841507,1.1675103902816772,0.4585186839103699,-0.0980106070637703,-0.04828576743602753,-0.5244278907775879,-0.24133801460266113,0.20960482954978943,-0.10017044842243195,-0.46644413471221924,-2.1678824424743652,0.45445963740348816,0.00251924991607666,-0.09017570316791534,-0.4948180019855499,0.07109862565994263,-0.39903438091278076,0.24677810072898865,-0.14950482547283173,-0.22752569615840912,-0.3884538412094116,-0.21851114928722382,0.3466642200946808,0.17338380217552185,0.14898407459259033,0.5642920136451721,0.49589040875434875,-0.09480932354927063,0.2870658040046692,-0.010927177965641022,0.4479326605796814,-0.2951125204563141,-0.1519293338060379,-0.49551406502723694,-0.550498366355896,-0.30695009231567383,0.17419855296611786,0.44847217202186584,-0.39700326323509216,0.12796758115291595,-0.33289846777915955,0.37866243720054626,0.5089653730392456,-3.6387674808502197,0.27244412899017334,0.8614378571510315,-0.019915945827960968,0.7825620174407959,0.0777798667550087,-0.4036986231803894,0.6247188448905945,-0.075248584151268,0.06814412772655487,-0.30296018719673157,-0.3532308042049408,0.29277077317237854,-0.1554775834083557,0.42786189913749695,0.09059780836105347,-0.10694223642349243,-0.5409708023071289,-0.3532765805721283,0.35946524143218994,0.7380738854408264,0.36556538939476013,-0.17581191658973694,0.4628639817237854,-0.5470167994499207,0.08532620966434479,0.20340299606323242,-0.39525091648101807,-0.1523929387331009,0.17867916822433472,0.5464344620704651,0.4028335213661194,-0.23062965273857117,0.5477423071861267,-0.2801942229270935,-0.23947173357009888,0.031742073595523834,3.7535929679870605,0.5738205313682556,-0.20948952436447144,0.3176042139530182,-0.5266517996788025,-0.03934717923402786,-0.14536824822425842,-0.1616453379392624,-0.4424569010734558,0.1850810945034027,0.1495758295059204,-0.2271069586277008,0.12439277768135071,-0.5669529438018799,0.19566920399665833,0.2960732877254486,0.7724828124046326,-0.5530921220779419,0.24177448451519012,0.032750096172094345,0.16590067744255066,-1.166520118713379,0.4068971574306488,-0.42613765597343445,-0.5339440703392029,0.06901426613330841,-0.5730804800987244,-0.13746625185012817,0.6204742193222046,-0.24043020606040955,0.04990212619304657,0.4150896966457367,0.14706146717071533,-0.8630397915840149,0.08742339164018631,-0.02248799055814743,-0.2790206968784332,0.5606024265289307,-0.41281789541244507,-0.1271285116672516,-0.455885648727417,0.10047633945941925,-1.359391212463379,1.4975367784500122,0.01210116408765316,1.2268563508987427,-0.005437653511762619,-0.040756955742836,-0.33234068751335144,-0.29766276478767395,-0.6062348484992981,0.1671804040670395,-0.1085120141506195,-0.040057502686977386,0.18802528083324432,1.2542284727096558,0.24479353427886963,-0.6044325828552246,0.09469419717788696,-0.7573079466819763,-0.2596057951450348,0.2897977828979492,-0.00592801533639431,0.3295215964317322,1.204839825630188,0.527709424495697,-0.49889472126960754,0.387007474899292,-0.5593054294586182,0.5632171034812927,0.03367441147565842,-0.4160923361778259,0.2782287299633026,0.05056861415505409,0.4176577031612396,0.02267366088926792,0.8658844232559204,-0.1505594551563263,0.6332945227622986,-0.3787396550178528,-0.6545153856277466,0.26714396476745605,0.9177296757698059,0.034053076058626175,-0.5364484786987305,0.25856679677963257,0.17568528652191162,0.645651638507843,0.08470761775970459,0.2111206352710724,0.9364684820175171,-1.092900276184082,1.1138160228729248,-0.7725265622138977,0.010470014065504074,0.03258197754621506,0.09553821384906769,-0.2530987858772278,0.3937576413154602,0.4755801856517792,-0.10455238819122314,0.20534050464630127,0.2114884853363037,-0.34152600169181824,-0.07144910097122192,0.08235849440097809,-0.43176451325416565,-0.17199769616127014,0.0867525115609169,-0.08301161229610443,-0.007739860564470291,-0.07774452865123749,-0.16380192339420319,0.4788553714752197,-0.09493500739336014,-0.2290177047252655,0.5086762309074402,0.34820103645324707,-0.15577837824821472,0.36887627840042114,0.6025668382644653,0.6828376054763794,0.49167367815971375,0.13933750987052917,-0.9758256077766418,0.028274741023778915,-0.49203962087631226,-0.5434192419052124,-0.6905521750450134,0.5054476261138916,-0.046765442937612534,0.37455782294273376,-0.001991886645555496,-0.1864078938961029,1.0553678274154663,0.3883928656578064,-0.3416140377521515,0.14414867758750916,0.2548806667327881,0.48716673254966736,-0.6073405742645264,0.5280838012695312,-0.20154663920402527,-0.05143338441848755,-0.04352479428052902,0.4530942142009735,-0.2055804431438446,0.23814904689788818,0.1774786114692688,0.016179032623767853,1.6223728656768799,0.783178448677063,-0.7955324053764343,0.3011959195137024,0.06925608962774277,0.09367021173238754,-0.08446107059717178,-1.729222297668457,-0.07787115126848221,-0.2822292149066925,0.7686655521392822,-0.16093173623085022,0.42902782559394836,-0.14985446631908417,0.005896816961467266,0.12689076364040375,0.2862291932106018,-0.22706212103366852,0.02873525768518448,0.08757070451974869,-0.2645665109157562,0.2814171314239502,0.9922921061515808,-0.24081042408943176,0.1537816822528839,0.2684158384799957,0.33454617857933044,-0.04199539124965668,-0.2701704204082489,-0.17860975861549377,0.34689003229141235,0.5412061810493469,-0.4246232211589813,0.6463500261306763,-0.025119274854660034,-0.28085729479789734,-0.8564736247062683,-0.3810987174510956,0.08972139656543732,-0.16166338324546814,-0.0038941651582717896,0.2679138481616974,0.3488039970397949,0.2908188998699188,-0.22674307227134705,1.3765301704406738,-0.12013226747512817,0.658076822757721,0.9497426748275757,-0.33069267868995667,-0.6589370965957642,-0.058509714901447296,-0.013538695871829987,0.4161022901535034,-0.17975158989429474,-0.47015926241874695,-0.505483090877533,0.01708865910768509,0.16129657626152039,0.17969509959220886,0.015130579471588135,-0.20076291263103485,-0.5525516271591187,0.4873291254043579,0.5859698057174683,0.43184694647789,-0.3523330092430115,0.13218101859092712,-0.06513381004333496,-0.4270475208759308,-1.975006341934204,-0.154206320643425,-0.028742697089910507,0.5830397605895996,-0.24134576320648193,-0.6120684742927551,0.25620442628860474,-0.36510133743286133,0.09901231527328491,-0.5014322400093079,0.30733969807624817,0.3638444244861603,0.14280830323696136,-1.0143474340438843,0.49400416016578674,0.6496044397354126,-0.044582679867744446,0.5353569984436035,-0.2326507270336151,-1.1415824890136719,-0.016555432230234146,0.2644641399383545,1.7535645961761475,0.12323059141635895,0.5255378484725952,-0.21627452969551086,0.06011461094021797,-0.3594464063644409,-1.5568379163742065,-0.021418340504169464,-0.528965413570404,-0.3912956118583679,0.5882479548454285,-0.4040752649307251,-0.34741857647895813,0.17011421918869019,0.6679895520210266,-0.5548747777938843,0.1798272281885147,0.11575090140104294,1.3892521858215332,-0.3109860122203827,-0.015021691098809242,-0.11601117998361588,0.5765765905380249,-0.8753777146339417,0.1849946528673172,0.24301613867282867,-0.35759294033050537,-0.04058492183685303,0.22611352801322937,-0.1485854834318161,-0.0180931705981493,0.43292924761772156,0.15517795085906982,0.49643176794052124,-0.2419595569372177,0.07287688553333282,0.42971187829971313,-0.2664320468902588,0.03580276668071747,-0.006592020392417908,-0.12234267592430115,-1.0227916240692139,-0.23390789330005646]}
(Arrayen för embedding är i detta fall 384 nummer, vilket motsvarar antal dimensioner för just denna modell, vilket är den minsta jag testat att använda. Det verkar vanligare att använda 768 dimensioner eller fler)
Om man även vill kunna generera svar så behöver man en modell som lämpar sig för detta, några modeller jag har testat med relativt gott resultat är:
- deepseek-r1:14b — Detta är en destillerad version av Qwen, skapad med DeepSeek-R1
- phi4:14b — Phi-4 is a 14B parameter, state-of-the-art open model from Microsoft.
- llama3.1:8b — Llama 3.1 is a new state-of-the-art model from Meta
Notera: Man bör välja en modell som är liten nog för att kunna laddas in i grafikkortets minne. Då Apple nuförtiden använder delat minne mellan CPU/GPU går det ofta bra att ladda in relativt stora modeller även om det inte alltid är lika snabbt som när man använder sig av ett dedikerat (eller flera) kort från Nvidia.
Resonerande modeller (som deepseek-r1:14b
) spenderar initialt tid på att “tänka” vilket kan leda till bättre slutresultat, men det tar ofta något längre tid innan den kommer fram till svaret.
Vektordatabaser
Det finns ett flertal alternativ när det kommer till databaser med stöd för att lagra vektorer; både mer etablerade databaser som PostgreSQL (via pgvector), SQLite (via sqlite-vec) och Elasticsearch men även några mer specifika lösningar som Qdrant och Milvus.
Om man redan använder PostgreSQL eller Elasticsearch skulle jag antagligen välja att använda dessa även för att göra vektorsökningar.
Jag fick ett rätt gott intryck av hur smidigt det var att komma igång med Qdrant i en container:
$ docker run -it --rm -p 6333:6333 -p 6334:6334 \
--name qdrant-server \
-v /home/peter/Data/Qdrant/qdrant_storage:/qdrant/storage:z \
-e QDRANT__SERVICE__API_KEY=SuperSecretQdrantKey \
qdrant/qdrant
Man kan då komma åt ett lokalt webbgränssnitt för Qdrant på https://localhost:6333/dashboard där man exempelvis kan visualisera de vektorer som ligger i en kollektion.
(I det specifika fallet ovan har jag importerat en lista med fiskarter som finns i Sverige, och färgat prickarna beroende på deras respektive livsmiljö)
LangChain
För att smidigt kunna utvärdera olika databaser för detta syfte kan det vara klyftigt att använda sig av någon abstraktion mellan olika “AI-byggstenar” som exempelvis LangChain (som har bibliotek för Python och JavaScript)
Jag föredrar språket Go framför Python och JavaScript, så det var fint att upptäcka att det finns ett liknande projekt som föga förvånande heter LangChainGo där man relativt smidigt kan beskriva olika steg som:
- Ladda in data (exempelvis från
CSV
) - Konvertering till “dokument”
- Skapa vektorer (för inbäddning med hjälp av en inbäddningsmodell)
- Lagring av vektorer i en vektordatabas
- Semantisk likhetssökning mot vektordatabasen
- Använda resultatet (från likhetssökningen i kontextet för en stor språkmodell, LLM)
qdrant-go
Om man vill ansluta till Qdrant ifrån Go kan man med fördel använda deras officiella bibliotek qdrant-go eller helt enkelt använda curl.
/ Peter