npunlock: qualcuno ha aperto le NPU Intel ai kernel C personalizzati

Il progetto npunlock dimostra che le NPU Intel Core Ultra possono eseguire codice C personalizzato sui core ACT-SHAVE. Il progetto, ancora sperimentale, apre alla creazione di operatori AI custom e a un uso più flessibile della NPU senza dover riportare alcuni calcoli sulla CPU.

Dentro le NPU Intel Core Ultra ci sono processori programmabili: il problema è che lo sviluppatore non può semplicemente prendere un file C, compilarlo e chiedere alla NPU di eseguire il suo codice. L’autore di un progetto open source chiamato npunlock (repository GitHub) ha trovato una strada per farlo.

Il risultato è interessante non soltanto per quello che permette di fare, ma perché mostra molto bene che cosa distingue una NPU (Neural Processing Unit) da una GPU programmabile attraverso CUDA. Con npunlock diventa infatti possibile scrivere un kernel C personalizzato, compilarlo per una delle unità presenti nella NPU Intel e inserirlo dentro un normale grafo di calcolo. Il progetto funziona, almeno per ora, su Windows x64 con Meteor Lake e NPU 3720.

La cosa sorprendente è che tutto nasce mettendo insieme pezzi che Intel non aveva pensato come un normale ambiente di sviluppo per gli utenti.

Una NPU non è soltanto una “macchina per moltiplicare matrici”

Quando si parla delle NPU integrate nei chip Intel Core Ultra, l’idea comune è quella di associarle a una sorta di “acceleratore rigido”: si consegna una rete neurale al sistema e l’hardware esegue le operazioni per cui è stato progettato.

All’interno della NPU ci sono certamente unità specializzate per le operazioni tipiche del machine learning, come moltiplicazioni tra matrici, convoluzioni e calcoli sui tensori. Ma esistono anche core chiamati ACT-SHAVE, derivati dalla tecnologia Movidius acquisita a suo tempo da Intel.

Gli ACT-SHAVE sono molto flessibili: possono eseguire codice, usare diversi formati numerici e occuparsi proprio delle operazioni che non conviene affidare alle unità matematiche più specializzate. Quindi il codice programmabile è già nell’hardware; il problema è come ci si può arrivare.

Come funziona npunlock: non sostituisce il compilatore Intel

Con una GPU CUDA il modello è relativamente semplice: lo sviluppatore scrive un kernel, lo compila e lo esegue sulla GPU. Il sistema offre API documentate proprio per questo scopo.

Con le NPU Intel, invece, non si lavora così: lo sviluppatore consegna al compilatore un grafo, cioè una descrizione delle operazioni da eseguire. Il compilatore prende quel grafo e decide autonomamente come trasformarlo in qualcosa che la NPU possa eseguire.

Una parte può finire sulle unità specializzate per i tensori; un’altra sugli ACT-SHAVE. Il compilatore decide inoltre come trasferire i dati, dove collocarli in memoria, come sincronizzare le varie attività e in quale ordine eseguirle.

npunlock interviene sul risultato finale: individua uno dei kernel preparati per gli ACT-SHAVE e sostituisce il relativo codice macchina con quello scritto dall’utente. Il grafo continua ad avere tutta la struttura costruita dal compilatore Intel, ma una sua parte esegue codice diverso ovvero quello indicato da npunlock.

Come si compila il codice C che deve funzionare lato NPU?

Qui arriva la parte quasi “archeologica” della vicenda: per compilare il codice destinato agli ACT-SHAVE, npunlock usa MoviTools, una vecchia toolchain Intel/Movidius.

Lo sviluppatore del progetto non l’ha recuperata da un moderno pacchetto SDK Intel ma l’ha estratta da un vecchio pacchetto driver Lenovo: non serve installare quel driver né effettuare alcun downgrade; interessa soltanto una parte del pacchetto che contiene gli strumenti necessari a compilare codice per gli ACT-SHAVE.

Il kernel prodotto da MoviTools prende così il posto di quello presente nel grafo compilato da Intel. Ovviamente non viene eseguito il file C testuale: il sorgente è compilato nel codice macchina previsto per i core ACT-SHAVE ma dal punto di vista dello sviluppatore il risultato è precisamente quello che interessa. Si scrive cioè una funzione C e la si fa eseguire dentro la NPU.

npunlock è tuttavia ancora un progetto sperimentale: come osservato in apertura, il percorso oggi verificato riguarda Meteor Lake, NPU 3720 e Windows x64. Non significa che sia già possibile prendere qualunque programma C e lanciarlo sul ogni NPU Intel. Ci sono ancora molti vincoli relativi ai tensori, ai tipi di dati, alla struttura dei grafi e al modo in cui il compilatore decide di trasformare le operazioni.

Lo stesso progetto preferisce fermarsi quando la struttura prodotta dal compilatore non corrisponde a casi già verificati, piuttosto che modificare alla cieca il binario della NPU.

Cosa si può fare concretamente con npunlock

In termini pratici, npunlock permette di provare a spostare sulla NPU operazioni che normalmente non sarebbero gestite direttamente dallo stack Intel.

Uno sviluppatore potrebbe, per esempio, creare una funzione matematica personalizzata, adattare un passaggio particolare di un modello AI oppure combinare più piccoli calcoli in un unico kernel, evitando che quella parte del lavoro debba tornare sulla CPU.

I campi applicativi possono essere numerosi: intelligenza artificiale generativa, riconoscimento vocale, elaborazione audio, visione artificiale, trattamento delle immagini, quantizzazione dei modelli e conversioni numeriche. Certo, npunlock non è ancora pronto per tutti questi scenari, ma dimostra che gli ACT-SHAVE possono essere usati come piccole unità programmabili all’interno della NPU, invece di limitarsi esclusivamente agli operatori previsti dal compilatore Intel.

Il vantaggio più interessante, in prospettiva, è proprio questo: poter mantenere sulla NPU una parte maggiore dell’elaborazione, riducendo i casi in cui il sistema deve affidarsi alla CPU perché incontra un’operazione non supportata. npunlock, insomma, apre la strada a un utilizzo più flessibile dell’hardware già presente nei Core Ultra.

Ti consigliamo anche

Link copiato negli appunti