Skip to content

Let ML.NET cancel unmanaged code. #6465

Open

Description

@andrasfuchs

System Information:

  • OS & Version: Windows 11 [Version 10.0.22621.819]
  • ML.NET Version: ML.NET v2.0.0
  • .NET Version: .NET 7.0.100

Describe the bug
I run an ML.NET experiment for 10 hours. I limited the training for FastTree and FastForest algorithms and I made sure that every new best model is saved even if the whole run fails. I locked Windows and let it run during the night.
When I checked it in the morning (12 hours after the experiment started) I couldn't even log in, I had to do a power off-power on to get access. When I checked the logs it looked like the last experiment was saved after ~5 hours of running.
The dataset wasn't particularly big this time, it was only a 205 MB CSV file. My system has 32 GB RAM, and I set the maximum memory usage for the experiment to 20 GB.

To Reproduce
Steps to reproduce the behavior:

  1. Create a pipeline that includes only FastTree and FastForest, for example:
var pipeline =
  mlContext.Auto().Featurizer(trainTestData.TrainSet, numericColumns: new[] { "Features" })
      .Append(mlContext.Auto().Regression(useFastTree: true, useLbfgs: false, useSdca: false, useFastForest: true, useLgbm: false));

  1. Create an ML.NET experiment and set its memory limit. I set it to 20 GB, because I usually have ~24 GB available when I start the training.
var experiment = mlContext.Auto().CreateExperiment();

experiment
    .SetPipeline(pipeline)
    .SetTrainingTimeInSeconds(trainingTimeInSeconds)
    .SetRegressionMetric(RegressionMetric.RSquared, labelColumn: "Label")
    .SetDataset(trainTestData.TrainSet, trainTestData.TestSet)
    .SetMonitor(monitor)
    .SetMaximumMemoryUsageInMegaByte(20 * 1024);
  1. Run the experiment for at least 10 hours
  2. Check if you can still use the system after 5+ hours of running

Expected behavior
I would expect the experiment to run without a system-freezing halt.

Screenshots, Code, Sample Projects
The 205 MB CSV dataset can be downloaded from here:
BBD_20221122__TrainingData.Sleep.MLP12__MLP12_0p25Hz-250Hz__Session_SegmentedData_Sleep_Level__15782rows.zip

Additional context
My project is open-source so both the source and the data are available. Let me know if you need them for testing.

Activity

  1. ghost added
    untriagedNew issue has not been triaged
    on Nov 23, 2022
  2. andrasfuchs commented on Nov 26, 2022

    @andrasfuchs
    ContributorAuthor

    I run further tests, and I think I found the root cause of this problem: the LightGbmRegression estimator can't be cancelled during it's startup and it crashes if the systems runs out of virtual memory.

    Here are my logs:

    11:32:57.1 info:     Running Trial #  16
    11:33:03.1 info:   Resources Trial #  16 - Estimator: LightGbmRegression                  -   Memory:        2,2 GB -      CPU:         41,8% - Duration:   0,1 minutes
    11:33:06.0 info:   Completed Trial #  16 - Estimator: LightGbmRegression                  -   Metric:        0,6090 - Duration:   0,1 minutes
    11:33:06.0 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    11:33:06.0 info:    New Best Trial #  16 - Estimator: LightGbmRegression                  -   Metric:        0,6090
    11:33:06.0 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    11:33:06.0 info:     Running Trial #  17
    11:33:12.0 info:   Resources Trial #  17 - Estimator: LightGbmRegression                  -   Memory:        2,7 GB -      CPU:         43,8% - Duration:   0,1 minutes
    11:33:18.1 info:   Resources Trial #  17 - Estimator: LightGbmRegression                  -   Memory:        6,8 GB -      CPU:         85,5% - Duration:   0,2 minutes
    11:33:24.1 info:   Resources Trial #  17 - Estimator: LightGbmRegression                  -   Memory:        6,8 GB -      CPU:         83,2% - Duration:   0,3 minutes
    11:33:24.1 warn:   Resources Trial #  17 - Cancellinng trial due to timeout
    11:33:24.1 info:      Failed Trial #  17 - Estimator: LightGbmRegression                  - Error: Operation was canceled.
    11:33:24.1 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    11:33:24.1 info:     Running Trial #  18
    11:33:27.1 info:   Completed Trial #  18 - Estimator: LbfgsPoissonRegressionRegression    -   Metric:        0,0656 - Duration:   0,1 minutes
    11:33:27.1 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    11:33:27.1 info:     Running Trial #  19
    11:33:33.2 info:   Resources Trial #  19 - Estimator: LightGbmRegression                  -   Memory:        2,8 GB -      CPU:         41,5% - Duration:   0,1 minutes
    11:33:35.7 info:   Completed Trial #  19 - Estimator: LightGbmRegression                  -   Metric:        0,5047 - Duration:   0,1 minutes
    11:33:35.8 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    11:33:35.8 info:     Running Trial #  20
    11:33:41.8 info:   Resources Trial #  20 - Estimator: LightGbmRegression                  -   Memory:        2,9 GB -      CPU:         45,4% - Duration:   0,1 minutes
    11:33:47.8 info:   Resources Trial #  20 - Estimator: LightGbmRegression                  -   Memory:       27,5 GB -      CPU:         84,2% - Duration:   0,2 minutes
    11:33:53.8 info:   Resources Trial #  20 - Estimator: LightGbmRegression                  -   Memory:       40,1 GB -      CPU:         91,2% - Duration:   0,3 minutes
    11:33:53.8 warn:   Resources Trial #  20 - Cancellinng trial due to timeout
    11:33:53.9 warn:   Resources Trial #  20 - Cancelling trial due to memory usage
    11:33:54.1 warn:   Resources Trial #  20 - Cancelling trial due to low virtual memory
    11:33:59.8 info:   Resources Trial #  20 - Estimator: LightGbmRegression                  -   Memory:       46,5 GB -      CPU:          0,0% - Duration:   0,4 minutes
    11:33:59.9 warn:   Resources Trial #  20 - Cancellinng trial due to timeout
    11:33:59.9 warn:   Resources Trial #  20 - Cancelling trial due to memory usage
    [LightGBM] [Warning] bad allocation
    [LightGBM] [Warning] bad allocation
    [LightGBM] [Warning] bad allocation
    [LightGBM] [Warning] bad allocation
    [LightGBM] [Warning] bad allocation
    [LightGBM] [Warning] bad allocation
    [LightGBM] [Warning] bad allocation
    [LightGBM] [Warning] bad allocation
    

    I set the cancellation thresholds to

    • 15 seconds timeout
    • 36+ GB of memory usage
    • <2 GB free virtual memory

    Please notice that the estimator was cancelled successfully in trials 4, 6, 9, 12,13 and 17. If you look at the last trial (20) you can see that my monitor tries to cancel the estimator again and again without success until the process runs out of virtual memory and it gets the "bad allocation" exception repeatedly and finally crashes the whole process.

  3. added this to the ML.NET 3.0 milestone on Nov 28, 2022
  4. ghost removed
    untriagedNew issue has not been triaged
    on Nov 28, 2022
  5. michaelgsharp commented on Nov 28, 2022

    @michaelgsharp
    Contributor

    @LittleLittleCloud any thoughts on this? looks like a cancellation error. Unless its a LightGBM issue itself.

  6. LittleLittleCloud commented on Nov 29, 2022

    @LittleLittleCloud
    Member

    LightGBM can't be canceled when it's calling into unmanaged dll because cancellation pattern of ml.net is not implemented there. @michaelgsharp is there a way to cancel a running estimator when it's running into unmanaged code by calling mlcontext.CancelExection()?

  7. andrasfuchs commented on Dec 2, 2022

    @andrasfuchs
    ContributorAuthor

    It might a little drastic, but I will try to do some experiments when I forcefully terminate the thread that runs the unmanaged code in my IMonitor event handler. For this I will need to modify the ML.NET part to pass the unmanaged ThreadId in the TrialSettings class, but if it works it would be still better than crashing the whole process because I run out of free virtual memory.

  8. LittleLittleCloud commented on Dec 2, 2022

    @LittleLittleCloud
    Member

    @andrasfuchs Another solution that might be an easier path for you is to use a smaller lightGBM search space. The current default lightGBM search space might be too large to an extend that doesn't actually benefit the final training result.

    Here's how to pass a smaller lightGBM search space, which we also apply when running azure benchmark and proves to have little impact to final result

    var lgbmDefaultOption = new LgbmOption
    {
           LabelColumnName = label,
           FeatureColumnName = featureName,
    };
    var lgbmSearchSpace = new SearchSpace<LgbmOption>(lgbmDefaultOption);
    
    // use a smaller NumberOfLeaves and NumberOfTrees to avoid OOM
    lgbmSearchSpace["NumberOfLeaves"] = new UniformIntOption(4, 1024 * 4, true, 4);
    lgbmSearchSpace["NumberOfTrees"] = new UniformIntOption(4, 1024 * 4, true, 4);
    
    // apply new lgbmSearchSpace
    var pipeline = context.Transforms.Conversion.MapValueToKey(label, label)
                                            .Append(context.Auto().Featurizer(trainData, columnInformation, featureName))
                                            .Append(context.Auto().MultiClassification(labelColumnName: label, featureColumnName: featureName, lgbmSearchSpace: lgbmSearchSpace))
  9. michaelgsharp commented on Dec 5, 2022

    @michaelgsharp
    Contributor

    @LittleLittleCloud looks like the work item for this should be to add that capability when we are calling into unmanaged code.

  10. added
    enhancementNew feature or request
    and removed
    untriagedNew issue has not been triaged
    on Dec 5, 2022
  11. changed the title [-]Long running AutoML experiment freezes Windows[/-] [+]Let ML.NET cancel unmanaged code.[/+] on Dec 5, 2022
  12. andrasfuchs commented on Dec 6, 2022

    @andrasfuchs
    ContributorAuthor

    @LittleLittleCloud Thank you for the suggestion, and sorry for not getting back to you sooner, I just wanted to make sure that I test the reduced search space correctly.

    It seems to be working fine: I could run 100+ LightGBM trials without any issues. The memory usage topped at 12.4 GB compared to the 46.5+ GB I had previously. I'll still do some test this week with long-running training sessions, but it looks like a great temporary solution!

    I include my source code and logs for reference.

    var trainTestData = mlContext.Data.TrainTestSplit(data, testFraction: 0.1);
    
    
    // We have to limit the search space for LightGBM to prevent out of memory expecion. See: https://github.com/dotnet/machinelearning/issues/6465#issuecomment-1335148576
    var lgbmDefaultOption = new LgbmOption
    {
    	LabelColumnName = "Label",
    	FeatureColumnName = "Features",
    };
    var lgbmSearchSpace = new SearchSpace<LgbmOption>(lgbmDefaultOption);
    
    // use a smaller NumberOfLeaves and NumberOfTrees to avoid OOM
    lgbmSearchSpace["NumberOfLeaves"] = new UniformIntOption(4, 1024 * 4, true, 4);
    lgbmSearchSpace["NumberOfTrees"] = new UniformIntOption(4, 1024 * 4, true, 4);
    
    var pipeline =
    	mlContext.Auto().Featurizer(trainTestData.TrainSet, numericColumns: new[] { "Features" })
    		.Append(mlContext.Auto().Regression(useFastTree: false, useLbfgs: false, useSdca: false, useFastForest: false, useLgbm: true, lgbmSearchSpace: lgbmSearchSpace));
    
    var monitor = new BodyMonitor.Models.MLContextLoggerMonitor(_logger, mlContext, pipeline, data.Schema, modelFilename);
    
    var experiment = mlContext.Auto().CreateExperiment();
    
    experiment
    	.SetPipeline(pipeline)
    	.SetTrainingTimeInSeconds(trainingTimeInSeconds)
    	.SetRegressionMetric(RegressionMetric.RSquared, labelColumn: "Label")
    	.SetDataset(trainTestData.TrainSet, trainTestData.TestSet)
    	.SetMonitor(monitor);
    
    var result = await experiment.RunAsync();
    12:12:12.4 info:     Running Trial #  99
    12:12:18.5 info:   Resources Trial #  99 - Estimator: LightGbmRegression                  -   Memory:        2,5 GB -      CPU:         36,6% - Duration:   0,1 minutes
    12:12:24.4 info:   Resources Trial #  99 - Estimator: LightGbmRegression                  -   Memory:        5,1 GB -      CPU:         67,7% - Duration:   0,2 minutes
    12:12:30.5 info:   Resources Trial #  99 - Estimator: LightGbmRegression                  -   Memory:        5,1 GB -      CPU:         61,3% - Duration:   0,3 minutes
    12:12:31.8 info:   Completed Trial #  99 - Estimator: LightGbmRegression                  -   Metric:        0,6796 - Duration:   0,3 minutes
    12:12:31.8 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:12:31.8 info:     Running Trial # 100
    12:12:37.8 info:   Resources Trial # 100 - Estimator: LightGbmRegression                  -   Memory:        2,8 GB -      CPU:         41,1% - Duration:   0,1 minutes
    12:12:43.8 info:   Resources Trial # 100 - Estimator: LightGbmRegression                  -   Memory:        5,7 GB -      CPU:         68,0% - Duration:   0,2 minutes
    12:12:49.8 info:   Resources Trial # 100 - Estimator: LightGbmRegression                  -   Memory:        5,7 GB -      CPU:         63,2% - Duration:   0,3 minutes
    12:12:52.5 info:   Completed Trial # 100 - Estimator: LightGbmRegression                  -   Metric:        0,6852 - Duration:   0,3 minutes
    12:12:52.5 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:12:52.5 info:     Running Trial # 101
    12:12:58.5 info:   Resources Trial # 101 - Estimator: LightGbmRegression                  -   Memory:        3,0 GB -      CPU:         45,6% - Duration:   0,1 minutes
    12:13:04.5 info:   Resources Trial # 101 - Estimator: LightGbmRegression                  -   Memory:        5,8 GB -      CPU:         66,5% - Duration:   0,2 minutes
    12:13:10.5 info:   Resources Trial # 101 - Estimator: LightGbmRegression                  -   Memory:        5,8 GB -      CPU:         66,3% - Duration:   0,3 minutes
    12:13:11.9 info:   Completed Trial # 101 - Estimator: LightGbmRegression                  -   Metric:        0,6935 - Duration:   0,3 minutes
    12:13:11.9 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:13:11.9 info:     Running Trial # 102
    12:13:17.9 info:   Resources Trial # 102 - Estimator: LightGbmRegression                  -   Memory:        2,8 GB -      CPU:         41,7% - Duration:   0,1 minutes
    12:13:23.9 info:   Resources Trial # 102 - Estimator: LightGbmRegression                  -   Memory:        5,4 GB -      CPU:         67,4% - Duration:   0,2 minutes
    12:13:29.9 info:   Resources Trial # 102 - Estimator: LightGbmRegression                  -   Memory:        5,4 GB -      CPU:         65,8% - Duration:   0,3 minutes
    12:13:31.8 info:   Completed Trial # 102 - Estimator: LightGbmRegression                  -   Metric:        0,7048 - Duration:   0,3 minutes
    12:13:31.8 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:13:31.8 info:     Running Trial # 103
    12:13:37.8 info:   Resources Trial # 103 - Estimator: LightGbmRegression                  -   Memory:        2,2 GB -      CPU:         46,1% - Duration:   0,1 minutes
    12:13:43.8 info:   Resources Trial # 103 - Estimator: LightGbmRegression                  -   Memory:        5,2 GB -      CPU:         69,0% - Duration:   0,2 minutes
    12:13:49.8 info:   Resources Trial # 103 - Estimator: LightGbmRegression                  -   Memory:        5,2 GB -      CPU:         63,2% - Duration:   0,3 minutes
    12:13:51.2 info:   Completed Trial # 103 - Estimator: LightGbmRegression                  -   Metric:        0,6820 - Duration:   0,3 minutes
    12:13:51.2 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:13:51.2 info:     Running Trial # 104
    12:13:57.2 info:   Resources Trial # 104 - Estimator: LightGbmRegression                  -   Memory:        2,6 GB -      CPU:         43,9% - Duration:   0,1 minutes
    12:14:03.2 info:   Resources Trial # 104 - Estimator: LightGbmRegression                  -   Memory:        5,6 GB -      CPU:         67,1% - Duration:   0,2 minutes
    12:14:09.2 info:   Resources Trial # 104 - Estimator: LightGbmRegression                  -   Memory:        5,6 GB -      CPU:         63,7% - Duration:   0,3 minutes
    12:14:10.8 info:   Completed Trial # 104 - Estimator: LightGbmRegression                  -   Metric:        0,6828 - Duration:   0,3 minutes
    12:14:10.8 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:14:10.8 info:     Running Trial # 105
    12:14:16.9 info:   Resources Trial # 105 - Estimator: LightGbmRegression                  -   Memory:        2,8 GB -      CPU:         48,7% - Duration:   0,1 minutes
    12:14:22.8 info:   Resources Trial # 105 - Estimator: LightGbmRegression                  -   Memory:        5,6 GB -      CPU:         69,1% - Duration:   0,2 minutes
    12:14:28.9 info:   Resources Trial # 105 - Estimator: LightGbmRegression                  -   Memory:        5,6 GB -      CPU:         65,1% - Duration:   0,3 minutes
    12:14:30.1 info:   Completed Trial # 105 - Estimator: LightGbmRegression                  -   Metric:        0,7070 - Duration:   0,3 minutes
    12:14:30.2 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:14:30.2 info:    New Best Trial # 105 - Estimator: LightGbmRegression                  -   Metric:        0,7070
    12:14:30.2 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    12:14:30.2 info:     Running Trial # 106
    12:14:36.2 info:   Resources Trial # 106 - Estimator: LightGbmRegression                  -   Memory:        3,0 GB -      CPU:         42,0% - Duration:   0,1 minutes
    12:14:42.2 info:   Resources Trial # 106 - Estimator: LightGbmRegression                  -   Memory:        5,7 GB -      CPU:         66,9% - Duration:   0,2 minutes
    12:14:48.2 info:   Resources Trial # 106 - Estimator: LightGbmRegression                  -   Memory:        5,7 GB -      CPU:         66,9% - Duration:   0,3 minutes
    12:14:49.8 info:   Completed Trial # 106 - Estimator: LightGbmRegression                  -   Metric:        0,6901 - Duration:   0,3 minutes
    
  13. andrasfuchs commented on Dec 6, 2022

    @andrasfuchs
    ContributorAuthor

    Update: @LittleLittleCloud It turns out it's not bulletproof, my experiment just crashed my system again after ~2 hours of running. I agree with @michaelgsharp, cancelling unmanaged code would be the ideal solution.
    I need to disable LightGBM for now.

  14. andrasfuchs commented on Dec 7, 2022

    @andrasfuchs
    ContributorAuthor

    The cancellation mechanism seems to be unreliable for FastForestRegression as well. I run a ~11 hour-long experiment, and if you look at the logs below you'll see that the cancellation of trial 741 took more than 1.5 minutes!

    The first cancellation request issued at 08:48:54, but it was only completed at 08:50:27. Would it be possible to apply a more aggressive task/thread cancellation so that we can stop a trial instantly?

    08:48:18.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:         15,6% - Duration:   14,4 minutes
    08:48:24.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:         19,2% - Duration:   14,5 minutes
    08:48:30.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:         16,0% - Duration:   14,6 minutes
    08:48:36.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:         16,0% - Duration:   14,7 minutes
    08:48:42.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:         14,9% - Duration:   14,8 minutes
    08:48:48.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:         15,2% - Duration:   14,9 minutes
    08:48:54.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:         16,7% - Duration:   15,0 minutes
    08:48:54.1 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:00.0 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   15,1 minutes
    08:49:00.3 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:06.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   15,2 minutes
    08:49:07.8 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:12.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   15,3 minutes
    08:49:12.4 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:18.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   15,4 minutes
    08:49:18.3 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:24.2 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   15,5 minutes
    08:49:24.7 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:30.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   15,6 minutes
    08:49:32.4 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:36.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,1% - Duration:   15,7 minutes
    08:49:36.5 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:42.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   15,8 minutes
    08:49:43.0 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:48.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,1% - Duration:   15,9 minutes
    08:49:48.5 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:49:54.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   16,0 minutes
    08:49:54.3 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:50:00.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   16,1 minutes
    08:50:00.3 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:50:06.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   16,2 minutes
    08:50:06.7 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:50:12.2 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   16,3 minutes
    08:50:12.7 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:50:18.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   16,4 minutes
    08:50:19.0 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:50:24.1 info:   Resources Trial # 741 - Estimator: FastForestRegression                -   Memory:        1,5 GB -      CPU:          0,0% - Duration:   16,5 minutes
    08:50:24.8 warn:   Resources Trial # 741 - Cancelling trial due to timeout
    08:50:27.4 fail:      Failed Trial # 741 - Estimator: FastForestRegression                -     Error: Operation was canceled.
    08:50:27.4 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    08:50:27.4 info:     Running Trial # 742
    08:50:33.5 info:   Resources Trial # 742 - Estimator: LbfgsPoissonRegressionRegression    -   Memory:        2,0 GB -      CPU:         44,9% - Duration:   0,1 minutes
    08:50:36.6 info:   Completed Trial # 742 - Estimator: LbfgsPoissonRegressionRegression    -   Metric:        0,1970 - Duration:   0,2 minutes
    08:50:36.6 info:  ------------------------------------------------------------------------------------------------------------------------------------------------------
    08:50:36.6 info:     Running Trial # 743
    08:50:42.7 info:   Resources Trial # 743 - Estimator: LbfgsPoissonRegressionRegression    -   Memory:        2,7 GB -      CPU:          7,7% - Duration:   0,1 minutes
    08:50:45.1 info:   Completed Trial # 743 - Estimator: LbfgsPoissonRegressionRegression    -   Metric:        0,1997 - Duration:   0,1 minutes
    
  15. LittleLittleCloud commented on Dec 7, 2022

    @LittleLittleCloud
    Member

    @andrasfuchs
    For FastForestRegression we can always improve cancellation experience by checking if MLContext is alive or not as long as it's running in managed code.

    For unmanaged code, the cancellation situation will be a bit more complex and might be out of ml.net's scope depends on if we own that unmanaged code. @michaelgsharp do you have any idea if there's an easier way to implement cancellation pattern in lightGBM unmanaged training part?

  16. andrasfuchs commented on Dec 22, 2022

    @andrasfuchs
    ContributorAuthor

    I understand if you are hesitant to implement a drastic unmanaged code termination in ML.NET, but could you pass the identifier of the thread that runs the trial (including the unmanaged code) to the IMonitor?
    Then the user could decide if they wanted to risk a thread termination or let the thread run even if it hits a performance metric threshold.
    My experience is that it would be still better to terminate the thread if we are running out of virtual memory, because the alternative is a system-wide crash that affects other running processes as well.

  17. LittleLittleCloud commented on Dec 22, 2022

    @LittleLittleCloud
    Member

    @andrasfuchs
    Just to see if I understand your suggestion correctly. Are you talking about just terminating the thread of current running trial, versus terminating the thread of the entire AutoMLExperiment.

    The two kinds of terminating will lead to different solutions. If you just want to terminate the entire AutoMLExperiment if it hits a performance threshold, I would suggest moving this termination logic to your code base by making sure to start AutoMLExperiment in a separate thread and monitoring system memory usage in order to terminate AutoMLExperiment thread if it's using too much memory.

    If you want to just terminate the current running trial without fail the entire AutoMLExperiment training, we probably need to do more than just pass the current trial's thread id to monitor for later termination. Because AutoMLExperiment kicks off trials using Task, which could be running on a thread that is shared with multiple other tasks and call termination might cause unexpected behavior.

    Overall, I feel like the dilemma can be summarized to perform cancellation or termination over a task that might not respond or doesn't implement a cancellation pattern. @tarekgh @michaelgsharp might know better on this dilemma and I can dig into it to see if there's existing current solutions.

  18. andrasfuchs commented on Dec 22, 2022

    @andrasfuchs
    ContributorAuthor

    @LittleLittleCloud
    Thank you for your explanation, I didn't know these properties of the AutoMLExperiment, it makes sense.

    Terminating the whole AutoMLExperiment wouldn't be ideal, but at least it would protect the system from crashing.

    I'm not totally sure about this, but if I remember correctly forcefully terminating a Task isn't supported, only Threads can be aborted/terminated.
    I assumed mistakenly that each trial has its own thread (with its managed and unmanaged sub-threads, and tasks) so it's possible to abort just that without killing the experiment if the normal cancellation technique fails.

    It is a dilemma indeed, and I'm interested in your findings!

  19. LittleLittleCloud commented on Dec 28, 2022

    @LittleLittleCloud
    Member

    I'm not totally sure about this, but if I remember correctly forcefully terminating a Task isn't supported, only Threads can be aborted/terminated.

    That's right, although there's hacky way to kill a task, it's nearly always be highly unrecommended. According to this discussion, Task should not be used for abortive cancellation purpose. And it's recommended to either use a process or thread when it's necessary to call into third-party code where cancellation pattern might not be well-implemented.

    So to resolve this issue, I can see two work-item here: 1) improving LightGbm cancellation experience by running the native code part in a separate thread or process so it can be terminated safely when there's no response and 2) In AutoML, use Thread to start trials

  20. added
    area-AutoMLAutomated machine learning, Model Builder, and ML.NET CLI
    and removed on Sep 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-AutoMLAutomated machine learning, Model Builder, and ML.NET CLIenhancementNew feature or requestyellowmaintenance only

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions