În ultimii ani, modelele de limbaj de mari dimensiuni (LLM - Large Language Models) au redefinit modul în care organizațiile procesează date și interacționează cu tehnologia. De la chatboturi conversaționale sau asistenți pentru generare de cod, la sisteme complexe de suport decizional și generare de conținut, LLM-urile au devenit omniprezente în peisajul tehnologic cotidian. Dat fiind faptul că aceste modele necesită o putere de calcul și capacitate de stocare considerabile, tind să fie găzduite în cloud și accesate prin intermediul unor API-uri comerciale, ceea ce ridică întrebări legate de confidențialitate, costuri recurente și control asupra datelor.
Tot mai multe echipe tehnice explorează alternativa: rularea locală a LLM-urilor (i.e. self-hosted), folosind modele open-source și infrastructură proprie. Această abordare promite autonomie, costuri mai predictibile și un control mai mare asupra comportamentului modelului - dar vine și cu provocări semnificative.
În acest articol, vom explora avantajele și limitările LLM-urilor self-hosted, cu accent pe aspecte precum costuri, cazuri de utilizare, provocări tehnice și ideea prompturilor (instrucțiuni textuale formulate de utilizator pentru a obține un răspuns relevant de la model) ca proprietate intelectuală. În a doua parte, vom prezenta un studiu de caz concret: cum am implementat un LLM local folosind llama.cpp, ce arhitectură am ales, ce obstacole am întâmpinat și ce am învățat din acest proces.
Argumentul principal în favoarea rulării locale a unui model LLM este controlul deplin asupra datelor. În contextul în care organizațiile gestionează informații confidențiale - de la date personale ale angajaților, la documentație internă, cod sursă sau strategii de business - externalizarea acestor date către un serviciu cloud ridică riscuri semnificative. Chiar și cu promisiuni de confidențialitate din partea furnizorilor de LLM-uri comerciale, datele pot fi supuse unor politici externe de stocare sau audit. Prin rularea locală, organizația păstrează datele în interiorul infrastructurii proprii, gestionând accesul și retenția conform politicilor interne.
Pe lângă aspectele legate de securitate, soluțiile self-hosted oferă costuri mai predictibile. În locul unui model de tarifare bazat pe volum (tokens, requests), organizațiile pot investi într-o infrastructură proprie și pot scala în funcție de nevoi, fără grija costurilor variabile lunare.
Nu în ultimul rând, modelele locale pot fi personalizate și integrate mai ușor în ecosistemul tehnologic intern. De la adaptarea prompturilor la specificul domeniului, până la integrarea cu surse de date interne, flexibilitatea este semnificativ mai mare decât în cazul soluțiilor comerciale din cloud.
Printre cele mai frecvente scenarii de utilizare pentru LLM-urile self-hosted se numără:
Chatboturi interne pentru suportul angajaților sau al clienților, cu acces la baze de date private;
Sisteme de suport tehnic care pot răspunde la întrebări recurente folosind documentația internă;
Aceste aplicații devin cu atât mai valoroase, cu cât datele implicate sunt sensibile sau specifice domeniului de activitate.
Desigur, autonomia vine cu un preț. Modelele LLM necesită resurse hardware considerabile - de la memorie RAM și spațiu de stocare, până la acceleratoare hardware (GPU-uri) pentru inferență performantă. Aceste cerințe pot genera costuri inițiale semnificative.
Implementarea și mentenanța unui astfel de sistem presupun o curbă de învățare și o echipă tehnică pregătită să gestioneze actualizări, optimizări și eventuale probleme de performanță.
În plus, modelele open-source nu beneficiază de actualizări automate sau de fine-tuning continuu, așa cum se întâmplă în cazul soluțiilor comerciale. Astfel, calitatea răspunsurilor poate varia în funcție de domeniu și de prompturile utilizate.
Un aspect adesea trecut cu vederea este valoarea prompturilor bine construite. Într-un sistem self-hosted, aceste prompturi - fie ele template-uri, instrucțiuni de sistem sau exemple concrete - devin parte din know-how-ul organizației.
Ingineria prompturilor nu este doar o abilitate tehnică, ci și o formă de capital intelectual. Prompturile optimizate pentru un anumit domeniu sau flux de lucru pot face diferența între un model util și unul inutilizabil. În acest sens, ele devin un avantaj competitiv greu de replicat.
Scopul experimentului pe care îl vom expune în acest articol a fost de a automatiza procesul de transformare a NOTAM-urilor (Notice to Airmen), mesaje de notificare pentru personalul aeronautic cu privire la starea navigației aeriene, proceduri sau pericole, în echivalentul lor digital - DNOTAM (Digital NOTAM), în speță scenariul [TWY.CLS] - închiderea unei piste de rulare (taxiway). Acest proces presupune extragere de informații din texte semi-standardizate, cu formulări libere și variate, și procesarea lor în vederea creării unui mesaj în format digital standardizat (bazat pe XML). În cadrul experimentelor noastre am ales să extragem informația într-un format JSON intermediar, urmând ca ulterior acest JSON să fie procesat pentru a construi mesajul DNOTAM complet.
Figura 1: Arhitectura sistemului pentru procesarea mesajelor NOTAM utilizând un model LLM local (Phi-3.5) rulat prin llama.cpp
În trecut, am mai abordat această problemă pentru alte scenarii (de exemplu, activarea spațiului aerian) folosind metode NLP clasice, precum rețele LSTM și recunoaștere de entități. De această dată, am dorit să explorăm potențialul modelelor LLM în rezolvarea aceleiași sarcini, având în vedere diversitatea mai mare a formulărilor întâlnite în mesajele legate de taxiways.
Pentru testare, am utilizat Ollama, llama3.java și llama.cpp, însă în acest articol vom detalia implementarea bazată pe llama.cpp, datorită controlului mai granular asupra execuției și a performanței mai bune în contextul nostru hardware.
Pentru rularea locală a modelului de limbaj am utilizat llama.cpp, o bibliotecă open‑source care permite inferența modelelor din familia LLaMA pe hardware obișnuit. Biblioteca a fost compilată cu suport CUDA, pentru a beneficia de accelerarea GPU, și configurată cu quantizare Q4_K_M, reducând semnificativ consumul de memorie fără a afecta substanțial acuratețea.
Experimentele au fost realizate pe un sistem on‑premises, cu următoarea configurație:
CPU: AMD Ryzen 7 7800X3D (8C / 16T)
RAM: 128 GB DDR5
GPU: NVIDIA GeForce RTX 4070 (12 GB VRAM)
Această configurație a oferit un echilibru bun între performanță și cost, permițând rularea locală a unui model de dimensiune medie cu timpi de răspuns de ordinul secundelor, fără a apela la infrastructură cloud.
Am evaluat mai multe modele open‑source de pe HuggingFace de dimensiuni reduse, adecvate pentru rulare pe sisteme locale sau dispozitive mai mici: phi‑3.5, phi‑4 și LLaMA 3. Testele au fost realizate pe un set comun de scenarii de inferență, incluzând prompturi simple, few‑shot și formulări bazate pe un DSL specific domeniului.
Evaluarea internă a urmărit precizia extragerii și completitudinea informației. Rezultatele au indicat phi‑3.5 ca fiind cea mai bună opțiune: pentru extragerea de date structurate în format JSON, acesta a obținut o acuratețe medie de aproximativ 88%, semnificativ peste LLaMA 3 (~58%) și ușor peste phi‑4. În plus, phi‑3.5 a generat mai puține erori de formatare și a extras mai consistent atributele relevante.
Pe baza acestor rezultate, phi‑3.5 a fost ales pentru implementarea finală, oferind un compromis favorabil între acuratețe, stabilitate și eficiență pe hardware local.
Modelul a fost integrat într-un pipeline intern de preprocesare și postprocesare. Mesajele NOTAM sunt mai întâi normalizate, apoi trimise către un server local lansat cu llama.cpp. Acesta este apelat dintr-un backend intern scris în Python, iar răspunsul JSON generat este validat și folosit pentru statistici, putând fi mai departe integrat într-o aplicație dedicată. Fluxul de date complet poate fi observat în Fig. 1.
Pentru a ilustra modul în care am integrat modelul phi-3.5 prin llama.cpp în pipeline-ul nostru, prezentăm mai jos câteva fragmente de cod simplificate. Aceste exemple sunt menite să explice pașii esențiali; implementarea completă conține validări extinse, tratarea erorilor și optimizări specifice, care nu sunt incluse aici pentru a menține claritatea expunerii.
Înainte de a lansa aplicația, bibliotecile și modelul trebuie descărcate și plasate în directorul llama.cpp. În plus, pentru a forța modelul să producă răspunsuri JSON corecte, se poate adăuga un fișier de gramatică (json.gbnf) în acel folder. Serverul se pornește direct din terminal, folosind modelul ales (în exemplu, phi-3.5) și indicând gramatica:
llama-server `
-m "<>\phi-3.5-mini-instruct-q4_k_m.gguf" `
--grammar-file "json.gbnf"
Această comandă lansează un server local, care pre-încarcă modelul phi-3.5 și aplică regulile din gramatică pentru a limita outputul la format JSON valid.
După pornirea serverului, putem interacționa cu modelul din orice limbaj care poate trimite cereri HTTP. Exemplul de mai jos, scris în Python, arată cum se construiește un prompt combinând instrucțiunile generale cu un NOTAM și cum se trimite cererea către endpointul /completion.
import json
import requests
URL = "http://localhost:8080/completion"
MODEL = "phi-3.5-mini-instruct-q4_k_m.gguf"
def send_notam(notam: str):
prompt = (
"You are an assistant that converts a NOTAM "
"into a DNOTAM JSON.\n"
f"NOTAM: {notam}\n\nOUTPUT:"
)
r = requests.post(
URL,
json={
"prompt": prompt,
"model": MODEL,
"n_predict": 512,
"temperature": 0.1,
"stream": False,
},
)
r.raise_for_status()
data = r.json()
choices = data.get("choices") or [{}]
text = data.get("content") or choices[0].get("text", "")
return json.loads(text) # Parse to dict/list; raises if invalid
print(
json.dumps(
send_notam("TWY B CLSD DUE WORKS."),
indent=2,
)
)
Primele testări au evidențiat mai multe limite ale utilizării LLM-urilor în acest context:
Inconsistența răspunsurilor generate - Modelul producea structuri JSON, însă nu întotdeauna corecte: unele răspunsuri erau incomplete sau conțineau câmpuri denumite incorect. Pentru a reduce aceste probleme, am introdus o gramatică GBNF care impunea forma generală a răspunsului. Această abordare a îmbunătățit consistența, însă nu a eliminat complet erorile de structurare.
Constrângeri legate de inferență și configurare - Modelul utilizat a fost cuantizat încă din faza inițială a experimentelor. Deși cuantizarea și ajustarea parametrilor de rulare (precum n_gpu_layers, threads sau dimensiunea contextului) au fost necesare pentru a face inferența fezabilă în mediul local, nu dispunem de date comparative care să cuantifice îmbunătățiri clare ale timpilor de răspuns, motiv pentru care acestea nu sunt discutate în detaliu.
În urma ajustărilor, sistemul a reușit să proceseze un mesaj NOTAM și să returneze structura JSON în 2-3 secunde în medie, cu o acuratețe generală de aproximativ 88% pe setul nostru de testare. Modelul phi-3.5 a demonstrat că poate extrage consistent atributul precum pista de rulare, intervalul de timp, motivul și remarcile relevante.
Privind dincolo de rezultatele modelului și abordând problema la modul general, dorim să evidențiem câteva aspecte importante:
Costuri hardware: investiția în echipament a fost deja acoperită printr-un proiect de cercetare anterior; pe termen lung, economiile aduse de evitarea unei interfețe API comerciale pot amortiza costurile inițiale.
Confidențialitatea datelor: în cazul NOTAM-urilor nu lucrăm cu informații sensibile, însă aceeași abordare se poate aplica în alte scenarii în care datele trebuie să rămână în infrastructura internă, fără a fi transmise către un furnizor extern.
Pe parcursul experimentelor am explorat și alte opțiuni pentru rularea locală a modelelor LLM:
Ollama: o platformă matură, cu suport extins pentru modele și o interfață prietenoasă. Este ușor de instalat și oferă integrare rapidă cu diverse aplicații. Totuși, flexibilitatea vine cu unele limitări: controlul asupra parametrilor de inferență este mai redus comparativ cu llama.cpp, iar integrarea în pipeline-uri personalizate poate necesita un efort suplimentar de personalizare.
În ultimii ani, tot mai multe organizații au analizat ideea de a-și rula propriile modele LLM local, încercând să cântărească avantajele și dezavantajele comparativ cu serviciile comerciale din cloud. Argumentele în favoarea unei implementări self-hosted sunt puternice: datele rămân exclusiv în infrastructura internă, ceea ce facilitează conformitatea cu reglementări precum GDPR și reduce riscul de expunere ingerințelor externe. În același timp, libertatea de a ajusta și adapta modelele la nevoile specifice, fără a depinde de furnizori terți sau de limite de trafic este crucială pentru aplicații sensibile sau cu volum mare. Chiar dacă presupune o investiție inițială mai mare în hardware și expertiză, costurile pe termen lung pot fi mai mici decât taxele pe interogare impuse de API-urile comerciale, mai ales dacă volumul de utilizare este ridicat.
Pe de altă parte, nu toate proiectele justifică un LLM self-hosted. Start-upurile sau organizațiile cu bugete restrânse pot fi descurajate de costurile hardware și de nevoia de personal specializat. De asemenea, pentru sarcini generale sau cu trafic fluctuant, serviciile cloud rămân o opțiune viabilă, oferind scalare automată și acces rapid la modele de ultimă generație.
În final, decizia înclină balanța în funcție de context: când datele sunt sensibile, volumul de solicitări este mare și se dorește control și personalizare, merită explorată varianta locală. În alte cazuri, un API comercial sau o abordare hibridă poate fi mai eficientă. Oricum ar fi, evoluția rapidă a comunității open-source și apariția modelelor tot mai eficiente fac din LLM-urile locale o direcție promițătoare, invitând dezvoltatorii și companiile să testeze și să contribuie la această nouă eră a inteligenței artificiale.