Skip to content

crnsh/onnx2mlgo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation


onnx2mlgo is an ONNX to MLGO transpiler.

Features:

  • Single CLI command to output Go files
  • Compatibility Checker shows all missing operators
  • Code generator

Currently this transpiler only transpiles a limited number of models. The CLI tells you which operations are missing and need to be implemented. Only ONNX models with initialized weights are supported.

You will have to manually import input data in the generated Go file.

If you find a bug, please let me know.

Installation

git clone git@github.com:crnsh/onnx2mlgo.git
cd onnx2mlgo
git submodule update --init --recursive
python3 -m pip install -r requirements.txt

For subsequent updates to the mlgo library, use the following command.

git submodule update --recursive --remote

Examples

Make sure you have Go installed!

This example shows how an MNIST ONNX model is transpiled to MLGO.

python3 onnx2mlgo/transpiler.py tests/mnist_fc.onnx -o mlgo/dist
cd mlgo/dist
go run model.go

To check whether the MNIST model works as expected, replace the main function of the transpiled model.go with the following main function.

func main() {

	model_weights_fname := "models/model-weights-f32.bin"
	ml.SINGLE_THREAD = true

	inputData := make([]float32, 784)

	// load a random test digit
	digitFile := "models/t10k-images.idx3-ubyte"
	fin, err := os.Open(digitFile)
	if err != nil {
		fmt.Println(err)
		return
	}
	// Seek to a random digit: 16-byte header + 28*28 * (random 0 - 10000)
	rand.Seed(time.Now().UnixNano())
	fin.Seek(int64(16+784*(rand.Int()%10000)), 0)
	buf := make([]byte, 784)
	if count, err := fin.Read(buf); err != nil || count != int(len(buf)) {
		fmt.Println(err, count)
		return
	}

	// render the digit in ASCII
	for row := 0; row < 28; row++ {
		for col := 0; col < 28; col++ {
			inputData[row*28+col] = float32(buf[row*28+col])
			var c string
			if buf[row*28+col] > 230 {
				c = "*"
			} else {
				c = "_"
			}
			fmt.Printf(c)
		}
		fmt.Println("")
	}
	fmt.Println("")

	output_tensor := model_eval(model_weights_fname, 1, inputData)

	ml.PrintTensor(output_tensor, "final tensor")

	maxIndex := 0
	for i := 0; i < 10; i++ {
		if output_tensor.Data[i] > output_tensor.Data[maxIndex] {
			maxIndex = i
		}
	}

	fmt.Println("Predicted digit is ", maxIndex)
}

Update imports.

import (
  "math"
  "math/rand"
  "time"
  "mlgo/ml"
  "os"
  "fmt"
  "errors"
)

Paste the MNIST input from the mlgo submodule to dist/models.

cp ../examples/mnist/models/mnist/t10k-images.idx3-ubyte models/

Run the model.go file.

go run model.go

The output should be the following.

____________________________
____________________________
____________________________
____________________________
____________________________
________________________**__
_____________*______******__
____________*************___
____________**********______
____________**______________
___________***______________
___________***______________
__________******____________
_________********___________
__________*******___________
_______________**___________
_______________**___________
_______________**___________
_______________**___________
________****___**___________
________****__***___________
________***__***____________
________*******_____________
_________*****______________
__________**________________
____________________________
____________________________
____________________________



=== [ final tensor | FP32 | 10:1:1 ] ===

 0 x 10 ...     -4070.744       -2108.515       -4699.833       -1760.301       -2717.388       2783.126        -4222.347   -5547.637986.424 -2058.314
Predicted digit is 5

About

ONNX to MLGO CLI transpiler.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages