perf(gemma4): optimize prefill and decode - #485
Conversation
…outs Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
…ation Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Local review draft. Dependencies and source-pinned experiment attribution are recorded in the gemma-perf-pr-prep-20260908 package. Not approved for production activation. Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
…ute scheduling Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
…ute scheduling Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
… paths Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com> # Conflicts: # hf_adapters/hf_common.py
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com> # Conflicts: # hf_adapters/hf_gemma4_moe.py # tests/cpu/_gemma4_decode_perf_helpers.py
|
Implemented change: consolidate the Gemma performance work into one HF PR Agreed concern: Six interdependent HF PRs and seven standalone test/helper files made review and merging unnecessarily fragmented. Implemented approach:
Validation and review: 48 selected host checks pass, plus Ruff/Black and mypy over 41 source files. Claude's independent combined-source review found no blocking code defect; its nonblocking points were resolved or documented. Fresh combined device CI and capability-present numerical/placement acceptance remain separate. The description preserves each historical speedup with its actual immediate control; percentages are not additive, and none is claimed as a new measurement of this head. Scope: Six files, +676/−31; three production files and three existing test files. Addressed in |
Combine the existing adapter feature heads using the signed P9 publication lineage. Omit its duplicate, unsigned preparation ancestors. The source tree matches the reviewed combined tree before the standalone-test removal. Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
…ites Replace seven source-parsing test files with focused imported-runtime checks and extend the existing Gemma device comparison through real generation. Keep ordinary forward coverage, independent block dispatch and fallback checks. Preserve uninspectable callbacks during automatic head selection. Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
0cf04e7 to
6b01e51
Compare
Refresh hf-adapters torch-spyre#485 onto 1b3c1a6 without changing the six-file optimization delta. Preserve the original feature commits and safety gates. Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
|
Author update — refreshed source and corrected CI environment Implemented change Head Implemented approach
This fixes environment identity at setup; it does not skip tests, weaken tolerances or modify shared development installations. Broader platform-specific image ownership is not invented by this change. Scope and dependencies The PR now has nine files, +719/−38: the unchanged six-file optimization/test diff plus three CI/setup files. No new test file or public model/backend interface.
Validation and performance The earlier refreshed model source passed 61 host checks and its pinned lint/type checks; no model source changed in this CI repair. The new setup passed shell syntax and a real-uv isolated fixture proving one environment, preservation of image packages and importability of a newly installed dependency. Fresh runner CI then passed the actual install/import probe, before exposing the two stale module callers. The extended fixture audits all build-action callers and successfully executes both module caller prefixes without a checkout The composed expert-function device check confirms P8 engages: the activation stage changes from HBM to LX with matching 8×4 reader ownership, and ON/OFF outputs match exactly within the fixed CPU-reference screen. Five interleaved pairs now measure 29.726537 → 28.997294 ms expert-function wall time; median paired saving 2.4831%, with all five pairs improving beyond the control noise gate. This belongs to #4347's P8 increment, not full-model or decode acceptance of this HF PR. Fresh CI and capability-present model qualification remain open, so this stays draft. Historical gains and their distinct controls remain in the description; no percentages are added together or relabeled as fresh measurements. |
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
1c50547 to
1c0f425
Compare
Signed-off-by: Adnan Hoque <adnan.hoque1@ibm.com>
|
/spyre-test |
❌ spyre-test: failureTriggered by: /spyre-test comment: #485 (comment) Plan (build waves + dependencies, per arch)amd64 flowchart LR
subgraph Lamd64_0["amd64 L0 · 1 parallel"]
n_amd64_torch_spyre_torch_spyre_dev["torch-spyre/torch-spyre-dev 🔴<br/>image · fc1752087216"]
end
subgraph Lamd64_1["amd64 L1 · 1 parallel"]
n_amd64_hf_adapters_hf_adapters_dev["hf-adapters/hf-adapters-dev 🟢<br/>image · c923b5d43e4c"]
end
subgraph Lamd64_2["amd64 L2 · 1 parallel"]
n_amd64_spyre_inference_spyre_inference_dev["spyre-inference/spyre-inference-dev 🔴<br/>image · 83521da27449"]
end
n_amd64_torch_spyre_torch_spyre_dev --> n_amd64_hf_adapters_hf_adapters_dev
n_amd64_hf_adapters_hf_adapters_dev --> n_amd64_spyre_inference_spyre_inference_dev
classDef sPending fill:#eceff1,stroke:#90a4ae,color:#37474f
classDef sBuilding fill:#fff8e1,stroke:#f9a825,color:#5d4037,stroke-width:2px
classDef sOk fill:#e8f5e9,stroke:#43a047,color:#1b5e20
classDef sReused fill:#e3f2fd,stroke:#1e88e5,color:#0d47a1
classDef sFailed fill:#ffebee,stroke:#e53935,color:#b71c1c,stroke-width:2px
classDef sDropped fill:#f5f5f5,stroke:#bdbdbd,color:#9e9e9e
class n_amd64_torch_spyre_torch_spyre_dev sOk;
class n_amd64_hf_adapters_hf_adapters_dev sOk;
class n_amd64_spyre_inference_spyre_inference_dev sOk;
✅ orch trigger-pr-validation — green · arches amd64 · fp amd64=caad41d3
GHA test runs:
|
|
GHA test runs:
|
|
GHA test runs:
|
|
GHA test runs:
|
Summary
Consolidates Gemma performance work from #485, #486, #487, #488, #489 and #490 into one review and merge unit, following Ariel's request. #485 is the surviving PR; the other five are superseded. The compiler changes remain separate.
Refreshed head:
47ec92a3b46be3a0d9ac40e5c0990a7b2c1f0c5e, incorporating HF main1b3c1a6d163977940779564cfb1a53f5aef9014c(September 10). Signed mergeab550856preserves the published feature history;e484f49bclarifies the read-copy capability wording. Separate commits1c0f425and47ec92afix the CI environment mismatch at installation and both module-test callers. Nine files, +719/−38: three model/generation files (+365/−30), three existing test files (+313/−1), and three CI/setup files (+41/−7). No new test file or public dependency change.All supported optimizations are automatic by default. Unsupported shapes, dtypes or compiler capabilities retain the existing path. Private controls remain only for comparisons and explicit support checks; no new public model API, generation loop, weight bank, cache representation or backend operation is introduced.
What changes
Prefill output work
Generation materializes only the final logit row before copying it to the CPU. Materialization matters: copying an offset view alone can convert the entire underlying allocation.
For Gemma's forward driver, generation also selects the last hidden-state row before the vocabulary projection and existing softcap. The backbone still processes all tokens and updates all caches. Ordinary forward still returns all rows, and decode is unchanged. Selection follows the actual prefill callback, including custom callbacks and chunked text prefill; callables without an inspectable signature retain their existing calling convention.
These two changes overlap: once the head computes one row, there is no full prefill-logit allocation for the copy optimization to remove.
In chunked text prefill the head processes one row per chunk, not just on the final chunk. Only the final chunk supplies generation's first token. The recorded one-shot timings do not measure this chunked case.
Decode weight delivery
The one-token/eight-route case pairs eight route owners with the compiler's consumer-compatible indexed-selection layout. The layout and assignment must be enabled together.
Prefill expert assignments
When the required compiler composition is available for matching FP16/BF16 E128/T512/H2816/F704, use gate/up token-by-hidden 8×4, down token-by-output 16×2, and retain 32 token groups around the persistent expert loop. Routing, GELU, scaling, original banks and expert accumulation are unchanged.
Configuration is scoped to the existing prefill/decode compile calls. Explicit unsupported prefill requests fail before attention/cache writes; named dimensions are cleaned up on errors.
Dependencies
Dependency check, September 10: #4283/#4284 are merged, but compiler main
447d19e1still lacks the required decode and input-stage capabilities. Refreshed #4349 at3bf56334supplies the decode capability. Refreshed #4347 ata9a4fd15suppliesconsumer_compatible_input_stagingthrough the existing chooser and separates generated-copy hint applicability from source history; it does not rewrite assignments after selection. Its source chain remains #3440 → #4152 → #4153 → #4347, with sibling #3955's completed-sum integration. Refreshed #4350 atbede205dis independently main-based. The existingread_copy_elisionoption proves neither that #4350 is present nor that any copy was removed: absent preservation, the existing final proof retains the copy safely. No extra capability flag or LX/core-assignment source is added to the adapter. Composed expert-function device qualification now demonstrates P8 engagement and LX activation staging; this is not full-model acceptance.Decode's historical placement results included both blocking changes. Source independence of the two controls is not a promise of independent on-chip residency or additive gains.
The fresh P8-only measurement in the composed expert function is 29.726537 → 28.997294 ms wall time, 2.4831% median paired saving across five improving pairs, with exact OFF/ON outputs and final activation LX placement. This is an incremental compiler-candidate result on the complete expert function, not new whole-model or decode evidence for this HF PR; details and controls are recorded in #4347.
Recorded performance — historical, not measurements of this consolidated head
Batch 1; original source/runtime pins and raw receipts remain in the preparation package. Each row has its own immediate control.
Do not add these percentages. The preceding compiler copy-removal result (41.521 → 31.406 ms, 24.4% lower expert-function time) belongs to #4350, not to this HF PR. Historical accepted 4× full-model prefill (6.4 → 1.6 s) and 8.8× expert-FFN results belong to the earlier merged campaign, not this diff.
Smaller, integrated test coverage
Removed seven new standalone test/helper files (1,504 lines), including source-parsing/AST scaffolding. Original commits and superseded branches retain them for recovery. No existing model test is removed or weakened.
Replacement coverage lives in existing suites:
tests/cpu/test_generate_cpu.py: actual generation and imported Gemma forward; one-shot/chunked/custom callback paths; unchanged cache-write positions and decode rows; vocabulary cropping, returned logits/scores, bounded head and materialized row storage; unsupported/uninspectable drivers.tests/cpu/test_adapter_cpu_accuracy.py: imported MoE implementation; both block controls together and separately for FP16/BF16; actual dispatch recording of every indexed-selection source and BMM shape; repeated indices/tails; capability/dtype/shape fallback and explicit prefill rejection before cache writes.tests/spyre/test_e2e_token_compare_spyre.py: reuse the already-loaded Gemma model and CPU reference to also check the real generation path, with fresh request caches. The old forward-only loop bypassed both generation optimizations. Existing model smoke, forward and token checks remain.Refreshed local result: 61 selected checks pass (18 focused Gemma/generation cases plus 43 existing input-normalization/cache cases). Ruff 0.15.6, Black 26.3.1, whitespace and mypy over all 43 adapter source files pass. These are host checks using Python 3.12, PyTorch 2.14.0 and Transformers 5.15.0, not a match to the earlier device-CI runtime. CPU/meta checks prove dispatch and algebra, not generated device placement, reduction numerics or current-head performance. The CPU test matrix is currently disabled upstream; these local checks are not presented as completed device CI.
Review and remaining acceptance
Two independent source-review passes found no remaining blocker after clarifying that the existing read-copy control is not a probe for #4350. The review covered the callable-driver fix, all four decode block combinations and pre-cache prefill validation. This is AI-assisted source review, not human maintainer approval or device acceptance. Optimization-specific validation can assert the existing eligibility predicate and inspect the emitted program; no additional production enablement flag is added.
Features remain traceable in the original signed source commits, including the rounding-changing gate/up block operation. This refresh preserves that history and adds upstream main without replaying or duplicating the optimization changes. The six-file feature diff and separate three-file CI repair remain independently reviewable.
CI environment repair
The
e484f49brun failed before model execution across the sampled suite families: dependency installation created a checkout.venv, whileuv run --active --no-syncran tests from the image's/home/senuser/.venv. Missingtransformers/oot_frameworkwere the result. Repeating a fresh pod did not change that contract mismatch.Commit
1c0f425sets the project environment to the already-active environment, makes bothuv addcalls resolve without implicit installation, and performs one explicit active sync. It preserves image Torch and unrelated image-only packages, compares Torch's version/path/native-binary hash before and after, checks dependency compatibility, and imports the required packages through the exact test invocation. The Makefile's missing-oot guidance points to that setup. No shared installation is changed by the local validation, and no test or tolerance is disabled.The real
uvcommand passed an isolated wheel-fixture check: image-owned package unchanged, unrelated image package retained, new dependency importable from the test command, and no second environment created. Fresh runner CI then passed this installation/probe, printing the intended image interpreter, Torch 2.13.0+cpu and Transformers 5.15.0. It exposed two module-test callers that still activated the absent checkout.venv;47ec92aremoves those environment switches and requires the prepared active environment instead. The extended fixture audits every build-action caller and executes both module caller prefixes successfully without a checkout.venv. Unrelated workflows that deliberately create their own environment are untouched. The latest full CI run remains required.Fresh combined device CI and capability-present model acceptance are required. A green run without the required compiler capabilities validates fallbacks, not blocked decode/prefill performance.
The previous CI run 34242808842 is not a result for this refresh: Gemma token comparison, including actual generation, passed, but its smoke test failed first in attention with a bus-fence error and on retry in the 64-token prefill FFN with a device compute error. Ministral and RoBERTa passed their retries. No treatment-specific source defect was identified, but the Gemma fault remains unattributed, not proven to be infrastructure. The new head needs fresh CI; no device failure or numerical threshold is suppressed by this refresh.
The historical gate/up comparison recorded maximum absolute difference 0.09375 and relative L2 about 0.00288048; that is a measurement, not an accepted error limit. CP11 also has an unresolved seeded all-NaN receipt. Neither consolidation nor passing host checks closes the correctness owner's disposition. No numerical limit is widened here.
Before performance acceptance, verify exact compiler/adapter revisions, real checkpoint logits/tokens, intended on-chip blocks/original-bank addresses and repeated whole-model timing. No new device speedup is claimed in this consolidation.