dotnet / machinelearning

ML.NET is an open source and cross-platform machine learning framework for .NET.
https://dot.net/ml
MIT License
9.05k stars 1.89k forks source link

Load ONNX model creates temp file #5342

Closed ntpthinh closed 4 years ago

ntpthinh commented 4 years ago

System information

Issue

Please paste or attach the code or logs or traces that would be helpful to diagnose the issue you are reporting.

harishsk commented 4 years ago

Can you please share the code you are using to load the onnx model?

ntpthinh commented 4 years ago

I simply load the saved model by ITransformer trainedModel = mlContext.Model.Load(modelLocation, out DataViewSchema modelSchema);

Code for saving model:

            var pipeline = mlContext.Transforms.LoadImages(
                    outputColumnName: "image_object",
                    imageFolder: null,
                    inputColumnName: nameof(ImageData.ImagePath))
            // step 2: resize the images
            .Append(mlContext.Transforms.ResizeImages(
                outputColumnName: "image_object_resized",
                imageWidth: ImageSettings.imageWidth,
                imageHeight: ImageSettings.imageHeight,
                inputColumnName: "image_object"
               ))

            // step 3: extract pixels in a format the TF model can understand
            // these interleave and offset values are identical to the images the model was trained on
            .Append(mlContext.Transforms.ExtractPixels(
                outputColumnName: ModelSettings.inputTensorName,
                inputColumnName: "image_object_resized",
                interleavePixelColors: ImageSettings.channelsLast,
                offsetImage: ImageSettings.mean,
                scaleImage: ImageSettings.scale))
            .Append(mlContext.Transforms.ApplyOnnxModel(modelFile: _modelFilePath, outputColumnName: ModelSettings.outputTensorName, inputColumnName: ModelSettings.inputTensorName));

            ITransformer mlModel = pipeline.Fit(dataView);
            mlContext.Model.Save(mlModel, dataView.Schema, _outputModelFilePath);
harishsk commented 4 years ago

So, you have a .onnx file that you are loading in your pipeline with mlContext.Transforms.ApplyOnnxModel. And then you save the whole pipeline into another ML.NET model. And you see the temp file that doesn't get deleted while loading that ML.NET model.

Is my understanding correct?

ntpthinh commented 4 years ago

That's right. Since mlContext.Transforms.ApplyOnnxModel only allows file url but I can only provide stream in my application so I have to work around like that.

harishsk commented 4 years ago

@pthinh14 Thanks for reporting the issue. It will be fixed as part of PR #5348 and be part of the next release.

antoniovs1029 commented 4 years ago

As a side note: @pthinh14 , if you're giving your customers the ML.NET model file they'll load with mlContext.Model.Load(modelLocation, out DataViewSchema modelSchema); then please note that the ML.NET model file is simply a .zip file which can be unzipped, and inside there will be a file called OnnxModel that will actually be your onnx model. I think they'll simply need to open it on a notepad editor, and remove a couple of characters at the beginning, and that'll be enough for them to have access to your original onnx model.

When saving your ML.NET model to disk, here is the code where the original onnx model gets saved into the .zip file: https://github.com/dotnet/machinelearning/blob/a76936546f5e269fc1da61f33ab541389e445294/src/Microsoft.ML.OnnxTransformer/OnnxTransform.cs#L307

I mention this as you've expressed you don't want your onnx model to be exposed to your customers.