Repository navigation
glm5-next : QSA without kq_mask (+ DSA) - #31009
Conversation
e640297 to
5d95901
Compare
3a882fd to
0570bcb
Compare
| // leave unallocated when the top-k layers use the indexer mask | ||
| if (self_kq_mask_mla->buffer) { | ||
| mctx->get_mla()->set_input_kq_mask(self_kq_mask_mla, ubatch, cparams.causal_attn); | ||
| } |
There was a problem hiding this comment.
My machine is too weak to run the real thing so I tested it with a slice of DeepSeek-V3.2
0570bcb to
439723a
Compare
ServeurpersoCom
left a comment
There was a problem hiding this comment.
My machine is too weak to run the real thing so I tested it with a slice of DeepSeek-V3.2
I ran it on the real GLM-5.3-Flash UD-IQ1_S on a rootless container with an RTX PRO 6000, full offload, FA on, q8_0 cache, against the merge base.
Memory: both the compute buffer and the pinned host buffer shrink by the size of the mask, so about 512 MiB each at 128k context and 2 GiB each at 256k. 128k with -ub 8192 now runs, master runs out of memory there.
Output: this model isn't deterministic run to run on CUDA, even on master, so I applied your #31084 to both the PR and master. With it, both give the exact same perplexity and KLD per chunk over 7 runs. The non-fused path and the toy DSA models (deepseek32, glm-dsa, hy_v4) match master too.
Speed: prefill is about 2% faster at -ub 8192, decode doesn't move. So it's a bit faster and saves a good amount of memory.
LGTM! And #31084 makes this model deterministic here, so it's worth pushing on its own.
| ggml_tensor * keep = ggml_fill(ctx0, ggml_new_tensor_1d(ctx0, kq_mask->type, n_kv), 0.0f); | ||
| ggml_tensor * sel = build_fused_top_k_mask(kq_mask, top_k, score, inp_kpool->pool_idxs, tail, keep, il); |
There was a problem hiding this comment.
Here we are indirectly using the kq_mask shape. So even though the kq_mask remains unallocated, the kpool logic is still "coupled" to the shape of the KQ mask. We should do follow-up refactors to fix that because it is a bit difficult to follow and also it causes problems such as: #29510 (comment)
|
@sanmai You should be able to merge this when ready. |
|
@ggerganov Appreciate that! Going to give it another look before merging. |
* glm5-next : QSA without kq_mask * DSA: dsa top-k mask change tested with layers 0,3 of DeepSeek-V3.2
* glm5-next : QSA without kq_mask * DSA: dsa top-k mask change tested with layers 0,3 of DeepSeek-V3.2
Overview
Just like in qwen4exp (#30965), attention layers are QSA so we should not need to allocate
kq_mask.Again, this saves 2 GB GPU/host memory at ub 4096 and 4 GB at ub 8192 that we could put towards the expert cache or a larger context.
Additional information
The same trick from #30965 but for GLM 5 and DSA arches.
As I also included a similar change to DSA as per #30815 (comment) I only tested it only with a slice of a full model; logits were idential.
Benchmarks
Compute buffers,
--moe-cache-mib 4000:All benchmarks below are on 5090@400W with 128GB DDR4.
Lots of benchmarks
32GB, 262k context
Performance benchmarks:
--moe-cache-mibThese are with
q5_1KV cache and a full context and--no-mmproj -cmoe --load-mode mmap.512k context
--moe-cache-mib5090 limited to 16 GB
On a simulated 16 GB card (
torch.empty(16 << 30, ...)) with 65k context I'm looking at:--moe-cache-mibWithout the MoE cache:
+32k context is not a lot, but it could be a deal breaker for some.
24 GB limited
--moe-cache-mibTrying it out
Requirements