Repository navigation
[WebGPU] Batch input uploads for built-in and plugin EPs - #33491
Conversation
Extract the shared uploader and built-in CopyTensors optimization from the QLoRA work so input-transfer performance can be reviewed independently. Group CPU-to-GPU inputs in staging buffers capped at 16 MiB, including on UMA, while retaining single-copy and mixed-transfer fallbacks. Include the existing round-trip test for empty and unaligned tensors, chunk boundaries, oversized inputs, and repeated writes. All five extracted files match the source branch exactly. Scoped lint and whitespace checks pass; standalone build and runtime tests have not been rerun on this branch. Source commits: 8eab658 and 034acaa; final source tree: 2971861.
Extract plugin batching from a49f019. Group same-device CPU-to-GPU inputs on a shared non-null WebGPU session stream using the bounded staging uploader, including on UMA. Preserve mapped-buffer, mixed-transfer, single-copy, and streamless fallbacks and existing command ordering. Include five existing submission-count and data-integrity regression tests covering repeated uploads, staging boundaries, empty inputs, oversized inputs, and single-input fallback. All four extracted files match source commit 2971861. Scoped lint and whitespace checks pass; standalone build and runtime tests have not been rerun on this branch.
There was a problem hiding this comment.
🟡 Changes recommended
Built-in batching accepts mapped destinations and bypasses their existing copy-and-unmap fallback, causing validation failures.
What changed in this PR
Extracts WebGPU input-upload batching into a shared implementation for built-in and plugin execution providers.
Changes:
- Groups eligible uploads into staging buffers capped at 16 MiB.
- Adds plugin batching on a shared owning session stream.
- Adds six regression tests for data integrity, boundary cases, and submission counts.
| File | Description |
|---|---|
onnxruntime/test/providers/webgpu/plugin/test_webgpu_allocators.cc |
Tests session uploads and submission counts. |
onnxruntime/test/providers/webgpu/data_transfer_test.cc |
Tests upload integrity across chunks and repeated writes. |
onnxruntime/core/providers/webgpu/webgpu_provider_factory.cc |
Checks plugin batch eligibility. |
onnxruntime/core/providers/webgpu/ep/sync_stream.h |
Declares stream-based batch uploads. |
onnxruntime/core/providers/webgpu/ep/sync_stream.cc |
Routes uploads through the owning provider. |
onnxruntime/core/providers/webgpu/data_transfer.h |
Declares built-in batch transfer support. |
onnxruntime/core/providers/webgpu/data_transfer.cc |
Routes eligible built-in transfers to batching. |
onnxruntime/core/providers/webgpu/buffer_manager.h |
Defines the shared batch-upload interface. |
onnxruntime/core/providers/webgpu/buffer_manager.cc |
Implements staging chunks and oversized-upload fallback. |
Review effort: Balanced
Check destination map state during the built-in batch preflight and fall back for the entire list before copying. This preserves the existing direct memcpy/unmap behavior for mapped inputs while retaining batching for unmapped inputs. Add coverage for mapped destinations first, last, and in both positions, plus repeated uploads after unmapping. The regression fails before the fix and passes after it. Verified built-in and plugin Vulkan builds, 6 built-in transfer tests, 62 enabled plugin tests, and scoped lint.
|
Thanks for working on this improvement and sharing the performance numbers! The reduction in upload overhead looks very promising. I have a few questions to better understand the tradeoffs and scope:
Thanks again for the optimization and for helping clarify these points! |
|
I compared both approaches locally on Intel Arc 140V with Vulkan. Here are the results and scope clarifications:
|
Xiaofei Han (xiaofeihan1)
left a comment
There was a problem hiding this comment.
Thanks for verifying this! LGTM, approved.
Keep the upstream upload implementation and regression coverage from microsoft#33491, including mapped-buffer fallback, and remove the superseded plugin upload test from the QLoRA diff.
### Description <!-- Describe your changes. --> Automatically use `Queue.WriteBuffer` for eligible CPU-to-GPU uploads up to and including 1 MiB. - Flush deferred readers before queue writes to preserve read-before-overwrite ordering. - Preserve mapped-buffer handling and staging for larger, unaligned, and capture/replay uploads. - Retain existing completion, validation, device-loss, and failure handling. - Add focused upload tests and document ordering, source-lifetime guarantees, and the size threshold. ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> Profiling Qwen/DFlash2 on A100 identified substantial host overhead from allocating, mapping, copying, and submitting a fresh staging buffer for each upload. Queue writes let Dawn reuse staging allocations and batch pending transfers with subsequent queue work, without adding CPU completion waits. The conservative 1 MiB cap is the largest consistently beneficial size measured on A100/Vulkan. Larger transfers can regress, so they retain the existing staging path rather than extrapolating the small-upload improvement. **Validation:** On Linux/A100/Vulkan, 80 native tests passed with one unrelated build-mode skip, and 100 GenAI tests passed. Both 512-token baseline and DFlash2 generation runs preserved exact tokens and speculative counters. Formatting and lint checks passed. ### Update: Rebased onto latest main, including merged PR #33491, and reran A100/Vulkan benchmarks to measure the incremental benefit of `Queue.WriteBuffer`. **Results**: - Baseline: **3.3% faster** (short), **6.8% faster** (long) - DFlash2 width 3: **2.5% faster** (short), **3.1% faster** (long) All generated tokens and speculative counters matched. Native and plugin tests passed. Existing batched uploads remain unaffected, and larger transfers retain the staging path. This confirms that the optimization provides additional performance benefits beyond #33491. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Description
Performance
Intel Arc 140V / Vulkan, previous A/B measurement: 44.84 MB of adapter data across 784 tensors: 95.3 → 10.8 ms upload host-call time (~8.8× faster).
Validation