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
8c4603c
master
1#include "stdafx.h" 2#include "ML/Tensor.h" 3#include "API/iMediaFoundation.cl.h" 4#include "API/iContext.cl.h" 5#include "API/sFullParams.h" 6#include "Utils/ReadStream.h" 7#include "ML/testUtils.h" 8#include "Utils/Trace/tracing.h" 9#include "modelFactory.h" 10#if BUILD_BOTH_VERSIONS 11 12namespace 13{ 14LPCTSTR traceFilePath = LR"(C:\Temp\2remove\Whisper\ref.bin)" ; 15using ComLight ::iReadStream ; 16} 17 18struct whisper_context ; 19struct ggml_tensor ; 20 21class GpuEncTest 22{ 23DirectCompute ::Tensor mel ,gpuResult ; 24 25DirectCompute ::Tensor tempGpu ; 26const ggml_tensor * tempRef = nullptr ; 27public : 28GpuEncTest (const whisper_context & wctx ,const int mel_offset ); 29void compare (const ggml_tensor * expected )const ; 30void compareMel (const ggml_tensor * expected )const ; 31}; 32 33class GpuDecTest 34{ 35 std::vector < float > logits ,probs ; 36const ggml_tensor * tempRef = nullptr ; 37 38public : 39 40GpuDecTest (const whisper_context & wctx ,const int * tokens ,const int n_tokens ,const int n_past ); 41 42void postpone (const ggml_tensor * t ); 43void comparePostponed (); 44void compare (const std::vector < float >& cpuLogits ,const std::vector < float >& cpuProbs )const ; 45}; 46 47static DirectCompute ::Tensor gpuEncode (const whisper_context & wctx ,const int mel_offset ); 48 49#include "source/whisper.cpp" 50#include "API/iContext.cl.h" 51#include "../ComLightLib/comLightServer.h" 52#include "ML/mlStartup.h" 53#include "Whisper/WhisperContext.h" 54#include "Whisper/ModelLoader.h" 55#include "Whisper/WhisperModel.h" 56#include "source.compat/convertThings.h" 57 58namespace Whisper 59{ 60inline HRESULT isZero (int i ) 61 { 62return (0 == i ) ?S_OK :E_FAIL ; 63 } 64 65class Context :public ComLight ::ObjectRoot < iContext > , 66public iModel 67 { 68virtual HRESULT COMLIGHTCALL isMultilingual ()override final 69 { 70return whisper_is_multilingual (& ctx ) ?S_OK :S_FALSE ; 71 } 72virtual const char * COMLIGHTCALL stringFromToken (whisper_token token )override final 73 { 74return whisper_token_to_str (& ctx ,token ); 75 } 76virtual HRESULT COMLIGHTCALL getSpecialTokens (SpecialTokens & rdi ) 77 { 78rdi .TranscriptionEnd = whisper_token_eot (& ctx ); 79rdi .TranscriptionStart = whisper_token_sot (& ctx ); 80rdi .PreviousWord = whisper_token_prev (& ctx ); 81rdi .SentenceStart = whisper_token_solm (& ctx ); 82rdi .Not = whisper_token_not (& ctx ); 83rdi .TranscriptionBegin = whisper_token_beg (& ctx ); 84rdi .TaskTranslate = whisper_token_translate (); 85rdi .TaskTranscribe = whisper_token_transcribe (); 86return S_OK ; 87 } 88 89// Performance information 90virtual HRESULT COMLIGHTCALL timingsPrint ()override final 91 { 92whisper_print_timings (& ctx ); 93return S_OK ; 94 } 95virtual HRESULT COMLIGHTCALL timingsReset ()override final 96 { 97whisper_reset_timings (& ctx ); 98return S_OK ; 99 } 100 101virtual HRESULT COMLIGHTCALL fullDefaultParams (eSamplingStrategy strategy ,sFullParams * rdi ) 102 { 103 static_assert( (int )eSamplingStrategy::Greedy == whisper_sampling_strategy::WHISPER_SAMPLING_GREEDY ); 104 static_assert( (int )eSamplingStrategy::BeamSearch == whisper_sampling_strategy::WHISPER_SAMPLING_BEAM_SEARCH ); 105const whisper_sampling_strategy wss = (whisper_sampling_strategy )(int )strategy ; 106whisper_full_params wfp = whisper_full_default_params (wss ); 107 108* rdi = makeNewParams (wfp ); 109return S_OK ; 110 } 111 112HRESULT COMLIGHTCALL runFull (const sFullParams & params ,const iAudioBuffer * buffer )override final 113 { 114whisper_full_params wfp = makeOldParams (params ,this ); 115const float * const samples = buffer -> getPcmMono (); 116const uint32_t n_samples = buffer -> countSamples (); 117return isZero (whisper_full (& ctx ,wfp ,samples , (int )n_samples ) ); 118 } 119 120HRESULT COMLIGHTCALL runStreamed (const sFullParams & params ,const sProgressSink & progress ,const iAudioReader * reader )override final 121 { 122logError (u8"The CPU reference implementation doesn’t support streaming" ); 123return E_NOTIMPL ; 124 } 125HRESULT COMLIGHTCALL runCapture (const sFullParams & params ,const sCaptureCallbacks & callbacks ,const iAudioCapture * reader )override final 126 { 127logError (u8"The CPU reference implementation doesn’t support audio capture" ); 128return E_NOTIMPL ; 129 } 130 131HRESULT COMLIGHTCALL getResults (eResultFlags flags ,iTranscribeResult ** pp )const override final 132 { 133makeNewResults (& ctx ,flags ,pp ); 134return S_OK ; 135 } 136 137HRESULT loadImpl (iReadStream * stm ); 138 139virtual HRESULT COMLIGHTCALL createContext (iContext ** pp )override final 140 { 141if (nullptr == pp ) 142return E_POINTER ; 143* pp = this ; 144 (* pp )-> AddRef (); 145return S_OK ; 146 } 147 148virtual HRESULT COMLIGHTCALL getModel (iModel ** pp )override final 149 { 150if (nullptr == pp ) 151return E_POINTER ; 152* pp = this ; 153 (* pp )-> AddRef (); 154return S_OK ; 155 } 156 157public : 158 159Context () 160 { 161if (nullptr != traceFilePath ) 162Tracing ::traceCreate (traceFilePath ); 163 } 164 165mutable whisper_context ctx ; 166 167HRESULT load (iReadStream * stm ); 168 169 ~Context () 170 { 171Tracing ::traceClose (); 172 173if (ctx .model .ctx ) 174 { 175ggml_free (ctx .model .ctx ); 176ctx .model .ctx = nullptr ; 177 } 178if (ctx .model .ctx_mem ) 179 { 180ggml_free (ctx .model .ctx_mem ); 181ctx .model .ctx_mem = nullptr ; 182 } 183if (ctx .buf_model ) 184 { 185delete ctx .buf_model ; 186ctx .buf_model = nullptr ; 187 } 188 } 189 190BEGIN_COM_MAP () 191COM_INTERFACE_ENTRY (iModel ); 192END_COM_MAP () 193 }; 194 195inline HRESULT readBytes (iReadStream * stm ,void * rdi ,size_t cb ) 196 { 197if (cb > INT_MAX ) 198return DISP_E_OVERFLOW ; 199if (cb == 0 ) 200return S_FALSE ; 201int n ; 202CHECK (stm -> read (rdi , (int )cb ,n ) ); 203if (n != (int )cb ) 204return E_EOF ; 205return S_OK ; 206 } 207 208template < typename T > 209inline HRESULT readStruct (iReadStream * stm ,T & dest ) 210 { 211return readBytes (stm ,& dest ,sizeof (T ) ); 212 } 213template < typename E > 214inline HRESULT readVector (iReadStream * stm , std::vector < E >& vec ) 215 { 216const size_t cb = sizeof (E )* vec .size (); 217if (cb > 0 ) 218return readBytes (stm ,vec .data (),cb ); 219return S_FALSE ; 220 } 221 222inline HRESULT readString (iReadStream * stm , std::string & str ) 223 { 224uint32_t len ; 225CHECK (readStruct (stm ,len ) ); 226if (len > 0 ) 227 { 228str .resize (len ); 229return readBytes (stm ,str .data (),len ); 230 } 231else 232 { 233str .clear (); 234return S_FALSE ; 235 } 236 } 237 238// load the model from a ggml file 239// file format: 240// - hparams 241// - pre-computed mel filters 242// - vocab 243// - weights 244// see the convert-pt-to-ggml.py script for details 245HRESULT Context ::loadImpl (iReadStream * stm ) 246 { 247// WhisperModel wm; 248// return wm.load( stm ); 249 250// Copy-pasted from whisper_model_load() function 251auto & model = ctx .model ; 252auto & vocab = ctx .vocab ; 253 254// verify magic 255 { 256uint32_t magic ; 257int cbRead ; 258CHECK (stm -> read (& magic ,4 ,cbRead ) ); 259if (magic != 0x67676d6c ) 260 { 261logError (u8"Invalid model file, bad magic" ); 262return E_INVALIDARG ; 263 } 264 } 265 266//load hparams 267 { 268auto & hparams = model .hparams ; 269CHECK (readStruct (stm ,hparams ) ); 270assert (hparams .n_text_state == hparams .n_audio_state ); 271 272if (hparams .n_audio_layer == 4 ) 273model .type = e_model::MODEL_TINY ; 274if (hparams .n_audio_layer == 6 ) 275model .type = e_model::MODEL_BASE ; 276if (hparams .n_audio_layer == 12 ) 277model .type = e_model::MODEL_SMALL ; 278if (hparams .n_audio_layer == 24 ) 279model .type = e_model::MODEL_MEDIUM ; 280if (hparams .n_audio_layer == 32 ) 281model .type = e_model::MODEL_LARGE ; 282 283logDebug (u8"%s: n_vocab = %d" ,__func__ ,hparams .n_vocab ); 284logDebug (u8"%s: n_audio_ctx = %d" ,__func__ ,hparams .n_audio_ctx ); 285logDebug (u8"%s: n_audio_state = %d" ,__func__ ,hparams .n_audio_state ); 286logDebug (u8"%s: n_audio_head = %d" ,__func__ ,hparams .n_audio_head ); 287logDebug (u8"%s: n_audio_layer = %d" ,__func__ ,hparams .n_audio_layer ); 288logDebug (u8"%s: n_text_ctx = %d" ,__func__ ,hparams .n_text_ctx ); 289logDebug (u8"%s: n_text_state = %d" ,__func__ ,hparams .n_text_state ); 290logDebug (u8"%s: n_text_head = %d" ,__func__ ,hparams .n_text_head ); 291logDebug (u8"%s: n_text_layer = %d" ,__func__ ,hparams .n_text_layer ); 292logDebug (u8"%s: n_mels = %d" ,__func__ ,hparams .n_mels ); 293logDebug (u8"%s: f16 = %d" ,__func__ ,hparams .f16 ); 294logDebug (u8"%s: type = %d" ,__func__ ,model .type ); 295 296ctx .buf_model = new std::vector < uint8_t > (); 297ctx .buf_model -> resize (MEM_REQ_MODEL .at (model .type ) ); 298ctx .buf_memory .resize (MEM_REQ_MEMORY .at (model .type ) ); 299ctx .buf_compute .resize ( std::max (MEM_REQ_ENCODE .at (model .type ),MEM_REQ_DECODE .at (model .type ) ) ); 300ctx .buf_compute_layer .resize ( std::max (MEM_REQ_ENCODE_LAYER .at (model .type ),MEM_REQ_DECODE_LAYER .at (model .type ) ) ); 301 } 302 303// load mel filters 304 { 305auto & filters = ctx .model .filters ; 306CHECK (readStruct (stm ,filters .n_mel ) ); 307CHECK (readStruct (stm ,filters .n_fft ) ); 308filters .data .resize (filters .n_mel * filters .n_fft ); 309CHECK (readVector (stm ,filters .data ) ); 310 } 311 312// load vocab 313 { 314int32_t n_vocab = 0 ; 315CHECK (readStruct (stm ,n_vocab ) ); 316 317//if (n_vocab != model.hparams.n_vocab) { 318// fprintf(stderr, "%s: invalid model file '%s' (bad vocab size %d != %d)\n", 319// __func__, fname.c_str(), n_vocab, model.hparams.n_vocab); 320// return false; 321//} 322 323 std::string word ; 324for (int i = 0 ;i < n_vocab ;i ++ ) 325 { 326CHECK (readString (stm ,word ) ); 327vocab .token_to_id [word ]= i ; 328vocab .id_to_token [i ]= word ; 329 } 330 331vocab .n_vocab = model .hparams .n_vocab ; 332if (vocab .is_multilingual () ) 333 { 334vocab .token_eot ++ ; 335vocab .token_sot ++ ; 336vocab .token_prev ++ ; 337vocab .token_solm ++ ; 338vocab .token_not ++ ; 339vocab .token_beg ++ ; 340 } 341 342if (n_vocab < model .hparams .n_vocab ) 343 { 344logDebug (u8"%s: adding %d extra tokens" ,__func__ ,model .hparams .n_vocab - n_vocab ); 345for (int i = n_vocab ;i < model .hparams .n_vocab ;i ++ ) 346 { 347if (i > vocab .token_beg ) 348word = "[_TT_" + std::to_string (i - vocab .token_beg )+ "]" ; 349else if (i == vocab .token_eot ) 350word = "[_EOT_]" ; 351else if (i == vocab .token_sot ) 352word = "[_SOT_]" ; 353else if (i == vocab .token_prev ) 354word = "[_PREV_]" ; 355else if (i == vocab .token_not ) 356word = "[_NOT_]" ; 357else if (i == vocab .token_beg ) 358word = "[_BEG_]" ; 359else 360word = "[_extra_token_" + std::to_string (i )+ "]" ; 361 362vocab .token_to_id [word ]= i ; 363vocab .id_to_token [i ]= word ; 364 } 365 } 366 } 367 368 { 369// this is the total memory required to run the inference 370const size_t mem_required = 371ctx .buf_model -> size ()+ 372ctx .buf_memory .size ()+ 373ctx .buf_compute .size ()+ 374ctx .buf_compute_layer .size (); 375logDebug (u8"%s: mem_required = %7.2f MB" ,__func__ ,mem_required /1024.0 /1024.0 ); 376 } 377 378// for the big tensors, we have the option to store the data in 16-bit floats 379// in order to save memory and also to speed up the computation 380const ggml_type wtype = model .hparams .f16 ?GGML_TYPE_F16 :GGML_TYPE_F32 ; 381 382size_t ctx_size = 0 ; 383size_t ctx_mem_size = 0 ; 384 385 { 386const auto & hparams = model .hparams ; 387 388const int n_vocab = hparams .n_vocab ; 389 390const int n_audio_ctx = hparams .n_audio_ctx ; 391const int n_audio_state = hparams .n_audio_state ; 392const int n_audio_layer = hparams .n_audio_layer ; 393 394const int n_text_ctx = hparams .n_text_ctx ; 395const int n_text_state = hparams .n_text_state ; 396const int n_text_layer = hparams .n_text_layer ; 397 398const int n_mels = hparams .n_mels ; 399 400// encoder 401 { 402// TODO: F16 .. maybe not? 403ctx_size += n_audio_ctx * n_audio_state * ggml_type_size (GGML_TYPE_F32 );// e_pe; 404 405ctx_size += 3 * n_mels * n_audio_state * ggml_type_size (wtype );// e_conv_1_w 406ctx_size += n_audio_state * ggml_type_size (GGML_TYPE_F32 );// e_conv_1_b 407 408ctx_size += 3 * n_audio_state * n_audio_state * ggml_type_size (wtype );// e_conv_2_w 409ctx_size += n_audio_state * ggml_type_size (GGML_TYPE_F32 );// e_conv_2_b 410 411ctx_size += n_audio_state * ggml_type_size (GGML_TYPE_F32 );// e_ln_w; 412ctx_size += n_audio_state * ggml_type_size (GGML_TYPE_F32 );// e_ln_b; 413 } 414 415// decoder 416 { 417// TODO: F16 .. maybe not? 418ctx_size += n_text_ctx * n_text_state * ggml_type_size (GGML_TYPE_F32 );// d_pe; 419 420ctx_size += n_vocab * n_text_state * ggml_type_size (wtype );// d_te; 421 422ctx_size += n_text_state * ggml_type_size (GGML_TYPE_F32 );// d_ln_w; 423ctx_size += n_text_state * ggml_type_size (GGML_TYPE_F32 );// d_ln_b; 424 } 425 426// encoder layers 427 { 428ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_ln_w 429ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_ln_b 430 431ctx_size += n_audio_layer * (4 * n_audio_state * n_audio_state * ggml_type_size (wtype ) );// mlp_0_w 432ctx_size += n_audio_layer * (4 * n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_0_b 433 434ctx_size += n_audio_layer * (4 * n_audio_state * n_audio_state * ggml_type_size (wtype ) );// mlp_1_w 435ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_1_b 436 437ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_ln_0_w 438ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_ln_0_b 439 440ctx_size += n_audio_layer * (n_audio_state * n_audio_state * ggml_type_size (wtype ) );// attn_q_w 441ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_q_b 442 443ctx_size += n_audio_layer * (n_audio_state * n_audio_state * ggml_type_size (wtype ) );// attn_k_w 444 445ctx_size += n_audio_layer * (n_audio_state * n_audio_state * ggml_type_size (wtype ) );// attn_v_w 446ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_v_b 447 448ctx_size += n_audio_layer * (n_audio_state * n_audio_state * ggml_type_size (wtype ) );// attn_ln_1_w 449ctx_size += n_audio_layer * (n_audio_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_ln_1_b 450 } 451 452// decoder layers 453 { 454ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_ln_w 455ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_ln_b 456 457ctx_size += n_text_layer * (4 * n_text_state * n_text_state * ggml_type_size (wtype ) );// mlp_0_w 458ctx_size += n_text_layer * (4 * n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_0_b 459 460ctx_size += n_text_layer * (4 * n_text_state * n_text_state * ggml_type_size (wtype ) );// mlp_1_w 461ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// mlp_1_b 462 463ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_ln_0_w 464ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_ln_0_b 465 466ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// attn_q_w 467ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_q_b 468 469ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// attn_k_w 470 471ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// attn_v_w 472ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_v_b 473 474ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// attn_ln_1_w 475ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// attn_ln_1_b 476// 477ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// cross_attn_ln_0_w 478ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// cross_attn_ln_0_b 479 480ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// cross_attn_q_w 481ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// cross_attn_q_b 482 483ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// cross_attn_k_w 484 485ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// cross_attn_v_w 486ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// cross_attn_v_b 487 488ctx_size += n_text_layer * (n_text_state * n_text_state * ggml_type_size (wtype ) );// cross_attn_ln_1_w 489ctx_size += n_text_layer * (n_text_state * ggml_type_size (GGML_TYPE_F32 ) );// cross_attn_ln_1_b 490 } 491 492ctx_mem_size += n_text_layer * n_text_ctx * n_text_state * ggml_type_size (GGML_TYPE_F16 );// memory_k 493ctx_mem_size += n_text_layer * n_text_ctx * n_text_state * ggml_type_size (GGML_TYPE_F16 );// memory_v 494 495ctx_mem_size += n_text_layer * n_audio_ctx * n_text_state * ggml_type_size (GGML_TYPE_F16 );// memory_cross_k 496ctx_mem_size += n_text_layer * n_audio_ctx * n_text_state * ggml_type_size (GGML_TYPE_F16 );// memory_cross_v 497 498ctx_size += (15 + 15 * n_audio_layer + 24 * n_text_layer )* 256 ;// object overhead 499 500logDebug (u8"%s: ggml ctx size = %7.2f MB" ,__func__ ,ctx_size / (1024.0 * 1024.0 ) ); 501 } 502 503// create the ggml context 504 { 505struct ggml_init_params params ; 506params .mem_size = ctx .buf_model -> size (); 507params .mem_buffer = ctx .buf_model -> data (); 508 509model .ctx = ggml_init (params ); 510if ( !model .ctx ) 511 { 512logError (u8"%s: ggml_init() failed" ,__func__ ); 513return E_INVALIDARG ; 514 } 515 } 516 517 std::map < std::string ,struct ggml_tensor *> tensors ; 518DirectCompute ::ModelLoader loader {model .hparams .n_audio_layer ,model .hparams .n_text_layer }; 519 520// prepare memory for the weights 521 { 522auto & ctx = model .ctx ; 523const auto & hparams = model .hparams ; 524const int n_vocab = hparams .n_vocab ; 525 526const int n_audio_ctx = hparams .n_audio_ctx ; 527const int n_audio_state = hparams .n_audio_state ; 528const int n_audio_layer = hparams .n_audio_layer ; 529 530const int n_text_ctx = hparams .n_text_ctx ; 531const int n_text_state = hparams .n_text_state ; 532const int n_text_layer = hparams .n_text_layer ; 533 534const int n_mels = hparams .n_mels ; 535 536model .layers_encoder .resize (n_audio_layer ); 537model .layers_decoder .resize (n_text_layer ); 538 539// encoder 540 { 541model .e_pe = ggml_new_tensor_2d (ctx ,GGML_TYPE_F32 ,n_audio_state ,n_audio_ctx ); 542loader .add (model .e_pe ,loader .model .enc .positionalEmbedding ); 543 544model .e_conv_1_w = ggml_new_tensor_3d (ctx ,wtype ,3 ,n_mels ,n_audio_state ); 545model .e_conv_1_b = ggml_new_tensor_2d (ctx ,GGML_TYPE_F32 ,1 ,n_audio_state ); 546loader .add (model .e_conv_1_w ,model .e_conv_1_b ,loader .model .enc .conv1 ); 547 548model .e_conv_2_w = ggml_new_tensor_3d (ctx ,wtype ,3 ,n_audio_state ,n_audio_state ); 549model .e_conv_2_b = ggml_new_tensor_2d (ctx ,GGML_TYPE_F32 ,1 ,n_audio_state ); 550loader .add (model .e_conv_2_w ,model .e_conv_2_b ,loader .model .enc .conv2 ); 551 552model .e_ln_w = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 553model .e_ln_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 554loader .add (model .e_ln_w ,model .e_ln_b ,loader .model .enc .lnPost ); 555 556// map by name 557tensors ["encoder.positional_embedding" ]= model .e_pe ; 558 559tensors ["encoder.conv1.weight" ]= model .e_conv_1_w ; 560tensors ["encoder.conv1.bias" ]= model .e_conv_1_b ; 561 562tensors ["encoder.conv2.weight" ]= model .e_conv_2_w ; 563tensors ["encoder.conv2.bias" ]= model .e_conv_2_b ; 564 565tensors ["encoder.ln_post.weight" ]= model .e_ln_w ; 566tensors ["encoder.ln_post.bias" ]= model .e_ln_b ; 567 568for (int i = 0 ;i < n_audio_layer ;++ i ) 569 { 570auto & layer = model .layers_encoder [i ]; 571auto & gpu = loader .model .enc .layers [i ]; 572 573layer .mlp_ln_w = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 574layer .mlp_ln_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 575loader .add (layer .mlp_ln_w ,layer .mlp_ln_b ,gpu .mlpLn ); 576 577layer .mlp_0_w = ggml_new_tensor_2d (ctx ,wtype ,n_audio_state ,4 * n_audio_state ); 578layer .mlp_0_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,4 * n_audio_state ); 579loader .add (layer .mlp_0_w ,layer .mlp_0_b ,gpu .mlp0 ); 580 581layer .mlp_1_w = ggml_new_tensor_2d (ctx ,wtype ,4 * n_audio_state ,n_audio_state ); 582layer .mlp_1_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 583loader .add (layer .mlp_1_w ,layer .mlp_1_b ,gpu .mlp1 ); 584 585layer .attn_ln_0_w = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 586layer .attn_ln_0_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 587loader .add (layer .attn_ln_0_w ,layer .attn_ln_0_b ,gpu .attnLn0 ); 588 589layer .attn_q_w = ggml_new_tensor_2d (ctx ,wtype ,n_audio_state ,n_audio_state ); 590layer .attn_q_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 591loader .add (layer .attn_q_w ,layer .attn_q_b ,gpu .attnQuery ); 592 593layer .attn_k_w = ggml_new_tensor_2d (ctx ,wtype ,n_audio_state ,n_audio_state ); 594loader .add (layer .attn_k_w ,gpu .attnKey ); 595 596layer .attn_v_w = ggml_new_tensor_2d (ctx ,wtype ,n_audio_state ,n_audio_state ); 597layer .attn_v_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 598loader .add (layer .attn_v_w ,layer .attn_v_b ,gpu .attnValue ); 599 600layer .attn_ln_1_w = ggml_new_tensor_2d (ctx ,wtype ,n_audio_state ,n_audio_state ); 601layer .attn_ln_1_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_audio_state ); 602loader .add (layer .attn_ln_1_w ,layer .attn_ln_1_b ,gpu .attnLn1 ); 603 604// map by name 605tensors ["encoder.blocks." + std::to_string (i )+ ".mlp_ln.weight" ]= layer .mlp_ln_w ; 606tensors ["encoder.blocks." + std::to_string (i )+ ".mlp_ln.bias" ]= layer .mlp_ln_b ; 607 608tensors ["encoder.blocks." + std::to_string (i )+ ".mlp.0.weight" ]= layer .mlp_0_w ; 609tensors ["encoder.blocks." + std::to_string (i )+ ".mlp.0.bias" ]= layer .mlp_0_b ; 610 611tensors ["encoder.blocks." + std::to_string (i )+ ".mlp.2.weight" ]= layer .mlp_1_w ; 612tensors ["encoder.blocks." + std::to_string (i )+ ".mlp.2.bias" ]= layer .mlp_1_b ; 613 614tensors ["encoder.blocks." + std::to_string (i )+ ".attn_ln.weight" ]= layer .attn_ln_0_w ; 615tensors ["encoder.blocks." + std::to_string (i )+ ".attn_ln.bias" ]= layer .attn_ln_0_b ; 616 617tensors ["encoder.blocks." + std::to_string (i )+ ".attn.query.weight" ]= layer .attn_q_w ; 618tensors ["encoder.blocks." + std::to_string (i )+ ".attn.query.bias" ]= layer .attn_q_b ; 619 620tensors ["encoder.blocks." + std::to_string (i )+ ".attn.key.weight" ]= layer .attn_k_w ; 621 622tensors ["encoder.blocks." + std::to_string (i )+ ".attn.value.weight" ]= layer .attn_v_w ; 623tensors ["encoder.blocks." + std::to_string (i )+ ".attn.value.bias" ]= layer .attn_v_b ; 624 625tensors ["encoder.blocks." + std::to_string (i )+ ".attn.out.weight" ]= layer .attn_ln_1_w ; 626tensors ["encoder.blocks." + std::to_string (i )+ ".attn.out.bias" ]= layer .attn_ln_1_b ; 627 } 628 } 629 630// decoder 631 { 632model .d_pe = ggml_new_tensor_2d (ctx ,GGML_TYPE_F32 ,n_text_state ,n_text_ctx ); 633loader .add (model .d_pe ,loader .model .dec .positionalEmbedding ); 634 635model .d_te = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_vocab ); 636loader .add (model .d_te ,loader .model .dec .tokenEmbedding ); 637 638model .d_ln_w = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 639model .d_ln_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 640loader .add (model .d_ln_w ,model .d_ln_b ,loader .model .dec .ln ); 641 642// map by name 643tensors ["decoder.positional_embedding" ]= model .d_pe ; 644 645tensors ["decoder.token_embedding.weight" ]= model .d_te ; 646 647tensors ["decoder.ln.weight" ]= model .d_ln_w ; 648tensors ["decoder.ln.bias" ]= model .d_ln_b ; 649 650for (int i = 0 ;i < n_text_layer ;++ i ) { 651auto & layer = model .layers_decoder [i ]; 652auto & gpu = loader .model .dec .layers [i ]; 653 654layer .mlp_ln_w = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 655layer .mlp_ln_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 656loader .add (layer .mlp_ln_w ,layer .mlp_ln_b ,gpu .mlpLn ); 657 658layer .mlp_0_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,4 * n_text_state ); 659layer .mlp_0_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,4 * n_text_state ); 660loader .add (layer .mlp_0_w ,layer .mlp_0_b ,gpu .mlp0 ); 661 662layer .mlp_1_w = ggml_new_tensor_2d (ctx ,wtype ,4 * n_text_state ,n_text_state ); 663layer .mlp_1_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 664loader .add (layer .mlp_1_w ,layer .mlp_1_b ,gpu .mlp1 ); 665 666layer .attn_ln_0_w = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 667layer .attn_ln_0_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 668loader .add (layer .attn_ln_0_w ,layer .attn_ln_0_b ,gpu .attnLn0 ); 669 670layer .attn_q_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 671layer .attn_q_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 672loader .add (layer .attn_q_w ,layer .attn_q_b ,gpu .attnQuery ); 673 674layer .attn_k_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 675loader .add (layer .attn_k_w ,gpu .attnKey ); 676 677layer .attn_v_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 678layer .attn_v_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 679loader .add (layer .attn_v_w ,layer .attn_v_b ,gpu .attnValue ); 680 681layer .attn_ln_1_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 682layer .attn_ln_1_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 683loader .add (layer .attn_ln_1_w ,layer .attn_ln_1_b ,gpu .attnLn1 ); 684 685layer .cross_attn_ln_0_w = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 686layer .cross_attn_ln_0_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 687loader .add (layer .cross_attn_ln_0_w ,layer .cross_attn_ln_0_b ,gpu .crossAttnLn0 ); 688 689layer .cross_attn_q_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 690layer .cross_attn_q_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 691loader .add (layer .cross_attn_q_w ,layer .cross_attn_q_b ,gpu .crossAttnQuery ); 692 693layer .cross_attn_k_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 694loader .add (layer .cross_attn_k_w ,gpu .crossAttnKey ); 695 696layer .cross_attn_v_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 697layer .cross_attn_v_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 698loader .add (layer .cross_attn_v_w ,layer .cross_attn_v_b ,gpu .crossAttnValue ); 699 700layer .cross_attn_ln_1_w = ggml_new_tensor_2d (ctx ,wtype ,n_text_state ,n_text_state ); 701layer .cross_attn_ln_1_b = ggml_new_tensor_1d (ctx ,GGML_TYPE_F32 ,n_text_state ); 702loader .add (layer .cross_attn_ln_1_w ,layer .cross_attn_ln_1_b ,gpu .crossAttnLn1 ); 703 704// map by name 705tensors ["decoder.blocks." + std::to_string (i )+ ".mlp_ln.weight" ]= layer .mlp_ln_w ; 706tensors ["decoder.blocks." + std::to_string (i )+ ".mlp_ln.bias" ]= layer .mlp_ln_b ; 707 708tensors ["decoder.blocks." + std::to_string (i )+ ".mlp.0.weight" ]= layer .mlp_0_w ; 709tensors ["decoder.blocks." + std::to_string (i )+ ".mlp.0.bias" ]= layer .mlp_0_b ; 710 711tensors ["decoder.blocks." + std::to_string (i )+ ".mlp.2.weight" ]= layer .mlp_1_w ; 712tensors ["decoder.blocks." + std::to_string (i )+ ".mlp.2.bias" ]= layer .mlp_1_b ; 713 714tensors ["decoder.blocks." + std::to_string (i )+ ".attn_ln.weight" ]= layer .attn_ln_0_w ; 715tensors ["decoder.blocks." + std::to_string (i )+ ".attn_ln.bias" ]= layer .attn_ln_0_b ; 716 717tensors ["decoder.blocks." + std::to_string (i )+ ".attn.query.weight" ]= layer .attn_q_w ; 718tensors ["decoder.blocks." + std::to_string (i )+ ".attn.query.bias" ]= layer .attn_q_b ; 719 720tensors ["decoder.blocks." + std::to_string (i )+ ".attn.key.weight" ]= layer .attn_k_w ; 721 722tensors ["decoder.blocks." + std::to_string (i )+ ".attn.value.weight" ]= layer .attn_v_w ; 723tensors ["decoder.blocks." + std::to_string (i )+ ".attn.value.bias" ]= layer .attn_v_b ; 724 725tensors ["decoder.blocks." + std::to_string (i )+ ".attn.out.weight" ]= layer .attn_ln_1_w ; 726tensors ["decoder.blocks." + std::to_string (i )+ ".attn.out.bias" ]= layer .attn_ln_1_b ; 727 728tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn_ln.weight" ]= layer .cross_attn_ln_0_w ; 729tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn_ln.bias" ]= layer .cross_attn_ln_0_b ; 730 731tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn.query.weight" ]= layer .cross_attn_q_w ; 732tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn.query.bias" ]= layer .cross_attn_q_b ; 733 734tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn.key.weight" ]= layer .cross_attn_k_w ; 735 736tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn.value.weight" ]= layer .cross_attn_v_w ; 737tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn.value.bias" ]= layer .cross_attn_v_b ; 738 739tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn.out.weight" ]= layer .cross_attn_ln_1_w ; 740tensors ["decoder.blocks." + std::to_string (i )+ ".cross_attn.out.bias" ]= layer .cross_attn_ln_1_b ; 741 } 742 } 743 } 744 745// create the ggml memory context 746 { 747struct ggml_init_params params ; 748params .mem_size = ctx .buf_memory .size (); 749params .mem_buffer = ctx .buf_memory .data (); 750model .ctx_mem = ggml_init (params ); 751if ( !model .ctx_mem ) 752 { 753logError (u8"%s: ggml_init() failed" ,__func__ ); 754return E_INVALIDARG ; 755 } 756 } 757 758// key + value memory 759 { 760auto & ctx = model .ctx_mem ; 761 762const auto & hparams = model .hparams ; 763 764const int n_text_state = hparams .n_text_state ; 765const int n_text_layer = hparams .n_text_layer ; 766const int n_text_ctx = hparams .n_text_ctx ; 767 768// key/value memory for the self-attention layer 769 { 770const int n_mem = n_text_layer * n_text_ctx ; 771const int n_elements = n_text_state * n_mem ; 772 773model .memory_k = ggml_new_tensor_1d (ctx ,GGML_TYPE_F16 ,n_elements ); 774model .memory_v = ggml_new_tensor_1d (ctx ,GGML_TYPE_F16 ,n_elements ); 775 } 776 777// key/value memory for the cross-attention layer 778 { 779const int n_audio_ctx = hparams .n_audio_ctx ; 780 781const int n_mem = n_text_layer * n_audio_ctx ; 782const int n_elements = n_text_state * n_mem ; 783 784model .memory_cross_k = ggml_new_tensor_1d (ctx ,GGML_TYPE_F16 ,n_elements ); 785model .memory_cross_v = ggml_new_tensor_1d (ctx ,GGML_TYPE_F16 ,n_elements ); 786 } 787 788const size_t memory_size = 789ggml_nbytes (model .memory_k )+ ggml_nbytes (model .memory_v )+ 790ggml_nbytes (model .memory_cross_k )+ ggml_nbytes (model .memory_cross_v ); 791 792logDebug (u8"%s: memory size = %7.2f MB" ,__func__ ,memory_size /1024.0 /1024.0 ); 793 } 794 795// load weights 796 { 797size_t total_size = 0 ; 798int n_loaded = 0 ; 799 std::string name ; 800 801while ( true ) 802 { 803int32_t n_dims ; 804int32_t length ; 805int32_t ftype ; 806 807HRESULT hr = readStruct (stm ,n_dims ); 808if (hr == E_EOF ) 809break ; 810CHECK (hr ); 811CHECK (readStruct (stm ,length ) ); 812CHECK (readStruct (stm ,ftype ) ); 813 814int32_t nelements = 1 ; 815int32_t ne [3 ]= {1 ,1 ,1 }; 816for (int i = 0 ;i < n_dims ;++ i ) 817 { 818CHECK (readStruct (stm ,ne [i ] ) ); 819nelements *=ne [i ]; 820 } 821 822name .resize (length ); 823CHECK (readBytes (stm ,name .data (),length ) ); 824 825if (tensors .find (name .data () )== tensors .end () ) 826 { 827logError (u8"%s: unknown tensor '%s' in model file" ,__func__ ,name .data () ); 828return E_INVALIDARG ; 829 } 830 831auto tensor = tensors [name .data () ]; 832if (ggml_nelements (tensor )!= nelements ) 833 { 834logError (u8"%s: tensor '%s' has wrong size in model file" ,__func__ ,name .data () ); 835return E_INVALIDARG ; 836 } 837 838if (tensor -> ne [0 ]!= ne [0 ]|| tensor -> ne [1 ]!= ne [1 ]|| tensor -> ne [2 ]!= ne [2 ] ) 839 { 840logError (u8"%s: tensor '%s' has wrong shape in model file: got [%d, %d, %d], expected [%d, %d, %d]" , 841__func__ ,name .data (),tensor -> ne [0 ],tensor -> ne [1 ],tensor -> ne [2 ],ne [0 ],ne [1 ],ne [2 ] ); 842return E_INVALIDARG ; 843 } 844 845const size_t bpe = (ftype == 0 ) ?sizeof (float ) :sizeof (ggml_fp16_t ); 846 847if (nelements * bpe != ggml_nbytes (tensor ) ) 848 { 849logError (u8"%s: tensor '%s' has wrong size in model file: got %zu, expected %zu" , 850__func__ ,name .data (),ggml_nbytes (tensor ),nelements * bpe ); 851return E_INVALIDARG ; 852 } 853 854CHECK (readBytes (stm ,tensor -> data ,ggml_nbytes (tensor ) ) ); 855 856//printf("%48s - [%5d, %5d, %5d], type = %6s, %6.2f MB\n", name.data(), ne[0], ne[1], ne[2], ftype == 0 ? "float" : "f16", ggml_nbytes(tensor)/1024.0/1024.0); 857total_size += ggml_nbytes (tensor ); 858n_loaded ++ ; 859// loader.tryLoad( tensor ); 860 } 861 862logDebug (u8"%s: model size = %7.2f MB" ,__func__ ,total_size /1024.0 /1024.0 ); 863if (n_loaded == 0 ) 864 { 865logError (u8"%s: no tensors loaded from model file" ,__func__ ); 866return E_INVALIDARG ; 867 } 868else if (n_loaded != (int )tensors .size () ) 869 { 870logError (u8"%s: not all tensors loaded from model file - expected %zu, got %d" ,__func__ ,tensors .size (),n_loaded ); 871return E_INVALIDARG ; 872 } 873model .n_loaded = n_loaded ; 874 } 875 876return S_OK ; 877 } 878 879HRESULT Context ::load (iReadStream * stm ) 880 { 881const int64_t t_start_us = ggml_time_us (); 882ctx .t_start_us = t_start_us ; 883HRESULT hr = loadImpl (stm ); 884ctx .t_load_us = ggml_time_us ()- t_start_us ; 885return hr ; 886 } 887 888HRESULT __stdcall loadReferenceCpuModel (const wchar_t * path ,iModel ** pp ) 889 { 890if (nullptr == path || nullptr == pp ) 891return E_POINTER ; 892 893ComLight ::Object < ReadStream > stream ; 894CHECK (stream .open (path ) ); 895 896ggml_time_init (); 897ComLight ::CComPtr < ComLight ::Object < Context >> obj ; 898CHECK (ComLight ::Object < Context > ::create (obj ) ); 899CHECK (obj -> load (& stream ) ); 900obj .detach (pp ); 901return S_OK ; 902 } 903} 904 905#include "Whisper/WhisperContext.h" 906#include "Whisper/ModelBuffers.h" 907#include "ML/testUtils.h" 908using namespace DirectCompute ; 909 910static DirectCompute ::Tensor gpuEncode (const whisper_context & wctx ,const int mel_offset ) 911{ 912return DirectCompute ::Tensor {}; 913#if 0 914using namespace DirectCompute ; 915WhisperContext & ctx = WhisperContext ::current (); 916 917Tensor cur ; 918sEncodeParams whisperParams ; 919const auto & mel_inp = wctx .mel ; 920 { 921const auto & model = wctx .model ; 922const auto & hparams = model .hparams ; 923whisperParams .n_len = (uint32_t )mel_inp .n_len ; 924whisperParams .n_mel = (uint32_t )mel_inp .n_mel ; 925 926const int n_ctx = wctx .exp_n_audio_ctx > 0 ?wctx .exp_n_audio_ctx :wctx .model .hparams .n_audio_ctx ; 927assert (n_ctx > 0 ); 928whisperParams .n_ctx = (uint32_t )n_ctx ; 929 930const int n_mels = hparams .n_mels ; 931assert (n_mels > 0 ); 932whisperParams .n_mels = (uint32_t )n_mels ; 933 934assert (mel_offset >=0 ); 935whisperParams .mel_offset = (uint32_t )mel_offset ; 936 937const int layersCount = hparams .n_audio_layer ; 938assert (layersCount > 0 ); 939whisperParams .layersCount = (uint32_t )layersCount ; 940 941const int n_state = hparams .n_audio_state ; 942const int n_head = hparams .n_audio_head ; 943assert (n_state >=0 ); 944assert (n_head >=0 ); 945 946whisperParams .n_state = (uint32_t )n_state ; 947whisperParams .n_head = (uint32_t )n_head ; 948 949int n_audio_ctx = hparams .n_audio_ctx ; 950assert (n_audio_ctx > 0 ); 951whisperParams .n_audio_ctx = (uint32_t )n_audio_ctx ; 952 953int n_text_state = hparams .n_text_state ; 954assert (n_text_state > 0 ); 955whisperParams .n_text_state = (uint32_t )n_text_state ; 956 957int n_text_layer = hparams .n_text_layer ; 958assert (n_text_layer > 0 ); 959whisperParams .n_text_layer = (uint32_t )n_text_layer ; 960 961int n_text_ctx = hparams .n_text_ctx ; 962assert (n_text_ctx > 0 ); 963whisperParams .n_text_ctx = (uint32_t )n_text_ctx ; 964 } 965 966return ctx .encode (mel_inp .data ,whisperParams ); 967#endif 968} 969 970GpuEncTest ::GpuEncTest (const whisper_context & wctx ,const int mel_offset ) 971{ 972return ; 973gpuResult = gpuEncode (wctx ,mel_offset ); 974} 975 976void GpuEncTest ::compare (const ggml_tensor * expected )const 977{ 978return ; 979WhisperContext & ctx = WhisperContext ::current (); 980ctx .dbgPrintDifference (expected ,gpuResult ,"GpuEncTest.compare" , false ); 981} 982 983void GpuEncTest ::compareMel (const ggml_tensor * expected )const 984{ 985return ; 986WhisperContext & ctx = WhisperContext ::current (); 987ctx .dbgPrintDifference (expected ,mel ,"GpuEncTest.compareMel" , false ); 988} 989 990/* 991void GpuEncTest::comparePostponed() 992{ 993if( nullptr == tempRef ) 994return; 995 996WhisperContext& ctx = WhisperContext::current(); 997ctx.dbgPrintDifference( tempRef, tempGpu, "comparePostponed" ); 998tempRef = nullptr; 999} */ 1000 1001__declspec(noinline )GpuDecTest ::GpuDecTest (const whisper_context & wctx ,const int * tokens ,const int n_tokens ,const int n_past ) 1002{ 1003#if 1 1004return ; 1005#else 1006sDecodeParams dp ; 1007 { 1008WhisperContext & ctx = WhisperContext ::current (); 1009const auto & model = wctx .model ; 1010const auto & hparams = model .hparams ; 1011dp .n_state = hparams .n_text_state ; 1012dp .n_head = hparams .n_text_head ; 1013dp .n_ctx = hparams .n_text_ctx ; 1014dp .n_past = n_past ; 1015dp .M = wctx .exp_n_audio_ctx > 0 ?wctx .exp_n_audio_ctx :hparams .n_audio_ctx ; 1016dp .n_text_layer = hparams .n_text_layer ; 1017dp .n_vocab = hparams .n_vocab ; 1018 } 1019 1020WhisperContext & ctx = WhisperContext ::current (); 1021ctx .decode (tokens ,n_tokens ,dp ,logits ,probs ); 1022#endif 1023} 1024 1025void __declspec(noinline )GpuDecTest ::compare (const std::vector < float >& cpuLogits ,const std::vector < float >& cpuProbs )const 1026{ 1027return ; 1028 1029if (cpuLogits .size ()!= logits .size () ) 1030 { 1031printf ("GpuDecTest.compare fail, size different\n" ); 1032return ; 1033 } 1034 1035computeDiff (logits .data (),cpuLogits .data (),logits .size () )."GpuDecTest.compare logits" ); 1036computeDiff (probs .data (),cpuProbs .data (),probs .size () )."GpuDecTest.compare probs" ); 1037} 1038 1039void __declspec(noinline )GpuDecTest ::postpone (const ggml_tensor * t ) 1040{ 1041return ; 1042 1043if (nullptr != tempRef ) 1044return ; 1045tempRef = t ; 1046} 1047 1048void __declspec(noinline )GpuDecTest ::comparePostponed () 1049{ 1050#if 1 1051return ; 1052#else 1053if (nullptr == tempRef ) 1054return ; 1055WhisperContext & ctx = WhisperContext ::current (); 1056ID3D11ShaderResourceView * srv = ctx .dbgDecodeTest ; 1057if (nullptr == srv ) 1058return ; 1059 1060ctx .dbgPrintDifference (tempRef ,ctx .dbgDecodeTest ,"GpuDecTest.comparePostponed" ); 1061tempRef = nullptr ; 1062#endif 1063} 1064#else 1065HRESULT __stdcallWhisper ::loadReferenceCpuModel (const wchar_t * path ,Whisper ::iModel ** pp ) 1066{ 1067logError (u8"This build of the DLL doesn’t implement the reference CPU-running Whisper model." ); 1068return E_NOTIMPL ; 1069} 1070#endif