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// Dispatch with [ ( neq1*neq2*neq3 + 31 ) / 32, 1, 1 ] thread groups 2#include "flashAttentionCommon.hlsli" 3Buffer < uint > lookupTable :register ( t3 ); 4 5void scaleTempVector ( uint i , const uint length , const float multiplier ) 6{ 7const uint end = i + length ; 8for ( ; i < end ; i ++ ) 9{ 10float f = temp [ i ]; 11f *= multiplier ; 12// Rounding in this shader causes numerical errors on my GeForce 1080 Ti GPU, driver 527.56 13// f = roundToFp16( f ); 14temp [ i ] = f ; 15} 16} 17 18inline float computeTempVectorMax ( uint i , const uint length ) 19{ 20// Compute per-thread maximum 21const uint end = i + length ; 22float ax = negativeInfinity ; 23for ( ; i < end ; i ++ ) 24ax = max ( ax , temp [ i ] ); 25return ax ; 26} 27 28#include "miscUtils.hlsli" 29#include "fp64Utils.hlsli" 30 31// Transform temp[ i ] = exp( temp[ i ] - tempMax ), and return the sum of these values 32inline double applySoftMax ( uint i , const uint length , const float tempMax ) 33{ 34// Transform the values, and compute per-thread sum 35const uint end = i + length ; 36double sum = 0 ; 37for ( ; i < end ; i ++ ) 38{ 39float f = temp [ i ]; 40[ branch ] 41if ( f != negativeInfinity ) 42{ 43f -= tempMax ; 44const uint index = fp16Rounded ( f ); 45const uint res16 = lookupTable [ index ]; 46f = f16tof32 ( res16 ); 47sum += f ; 48} 49else 50f = 0 ; 51 52temp [ i ] = f ; 53} 54return sum ; 55} 56 57[ numthreads ( 32 , 1 , 1 ) ] 58void main ( uint3 dtid : SV_DispatchThreadID ) 59{ 60const uint neq0 = q_elements [ 0 ]; 61const uint neq1 = q_elements [ 1 ]; 62const uint neq2 = q_elements [ 2 ]; 63const uint neq3 = q_elements [ 3 ]; 64 65const uint nek0 = k_elements [ 0 ]; 66const uint nek1 = k_elements [ 1 ]; 67 68const uint nev1 = v_elements [ 1 ]; 69 70const uint ne0 = res_elements [ 0 ]; 71const uint ne1 = res_elements [ 1 ]; 72 73const uint nbk0 = k_strides [ 0 ]; 74const uint nbk1 = k_strides [ 1 ]; 75const uint nbk2 = k_strides [ 2 ]; 76const uint nbk3 = k_strides [ 3 ]; 77 78const uint nbq0 = q_strides [ 0 ]; 79const uint nbq1 = q_strides [ 1 ]; 80const uint nbq2 = q_strides [ 2 ]; 81const uint nbq3 = q_strides [ 3 ]; 82 83const uint nbv0 = v_strides [ 0 ]; 84const uint nbv1 = v_strides [ 1 ]; 85const uint nbv2 = v_strides [ 2 ]; 86const uint nbv3 = v_strides [ 3 ]; 87 88const uint nb0 = res_strides [ 0 ]; 89const uint nb1 = res_strides [ 1 ]; 90const uint nb2 = res_strides [ 2 ]; 91const uint nb3 = res_strides [ 3 ]; 92 93const uint D = neq0 ; 94const uint N = neq1 ; 95const uint P = nek1 - N ; 96// const uint M = P + N; 97const uint M = nek1 ; 98 99const uint ir = dtid . x ; 100if ( ir >= neq1 * neq2 * neq3 ) 101return ; 102 103const uint iq3 = ir / ( neq2 * neq1 ); 104const uint iq2 = ( ir - iq3 * neq2 * neq1 ) / neq1 ; 105const uint iq1 = ( ir - iq3 * neq2 * neq1 - iq2 * neq1 ); 106 107const uint tempIndex = ir * tempBufferStride ; 108 109// Softmax 110float tvm = computeTempVectorMax ( tempIndex , M ); 111double sum = applySoftMax ( tempIndex , M , tvm ); 112 113scaleTempVector ( tempIndex , M , ( float )( 1.0 / sum ) ); 114}