Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions backends/webgpu/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
Expand Down Expand Up @@ -116,6 +116,51 @@

set_property(TARGET webgpu_backend PROPERTY CXX_STANDARD 17)

if(EMSCRIPTEN)
add_executable(
gemma4_plain_wasm
${EXECUTORCH_ROOT}/examples/models/gemma4/runner/gemma4_plain_wasm.cpp
)
target_include_directories(
gemma4_plain_wasm PRIVATE $<BUILD_INTERFACE:${EXECUTORCH_ROOT}/..>
)
target_link_libraries(
gemma4_plain_wasm PRIVATE webgpu_backend webgpu_model_loader extension_tensor
)
target_compile_options(
gemma4_plain_wasm PRIVATE -fexceptions "--use-port=emdawnwebgpu"
)
if(EXECUTORCH_BUILD_WEBGPU_PROFILING)
target_compile_definitions(
gemma4_plain_wasm PRIVATE WGPU_BACKEND_ENABLE_PROFILING
)
endif()
target_link_options(
gemma4_plain_wasm
PRIVATE
-fexceptions
"--use-port=emdawnwebgpu"
-sASYNCIFY
-sALLOW_MEMORY_GROWTH=1
-sMAXIMUM_MEMORY=4GB
-sFORCE_FILESYSTEM=1
--no-entry
"-sEXPORTED_FUNCTIONS=_et_init,_et_load,_et_unload,_et_reset,_et_prefill_batch,_et_prefill_step,_et_step,_et_profile_enable,_et_profile,_et_get_last_prefill_token_count,_et_get_route_contract_version,_et_get_last_route_mask,_et_get_last_route_conflict_count,_malloc,_free"
"-sEXPORTED_RUNTIME_METHODS=ccall,cwrap,FS,HEAP32"
-sSTACK_SIZE=8388608
-sASYNCIFY_STACK_SIZE=1048576
-sMODULARIZE=1
-sEXPORT_NAME=createWebGPULlama
)
set_target_properties(
gemma4_plain_wasm
PROPERTIES OUTPUT_NAME "webgpu_llama"
RUNTIME_OUTPUT_DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/browser_gemma4_plain"
CXX_STANDARD 17
)
endif()

install(
TARGETS webgpu_backend
EXPORT ExecuTorchTargets
Expand Down
5 changes: 4 additions & 1 deletion examples/models/gemma4/BUCK
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
load("@fbcode_macros//build_defs:build_file_migration.bzl", "fbcode_target", "non_fbcode_target")
load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
load(":targets.bzl", "define_common_targets")
load(":targets.bzl", "define_common_targets", "define_webgpu_python_targets")

oncall("executorch")

non_fbcode_target(_kind = define_common_targets,)

fbcode_target(_kind = define_common_targets,)

define_webgpu_python_targets()

# Text decoder module
fbcode_target(_kind = runtime.python_library,
name = "text_decoder",
Expand Down Expand Up @@ -77,6 +79,7 @@ fbcode_target(_kind = runtime.python_binary,
"//executorch/kernels/quantized:aot_lib",
],
deps = [
":webgpu_support",
":text_decoder",
":speech_transform",
":quant_utils",
Expand Down
78 changes: 78 additions & 0 deletions examples/models/gemma4/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,84 @@ buck2 run fbcode//executorch/examples/models/gemma4:export_gemma4 -- \
--checkpoint_path /tmp/gemma4-e2b-it --no-audio
```

### Plain E2B WebGPU

The WebGPU path is independently exportable and text-only. It preserves an
8960-token KV capacity while bounding each input call to 512 tokens, returns a
delegated `Long[1, 1]` greedy token, and splits external constants into three
ordered PTD files below the browser binding/fetch limit. The default XNNPACK
export and runner are unchanged.

Acquire the checkpoint from
`google/gemma-4-E2B-it-qat-q4_0-unquantized` at immutable revision
`6befbaca7398925921802abd1f277b495b78b738`, then validate every staged byte:

```bash
hf download google/gemma-4-E2B-it-qat-q4_0-unquantized \
model.safetensors config.json tokenizer.json tokenizer_config.json \
generation_config.json processor_config.json chat_template.jinja \
README.md .gitattributes \
--revision 6befbaca7398925921802abd1f277b495b78b738 \
--local-dir /tmp/gemma4-e2b-it
```

```bash
buck2 run fbcode//executorch/examples/models/gemma4:webgpu_artifact_manifest -- \
validate-acquisition --checkpoint-root /tmp/gemma4-e2b-it
```

From clean fbsource and ExecuTorch OSS checkouts, seal the reviewed plain-Gemma
source union and generator-derived WGSL closure before exporting the model:

```bash
: "${FBSOURCE_ROOT:?set the clean fbsource checkout root}"
: "${OSS_ROOT:?set the clean ExecuTorch OSS checkout root}"
python -m executorch.examples.models.gemma4.webgpu_artifact_manifest \
create-source-manifest --fbsource-root "$FBSOURCE_ROOT" \
--oss-root "$OSS_ROOT" \
--output /tmp/gemma4-source-manifest.json
python -m executorch.examples.models.gemma4.webgpu_artifact_manifest \
create-wgsl-manifest \
--backend-root "$FBSOURCE_ROOT/xplat/executorch/backends/webgpu" \
--output /tmp/gemma4-wgsl-manifest.json
python -m executorch.examples.models.gemma4.webgpu_artifact_manifest \
create-source-receipt \
--fbsource-root "$FBSOURCE_ROOT" --oss-root "$OSS_ROOT" \
--backend-root "$FBSOURCE_ROOT/xplat/executorch/backends/webgpu" \
--output /tmp/gemma4-source-receipt.json
```

Export plain Gemma 4:

```bash
buck2 run fbcode//executorch/examples/models/gemma4:export_gemma4 -- \
--checkpoint_path /tmp/gemma4-e2b-it \
--output_path /tmp/gemma4-webgpu/model.pte \
--backend webgpu --quantize 8da4w+emb4 \
--max_seq_len 8960 --max_input_len 512 \
--no-audio --no-vision \
--source_receipt_path /tmp/gemma4-source-receipt.json \
--artifact_manifest_output /tmp/gemma4-e2b-webgpu.json
```

The source-closure gate writes `gemma4-source-receipt.json` before this export.
The exporter reads the actual tensor-data insertion order, writes all three
content-named PTDs, and creates the manifest without renaming or globbing them.
Keep the manifest output outside the flat artifact staging directory.

```bash
buck2 run fbcode//executorch/examples/models/gemma4:webgpu_artifact_manifest -- \
validate --root /tmp/gemma4-webgpu \
--manifest /tmp/gemma4-e2b-webgpu.json
```

`manifests/gemma4_e2b_webgpu.json` pins the accepted ctx8960 behavior-oracle
quartet, but marks its old-worktree source closure as pending. It cannot satisfy
the production validator because it has no final-source receipt. Rebuild it
from the reviewed stack before claiming source-current performance or
reproduction. Dashboard and internal publication paths are evidence only and
are never source dependencies.

## Model Variants

Default export includes all modalities (audio + vision + text). Default context length: 1024 tokens (`--max_seq_len`).
Expand Down
Loading
Loading