Skip to content

Fix CI: Fix models Backend webgpu by supporting GGML_OP_DUP - #30216

Merged
ServeurpersoCom merged 1 commit into
ggml-org:masterfrom
ServeurpersoCom:ci-webgpu-dup
Oct 9, 2026
Merged

ServeurpersoCom merged 1 commit into
ggml-org:masterfrom
ServeurpersoCom:ci-webgpu-dup

Conversation

@ServeurpersoCom

Copy link
Copy Markdown
Contributor

Overview

Fix CI:
Models Backend webgpu-nvidia segfaults on master since #29622, on the very first model of test-llama-archs.

The new mixed batch path writes the token rows with set_rows into a ggml_dup of the embeddings. WebGPU had no GGML_OP_DUP, so the dup stayed on the CPU, while the set_rows writing in place into it was scheduled on WebGPU. WebGPU then got a destination living in a CPU buffer, read its context as a WebGPU buffer, and Dawn crashed. CUDA and Vulkan support DUP, so they never hit it.

DUP is the same copy as CPY and CONT, so it now goes through the same path and the whole mixed chain stays on WebGPU.

Additional information

Tested on an RTX PRO 6000 through WebGPU with the CI Dawn build:

  • test-llama-archs -s 1: segfault -> 160 rows, 0 FAIL
  • test-backend-ops DUP 7/7, CPY 144/144, CONT 72/72

Follow-up #29622

Requirements

The mixed batch path of PR-29622 writes the token rows with set_rows
into a dup of the embeddings. WebGPU did not support DUP, so the dup
ran on the CPU while the set_rows writing into it was scheduled on
WebGPU, which then bound a CPU buffer and crashed. DUP is the same copy
as CPY and CONT and now goes through the same path.
@ServeurpersoCom
ServeurpersoCom requested a review from a team as a code owner October 9, 2026 08:47
@ggerganov

ggerganov commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

@ServeurpersoCom Thanks. You can try to tackle the failing server test next:

https://github.com/ggml-org/llama.cpp/actions/runs/37903861970/job/113732486606#step:6:4633

I've root-caused it to be due to graph reallocations when we use backend sampling. Basically, we reserve a graph for the worst case of all sequences having a sampling enabled. But then the test runs a decoding batch using only one sequence, which changes the number of nodes.

There are 2 possible ways to fix it:

  • When backend sampling is enabled, the graph always attaches all sampling chains for all sequences. And via ggml_build_forward_select we "activate" only those that are actually used in the batch
  • Update the reserve logic in llama_context to not reserve for all possible sequences, but only for those that have a sampler

Both options are a bit tricky and I am not sure if it would increase the complexity a lot. So worst case is to adapt the failing tests to not trigger this and add TODOs to rework this in the future.

@github-actions github-actions Bot added ggml changes relating to the ggml tensor library for machine learning WebGPU labels Oct 9, 2026
@ggerganov
ggerganov requested a review from yomaytk October 9, 2026 09:35

@yomaytk yomaytk left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@yomaytk yomaytk mentioned this pull request Oct 9, 2026
@ServeurpersoCom

Copy link
Copy Markdown
Contributor Author

I've root-caused it to be due to graph reallocations when we use backend sampling. Basically, we reserve a graph for the worst case of all sequences having a sampling enabled. But then the test runs a decoding batch using only one sequence, which changes the number of nodes.

There are 2 possible ways to fix it:

* When backend sampling is enabled, the graph always attaches all sampling chains for all sequences. And via `ggml_build_forward_select` we "activate" only those that are actually used in the batch

* Update the reserve logic in `llama_context` to not reserve for all possible sequences, but only for those that have a sampler

Both options are a bit tricky and I am not sure if it would increase the complexity a lot. So worst case is to adapt the failing tests to not trigger this and add TODOs to rework this in the future.

Thanks for the root cause! Option 1 turned out to be small: build_sampling already did it for inactive samplers, so every sampler now always builds n_outputs_max_per_seq chains and decodes keep the topology of the reserve.
The draft test passes and the server suite is green with and without backend sampling on a NO_REALLOC build, opening a PR shortly.

@ServeurpersoCom

ServeurpersoCom commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor Author

The two WebGPU self-hosted reds are on master too, not related to DUP (DUP, CPY and CONT all pass in that log) I'll see if I can follow up

@ServeurpersoCom
ServeurpersoCom merged commit e94acad into ggml-org:master Oct 9, 2026
21 of 23 checks passed
ckti pushed a commit to ckti/llama.cpp-consolidated that referenced this pull request Oct 12, 2026
The mixed batch path of PR-29622 writes the token rows with set_rows
into a dup of the embeddings. WebGPU did not support DUP, so the dup
ran on the CPU while the set_rows writing into it was scheduled on
WebGPU, which then bound a CPU buffer and crashed. DUP is the same copy
as CPY and CONT and now goes through the same path.
@BrewTestBot BrewTestBot mentioned this pull request Oct 15, 2026
1 task done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ggml changes relating to the ggml tensor library for machine learning WebGPU

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants