Crates.io | stonnx |
lib.rs | stonnx |
version | 0.1.3 |
source | src |
created_at | 2023-12-20 19:34:22.403046 |
updated_at | 2023-12-21 16:46:35.09462 |
description | A Rust library to run inference on ONNX models |
homepage | |
repository | |
max_upload_size | |
id | 1075809 |
size | 608,049 |
Il nome deriva dalla fusione di Steelix (pokemon di metallo, scelto perchè il progetto è scritto in Rust) e ONNX. Inoltre è anche un gioco di parole con stonks.
Il progetto consiste nella realizzazione di un interprete ONNX utilizzando il linguaggio Rust. Le richieste da rispettare sono le seguenti:
Scaricare i modelli ONNX utilizzando gli script download_models.ps1
(windows) o download_models.sh
(linux/macOS) presenti nella cartella scripts
oppure scaricarli manualmente da questo ed estrarli nella root del repository. Originariamente i modelli erano stati inseriti nel repository utilizzando git-lfs ma questo ha causato problemi con il repository fornitoci dal politecnico in quanto la quota di spazio e banda disponibile era troppo bassa;
Eseguire il comando cargo build --release
per compilare il progetto;
rayon
(per compilare con il parallelismo da noi implementato utilizzare il comando cargo build --features custom-threadpool --release
);Eseguire il comando cargo run --release -- --model <modelname>
oppure cargo run --release --features custom-threadpool -- --model <modelname>
modelname
è il percorso alla cartella contenente il modello. Nel caso il percorso sia relativo, verrà assunto relativo a $pwd/models
dove $pwd
rappresenta la cartella in cui risiede l'eseguibile. Nella cartello contenente il modello ci dovrà essere un file inputs.json
con il seguente schema:
{
"inputs": [
"<percorso verso input del modello>",
...
],
"outputs": [
"<percorso verso output attesi del modello>",
...
],
"modelpath": "<percorso al file .onnx contenente il modello>"
}
tutti i percorsi all'interno di questo file possono essere relativi o assoluti, se relativi, saranno assunti relativi a $pwd/models/$modelname
.
Dopo aver clonato il repository, ci saranno dei modelli non presenti all'interno della cartella models
, questi verranno scaricati automaticamente da internet durante la prima build del progetto.
Nel caso in cui si volesse visualizzare l'esecuzione degli operatori è possibile aggiungere l'opzione --verbose
al comando precedente (di default verbose è 0).
cargo run --release -- --model <modelname> --verbose 1
verbose = 0
: non visualizza nullaverbose = 1
: visualizza informazioni riguardanti l'esecuzione degli operatoriverbose = 2
: inserisce gli output di ogni operatore in un file .npy
verbose = 4
: inserisce anche gli output intermedi di ogni operatore in un file .npy
Un esempio di esecuzione del modello googlenet
è la seguente: cargo run --release --features custom-threadpool -- --verbose 0 --model googlenet-12
Inoltre può essere aggiunto il comando --gengraph
per generare file che poi possono essere usati per disegnare grafi dei modelli. Il programma può generare il grafo in un formato proprietario json
(che può essere letto da questo tool) oppure in generico formato dot
(da usare con graphviz). Il formato del grafo può essere controllato dall'opzione --graphtype
che può essere json
o dot
(default: json
). Il file generato sarà posto nella stessa cartella in cui risiede il modello eseguito.
Eseguire il comando cargo doc --open
per visualizzare la documentazione del progetto.
I modelli testati fanno riferimento a quelli presenti nella sezione archive del repository ufficiale di ONNX, in quanto a inizio Dicembre 2023 sono stati aggiornati e aggiunti nuovi modelli, ma lo sviluppo di questo programma è cominciato molto prima dell'aggiornamento del Model Zoo. I modelli testati sono i seguenti:
Nota: durante la scelta dei modelli è stato selezionata la versione più recente presente nella sezione archive del repository di ONNX.
Sono state utilizzate le seguenti crate:
src/main.rs
: file principale del progetto, contiene la funzione main e la gestione degli argomenti da linea di comando;
src/operators
: contiene i file con le implementazioni degli operatori ONNX;
Add
, AveragePool
, BatchNormalization
, Concat
, Conv
, Dropout
, Flatten
, Gemm
, GlobalAveragePool
, MaxPool
, MatMul
, Mul
, Relu
, Reshape
, Softmax
, Sum
, Transpose
;src/onnxparser
: contiene i file con l'implementazione del parser per estrarre le informazioni dal file ONNX;
build.rs
) dal compilatore di protobuf utilizzando la libreria protobuf_codegen
.src/executor
: contiene l'implementazione per l'esecuzione della rete, sono presenti:
rayon
) e la gestione della comunicazione tra i thread;src/parallel
: contiene i file per l'implementazione del parallelismo con threadpool;
rayon
(di default);--features custom-threadpool
);src/protograph
: contiene i file per l'implementazione della creazione di un file .json
contenente il grafo della rete;
src/protos
: contiene il file onnx.proto
utilizzato per la creazione del file .rs
contenente le strutture dati per la gestione dei file protobuf;
src/common/mod.rs
: contiene le strutture dati utilizzate per la gestione dei file ONNX;
verbose
;.json
contenenti il grafo della rete;opset_version
degli operatori;ArrayElement
);src/utils
: gestione di operazioni utili per la creazione dei tensori e la gestione di questi ultimi;
Il programma ha quattro step principali:
queue
(una coda sincronizzata per la gestione dei compiti), workers
(una collezione di thread) e una queuestate
(un contatore per tracciare il numero di operazioni in coda);
Condvar
, di conseguenza, uno dei thread liberi prende l'operazione e la esegue, quando questa viene completata, il thread notifica il thread principale che il compito è stato eseguito, il thread principale aggiorna il grafo delle dipendenze e aggiunge alla coda le operazioni che ora possono essere eseguiti, e così via, finchè non ci sono più compiti da eseguire;Mutex
e Condvar
per l'accesso sincronizzato alla coda e per la comunicazione tra i thread;Conv
, Exp
, Sqrt
, Pow
, MaxPool
, AveragePool
ma non solo. In particolare il parallelismo è stato introdotto nei punti dove vengono eseguiti loop molto pesanti, come ad esempio il calcolo della convoluzione, all'interno degli operatori, invece che usare il ThreadPool scritto da noi, viene utilizzata principalmente la feature di rayon degli iteratori paralleli;
Il programma viene compilato come libreria dinamica (.dll / .so / .dylib) con il nome stonnx_api
e può essere utilizzato normalmente attraverso i binding esposti.
Si è reso disponibile un binding verso i seguenti linguaggi:
I bindings, molto limitati per il momento, sono stati fatti mettendo a disposizione qualche funzione per la creazione della rete e l'esecuzione della stessa.
Vedi BENCHMARKS