Skip to content

feat(example): Add Spark-X2.5 model example with hybrid attention support - #22865

Open
dongjiang1989 wants to merge 2 commits into
pytorch:mainfrom
XHToken:add-spark-x2.5
Open

dongjiang1989 wants to merge 2 commits into
pytorch:mainfrom
XHToken:add-spark-x2.5

Conversation

@dongjiang1989

Copy link
Copy Markdown

Summary

Add examples/models/spark_x2_5/ with support for the Spark-X2.5-1.7B and Spark-X2.5-4B models from XHToken. These are compact, general-purpose language models with a hybrid attention architecture (3 sliding-window attention layers + 1 full-attention layer, repeating) that natively supports context windows up to 1M tokens.

Architecture highlights

  • Hybrid attention: pattern of 3 sliding-window + 1 full-attention layer (28 layers for 1.7B, 36 for 4B)
  • Per-layer-type RoPE: full-attention layers use rope_theta=5M, partial_rotary_factor=0.25; sliding-attention layers use rope_theta=10K, partial_rotary_factor=1.0
  • Headwise attention output gate: per-head sigmoid gate broadcast over head dim (a lighter variant of use_attn_o_gate)
  • Sliding window KV cache (RingKVCache, window=512 tokens)
  • GELU activation in MLP (vs default SiLU)
  • Tied word embeddings

Files added (in examples/models/spark_x2_5/)

  • convert_weights.py — HF safetensors → Meta format conversion with fused QKV split, sharded checkpoint support, and tied embeddings handling
  • config/ — JSON configs for 1.7B and 4B variants; XNNPack (fp32, q8da4w), CoreML, and MLX export configs
  • test_spark_x2_5.py — config validation and model registration tests
  • BUCK, README.md — build target and usage documentation

Core changes to existing files

  • examples/models/llama/model_args.py — add headwise_attn_output_gate and rope_parameters fields
  • examples/models/llama/feed_forward.pyFeedForward now accepts act_fn parameter (was hardcoded to SiLU)
  • examples/models/llama/attention.py — headwise attention output gate (dim→n_heads, broadcast over head_dim), per-layer is_sliding detection, RingKVCache for sliding-window layers, mutual-exclusion validation for gate flags
  • examples/models/llama/llama_transformer.py — per-layer-type RoPE via _build_ropes() helper, freqs_by_type dispatch in _forward_layers(), act_fn plumbed to FeedForward
  • examples/models/llama/export_llama_lib.py — register spark_x2_5_1_7b and spark_x2_5_4b in EXECUTORCH_DEFINED_MODELS, HUGGING_FACE_REPO_IDS, and weight-conversion dispatch
  • extension/llm/export/config/llm_config.py — add spark_x2_5_1_7b and spark_x2_5_4b to ModelType enum

Example export

python -m extension.llm.export.export_llm \
  --config examples/models/spark_x2_5/config/spark_x2_5_xnnpack_q8da4w.yaml \
  +base.model_class="spark_x2_5_1_7b" \
  +base.params="examples/models/spark_x2_5/config/spark_x2_5_1_7b_config.json" \
  +export.output_name="spark_x2_5_1_7b_8da4w.pte"

Test plan

Unit tests

pytest examples/models/spark_x2_5/test_spark_x2_5.py -v
# 3 passed

Model construction + forward pass (both variants)

from executorch.examples.models.llama.model_args import ModelArgs
from executorch.examples.models.llama.llama_transformer import construct_transformer

# 1.7B: 28 layers, dim=2048
# 4B:   36 layers, dim=2560
# Both: prefill + multi-step decode with KV cache succeed
# Layer types: sliding→RingKVCache, full→KVCache
# Per-layer RoPE: 2 distinct RoPE instances (full_attention, sliding_attention)

Sharded checkpoint conversion

# Spark-X2.5-1.7B uses 2 shards, 4B uses 5 shards
# Verified: 283 keys converted correctly, QKV split matches, tied embeddings preserved

Lint

flake8 examples/models/spark_x2_5/ examples/models/llama/model_args.py \
    examples/models/llama/feed_forward.py examples/models/llama/attention.py \
    examples/models/llama/llama_transformer.py examples/models/llama/export_llama_lib.py \
    extension/llm/export/config/llm_config.py --max-line-length=120
# No warnings

This PR was authored with AI assistance (Claude Code).

@pytorch-bot

pytorch-bot Bot commented Sep 16, 2026

Copy link
Copy Markdown

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/pytorch/executorch/22865

Note: Links to docs will display an error until the docs builds have been completed.

⚠️ 22 Awaiting Approval

As of commit 0ea99af with merge base c65f1dc (image):

AWAITING APPROVAL - The following workflows need approval before CI can run:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@meta-cla

meta-cla Bot commented Sep 16, 2026

Copy link
Copy Markdown

Hi @dongjiang1989!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

@linux-foundation-easycla

linux-foundation-easycla Bot commented Sep 16, 2026

Copy link
Copy Markdown

CLA Signed
The committers listed above are authorized under a signed CLA.

  • ✅ login: dongjiang1989 / name: dongjiang1989 (c825ccf)

@github-actions

Copy link
Copy Markdown

This PR needs a release notes: label

If your change should be included in the release notes (i.e. would users of this library care about this change?), please use a label starting with release notes:. This helps us keep track and include your important work in the next release notes.

To add a label, you can comment to pytorchbot, for example
@pytorchbot label "release notes: none"

For more information, see
https://github.com/pytorch/pytorch/wiki/PyTorch-AutoLabel-Bot#why-categorize-for-release-notes-and-how-does-it-work.

Add examples/models/spark_x2_5/ with support for the Spark-X2.5-1.7B and
Spark-X2.5-4B models from XHToken. These are hybrid-attention LLMs (3:1
sliding-window to full-attention layers) with native 1M-token context,
per-layer-type RoPE configs, headwise sigmoid attention gates, and GELU
activation.

New module:
- convert_weights.py: HF safetensors to Meta format conversion, including
  fused QKV projection splitting, sharded checkpoint support, and tied
  embeddings handling.
- config/: JSON configs for 1.7B (28 layers) and 4B (36 layers) variants,
  plus XNNPack (fp32/q8da4w), CoreML, and MLX export configs.
- test_spark_x2_5.py: config validation and model registration tests.
- BUCK, README.md: build and usage documentation.

Core changes to support Spark-X2.5 architecture:
- model_args.py: Add headwise_attn_output_gate and rope_parameters fields.
- feed_forward.py: FeedForward now accepts act_fn parameter (was hardcoded
  to SiLU).
- attention.py: Add headwise attention output gate (dim->n_heads broadcast
  over head_dim), per-layer is_sliding detection, RingKVCache for
  sliding-window layers.
- llama_transformer.py: Per-layer-type RoPE construction via _build_ropes(),
  freqs_by_type dispatch in _forward_layers(), act_fn plumbed to FeedForward.
- export_llama_lib.py, llm_config.py: Register spark_x2_5_1_7b and
  spark_x2_5_4b model types.

This commit was authored with AI assistance (Claude Code).

Signed-off-by: dongjiang1989 <dongjiang1989@126.com>
@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Sep 16, 2026
@dongjiang1989 dongjiang1989 changed the title Add Spark-X2.5 model example with hybrid attention support feat(example): Add Spark-X2.5 model example with hybrid attention support Sep 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant