Esempio n. 1
0
        public async Task <ModelTrainingJob> StartTraining([ActivityTrigger] ModelTrainingJob job, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext ec)
        {
            var snip = $"Orchestration { job.OrchestrationId}: { ec.FunctionName} - ";
            var orchestrationContainer = orchestrationBlobClient.GetContainerReference($"{job.OrchestrationId}");

            job.OrchestrationContainerName = orchestrationContainer.Name;
            await orchestrationContainer.CreateIfNotExistsAsync();

            var uri = $"{recognizerServiceBaseUrl}{BaseConstants.FormRecognizerApiPath}";

            JObject body = new JObject(
                new JProperty("source", job.BlobSasUrl),
                new JProperty("sourceFilter",
                              new JObject(
                                  new JProperty("prefix", job.BlobFolderName),
                                  new JProperty("includeSubFolders", job.IncludeSubFolders)
                                  )
                              ),
                new JProperty("useLabelFile", job.UseLabelFile)
                );
            string json = body.ToString();

            string getUrl = "";

            log.LogTrace($"{snip} Training Request was prepared {job.BlobSasUrl}");
            using (var content = new StringContent(json, System.Text.Encoding.UTF8, "application/json"))
            {
                client.DefaultRequestHeaders.Add(BaseConstants.OcpApimSubscriptionKey, recognizerApiKey);
                HttpResponseMessage response = await client.PostAsync(uri, content);

                if (response.IsSuccessStatusCode)
                {
                    log.LogTrace($"{snip} Training Request was submitted.  StatusCode {response.StatusCode}");
                    HttpHeaders headers = response.Headers;
                    if (headers.TryGetValues("location", out IEnumerable <string> values))
                    {
                        getUrl = values.First();
                    }
                }
                else
                {
                    var test = await response.Content.ReadAsStringAsync();

                    throw new Exception($"That didnt work.  Trying to submit model training request {test} request was {json} Response:{response.StatusCode.ToString()}");
                }
            }

            job.RecognizerStatusUrl = getUrl;
            log.LogInformation($"{snip} Training Request for Document Format {job.DocumentFormat} Completed successfully");
            return(job);
        }
Esempio n. 2
0
        public async Task <ModelTrainingJob> TrainingCompleted([ActivityTrigger] ModelTrainingJob job, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext ec)
        {
            var snip = $"Orchestration { job.OrchestrationId}: { ec.FunctionName} -";
            var mtr  = HorusSql.UpdateModelTraining(job, log);

            job.ModelVersion = mtr.ModelVersion.ToString();
            var orchestrationContainer = orchestrationBlobClient.GetContainerReference(job.OrchestrationContainerName);
            await orchestrationContainer.CreateIfNotExistsAsync();

            var jobBlobName = $"{job.DocumentFormat}{BaseConstants.TrainingJobFileExtension}";
            var jobBlob     = orchestrationContainer.GetBlockBlobReference(jobBlobName);
            await jobBlob.UploadTextAsync(JsonConvert.SerializeObject(job));

            log.LogInformation($"{snip} - Completed successfully - Job blob {job.JobBlobName} was uploaded to container {job.OrchestrationContainerName}");
            return(job);
        }
Esempio n. 3
0
        public async Task TriggerTrainModel([ServiceBusTrigger("%TrainingQueue%", Connection = "IncomingDocumentServiceBusConnectionString")] Message message, [DurableClient] IDurableOrchestrationClient starter, ILogger log, ExecutionContext ec)
        {
            log.LogInformation($"{ec.FunctionName} function was triggered by receipt of service bus message {message.MessageId}");
            string payload = System.Text.Encoding.UTF8.GetString(message.Body);
            var    trm     = JsonConvert.DeserializeObject <TrainingRequestMessage>(payload);

            HorusSql.CheckAndCreateDatabaseIfNecessary(log);

            var job = new ModelTrainingJob {
                BlobFolderName    = trm.BlobFolderName,
                BlobSasUrl        = trm.BlobSasUrl,
                DocumentFormat    = trm.DocumentFormat,
                IncludeSubFolders = "false",
                UseLabelFile      = "true"
            };
            string orchestrationId = await starter.StartNewAsync("ModelTrainer", null, job);

            log.LogInformation($"{ec.FunctionName} processed message {message.MessageId}.  Orchestration {orchestrationId}");
        }
Esempio n. 4
0
        public async Task <ModelTrainingJob> TrainingErrorHandler([ActivityTrigger] ModelTrainingJob job, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext ec)
        {
            try
            {
                var snip = $"Orchestration { job.OrchestrationId}: { ec.FunctionName} -";
                var orchestrationContainer = orchestrationBlobClient.GetContainerReference(job.OrchestrationContainerName);
                await orchestrationContainer.CreateIfNotExistsAsync();

                var jobBlobName = $"{job.DocumentFormat}{BaseConstants.TrainingJobFileExtension}";
                var jobBlob     = orchestrationContainer.GetBlockBlobReference(jobBlobName);
                await jobBlob.UploadTextAsync(JsonConvert.SerializeObject(job));

                var exceptionBlobName = $"{job.DocumentFormat}{BaseConstants.ExceptionExtension}";
                var exceptionBlob     = orchestrationContainer.GetBlockBlobReference(exceptionBlobName);
                await exceptionBlob.UploadTextAsync(JsonConvert.SerializeObject(job.Exception));

                log.LogInformation($"{snip} - Exception Handled - Exception of Type {job.Exception.GetType()} added to blob {job.JobBlobName} was uploaded to container{job.OrchestrationContainerName}");
                return(job);
            }
            catch (Exception ex)
            {
                throw new HorusTerminalException(ex);
            }
        }
Esempio n. 5
0
        public static ModelTrainingRecord UpdateModelTraining(ModelTrainingJob m, ILogger log)
        {
            using (SqlConnection connection = new SqlConnection(sqlConnectionString))
            {
                connection.Open();
                SqlCommand     command = connection.CreateCommand();
                SqlTransaction transaction;
                transaction         = connection.BeginTransaction("TrainingRequestTransaction");
                command.Connection  = connection;
                command.Transaction = transaction;
                int currentVersion = 0;
                int newVersion     = 0;
                try
                {
                    command.CommandText = $"SELECT MAX(ModelVersion) AS Current_Version from ModelTraining WHERE DocumentFormat='{m.DocumentFormat}'";
                    SqlDataReader reader = command.ExecuteReader();
                    try
                    {
                        while (reader.Read())
                        {
                            if (reader["Current_Version"] != System.DBNull.Value)
                            {
                                currentVersion = Convert.ToInt32(reader["Current_Version"]);
                            }
                            else
                            {
                                currentVersion = 0;
                            }
                        }
                    }
                    finally
                    {
                        reader.Close();
                    }

                    newVersion = currentVersion + 1;

                    // Add the row
                    string insertClause = $"Insert into ModelTraining (DocumentFormat, ModelVersion, ModelId, CreatedDateTime, UpdatedDateTime, BlobSasUrl, BlobfolderName, IncludeSubFolders, UseLabelFile, AverageModelAccuracy, TrainingDocumentResults";
                    string valuesClause = $" VALUES ('{m.DocumentFormat}', '{newVersion}','{m.ModelId}', '{m.CreatedDateTime:yyyy-MM-dd HH:mm:ss.fff}', '{m.UpdatedDateTime:yyyy-MM-dd HH:mm:ss.fff}', '{m.BlobSasUrl}', '{m.BlobFolderName}','{m.IncludeSubFolders}', '{m.UseLabelFile}','{m.AverageModelAccuracy}','{m.TrainingDocumentResults}'";
                    insertClause       += ") ";
                    valuesClause       += ")";
                    command.CommandText = insertClause + valuesClause;


                    command.ExecuteNonQuery();


                    transaction.Commit();
                }
                catch (Exception e)
                {
                    log.LogError($"Exception prevented writing training request for document format {m.DocumentFormat} model id={m.ModelId} to database (transaction was rolled back).  Message is {e.Message}");
                    transaction.Rollback();
                    throw e;
                }

                ModelTrainingRecord mtr = new ModelTrainingRecord {
                    ModelId = m.ModelId, ModelVersion = newVersion, AverageModelAccuracy = m.AverageModelAccuracy, DocumentFormat = m.DocumentFormat, UpdatedDateTime = m.UpdatedDateTime
                };
                log.LogInformation($"Training request for document format {m.DocumentFormat}, version={newVersion}, model id={m.ModelId}  was written to the database");
                return(mtr);
            }
        }
Esempio n. 6
0
        public async Task <ModelTrainingJob> CheckTrainingStatus([ActivityTrigger] ModelTrainingJob job, ILogger log, Microsoft.Azure.WebJobs.ExecutionContext ec)
        {
            var snip = $"Orchestration { job.OrchestrationId}: { ec.FunctionName} -";

            log.LogTrace($"{snip} Checking training request status");
            string  responseBody;
            JObject jsonContent;
            string  jobStatus;

            client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", recognizerApiKey);
            var response = await client.GetAsync(job.RecognizerStatusUrl);

            if (response.IsSuccessStatusCode)
            {
                responseBody = await response.Content.ReadAsStringAsync();

                jsonContent = JObject.Parse(responseBody);
                if (jsonContent["modelInfo"]["status"] != null)
                {
                    jobStatus = jsonContent["modelInfo"]["status"].ToString();
                    if (jobStatus.ToLower() == "ready")
                    {
                        job.ModelId = jsonContent["modelInfo"]["modelId"].ToString();
                        string dateAsString = DateTime.Now.ToString();
                        try
                        {
                            dateAsString = jsonContent["modelInfo"]["createdDateTime"].ToString();
                        }
                        catch { }

                        DateTime dateValue;
                        if (DateTime.TryParse(dateAsString, out dateValue))
                        {
                            job.CreatedDateTime = dateValue;
                        }

                        dateAsString = DateTime.Now.ToString();
                        try
                        {
                            dateAsString = jsonContent["modelInfo"]["lastUpdatedDateTime"].ToString();
                        }
                        catch { }

                        if (DateTime.TryParse(dateAsString, out dateValue))
                        {
                            job.UpdatedDateTime = dateValue;
                        }



                        string numberAsString = "0";
                        try
                        {
                            numberAsString = jsonContent["trainResult"]["averageModelAccuracy"].ToString();
                        }
                        catch { }

                        decimal numberValue = 0;
                        if (Decimal.TryParse(numberAsString, out numberValue))
                        {
                            job.AverageModelAccuracy = numberValue;
                        }
                        else
                        {
                            job.AverageModelAccuracy = 0;
                        }

                        job.TrainingDocumentResults = jsonContent["trainResult"]["trainingDocuments"].ToString();
                    }
                    if (jobStatus.ToLower() == "invalid")
                    {
                        throw new Exception($" Training failed. Status={jobStatus} The response body was {responseBody}");
                    }
                    job.LatestRecognizerStatus = jobStatus;

                    log.LogInformation($"{snip} Training Request Status is {jobStatus}");
                    return(job);
                }
                throw new Exception($" Training failed. Status=null The response body was {responseBody}");
            }
            throw new Exception($" Training failed. Http Status Code {response.StatusCode}");
        }