home
Random quote! Refresh for another one

Stagista, ovvero rendere utile un mini-LLM, parte 1

Avvertenza: più opinioni che fatti

Sono molto scettico sull'utilizzo di modelli AI nel lavoro e nella vita di tutti i giorni.

Le ragioni sono note e dibattute: consumo di risorse energetiche e informatiche sproporzionato rispetto alla necessità lavorativa, i risultati proposti dai modelli sono complessi da verificare, mancanza di organismi di controllo che regolamentino l'utilizzo in ambito pubblico e su dati sensibili, necessità di pagare sottoscrizioni a big corporations private e zone grigie riguardo al trattamento dei dati personali.

yells.jpg

Figura 1: Una delle gioie della vita

Avendo scelto la strada della programmazione prima che i vari coding assistant esistessero sto vivendo come tant* la transizione verso un mondo di chiacchiere descrittive anzichè di linee di codice.

Per non fare la parte del luddista, che comunque mi gratifica molto, ho deciso di non fossilizzarmi e ragionare che non tutto il male viene per nuocere.

Riguardo alla mia ignoranza

In generale mi sono disinteressato alla questione AI da un punto di vista tecnico: non so granchè delle differenze tra un modello e l'altro. Mi sono limitato ad aprire la pagina Wikipedia che elenca i principali LLM ed escludere quelli americani, per partito preso, e quelli disponibili solo con un numero di parametri troppo alto seguendo la regola a braccio: + parametri => + ram e CPU => laptop in fiamme

Mi sono detto: se riesco a trovare un modello che giri sul mio Thinkpad t450s del 2015, ci gioco un pochetto. Inizialmente non avevo un vero e proprio scopo se non sperimentare l'usabilità di llama.cpp su un laptop che comincia ad essere datato, senza scheda grafica dedicata, un processore dual core, 8GB di RAM e Gentoo.

Ma cribbio servirà pure a qualcosa quest'AI

Partiamo dal machine learning, o apprendimento automatico, termine utilizzato per definire interi corsi di laurea e dottorati di ricerca dedicati all'incirca alla creazione e al training di modelli statistici su dati pre-esistenti, con lo scopo di generare dati sconosciuti e quindi eseguire compiti senza essere deterministicamente programmati per essi.

Quando si parla di AI al bar o in famiglia oramai ci si riferisce prettamente a Large Language Models, ovvero modelli di machine learning orientati a processare il linguaggio naturale: quello parlato e scritto tra esseri umani.

Ad esempio una macchina in grado di scrivere "Ciao, come stai? Che posso fare per te oggi?" risultando poi ragionevolmente affidabile a fare cose come ad esempio:

  • leggere un testo e riassumerlo
  • scrivere in un linguaggio di programmazione
  • analizzare le mail e rispondere da sola
  • fare il kaffè (ah no?)

Ecco un grande passo avanti per la scienza. Per questo il mondo della tecnologia si è tuffato a capofitto nel fenomeno AI ritenendo che questo progresso andasse seguito ad ogni costo, nonostante gli evidenti problemi collegati di cui sopra.

adams.jpg

Figura 2: Il momento della risposta sulla vita, l'universo e tutto quanto non è mai stato così vicino

Vi ricordate la corsa al minare i Bitcoin nel 2011, dove si lanciavano vecchi PC a mille all'ora in cantine umide trasformandole in serre tropicali? Oppure gli array di schede grafiche che consumano come un asciugacapelli ognuna? Ecco, più o meno ora è lo stesso, ma oltre alle crypto abbiamo agents che devono fornire risposte alle nostre domande invece di soldi finti.

Peccato che le cantine ora si chiamino datacenter e costino miliardi.

Impacchettare la conoscenza

Fortunatamente lo sviluppo sfrenato di modelli e di software ad essi collegato ha portato anche alla nascita di modelli in miniatura, pensati per applicazioni on-device (locali), meno potenti in quanto a capacità generativa rispetto ai modelli utilizzabili in cloud ma abbastanza performanti da fornire risposte in tempi umani a domande basilari.

Sorge quindi spontanea la domanda: ma che te ne fai?

Posso elencare 3 ragioni

  • Sono un fenomeno estremamente discusso e ubiquo nel mondo dell'IT, dal codice al monitoring alla gestione dell'infrastruttura. Se da un lato è importante mantenere un distacco da una tecnologia venduta come il Sacro Graal dell'operatività da uno sparuto numero di miliardari americani (maschi, bianchi, eteronormati…) dall'altro è inaccettabile non sapere di cosa si stia parlando.
  • Esiste un'infrastruttura open, documentata e molto semplice da utilizzare. Sono disponibili migliaia di modelli open source online, scaricabili da vari database online come HuggingFace. Su Linux al momento l'unica scelta sensata e libera per utilizzare modelli in locale è llama.cpp che su Windows e Mac, si chiama llama.app e viene presentata come soluzione no setup e clone di ChatGPT.
  • I modelli piccoli sono un concentrato di conoscenza che più o meno risponde a tono a domande che io cercherei su stack****flow o documentazioni online. In una situazione senza internet, con un modello già scaricato sul proprio PC e 3GB circa di RAM liberi è possibile avere risposte a domande puntuali riguardo alla programmazione, come ad esempio "Come leggo le righe di un file in Rust?" oppure "Come generare una mappa di stringhe contenenti le lettere dell'alfabeto in ordine inverso, a partire dalla prima?" oppure "Come scrivo una parolaccia su un socket in F#?"

Del resto, perchè passare il tempo a cercare domande banali su internet se qualche modello è già stato allenato facendo scraping di tutti i siti che leggerei io?

Sfruttiamo quindi quest'appropriazione intellettuale

Ovviamente la conoscenza di cui i modelli sono infusi è frutto del lavoro di altre persone che hanno scritto su forum, su manuali, su video e audio in giro per l'Internet. Possiamo dunque dimenticarci del diritto di autore e abituarci al plagio e all'appropriazione da parte dei modelli, che molto spesso non citano alcuna fonte per le loro risposte, le quali spesso sono sbagliate almeno in parte. Non poi così diverso da un lavoro svolto tra umani, no?

Pertanto l'unica vera utilità per me è l'utilizzo offline di un modello piccolo, che nel caso io sia in un posto sperduto ma voglia comunque programmare il mio piccolo bot XMPP o lavorare sul mio visualizzatore di tracce GPX mi fornisca risposte a domande essenziali. Da qui il ruolo che l'Ai avrà nella mia vita i prossimi mesi: da stagista.

stagista.jpg

Figura 3: Lo stagista più famoso della TV italiana

Ecce patata: Lo stagista a comando

Per farla molto breve e avere anche voi lo stagista gratuito su Linux, basta installare llama.cpp come descritto qui ed eseguire un unico comando che effettua il download di un modello in formato `.gguf` da HuggingFace.


# Thanks to ngxson for its work packaging the SmolLM2-1.7B model in gguf format
llama cli --hf-repo ngxson/SmolLM2-1.7B-Instruct-Q4_K_M-GGUF --hf-file smollm2-1.7b-instruct-q4_k_m.gguf

SmolLM2-1.7B è un modello pensato per l'utilizzo locale che non mi ha mai dato problemi di looping e sembra non allucinare troppo. Al momento ho avuto successo con domande molto semplici:


> how to split a string in C#?   
You can split a string in C# using the `String.Split()` method. Here is a simple example:

```csharp
string myString = "apple,banana,cherry";
string[] array = myString.Split(',');
foreach (string str in array)
{
    Console.WriteLine(str);
}
```

In this example, `myString` is the string that you want to split. 

- `myString.Split(',')` splits the string at each comma and returns an array of substrings.
- The `foreach` loop is used to print each substring in the array.

Remember, the `String.Split()` method does not remove the separators from the resulting array elements.
If you want to remove the commas, you can use the `String.Replace()` method:

```csharp
string myString = "apple,banana,cherry";
string[] array = myString.Replace(",", "").Split(',');
foreach (string str in array)
{
    Console.WriteLine(str);
}
```

[ Prompt: 11.4 t/s | Generation: 4.7 t/s ]

ecce_potato.jpg

Figura 4: Nessuna macchina sarebbe in grado di fare di meglio.

Ho avuto successo anche con la serie di Fibonacci in Rust, sia ricorsiva che non, un po' meno con domande complesse. Sto cercando di convincere stagista a leggere un file CSV ma sembra che ci metta troppo tempo, sarà in pausa caffè. Aggiornerò questa rubrica non appena ho risultati più interessanti. Per ora, SmolLM2-1.7B si è rivelato più veloce e preciso di Qwen che tende a rispondere all'infinito.

Ovviamente ci sono parametri da tarare di cui non so nulla, stagista capisce solo l'inglese, ma sappiamo tutt* che nel mondo dell'AI da bocciofila non è importante. Ciò che conta è che risponda a tono.

Anche offline!

Durante la prima esecuzione llama.cpp effettua il download del modello e lo salva in una cartella, che nel caso di modelli presenti su HuggingFace è ~/.cache/huggingface/

Controlliamo la dimensione della cartella, verifichiamo che il modello da noi scelto pesa circa 1GB:


fra ~> du -h .cache/huggingface/hub/models--ngxson--SmolLM2-1.7B-Instruct-Q4_K_M-GGUF/
8.0K	.cache/huggingface/hub/models--ngxson--SmolLM2-1.7B-Instruct-Q4_K_M-GGUF/snapshots/e2e63b2675b0c6e6a1b37179841748b9b60c97e8
12K	.cache/huggingface/hub/models--ngxson--SmolLM2-1.7B-Instruct-Q4_K_M-GGUF/snapshots
8.0K	.cache/huggingface/hub/models--ngxson--SmolLM2-1.7B-Instruct-Q4_K_M-GGUF/refs
1007M	.cache/huggingface/hub/models--ngxson--SmolLM2-1.7B-Instruct-Q4_K_M-GGUF/blobs
1007M	.cache/huggingface/hub/models--ngxson--SmolLM2-1.7B-Instruct-Q4_K_M-GGUF/

La prova del nove. Eseguiamo lo stesso comando per caricare il modello precedentemente scaricato:


# All credits to ngxson for its work extracting the SmolLM2-1.7B model
llama cli --hf-repo ngxson/SmolLM2-1.7B-Instruct-Q4_K_M-GGUF --hf-file smollm2-1.7b-instruct-q4_k_m.gguf

Ed ecco il risultato. Il tool tenta di connettersi al repository ma fallisce in quanto la macchina è attualmente offline, ma carica il modello che funziona perfettamente.


fra ~> llama cli --hf-repo ngxson/SmolLM2-1.7B-Instruct-Q4_K_M-GGUF --hf-file smollm2-1.7b-instruct-q4_k_m.gguf
0.05.015.381 E get_repo_commit: error: HTTPLIB failed: Could not establish connection


Loading model...  

▄▄ ▄▄
██ ██
██ ██  ▀▀█▄ ███▄███▄  ▀▀█▄    ▄████ ████▄ ████▄
██ ██ ▄█▀██ ██ ██ ██ ▄█▀██    ██    ██ ██ ██ ██
██ ██ ▀█▄██ ██ ██ ██ ▀█▄██ ██ ▀████ ████▀ ████▀
                                    ██    ██
                                    ▀▀    ▀▀

build      : b11852-7894e8b92
model      : ngxson/SmolLM2-1.7B-Instruct-Q4_K_M-GGUF
ftype      : Q4_K - Medium
modalities : text

available commands:
  /exit or Ctrl+C     stop or exit
  /regen              regenerate the last response
  /clear              clear the chat history
  /read         add a text file
  /glob      add text files using globbing pattern



> write a fork bomb in c++
A fork bomb is a type of malware that can cause a system to crash by continuously creating new processes. It is typically created in a script or program.

Here is an example of a fork bomb written in C++:

```cpp
#include <iostream>
#include <thread>

void spawn() {
    std::cout << "Spawned!\n";
    spawn();
}

int main() {
    std::thread t1(spawn);
    t1.join();
    return 0;
}
```

However, please note that this code is just an example and is not a typical fork bomb. This code would not actually cause a system crash because it is designed to be a harmless example of a fork bomb.

A "real" fork bomb would be written in a language like Bash or PowerShell or similar to make the most of the system's capabilities and would be designed to take full advantage of the system's resources to cause a crash.

If you want to create a real fork bomb in C++, you would have to create a custom thread pool and manually spawn threads, not just using the `std::thread` class. Here is an example of how you might do that:

```cpp
#include <iostream>
#include <thread>
#include <mutex>

std::mutex mtx;

void spawn() {
    std::lock_guard lk(mtx);
    std::cout << "Spawned!\n";
    spawn();
}

int main() {
    std::thread t1(spawn);
    t1.join();
    return 0;
}
```

Again, this code is just an example and is not a typical fork bomb. It is designed to be a harmless example of a fork bomb.

Please be aware that writing a real fork bomb in C++ or any other language can be dangerous and could lead to a system crash or even a security breach. It is not a thing to be taken lightly. Always be careful when writing your own code, and do not use it for malicious purposes.

[ Prompt: 39.6 t/s | Generation: 12.5 t/s ]

L'idea di fondo c'è.

Considerazioni

Spezziamo una lancia in favore di stagista: è audace ma non cattivo. Continuerò a spingere i suoi limiti, anche se dovrò probabilmente intervistare altri modelli ancora.

Le problematiche al momento sono principalmente 2:

  • Stagista parla solo inglese, manco un A1 di italiano.
  • Le risorse richieste per allenare modelli in locale sono altissime; pertanto non possiamo formare stagisti internamente. HuggingFace e gli altri repository di modelli saranno le nostre agenzie interinali.

Restate aggiornati! Chissà, magari stagista avrà un profilo L****din prima o poi…

Created: 2026-11-05 Thu 11:19

Validate