yum-archive/TaSTT-Whisper
High-performance GPGPU inference of OpenAI's Whisper automatic speech recognition (ASR) model
git clone https://git.yummers.dev/yum-archive/TaSTT-Whisper
b188f58
master
1using ComLight ; 2using System . Runtime . InteropServices ; 3using System . Runtime . Intrinsics . X86 ; 4using Whisper . Internal ; 5 6namespace Whisper 7{ 8/// <summary>Factory methods implemented by the C++ DLL</summary> 9public static class Library 10{ 11static Library () 12{ 13if ( Environment . OSVersion . Platform != PlatformID . Win32NT ) 14throw new ApplicationException ( "This library requires Windows OS" ); 15if ( ! Environment . Is64BitProcess ) 16throw new ApplicationException ( "This library only works in 64-bit processes" ); 17if ( RuntimeInformation . ProcessArchitecture != Architecture . X64 ) 18throw new ApplicationException ( "This library requires a processor with AMD64 instruction set" ); 19if ( ! Sse41 . IsSupported ) 20throw new ApplicationException ( "This library requires a CPU with SSE 4.1 support" ); 21NativeLogger . startup (); 22} 23 24const string dll = "Whisper.dll" ; 25 26[ DllImport ( dll , CallingConvention = RuntimeClass . defaultCallingConvention , PreserveSig = false )] 27internal static extern void setupLogger ( [ In ] ref sLoggerSetup setup ); 28 29[ DllImport ( dll , CallingConvention = RuntimeClass . defaultCallingConvention , PreserveSig = true )] 30static extern int loadModel ( [ MarshalAs ( UnmanagedType . LPWStr )] string path , eModelImplementation impl , eGpuModelFlags flags , 31[ In ] ref sLoadModelCallbacks callbacks , 32[ MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( Marshaler < iModel > ) )] out iModel model ); 33 34/// <summary>Load Whisper model from GGML file on disk</summary> 35/// <remarks>Models are large, depending on user’s disk speed this might take a while, and this function blocks the calling thread.<br/> 36/// Consider <see cref="loadModelAsync" /> instead.</remarks> 37/// <seealso href="https://huggingface.co/datasets/ggerganov/whisper.cpp" /> 38public static iModel loadModel ( string path , eGpuModelFlags flags = eGpuModelFlags . None , eModelImplementation impl = eModelImplementation . GPU ) 39{ 40iModel model ; 41sLoadModelCallbacks callbacks = default ; 42NativeLogger . prologue (); 43int hr = loadModel ( path , impl , flags , ref callbacks , out model ); 44NativeLogger . throwForHR ( hr ); 45return model ; 46} 47 48/// <summary>Load Whisper model on a background thread, with optional progress reporting and cancellation</summary> 49public static Task < iModel > loadModelAsync ( string path , CancellationToken cancelToken , eGpuModelFlags flags = eGpuModelFlags . None , Action < double >? pfnProgress = null , eModelImplementation impl = eModelImplementation . GPU ) 50{ 51TaskCompletionSource < iModel > tcs = new TaskCompletionSource < iModel > (); 52 53WaitCallback wcb = delegate ( object ? state ) 54{ 55try 56{ 57sLoadModelCallbacks callbacks = new sLoadModelCallbacks ( cancelToken , pfnProgress ); 58 59iModel model ; 60NativeLogger . prologue (); 61int hr = loadModel ( path , impl , flags , ref callbacks , out model ); 62NativeLogger . throwForHR ( hr ); 63 64tcs . SetResult ( model ); 65} 66catch ( Exception ex ) 67{ 68tcs . SetException ( ex ); 69} 70}; 71 72ThreadPool . QueueUserWorkItem ( wcb ); 73return tcs . Task ; 74} 75 76[ DllImport ( dll , CallingConvention = RuntimeClass . defaultCallingConvention , PreserveSig = true )] 77static extern int initMediaFoundation ( [ MarshalAs ( UnmanagedType . CustomMarshaler , MarshalTypeRef = typeof ( Marshaler < iMediaFoundation > ) )] out iMediaFoundation mf ); 78 79/// <summary>Initialize Media Foundation runtime</summary> 80public static iMediaFoundation initMediaFoundation () 81{ 82iMediaFoundation mf ; 83NativeLogger . prologue (); 84int hr = initMediaFoundation ( out mf ); 85NativeLogger . throwForHR ( hr ); 86return mf ; 87} 88 89// The .NET runtime uses UTF-16 for the strings, so we only need the Unicode version of this function. 90// The native DLL exports both Unicode and ASCII versions. 91[ DllImport ( dll , CallingConvention = RuntimeClass . defaultCallingConvention , PreserveSig = true )] 92static extern uint findLanguageKeyW ( [ MarshalAs ( UnmanagedType . LPWStr )] string lang ); 93 94/// <summary>Try to resolve language code string like <c>"en"</c>, <c>"pl"</c> or <c>"uk"</c> into the strongly-typed enum.</summary> 95/// <remarks>The function is case-sensitive, <c>"EN"</c> or <c>"UK"</c> gonna fail.</remarks> 96public static eLanguage ? languageFromCode ( string lang ) 97{ 98uint key = findLanguageKeyW ( lang ); 99if ( key != uint . MaxValue ) 100return ( eLanguage ) key ; 101return null ; 102} 103 104/// <summary>Set up delegate to receive log messages from the C++ library</summary> 105public static void setLogSink ( eLogLevel lvl , eLoggerFlags flags = eLoggerFlags . SkipFormatMessage , pfnLogMessage ? pfn = null ) 106{ 107NativeLogger . setup ( lvl , flags , pfn ); 108} 109} 110}