The model code was spread across eight crates that had grown into each other:
ggml and cuda and mlx each owned part of a tensor runtime, llama and tts and
voice2 each owned part of a model, and libs/diffusion owned everything else.
They are now one tree with an explicit shape:
libs/ai/cuda — kernels and launch surface
libs/ai/metal — Metal shaders and the shim
libs/ai/llm — the language-model runtime (sessions, lanes, contexts,
the CUDA and Metal executors, the compiled Metal path)
libs/ai/models/ — common, flux, h3, music, paint, speech, stems, vision
libs/diffusion is not deleted but demoted: what remains is the VALIDATOR
crate — several dozen `*_validate.rs` oracles that check a native
implementation against a reference, which is where they belong now that the
implementations live next door.
The functional work inside the move is mostly in the LLM runtime: N lanes that
draft while one verify batch serves all of them, per-slot prefill over a shared
folded attention arena, speculation that survives batching, and a scheduler
that reports rather than publishes. And in the CUDA build: a machine without
usable CUDA must still LINK (and say so), the default kernel arch is the
building machine's GPU, `NO_CUDA` forces the stub even where the toolkit
exists, and kernels compile in parallel with progress.
libs/video_flow is new here: classical optical flow estimation and the `mkfl`
motion-field payload — a flow field measured from a clip without a model,
which is what drives free-rate bounce-looping playback and the uprez/tween
enhance pipe.
176 lines
5.3 KiB
Text
176 lines
5.3 KiB
Text
#include <cuda_runtime.h>
|
|
#include <math.h>
|
|
#include <stdint.h>
|
|
|
|
static __global__ void makepad_cuda_gated_delta_net_f32_kernel(
|
|
const float * __restrict__ q,
|
|
const float * __restrict__ k,
|
|
const float * __restrict__ v,
|
|
const float * __restrict__ g,
|
|
const float * __restrict__ beta,
|
|
const float * __restrict__ state,
|
|
float * __restrict__ dst,
|
|
uint32_t sv,
|
|
uint32_t h,
|
|
uint32_t n_tokens,
|
|
uint32_t n_seqs,
|
|
uint32_t sq1,
|
|
uint32_t sq2,
|
|
uint32_t sq3,
|
|
uint32_t sv1,
|
|
uint32_t sv2,
|
|
uint32_t sv3,
|
|
uint32_t sb1,
|
|
uint32_t sb2,
|
|
uint32_t sb3,
|
|
uint32_t neqk1,
|
|
uint32_t rq3,
|
|
uint32_t kda) {
|
|
const uint32_t head_idx = blockIdx.x;
|
|
const uint32_t seq_idx = blockIdx.y;
|
|
const uint32_t col = blockIdx.z;
|
|
const uint32_t lane = threadIdx.x;
|
|
if (col >= sv) {
|
|
return;
|
|
}
|
|
|
|
extern __shared__ float smem[];
|
|
float * state_shared = smem;
|
|
float * reduce_shared = smem + sv;
|
|
|
|
const uint32_t v_heads_per_k = h / neqk1;
|
|
const uint32_t iq1 = head_idx / v_heads_per_k;
|
|
const uint32_t iq3 = seq_idx / rq3;
|
|
|
|
const uint32_t attn_elems = sv * h * n_tokens * n_seqs;
|
|
float * attn_out = dst;
|
|
float * state_out = dst + attn_elems;
|
|
|
|
const uint32_t state_offset = (seq_idx * h + head_idx) * sv * sv;
|
|
const float * state_col = state + state_offset + col * sv;
|
|
float * state_col_out = state_out + state_offset + col * sv;
|
|
const float scale = rsqrtf((float) sv);
|
|
|
|
for (uint32_t row = lane; row < sv; row += blockDim.x) {
|
|
state_shared[row] = state_col[row];
|
|
}
|
|
__syncthreads();
|
|
|
|
for (uint32_t token_idx = 0; token_idx < n_tokens; token_idx++) {
|
|
const float * q_t = q + iq3 * sq3 + token_idx * sq2 + iq1 * sq1;
|
|
const float * k_t = k + iq3 * sq3 + token_idx * sq2 + iq1 * sq1;
|
|
const float * v_t = v + seq_idx * sv3 + token_idx * sv2 + head_idx * sv1;
|
|
const uint32_t gb_offset = seq_idx * sb3 + token_idx * sb2 + head_idx * sb1;
|
|
const float * beta_t = beta + gb_offset;
|
|
const float * g_t = g + (kda ? gb_offset * sv : gb_offset);
|
|
|
|
float kv_partial = 0.0f;
|
|
if (kda) {
|
|
for (uint32_t row = lane; row < sv; row += blockDim.x) {
|
|
kv_partial += expf(g_t[row]) * state_shared[row] * k_t[row];
|
|
}
|
|
} else {
|
|
for (uint32_t row = lane; row < sv; row += blockDim.x) {
|
|
kv_partial += state_shared[row] * k_t[row];
|
|
}
|
|
}
|
|
reduce_shared[lane] = kv_partial;
|
|
__syncthreads();
|
|
for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) {
|
|
if (lane < stride) {
|
|
reduce_shared[lane] += reduce_shared[lane + stride];
|
|
}
|
|
__syncthreads();
|
|
}
|
|
|
|
const float beta_val = *beta_t;
|
|
const float g_scalar = kda ? 0.0f : expf(*g_t);
|
|
const float delta = kda
|
|
? (v_t[col] - reduce_shared[0]) * beta_val
|
|
: (v_t[col] - g_scalar * reduce_shared[0]) * beta_val;
|
|
|
|
float attn_partial = 0.0f;
|
|
for (uint32_t row = lane; row < sv; row += blockDim.x) {
|
|
const float gate = kda ? expf(g_t[row]) : g_scalar;
|
|
const float updated = gate * state_shared[row] + k_t[row] * delta;
|
|
state_shared[row] = updated;
|
|
attn_partial += updated * q_t[row];
|
|
}
|
|
reduce_shared[lane] = attn_partial;
|
|
__syncthreads();
|
|
for (uint32_t stride = blockDim.x >> 1; stride > 0; stride >>= 1) {
|
|
if (lane < stride) {
|
|
reduce_shared[lane] += reduce_shared[lane + stride];
|
|
}
|
|
__syncthreads();
|
|
}
|
|
|
|
if (lane == 0) {
|
|
attn_out[((seq_idx * n_tokens + token_idx) * h + head_idx) * sv + col] =
|
|
reduce_shared[0] * scale;
|
|
}
|
|
__syncthreads();
|
|
}
|
|
|
|
for (uint32_t row = lane; row < sv; row += blockDim.x) {
|
|
state_col_out[row] = state_shared[row];
|
|
}
|
|
}
|
|
|
|
extern "C" cudaError_t makepad_cuda_gated_delta_net_f32(
|
|
const float * q,
|
|
const float * k,
|
|
const float * v,
|
|
const float * g,
|
|
const float * beta,
|
|
const float * state,
|
|
float * dst,
|
|
uint32_t sv,
|
|
uint32_t h,
|
|
uint32_t n_tokens,
|
|
uint32_t n_seqs,
|
|
uint32_t sq1,
|
|
uint32_t sq2,
|
|
uint32_t sq3,
|
|
uint32_t sv1,
|
|
uint32_t sv2,
|
|
uint32_t sv3,
|
|
uint32_t sb1,
|
|
uint32_t sb2,
|
|
uint32_t sb3,
|
|
uint32_t neqk1,
|
|
uint32_t rq3,
|
|
uint32_t kda,
|
|
cudaStream_t stream) {
|
|
if (sv == 0 || h == 0 || n_seqs == 0) {
|
|
return cudaSuccess;
|
|
}
|
|
const uint32_t block = sv <= 32 ? 32 : (sv <= 64 ? 64 : 128);
|
|
const dim3 grid(h, n_seqs, sv);
|
|
const size_t shared_bytes = (sv + block) * sizeof(float);
|
|
makepad_cuda_gated_delta_net_f32_kernel<<<grid, block, shared_bytes, stream>>>(
|
|
q,
|
|
k,
|
|
v,
|
|
g,
|
|
beta,
|
|
state,
|
|
dst,
|
|
sv,
|
|
h,
|
|
n_tokens,
|
|
n_seqs,
|
|
sq1,
|
|
sq2,
|
|
sq3,
|
|
sv1,
|
|
sv2,
|
|
sv3,
|
|
sb1,
|
|
sb2,
|
|
sb3,
|
|
neqk1,
|
|
rq3,
|
|
kda);
|
|
return cudaGetLastError();
|
|
}
|