Warm up pyannote and FunASR runtimes
PR and Push Build/Test / build-and-test (push) Successful in 6m48s

This commit is contained in:
2026-05-28 13:05:27 +02:00
parent 7ff93b73b3
commit c46c587e65
14 changed files with 696 additions and 20 deletions
@@ -1,27 +1,41 @@
using MeetingAssistant.LaunchProfiles;
namespace MeetingAssistant.Transcription;
public sealed class SpeechRecognitionPipelineHostedService : IHostedService
{
private readonly ISpeechRecognitionPipelineFactory pipelineFactory;
private readonly ILaunchProfileOptionsProvider? launchProfiles;
private readonly ILogger<SpeechRecognitionPipelineHostedService> logger;
private CancellationTokenSource? startupCancellation;
private Task? startupTask;
private ISpeechRecognitionPipeline? startupPipeline;
private List<ISpeechRecognitionPipeline> startupPipelines = [];
public SpeechRecognitionPipelineHostedService(
ISpeechRecognitionPipelineFactory pipelineFactory,
ILogger<SpeechRecognitionPipelineHostedService> logger)
: this(pipelineFactory, null, logger)
{
}
public SpeechRecognitionPipelineHostedService(
ISpeechRecognitionPipelineFactory pipelineFactory,
ILaunchProfileOptionsProvider? launchProfiles,
ILogger<SpeechRecognitionPipelineHostedService> logger)
{
this.pipelineFactory = pipelineFactory;
this.launchProfiles = launchProfiles;
this.logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
startupCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
startupPipeline = pipelineFactory.Create();
var cancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
var pipelines = CreateStartupPipelines();
startupCancellation = cancellation;
startupPipelines = pipelines;
startupTask = Task.Run(
() => WarmUpPipelineAsync(startupPipeline, startupCancellation.Token),
() => WarmUpPipelinesAsync(pipelines, cancellation.Token),
CancellationToken.None);
return Task.CompletedTask;
}
@@ -30,15 +44,15 @@ public sealed class SpeechRecognitionPipelineHostedService : IHostedService
{
var cancellation = startupCancellation;
var task = startupTask;
var pipeline = startupPipeline;
if (cancellation is null || task is null || pipeline is null)
var pipelines = startupPipelines;
if (cancellation is null || task is null)
{
return;
}
startupCancellation = null;
startupTask = null;
startupPipeline = null;
startupPipelines = [];
await cancellation.CancelAsync();
try
{
@@ -49,11 +63,43 @@ public sealed class SpeechRecognitionPipelineHostedService : IHostedService
}
finally
{
await pipeline.DisposeAsync();
foreach (var pipeline in pipelines)
{
await pipeline.DisposeAsync();
}
cancellation.Dispose();
}
}
private List<ISpeechRecognitionPipeline> CreateStartupPipelines()
{
if (launchProfiles is null)
{
return [pipelineFactory.Create()];
}
return launchProfiles.GetProfiles()
.Where(ShouldWarmUpProfile)
.Select(profile => pipelineFactory.Create(profile.Name))
.ToList();
}
private static bool ShouldWarmUpProfile(LaunchProfile profile)
{
return profile.Name.Equals(
ConfigurationLaunchProfileOptionsProvider.DefaultProfileName,
StringComparison.OrdinalIgnoreCase) ||
profile.Options.Recording.TranscriptionProvider.Equals("funasr", StringComparison.OrdinalIgnoreCase);
}
private async Task WarmUpPipelinesAsync(
IReadOnlyList<ISpeechRecognitionPipeline> pipelines,
CancellationToken cancellationToken)
{
await Task.WhenAll(pipelines.Select(pipeline => WarmUpPipelineAsync(pipeline, cancellationToken)));
}
private async Task WarmUpPipelineAsync(
ISpeechRecognitionPipeline pipeline,
CancellationToken cancellationToken)