Skip to content

IK's experiments with DS4 - #2147

Closed
ikawrakow wants to merge 38 commits into
mainfrom
ik/ds4_play1
Closed

IK's experiments with DS4#2147
ikawrakow wants to merge 38 commits into
mainfrom
ik/ds4_play1

Conversation

@ikawrakow

@ikawrakow ikawrakow commented Jul 17, 2026

Copy link
Copy Markdown
Owner

I started from commit 3d6acd350d781e7bb527f5b59aa506234bf7f113 in PR #2110 and added a few optimizations.

After the latest commits:

  • PPL is now the same as llama.cpp. The issue was that the SWIGLU limits were not taken into account
  • It is now much faster than Port Deepseek v4 #2110. Hybrid TG is almost 2.5X better than Port Deepseek v4 #2110 for short context

The missing piece is that SWA is not taken into account. Or rather, it is taken into account by using the appropriate masks, but the masks are built in such a way that the usual SWA tricks that ik_llama.cpp implements cannot be used. This makes performance decrease with context much more than it should.

In any case, here is what I get with the latest version using the Q4_K model from antirez (the model is 164.6 GB).

Hybrid

GGML_CUDA_NO_PINNED=1 ./bin/llama-sweep-bench -m $model \
   -c 32768 -ub 2048 -n 64 -t 64 -fidx -wgt 1 -ngl 100 --cpu-moe

2x3090+Ryzen-3995WX. Didn't bother trying to have some experts on the GPUs.

PP TG N_KV T_PP s S_PP t/s T_TG s S_TG t/s
2048 64 0 9.329 219.54 3.516 18.20
2048 64 2048 9.870 207.49 3.840 16.67
2048 64 4096 10.402 196.88 3.807 16.81
2048 64 6144 11.036 185.57 3.897 16.42
2048 64 8192 11.696 175.10 4.077 15.70
2048 64 10240 12.366 165.62 4.162 15.38
2048 64 12288 13.060 156.81 4.267 15.00
2048 64 14336 13.758 148.86 4.381 14.61
2048 64 16384 14.415 142.07 4.548 14.07
2048 64 18432 15.156 135.13 4.612 13.88
2048 64 20480 15.747 130.06 4.835 13.24
2048 64 22528 16.659 122.94 4.917 13.02
2048 64 24576 17.427 117.52 5.018 12.75
2048 64 26624 18.132 112.95 5.138 12.46
2048 64 28672 18.809 108.88 5.264 12.16
2048 64 30720 19.527 104.88 5.354 11.95

CPU only

GGML_CUDA_NO_PINNED=1 ./bin/llama-sweep-bench -m $model \
   -c 32768 -ub 2048 -n 64 -t 64 -fidx -wgt 1
PP TG N_KV T_PP s S_PP t/s T_TG s S_TG t/s
2048 64 0 21.675 94.49 7.651 8.37
2048 64 2048 24.094 85.00 9.151 6.99
2048 64 4096 26.057 78.60 10.750 5.95
2048 64 6144 27.826 73.60 12.097 5.29
2048 64 8192 29.767 68.80 13.259 4.83
2048 64 10240 31.697 64.61 14.346 4.46
2048 64 12288 33.531 61.08 15.755 4.06
2048 64 14336 36.058 56.80 16.870 3.79
2048 64 16384 38.134 53.71 18.099 3.54
2048 64 18432 39.368 52.02 19.087 3.35
2048 64 20480 40.477 50.60 20.185 3.17
2048 64 22528 42.365 48.34 20.832 3.07
2048 64 24576 45.028 45.48 21.882 2.92
2048 64 26624 46.994 43.58 23.211 2.76
2048 64 28672 49.109 41.70 24.157 2.65
2048 64 30720 51.102 40.08 25.648 2.50

SamuelOliveirads and others added 27 commits July 2, 2026 17:07
# Conflicts:
#	convert_hf_to_gguf.py
#	ggml/src/ggml.c
#	src/CMakeLists.txt
#	src/llama-build-context.cpp
#	src/llama-build-context.h
#	src/llama-hparams.cpp
#	src/llama-load-tensors.cpp
@ikawrakow ikawrakow mentioned this pull request Jul 17, 2026
hchengit and others added 2 commits July 17, 2026 13:18
…a-dflash.cpp (#2134)

llama-dflash.cpp calls ggml_backend_is_metal() and
ggml_backend_metal_set_n_cb() inside an #ifdef GGML_USE_METAL block but
never includes ggml-metal.h, so any Metal-enabled build fails to
compile. Add the same guarded include llama.cpp already uses.
* Add ggml_sum_rows_ext

* openPangu: use ggml_sum_rows_ext also in mhc_post

* openPangu: use ggml_sum_rows_ext also in mhc_tail

* Minor
@SamuelOliveirads

Copy link
Copy Markdown
Collaborator

I tested it against the PR draft and even though it’s on Windows, which is much slower, I saw 39% better performance using this PR.

Regarding SWA it does indeed have the issue you pointed out there. Since it’s an open issue, if you’d like, we can proceed with this PR, resolve the SWA issue, reapply the fixes from the commits that are in the draft but didn’t make it here, of course, with the necessary adjustments to prevent regression, and them move forward with any remaining pending issues.

Regarding the implementation of Sinkhorn/HCA, did you check to see if the PPL changed? I didn’t have time to test it in this PR but I hope it doesn’t cause the same problem I encountered when I tried it in the draft.

@ikawrakow

Copy link
Copy Markdown
Owner Author

Regarding the implementation of Sinkhorn/HCA, did you check to see if the PPL changed?

Obviously. Especially after the claim in the other PR that using ggml_sinkhorn increased PPL by 50%.

I think this branch is in a good shape and as everything that it needs to have for now. I cherry-picked some but not all of your changes in the last round of edits of #2110

@usrlocalben

usrlocalben commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Should this be evaluated with the same DSA-related params as GLM-5.2? i.e. -mla 1 --dsa -fidx -ctk f16

edit: oops, I now see the example args above

@usrlocalben

usrlocalben commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

I compared decode throughput between

(afaik FD's fork is the best available "mainline" version, but maybe that has changed in the last few days)

First I sweep for ik_llama's optimal thread count for the MXFP4 FFN, and I find t=64 to be optimal on my hw.
I do similar probes for llama.cpp and 64 seems to be the best as well.

I'm interested in cpu-moe decode perf only, so I measure at low (0-100) ctx.

--numa distribute w/drop_caches, warmup-runs etc. in both cases before measuring.
figures below are average of 5 runs after warmup runs.

I notice that llama.cpp doesn't warm up the ffn tensors the way ik_ does, so I run a number of "tell me a story" prompts until TG rate settles.

CPU is 2x EPYC 9B14 w/24x DDR5 4800.
GPU is 1x RTX 6000 Pro Max-Q
Quant is @sayap 's MXFP4 dsv4f GGUF.

ik_llama.cpp ds4_play1 = 28.37t/s
llama.cpp fairydreaming/ds4 = 34.90t/s

and if one doesn't mind running a mysterious closed-source binary :
jasl's vllm ds4 fork + lk-moe w/OEM safetensors = 46.6t/s 🤷

llama.cpp shows about 20% improvement in decode throughput at 0-100ctx.

@SamuelOliveirads

Copy link
Copy Markdown
Collaborator

llama.cpp shows about 20% improvement in decode throughput at 0-100ctx.

Since Mainline merged DSV4 a few weeks ago they've had time to make optimizations. See ggml-org/llama.cpp#25370, ggml-org/llama.cpp#24231, ggml-org/llama.cpp#25545, and ggml-org/llama.cpp#25585. We may already have many of these as Sinkhorn, Indexer, etc., but that doesn’t mean we’ll have a PR that can implement everything from scratch with the best possible performance (although Ik is already optimizing several factors).

@usrlocalben

usrlocalben commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

@SamuelOliveirads sorry, to be clear it's fairydreaming llama.cpp which I think has the advance PRs applied, I said this at the top but omitted it in the line you quoted

also the goal was just to bench the MXFP4 FFN so DSA/attention/etc. impact should be minimal at 0-100tok context

@SamuelOliveirads

Copy link
Copy Markdown
Collaborator

No need to worry, I just wanted to point out that from the perspective of implementing the architecture and having the functional model in place this PR has already achieved that, in my view, it’s ready for a merge.

@ikawrakow

ikawrakow commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

@usrlocalben

(afaik FD's fork is the best available "mainline" version, but maybe that has changed in the last few days)

Sadly, FD's PR does not work with Antirez GGUFs so I can verify your measurement (disk is full and I don't see what I can delete ATM). The closed source blob you mention most likely uses MTP.
I was on the wrong branch.

The fact that you are only interested in --cpu-moe with a 96 GB GPU seem to indicate gigantic compute buffers for the FD PR. Or is there another reason you wouldn't load some MoE layers into those 96 GB of VRAM?
Scratch also that. I pulled FD's branch and see that compute buffer sizes are comparable to what we have in this PR.

@usrlocalben

Copy link
Copy Markdown
Contributor

@ikawrakow

I didn't use routed expert offloading for any of those measurements nor MTP. (with MTP, I observe lvllmds4 reach 60-70t/s decode, all other params unchanged. It's quite impressive excepting the binary situation.)

My intent is to measure as best as possible the routed MoE/FFN throughput (i.e. CPU's part of the attn/moe duty cycle) only by comparing e.g. 0-100 ctx range decode and all _exps tensors on CPU.

The economics of sparse MoE for single/low user are terrible wrt. putting _exp layers in $VRAM. (Kimi K2.x being the most extreme example at 8/384 2% density, K3 worse at 16/896 1.8% density)

I'll wait until ds4 support is merged to do a more thorough exposition of the figures I gave above, perhaps in discussions.

@ikawrakow

Copy link
Copy Markdown
Owner Author

Closing in favor of #2165

@ikawrakow ikawrakow closed this Jul 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants