refactor external clients

put model batch size as parameter in config
This commit is contained in:
Alex Bezdieniezhnykh
2025-03-24 00:33:41 +02:00
parent 32f9de3c71
commit 6429ad62c2
28 changed files with 352 additions and 226 deletions
@@ -5,14 +5,15 @@ namespace Azaion.Common.DTO.Config;
[MessagePackObject]
public class AIRecognitionConfig
{
[Key(nameof(FramePeriodRecognition))] public int FramePeriodRecognition { get; set; }
[Key(nameof(FrameRecognitionSeconds))] public double FrameRecognitionSeconds { get; set; }
[Key(nameof(ProbabilityThreshold))] public double ProbabilityThreshold { get; set; }
[Key("f_pr")] public int FramePeriodRecognition { get; set; }
[Key("f_rs")] public double FrameRecognitionSeconds { get; set; }
[Key("pt")] public double ProbabilityThreshold { get; set; }
[Key(nameof(TrackingDistanceConfidence))] public double TrackingDistanceConfidence { get; set; }
[Key(nameof(TrackingProbabilityIncrease))] public double TrackingProbabilityIncrease { get; set; }
[Key(nameof(TrackingIntersectionThreshold))] public double TrackingIntersectionThreshold { get; set; }
[Key("t_dc")] public double TrackingDistanceConfidence { get; set; }
[Key("t_pi")] public double TrackingProbabilityIncrease { get; set; }
[Key("t_it")] public double TrackingIntersectionThreshold { get; set; }
[Key(nameof(Data))] public byte[] Data { get; set; } = null!;
[Key(nameof(Paths))] public List<string> Paths { get; set; } = null!;
[Key("d")] public byte[] Data { get; set; } = null!;
[Key("p")] public List<string> Paths { get; set; } = null!;
[Key("m_bs")] public int ModelBatchSize { get; set; } = 2;
}
+5 -2
View File
@@ -8,7 +8,9 @@ namespace Azaion.Common.DTO.Config;
public class AppConfig
{
public PythonConfig PythonConfig { get; set; } = null!;
public InferenceClientConfig InferenceClientConfig { get; set; } = null!;
public GpsDeniedClientConfig GpsDeniedClientConfig { get; set; } = null!;
public QueueConfig QueueConfig { get; set; } = null!;
@@ -85,7 +87,8 @@ public class ConfigUpdater : IConfigUpdater
//Save without sensitive info
var publicConfig = new
{
PythonConfig = config.PythonConfig,
InferenceClientConfig = config.InferenceClientConfig,
GpsDeniedClientConfig = config.GpsDeniedClientConfig,
DirectoriesConfig = config.DirectoriesConfig,
AnnotationConfig = config.AnnotationConfig,
AIRecognitionConfig = config.AIRecognitionConfig,
+29 -15
View File
@@ -100,26 +100,40 @@ public class FailsafeAnnotationsProducer
.ToListAsync(token: cancellationToken);
var messages = new List<AnnotationCreatedMessage>();
var badImages = new List<string>();
foreach (var annotation in annotations)
{
var image = await File.ReadAllBytesAsync(annotation.ImagePath, cancellationToken);
var annCreateMessage = new AnnotationCreatedMessage
try
{
Name = annotation.Name,
OriginalMediaName = annotation.OriginalMediaName,
Time = annotation.Time,
CreatedRole = annotation.CreatedRole,
CreatedEmail = annotation.CreatedEmail,
CreatedDate = annotation.CreatedDate,
Status = annotation.AnnotationStatus,
var image = await File.ReadAllBytesAsync(annotation.ImagePath, cancellationToken);
var annCreateMessage = new AnnotationCreatedMessage
{
Name = annotation.Name,
OriginalMediaName = annotation.OriginalMediaName,
Time = annotation.Time,
CreatedRole = annotation.CreatedRole,
CreatedEmail = annotation.CreatedEmail,
CreatedDate = annotation.CreatedDate,
Status = annotation.AnnotationStatus,
ImageExtension = annotation.ImageExtension,
Image = image,
Detections = JsonConvert.SerializeObject(annotation.Detections),
Source = annotation.Source,
ImageExtension = annotation.ImageExtension,
Image = image,
Detections = JsonConvert.SerializeObject(annotation.Detections),
Source = annotation.Source,
};
messages.Add(annCreateMessage);
}
catch (Exception e)
{
_logger.LogError(e, e.Message);
badImages.Add(annotation.Name);
}
}
};
messages.Add(annCreateMessage);
if (badImages.Any())
{
await db.AnnotationsQueue.Where(x => badImages.Contains(x.Name)).DeleteAsync(token: cancellationToken);
_dbFactory.SaveToDisk();
}
return messages;
});
+14 -15
View File
@@ -2,12 +2,12 @@
using Azaion.Common.Database;
using Azaion.Common.DTO.Config;
using Azaion.CommonSecurity;
using Azaion.CommonSecurity.DTO;
using Azaion.CommonSecurity.DTO.Commands;
using Azaion.CommonSecurity.Services;
using MessagePack;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NetMQ;
using NetMQ.Sockets;
namespace Azaion.Common.Services;
@@ -16,30 +16,29 @@ public interface IInferenceService
Task RunInference(List<string> mediaPaths, Func<AnnotationImage, Task> processAnnotation, CancellationToken ct = default);
}
public class PythonInferenceService(ILogger<PythonInferenceService> logger, IOptions<PythonConfig> pythonConfigOptions, IOptions<AIRecognitionConfig> aiConfigOptions) : IInferenceService
public class InferenceService(ILogger<InferenceService> logger, [FromKeyedServices(SecurityConstants.EXTERNAL_INFERENCE_PATH)] IExternalClient externalClient, IOptions<AIRecognitionConfig> aiConfigOptions) : IInferenceService
{
public async Task RunInference(List<string> mediaPaths, Func<AnnotationImage, Task> processAnnotation, CancellationToken ct = default)
{
var pythonConfig = pythonConfigOptions.Value;
var aiConfig = aiConfigOptions.Value;
using var dealer = new DealerSocket();
var clientId = Guid.NewGuid();
dealer.Options.Identity = Encoding.UTF8.GetBytes(clientId.ToString("N"));
dealer.Connect($"tcp://{pythonConfig.ZeroMqHost}:{pythonConfig.ZeroMqPort}");
aiConfig.Paths = mediaPaths;
dealer.SendFrame(RemoteCommand.Serialize(CommandType.Inference, aiConfig));
externalClient.Send(RemoteCommand.Create(CommandType.Inference, aiConfig));
while (!ct.IsCancellationRequested)
{
try
{
var annotationStream = dealer.Get<AnnotationImage>(bytes => bytes.Length == 4 && Encoding.UTF8.GetString(bytes) == "DONE", ct: ct);
if (annotationStream == null)
break;
var bytes = externalClient.GetBytes(ct: ct);
if (bytes == null)
throw new Exception("Can't get bytes from inference client");
await processAnnotation(annotationStream);
if (bytes.Length == 4 && Encoding.UTF8.GetString(bytes) == "DONE")
return;
var annotationImage = MessagePackSerializer.Deserialize<AnnotationImage>(bytes, cancellationToken: ct);
await processAnnotation(annotationImage);
}
catch (Exception e)
{