Skip to content

[WebGPU] Graph capture support for KV-shared decoder models - #29000

Closed
feich-ms wants to merge 1 commit into
mainfrom
user/feich/webgpu-gc-production
Closed

[WebGPU] Graph capture support for KV-shared decoder models#29000
feich-ms wants to merge 1 commit into
mainfrom
user/feich/webgpu-gc-production

Conversation

@feich-ms

@feich-ms feich-ms commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Two changes required for WebGPU graph capture to work on models with KV-shared layers (e.g. Gemma4), independent of how the model was built (works with both enable_webgpu_graph=true and without):

  • ConstantOfShape WebGPU kernel — KV-shared layers emit ConstantOfShape to create zero-filled tensors. Without a WebGPU kernel, these fall back to CPU, flooding the captured graph with MemcpyFromHost. Registered opset-by-opset (9, 20, 21, 23, 24) to match ONNX spec changes.
  • PrepareIndirectDispatch for kv_empty layers — KV-shared layers skip CopyKVCache (no new K/V), which normally populates the indirect dispatch buffer. A single-thread shader fills it from seqlen_k[0]+1 when CopyKVCache is skipped under graph capture. Also widens the indirect dispatch predicate to cover GPU-resident total_sequence_length (sentinel 0).

Test plan

  • CI passes (build + existing WebGPU tests)
  • Verify ConstantOfShape kernel handles float/int32/int64 and zero-element outputs
  • Verify PrepareIndirectDispatch fires correctly for kv_empty decode under GC
  • E2e test with Gemma4 model built with enable_webgpu_graph=true (pending genai builder support)

🤖 Generated with Claude Code

@feich-ms feich-ms added the ep:WebGPU ort-web webgpu provider label Jun 11, 2026
@feich-ms
feich-ms marked this pull request as draft June 11, 2026 03:44
@feich-ms
feich-ms force-pushed the user/feich/webgpu-gc-production branch 2 times, most recently from 00f7030 to a9f679b Compare June 11, 2026 03:52
Three changes required for graph capture to work on models with
KV-shared layers (e.g. Gemma4), independent of how the model was built:

1. ConstantOfShape WebGPU kernel — KV-shared layers use ConstantOfShape
   to create zero-filled tensors. Without a WebGPU kernel, these fall
   back to CPU, flooding the captured graph with MemcpyFromHost.
   Registered opset-by-opset (9, 20, 21, 23, 24) to match ONNX spec
   changes and KernelRegistry::VerifyVersion semantics.

2. GraphCacheManager buffer quarantine — during graph capture/replay,
   released buffers must not be immediately reused because captured
   bind_groups still reference them. Tracks GraphCaptureState in a
   member; Default mode keeps PR #27453 immediate-reuse optimization,
   Capturing/Replaying quarantines to captured_buffers_.

3. PrepareIndirectDispatch for kv_empty layers — KV-shared layers skip
   CopyKVCache (no new K/V to append), which normally populates the
   indirect dispatch buffer. Under graph capture, step 2+ crashes with
   Invalid dispatch group size (0, 1, 1). A single-thread shader now
   fills the buffer from seqlen_k[0]+1 when CopyKVCache is skipped.

Co-Authored-By: Claude Opus 4 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ep:WebGPU ort-web webgpu provider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant