Deepseek 4: -sm tensor - #26490
Conversation
|
@gaugarg-nv since Johannes is busy would you mind reviewing this PR? |
Thanks, that indeed turn up a bug which is now fixed with 3bbafa2 |
|
Is this change compatible with draft model? main model loads fine under --split-mode tensor, but the DSpark draft fails the same command works on current master (build 10248 / e8e06f7) |
|
Would appreciate if other people can also test this and we can merge. This has been tested on 2x, 4x and 5x GPUs |
| if (tensor->view_src != nullptr) { | ||
| // full-tensor view created with ggml_view_tensor, transparent for the split state | ||
| split_state = ggml_backend_meta_get_split_state(stc, tensor->view_src, assume_sync); | ||
| } else { | ||
| split_state = {GGML_BACKEND_SPLIT_AXIS_MIRRORED, {0}, {1}, 1}; | ||
| } |
There was a problem hiding this comment.
Why do we need to handle the views differently here?
|
Were the review comments that @JohannesGaessler left on https://github.com/ggml-org/llama.cpp/pull/25860/changes taken into account here? A lot of the implementation still looks the same to me, while the original PR was clearly presented as an incomplete proof of concept. What changed to address those earlier issues? Also, since the KV cache and DSV4 state are still mirrored, am I right that context memory isn’t distributed across GPUs and 1M-token contexts still aren’t possible in tensor split mode? I tested this version and I’m seeing roughly the same PP and TG improvements as with #25860. Could the lack of TG improvement on your setup be related to PCIe bandwidth—x8 vs x16, the available CPU PCIe lanes, or the risers being used? |
|
@S3kundes Yup I see roughly the same speeds. Feel free to close the other PR |
Tested with 5 x GPU and 8 x GPU, old Turing 24GB, both are working. Performance-wise: |
|
[AGENT] Independent test on four consumer GPUs, since you asked for outside testing before merge. Summary: the prefill gain reproduces strongly, decode regresses slightly, and VRAM distribution becomes even. One numerical question at the end. Setup
Model: Server flags, identical apart from ResultsBoth rows are from the same build, so this isolates layout rather than engine version. Decode is a 256-token deterministic run, prefill is a 15,412-token prompt.
So the prompt-processing win holds up on PCIe 3.0 without NVLink. Decode was slightly worse rather than flat, which is consistent with more inter-GPU traffic per token on a slow interconnect. The even VRAM distribution is a worthwhile secondary benefit that I did not see mentioned. Layer split left one card about 2 GiB lighter than another, and on a four-card build the fullest card is what caps context. For reference, mainline Quality checkI ran a 75-scenario deterministic benchmark (tool calling, instruction following, structured output, data extraction, reasoning/math) at pass@1 under both layouts:
The single differing scenario was a reasoning item that passed 2 of 3 times when rerun in isolation under tensor split, so I read that as sampling variance, not a regression. One thing I could not resolveA temperature-zero, fixed-seed, 256-token completion produced a different output hash under tensor split than under layer split, on the same build and same model file. Both outputs were coherent and on-topic, and an exact-instruction canary returned the expected token, so this does not look like corruption. My assumption is that splitting tensors changes floating-point reduction order, one token diverges, and the rest follow. That would be expected rather than a bug. But I wanted to flag it explicitly in case exact parity with layer split is something you consider a requirement, since it is the one claim I could not verify. Happy to rerun anything specific on this hardware if useful. |
|
2xMI50 32GB +AMD EPYC 7352 128GB ram (-sm layer works at about 10t/s note only half DDR4 channels populated) -sm tensor with --n-gpu-layers 18 results about 7t/s 0.14.793.130 I load_tensors: Meta() model buffer size = 29769.34 MiB Something seems not right about this though as the Meta() buffer should be the combined size of each GPU right? When I was running the model 29+GB was used on each GPU. Also with SM layer it was offloading about 42layers to the GPUs. Trying to let it auto fit just resulted in it crashing with. 0.00.301.944 I load_tensors: loading model tensors, this can take a while... (load_mode = dio) my script it quantizing the context or not didn't seem to affect the outcomes: Edit: also both GPUs are on PCIE 3.0 @ 16x links |
|
[AGENT] Tester datapoint from a CPU-expert-offload rig (Ampere Altra aarch64 + 2× RTX 4090, DeepSeek-V4-Flash-0731 MXFP4, experts on CPU):
Given cb88's MI50 result above loads with |
|
2x ROCm R9700 with a partial CPU MOE offload hits the same |
f055961 to
f48c77b
Compare
|
@am17an: I quickly tested the almost-final PR (f48c77bfc9b4fe96c4edc918880039f25d23ec71) on 2x RTX 6000 Pro and compared to master: master: Assertion upon start with -sm tensor PP seems to go down from 1600 toks/s to about 1380 toks/s during the brief test case. Not sure what's going on there. TG is about the same. From a stability viewpoint the branch is stable. ✅ Log from -sm tensor: 8.29.457.768 I slot print_timing: id 1 | task 2285 | prompt processing, n_tokens = 10240, progress = 0.56, t = 7.41 s / 1381.62 tokens per second Compared to default split mode: 1.35.209.929 I slot print_timing: id 0 | task 79 | prompt processing, n_tokens = 10210, progress = 0.53, t = 6.28 s / 1626.08 tokens per second Tested with DSpark enabled and --spec-draft-n-max 5, though that should not matter for PP imho. |
|
Can you try without dspark? |
|
I pr'ed similar #26636 to solve spec-draft-device |
|
The exps and the shared exps can have a delayed all-reduce similar to earlier add pattern. Doing this reduces all-reduce per layer from 3 to 2, it seems to help performance |
a6cd579 to
cee363e
Compare
|
Latest results on 4x 4090s,
|
|
I test -sm tensor -ts 43,43 on dual rtx pro 5000,but the prefill was worse then layer split, i use b10608 release. So what the problem? |
* DSV4: sm tensor * set coarser granularity for head splits * fix dspark * add model saving for dsv4 + allow dflash to return on specific device * add comment about dsv4 seq_rm * simplify * add shared expert delayed allreduce * remove special test for dsv4
|
I found a bug here with dspark which can be fixed by bumping |
|
As I already commented in #25860 , the attention should not be mirrored. If there only is a single attention head that will at least not gimp the performance but it will still result in overallocation of the KV cache. If this exact architecture only exists with a single K/V head it may make sense to implement support for a split state that is explicitly assigning everything to a single GPU since implementing and maintaining the theoretical logic for >1 attention heads would not be worthwhile. |
* DSV4: sm tensor * set coarser granularity for head splits * fix dspark * add model saving for dsv4 + allow dflash to return on specific device * add comment about dsv4 seq_rm * simplify * add shared expert delayed allreduce * remove special test for dsv4


Overview
Add
-sm tensorfor DeepSeek4. The FA is mirrored because there is only 1 K head (Q has 64). Apart from that addmemset_tensoris added to the meta backend.Additional information
on 4x 4090s I see a PP increase of 50% but TG does not increase.
Requirements