/// <summary> /// Enable model monitoring for the <see cref="IModelStorageProvider"/>. /// Overrides the default model storage provider. /// </summary> /// <typeparam name="TData"></typeparam> /// <typeparam name="TPrediction"></typeparam> /// <param name="builder"></param> /// <param name="storageName">The name of the ML model in the storage provider.</param> /// <param name="modelStorageProvider">The model storage provider. The default model storage provider is <see cref="InMemoryModelStorageProvider"/>.</param> /// <returns></returns> public static IModelPredictionEngineBuilder <TData, TPrediction> WithStorageProvider <TData, TPrediction>( this IModelPredictionEngineBuilder <TData, TPrediction> builder, string storageName, IModelStorageProvider modelStorageProvider = null) where TData : class where TPrediction : class, new() { builder.Services.Configure(builder.ModelName, (Action <ModelPredictionEngineOptions <TData, TPrediction> >)((mlOptions) => { mlOptions.CreateModel = (mlContext) => { if (modelStorageProvider == null) { modelStorageProvider = new InMemoryModelStorageProvider(); } ChangeToken.OnChange( () => modelStorageProvider.GetReloadToken(), () => mlOptions.Reload()); return(GetTransfomer(storageName, mlContext, modelStorageProvider)); }; })); return(builder); }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { var instrumentId = Configuration.Bind <ApplicationInsightsOptions>("ApplicationInsights", true); services.AddApplicationInsightsTelemetry(options => { options.InstrumentationKey = instrumentId.InstrumentationKey; }); services.AddDeveloperListRegisteredServices(o => { o.PathOutputOptions = PathOutputOptions.Json; }); services.AddControllers(); services.AddSwaggerGen(options => options.SwaggerDoc("v1", new OpenApiInfo { Title = $"{AppName} API", Version = "v1" })); // add ML.NET Models var spamInMemoryModelStorageProvider = new InMemoryModelStorageProvider(); services.AddSpamDetectionModelBuilder(spamInMemoryModelStorageProvider); var spamName = "SpamModel"; services.AddModelPredictionEngine <SpamInput, SpamPrediction>(spamName) .WithStorageProvider(nameof(SpamModelBuilderService), spamInMemoryModelStorageProvider); var sentimentFileModeStorageProvider = new FileModelStorageProvider(); services.AddSentimentModelBuilder(sentimentFileModeStorageProvider); var sentimentName = "SentimentModel"; services.AddModelPredictionEngine <SentimentIssue, SentimentPrediction>(sentimentName) .WithStorageProvider($"{nameof(SentimentModelBuilderService)}.zip", sentimentFileModeStorageProvider); services.AddScheduler(builder => { builder.AddJob <RebuildMLModelScheduledJob, RebuildMLModelsOptions>(); builder.UnobservedTaskExceptionHandler = null; }); // add healthchecks services.AddHealthChecks() .AddMemoryHealthCheck() .AddMachineLearningModelCheck <SpamInput, SpamPrediction>($"{spamName}_check") .AddMachineLearningModelCheck <SentimentIssue, SentimentPrediction>($"{sentimentName}_check") .AddSigtermCheck("sigterm_check") .AddLoggerPublisher(new List <string> { "sigterm_check" }); }