Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
5f8bc9a
gguf: requantize GLM 5.3 KDA projections from BF16
trueimage Sep 2, 2026
2631881
metal: widen the GLM 5.3 BF16 matvec weight loads
trueimage Sep 2, 2026
77e47f3
metal: keep eight GLM 5.3 BF16 weight loads in flight
trueimage Sep 2, 2026
fa86134
gguf: extend the GLM 5.3 requantizer to the head and embedding
trueimage Sep 2, 2026
4d66a7c
glm: measure the KDA decode stage instead of estimating it
trueimage Sep 2, 2026
13520a8
tests: cover the widened GLM 5.3 BF16 matvec paths, and link the test…
trueimage Sep 2, 2026
33fbeb1
metal: hoist the uniform KDA decay exponential out of the channel loop
trueimage Sep 2, 2026
3543ca3
glm: split the residual row of the decode budget with hc and head abl…
trueimage Sep 2, 2026
b928a2d
metal: fuse the GLM 5.3 mHC producer with BF16 mix weights
trueimage Sep 2, 2026
53b0d39
glm: make the DSA split block rows sweepable, and record that it does…
trueimage Sep 2, 2026
83fdf77
doc: price what is left of the GLM decode step against the bandwidth …
trueimage Sep 2, 2026
792f384
Address the second review: temp-file aliasing, overflow checks, stale…
trueimage Sep 2, 2026
f2e0dd6
glm: add non-destructive stage timing, and check it against the ablat…
trueimage Sep 2, 2026
61be528
metal: pair the GLM 5.3 KDA gate projections
trueimage Sep 2, 2026
d8245b8
doc: refresh the cumulative engine-only figure after the gate pairing
trueimage Sep 2, 2026
708f239
glm: make the prefill constants settable, and sweep them
trueimage Sep 2, 2026
ae0c4a3
metal: fold the HC expansion into the KDA output projection
trueimage Sep 2, 2026
15281f0
doc: refresh the cumulative engine-only figure after the HC-expand ep…
trueimage Sep 2, 2026
d8d1131
glm: fold the remaining HC expansions into their producers
trueimage Sep 2, 2026
9efcfee
doc: refresh the cumulative engine-only figure after the HC-expand ep…
trueimage Sep 2, 2026
0070b59
glm: price the router, and correct the shared expert's bandwidth
trueimage Sep 2, 2026
9d4b3e9
doc: characterise the DSA attention core, the last stage with headroom
trueimage Sep 2, 2026
a26839a
glm: restrict the FFN HC-expand deferral to Metal, and repeat what ac…
trueimage Sep 2, 2026
a79db8d
doc: correct the DSA analysis, which was wrong by 23x, and the layer …
trueimage Sep 2, 2026
0d77175
glm: price qk_low separately from the indexed attention kernel
trueimage Sep 2, 2026
95f1723
metal: fuse the GLM 5.3 shared down-projection with the HC expand
trueimage Sep 2, 2026
23ecfe5
doc: refresh the cumulative figure and revise the shared-down entry
trueimage Sep 2, 2026
b0df1c8
metal: fold beta into the KDA gate pair
trueimage Sep 3, 2026
fd7b3de
glm: count dispatches per decode token
trueimage Sep 3, 2026
7e85f4c
doc: refresh the cumulative engine-only figure after the gate trio
trueimage Sep 3, 2026
c8ceb00
doc: correct the cumulative figure to the measured value
trueimage Sep 3, 2026
3ab590e
glm: let GLM 5.3 use the grouped/split DSA attention kernel
trueimage Sep 3, 2026
b28da44
metal: keep the scalar GLM 5.3 BF16 accumulation under --quality
trueimage Sep 3, 2026
a72c2c6
doc: label the dispatch counter for what it counts, and date the arti…
trueimage Sep 3, 2026
ab93f37
doc: record the end-to-end check of --quality against the base commit
trueimage Sep 3, 2026
daacd23
metal: drop the widened GLM 5.3 BF16 weight loads
trueimage Sep 3, 2026
e1ee00a
glm: attend GLM 5.3 with the generic kernel's arithmetic, staged and …
trueimage Sep 3, 2026
a14af19
doc: record the exact DSA kernels, the dropped BF16 widening, and the…
trueimage Sep 3, 2026
67dfca8
glm: keep the unchecked split variant for GLM 5.2-path models
trueimage Sep 3, 2026
a0399bc
glm: put the GLM 5.3 Flash rollback switches behind one table with an…
trueimage Sep 3, 2026
a047bd0
doc: re-verify against the synced main after the rebase
trueimage Sep 3, 2026
8969dbb
glm: take the phased DSA kernels only from 128 selected rows
trueimage Sep 3, 2026
8717f54
glm: give the GLM 5.3 prefill qk-low kernel a token tile
trueimage Sep 4, 2026
0f5e082
glm: carry two heads per simdgroup in indexed prefill attention
trueimage Sep 4, 2026
300c1a7
glm: cull the empty half of short routed-expert tiles for Q4_K
trueimage Sep 4, 2026
77c34bc
glm: split the GLM 5.3 KDA stage in the layer profiler
trueimage Sep 4, 2026
bc74d49
glm: make the GLM 5.3 KDA prepare kernel token-parallel in blocks
trueimage Sep 4, 2026
95c98b3
Fix GLM Flash prefill exactness and improve KDA recurrence
trueimage Sep 4, 2026
4b00b59
Keep GLM prefill notes local
trueimage Sep 4, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
/ds4_test
/ds4flash.gguf
/TODO.md
glm53flash_prefill*.md
/gguf/
/core
/core.*
Expand Down
16 changes: 13 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -365,13 +365,21 @@ tests/test_deepseek4_vision_image: tests/test_deepseek4_vision_image.o ds4_image
$(CC) $(CFLAGS) -o $@ $^ -lm

ifeq ($(UNAME_S),Darwin)
$(GLM53_KDA_TEST): tests/test_glm53_kda.o ds4_metal.o
$(GLM53_KDA_TEST): tests/test_glm53_kda.o ds4_metal.o ds4_image.o
$(CC) $(CFLAGS) -o $@ $^ $(METAL_LDLIBS)
else
$(GLM53_KDA_TEST): tests/test_glm53_kda.o ds4_cuda.o $(MMQ_OBJS)
$(GLM53_KDA_TEST): tests/test_glm53_kda.o ds4_cuda.o ds4_image.o $(MMQ_OBJS)
$(NVCC) $(NVCCFLAGS) -o $@ $^ $(CUDA_LDLIBS)
endif

# Only the Metal build of this test is exercised by `make test`; the CUDA
# variant still builds through `make test-glm53-kda`.
ifeq ($(UNAME_S),Darwin)
GLM53_KDA_DEFAULT_TEST := $(GLM53_KDA_TEST)
else
GLM53_KDA_DEFAULT_TEST :=
endif

.PHONY: test-glm53-kda
test-glm53-kda: $(GLM53_KDA_TEST)
./$(GLM53_KDA_TEST)
Expand Down Expand Up @@ -565,7 +573,8 @@ tests/test_prompt_prefix: tests/test_prompt_prefix.o ds4_prompt_prefix.o

test: ds4_test ds4_agent_test ds4-eval q4k-dot-test mxfp4-dot-test \
tests/test_layer_pack tests/test_engine_mgpu_placement tests/test_gpu_args \
tests/test_deepseek4_vision_image tests/test_prompt_prefix $(SAMPLING_TEST) ds4 ds4-server ds4-bench ds4-agent
tests/test_deepseek4_vision_image tests/test_prompt_prefix $(SAMPLING_TEST) $(GLM53_KDA_DEFAULT_TEST) \
ds4 ds4-server ds4-bench ds4-agent
./ds4-eval --self-test-extractors
./ds4_agent_test
./ds4_test
Expand All @@ -576,6 +585,7 @@ test: ds4_test ds4_agent_test ds4-eval q4k-dot-test mxfp4-dot-test \
./tests/test_prompt_prefix
./tests/test_sampling
./tests/test_deepseek4_vision_image
@if [ -n "$(GLM53_KDA_DEFAULT_TEST)" ]; then ./$(GLM53_KDA_TEST); fi

dspark-acceptance: ds4
DS4_DSPARK_MODEL="$(DS4_DSPARK_MODEL)" \
Expand Down
972 changes: 849 additions & 123 deletions ds4.c

Large diffs are not rendered by default.

118 changes: 118 additions & 0 deletions ds4_gpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,22 @@ enum {
DS4_GPU_TEST_MXFP4_DOWN_HALF_LUT = 1u << 4,
DS4_GPU_TEST_OUTPUT_HC_WEIGHTS4 = 1u << 5,
DS4_GPU_TEST_HC_RMS_SCALE_PROJ = 1u << 6,
/* Exercise GLM prefill kernels on synthetic shapes/devices, while keeping
* TP and streaming exclusions. The second flag forces the last KDA block
* to finish before block 0 to test incoming-state ownership. */
DS4_GPU_TEST_GLM53_PREFILL = 1u << 7,
DS4_GPU_TEST_GLM53_KDA_LAST_BLOCK_FIRST = 1u << 8,
};
void ds4_gpu_test_set_flags(uint32_t flags);
enum {
DS4_GPU_GLM53_PREFILL_QK_LOW = 1u << 0,
DS4_GPU_GLM53_PREFILL_INDEXED_ATTN = 1u << 1,
DS4_GPU_GLM53_PREFILL_MOE_TAIL_CULL = 1u << 2,
DS4_GPU_GLM53_PREFILL_KDA_PREPARE = 1u << 3,
DS4_GPU_GLM53_PREFILL_KDA_RECURRENCE = 1u << 4,
};
/* Returns and clears dispatch coverage recorded only in GLM prefill test mode. */
uint32_t ds4_gpu_test_glm53_prefill_take_dispatches(void);
void ds4_gpu_release_zero_prefix_prefill_mask_cache(void);
#else
static inline int ds4_gpu_device_is_pre_m5_apple_silicon(void) { return 0; }
Expand Down Expand Up @@ -1641,6 +1655,47 @@ int ds4_gpu_glm_attention_indexed_decode_typed_tensor(
float beta_fast,
float beta_slow);

int ds4_gpu_glm_attention_indexed_decode_exact_typed_tensor(
ds4_gpu_tensor *heads,
ds4_gpu_tensor *scores,
ds4_gpu_tensor *lora,
ds4_gpu_tensor *denom,
const ds4_gpu_tensor *qk_low,
const ds4_gpu_tensor *kv_lora_cache,
const void *model_map,
uint64_t model_size,
uint64_t value_weight_offset,
uint32_t value_weight_type,
const ds4_gpu_tensor *selected,
uint32_t n_selected,
uint32_t cache_cap,
bool cache_f16,
uint32_t n_head,
uint32_t kv_lora_dim,
uint32_t qk_nope,
uint32_t qk_rope,
uint32_t value_dim);

int ds4_gpu_glm_attention_indexed_decode_exact_tensor(
ds4_gpu_tensor *heads,
ds4_gpu_tensor *scores,
ds4_gpu_tensor *lora,
ds4_gpu_tensor *denom,
const ds4_gpu_tensor *qk_low,
const ds4_gpu_tensor *kv_lora_cache,
const void *model_map,
uint64_t model_size,
uint64_t value_weight_offset,
const ds4_gpu_tensor *selected,
uint32_t n_selected,
uint32_t cache_cap,
bool cache_f16,
uint32_t n_head,
uint32_t kv_lora_dim,
uint32_t qk_nope,
uint32_t qk_rope,
uint32_t value_dim);

int ds4_gpu_glm_attention_indexed_decode_split_group8_tensor(
ds4_gpu_tensor *heads,
ds4_gpu_tensor *partial_lora,
Expand Down Expand Up @@ -2927,6 +2982,27 @@ int ds4_gpu_hc_expand_add_rms_norm_mix_split_norm_f16_tensor(
float hc_eps,
float norm_eps);

int ds4_gpu_hc_rms_norm_mix_split_norm_bf16_tensor(
ds4_gpu_tensor *mix,
ds4_gpu_tensor *out,
ds4_gpu_tensor *norm_out,
ds4_gpu_tensor *split,
const ds4_gpu_tensor *residual_hc,
const void *model_map,
uint64_t model_size,
uint64_t mix_weight_offset,
uint64_t scale_offset,
uint64_t base_offset,
uint64_t norm_weight_offset,
uint32_t n,
uint32_t mix_dim,
uint32_t n_embd,
uint32_t n_hc,
uint32_t sinkhorn_iters,
float eps,
float hc_eps,
float norm_eps);

#endif
int ds4_gpu_output_hc_weights_tensor(
ds4_gpu_tensor *out,
Expand Down Expand Up @@ -3097,6 +3173,48 @@ int ds4_gpu_glm53_matmul_bf16_qkv(
uint32_t out_dim,
const ds4_gpu_tensor *x);

int ds4_gpu_glm53_matmul_bf16_pair(
ds4_gpu_tensor *out_a,
ds4_gpu_tensor *out_b,
const void *model_map,
uint64_t model_size,
uint64_t weight_a_offset,
uint64_t weight_b_offset,
uint32_t in_dim,
uint32_t out_dim,
const ds4_gpu_tensor *x_a,
const ds4_gpu_tensor *x_b);

uint64_t ds4_gpu_encoder_count(void);

int ds4_gpu_glm53_matmul_bf16_trio(
ds4_gpu_tensor *out_a,
ds4_gpu_tensor *out_b,
ds4_gpu_tensor *out_c,
const void *model_map,
uint64_t model_size,
uint64_t weight_a_offset,
uint64_t weight_b_offset,
uint64_t weight_c_offset,
uint32_t in_dim,
uint32_t out_dim_ab,
uint32_t out_dim_c,
const ds4_gpu_tensor *x);

int ds4_gpu_glm53_matmul_bf16_hc_expand4(
ds4_gpu_tensor *out,
ds4_gpu_tensor *hc_out,
const void *model_map,
uint64_t model_size,
uint64_t weight_offset,
uint32_t in_dim,
uint32_t out_dim,
const ds4_gpu_tensor *x,
const ds4_gpu_tensor *residual_hc,
const ds4_gpu_tensor *post,
const ds4_gpu_tensor *comb,
uint32_t n_hc);

#ifndef DS4_GLM53_VISION_TYPES_DEFINED
#define DS4_GLM53_VISION_TYPES_DEFINED
#define DS4_GLM53_VISION_LAYERS 24u
Expand Down
Loading