148 lines
4.1 KiB
Plaintext
148 lines
4.1 KiB
Plaintext
layout(set=0, binding=0) writeonly buffer s0 {
|
|
FLOAT data[];
|
|
} uOutput;
|
|
|
|
layout(set=0, binding=1) readonly buffer s1 {
|
|
FLOAT data[];
|
|
} uQuery;
|
|
|
|
layout(set=0, binding=2) readonly buffer s2 {
|
|
FLOAT data[];
|
|
} uKey;
|
|
|
|
layout(set=0, binding=3) readonly buffer s3 {
|
|
FLOAT data[];
|
|
} uValue;
|
|
|
|
layout(set=0, binding=4) readonly buffer s4 {
|
|
FLOAT4 data[];
|
|
} uCacheKey;
|
|
|
|
layout(set=0, binding=5) readonly buffer s5 {
|
|
FLOAT4 data[];
|
|
} uCacheValue;
|
|
|
|
layout(set=0, binding=6) readonly buffer s6 {
|
|
FLOAT data[];
|
|
} uMask;
|
|
|
|
layout(set=0, binding=7) readonly uniform constBuffer {
|
|
ivec4 s0; // qLen, kLen, headNum, kvHeadNum
|
|
ivec4 s1; // headDim, group, pastLen, totalLen
|
|
ivec4 s2; // maskQlen, maskKvlen, maskMode, cacheMaxLen
|
|
vec4 f0; // scale, 0, 0, 0
|
|
} uConst;
|
|
|
|
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|
|
|
const int MAX_D4 = 64; // headDim <= 256
|
|
const float NEG_INF = -3.402823466e38;
|
|
|
|
void main() {
|
|
const int h = int(gl_GlobalInvocationID.x);
|
|
const int q = int(gl_GlobalInvocationID.y);
|
|
|
|
const int qLen = uConst.s0.x;
|
|
const int kLen = uConst.s0.y;
|
|
const int headNum = uConst.s0.z;
|
|
const int kvHeadNum = uConst.s0.w;
|
|
|
|
if (h >= headNum || q >= qLen) {
|
|
return;
|
|
}
|
|
|
|
const int headDim = uConst.s1.x;
|
|
const int group = uConst.s1.y;
|
|
const int pastLen = uConst.s1.z;
|
|
const int totalLen = uConst.s1.w;
|
|
|
|
const int maskMode = uConst.s2.z;
|
|
const int maskQlen = uConst.s2.x;
|
|
const int maskKvlen = uConst.s2.y;
|
|
const int maxLen = uConst.s2.w;
|
|
|
|
const float scale = uConst.f0.x;
|
|
|
|
const int kvh = h / group;
|
|
if (kvh >= kvHeadNum) {
|
|
return;
|
|
}
|
|
const int d4Size = headDim / 4;
|
|
if (d4Size > MAX_D4) {
|
|
return;
|
|
}
|
|
if (maxLen <= 0) {
|
|
return;
|
|
}
|
|
|
|
// query: [1, qLen, headNum, headDim]
|
|
const int qBase = (q * headNum + h) * headDim;
|
|
vec4 outVec[MAX_D4];
|
|
for (int i = 0; i < d4Size; ++i) {
|
|
outVec[i] = vec4(0.0);
|
|
}
|
|
|
|
float m = -3.402823466e38;
|
|
float s = 0.0;
|
|
|
|
const int kStart = (maskMode == 1 && maskKvlen > 0 && totalLen > maskKvlen) ? (totalLen - maskKvlen) : 0;
|
|
|
|
for (int k = 0; k < totalLen; ++k) {
|
|
float dotSum = 0.0;
|
|
for (int i = 0; i < d4Size; ++i) {
|
|
const int d = i * 4;
|
|
const int qOff = qBase + d;
|
|
// cacheK (packed): [kvHeadNum, headDim/4, maxLen, 4]
|
|
const int kOff = (kvh * d4Size + i) * maxLen + k;
|
|
vec4 qv = vec4(float(uQuery.data[qOff + 0]), float(uQuery.data[qOff + 1]), float(uQuery.data[qOff + 2]),
|
|
float(uQuery.data[qOff + 3]));
|
|
vec4 kv = vec4(uCacheKey.data[kOff]);
|
|
dotSum += dot(qv, kv);
|
|
}
|
|
float score = dotSum * scale;
|
|
if (maskMode == 1) {
|
|
if (q < maskQlen && maskKvlen > 0 && k >= kStart) {
|
|
const int mk = k - kStart;
|
|
if (mk >= 0 && mk < maskKvlen) {
|
|
score += float(uMask.data[q * maskKvlen + mk]);
|
|
}
|
|
}
|
|
} else if (maskMode == 2 && k > (pastLen + q)) {
|
|
score = NEG_INF;
|
|
}
|
|
|
|
float w = 0.0;
|
|
if (score > m) {
|
|
float factor = exp(m - score);
|
|
for (int i = 0; i < d4Size; ++i) {
|
|
outVec[i] *= factor;
|
|
}
|
|
s = s * factor + 1.0;
|
|
m = score;
|
|
w = 1.0;
|
|
} else {
|
|
w = exp(score - m);
|
|
s += w;
|
|
}
|
|
|
|
// cacheV (kvh-major, packed-D): [kvHeadNum, maxLen, headDim/4, 4]
|
|
const int vOff4Base = ((kvh * maxLen + k) * d4Size);
|
|
for (int i = 0; i < d4Size; ++i) {
|
|
vec4 vv = vec4(uCacheValue.data[vOff4Base + i]);
|
|
outVec[i] += w * vv;
|
|
}
|
|
}
|
|
|
|
float invS = 1.0 / s;
|
|
// output: [1, qLen, headNum * headDim]
|
|
const int outBase = (q * headNum + h) * headDim;
|
|
for (int i = 0; i < d4Size; ++i) {
|
|
vec4 v = outVec[i] * invS;
|
|
const int d = i * 4;
|
|
uOutput.data[outBase + d + 0] = FLOAT(v.x);
|
|
uOutput.data[outBase + d + 1] = FLOAT(v.y);
|
|
uOutput.data[outBase + d + 2] = FLOAT(v.z);
|
|
uOutput.data[outBase + d + 3] = FLOAT(v.w);
|
|
}
|
|
}
|