Skip to content

Head parallel and batch fold blocking for Qwen3-VL MOE - #1229

Open
kdulla wants to merge 34 commits into
quic:mainfrom
kdulla:qwen3_vl_moe_kv_main
Open

Head parallel and batch fold blocking for Qwen3-VL MOE#1229
kdulla wants to merge 34 commits into
quic:mainfrom
kdulla:qwen3_vl_moe_kv_main

Conversation

@kdulla

@kdulla kdulla commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR adds support for new blocking modes, including head parallel blocking, prefill blocking, decode MOE blocking and batch-fold blocking. Head parallel blocking is introduced for causal models while the other approaches are introuced for Qwen3-VL MOE. Expert Parallelism is enabled via expert_parallel compile option while new flags in qaic_config can be passed for different attention blocking configurations. Additionally, this PR contains updated tests for the new blocking modes introduced.

Modes Added

  • Head parallel softmax kv blocking:
    • split heads across cores, enabled for both causal models and Qwen3VL-moe
    • Enabled by passing kv_blocking_headpar_split (Default: 0 or 16) in qaic config with kv blocking mode
    • invokes newly created blocked_kv_attention_forward_headpar_offline attention forward
  • Batch fold + head parallel kv blocking:
    • fold batch size and head dimensions before applying head parallel dimension, intended for high batch size use cases, enabled for Qwen3-VL-moe
    • Enabled by passing batch_fold: True in qaic config with kv blocking mode
    • invokes newly created blocked_kv_attention_forward_decode_headpar_batch attention forward
    • Alters cache layout to be [1, BS * NH, SL, D]
  • Online softmax prefill:
    • Applies online softmax to chunked prefill blocks, intended for long-context prefill efficiency
    • Enabled by passing prefill_blocking_mode: "online", prefill_block_chunks, and prefill_n_rep_chunk in qaic_config
    • Invokes newly created blocked_qkv_attention_forward_prefill_online attention forward

Additionally, pre-existing KV blocking modes have been updated to correctly use ctx_len from compile_time for computing block sizes instead of past_seen-tokens.

Scripts

E2E run on Qwen3-VL moe with batch fold and prefill blocking can be ran via:
python examples/image_text_to_text/models/qwen3_vl_moe/qwen3_vl_disagg_mode.py

Unit tests on Qwen3-VL moe can be ran via:
pytest tests/transformers/models/image_text_to_text/test_qwen3_vl_moe_disagg_blocked.py

Unit tests for head parallel softmax on causal models added to tests/transformers/models/causal_lm_models/test_causal_lm_blocking_hqkv.py

@kdulla
kdulla marked this pull request as draft July 31, 2026 12:28
@ochougul
ochougul marked this pull request as ready for review August 5, 2026 07:36
@ochougul
ochougul marked this pull request as draft August 5, 2026 07:39
@kdulla
kdulla force-pushed the qwen3_vl_moe_kv_main branch 2 times, most recently from fea1490 to 4f454a7 Compare August 6, 2026 06:40
@kdulla
kdulla marked this pull request as ready for review August 6, 2026 07:31
ochougul and others added 19 commits August 7, 2026 11:45
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Co-authored-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
## Summary of Changes
- Adds
examples/image_text_to_text/models/qwen3_vl_moe/qwen3_vl_moe_blocking_headpar_example.py,
a self-contained
end-to-end script that exercises three blocked-attention configurations
for the Qwen3-VL-MoE
- Added support in Qwen3VL-MOE forward to use prefill_blocked_interface
if requested by user.

## Blocking modes covered in example script
-  --blocking-mode decode
  Decode QPC: HQKV +  kv_blocking_headpar_split=0
-  --blocking-mode prefill_par
  Decode QPC: HQKV
  Prefill QPC: prefill_blocking_mode="qkv"
  Description: Separate QPCs;
    chunked-prefill + manual decode loop
-  --blocking-mode prefill_online
  Decode QPC: HQKV
  Prefill QPC:
  prefill_blocking_mode="online"
  Description: Same as above with
    online-softmax prefill
 - --blocking-mode all
  Decode QPC: —
  Prefill QPC: —
  Description: Runs all three back-to-back

## Usage
python
examples/image_text_to_text/models/qwen3_vl_moe/qwen3_vl_moe_blocking_headpar_example.py
--blocking-mode all

---------

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Updated qwen3vl moe disaggregated inference example script

---------

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: ochougul <ochougul@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Updated missing write in prefill mode and changed an incorrect skip on min pos id instead of max.

---------

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
added batch fold decode attention forward and updated example scripts accordingly

---------

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: kdulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: ochougul <ochougul@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: ochougul <ochougul@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: ochougul <ochougul@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
…quic#1186)

Identified incorrect implementation in read cache, updated cache layout
and read calls accordingly, still has ongoing compilation bug.

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: ochougul <ochougul@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Prefill and decode run for 1 iteration

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
…quic#1192)

Adjusted prefill normalization and decode cache layout in example script

---------

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: kdulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Added qwen3 moe optimizations to qwen3vl moe, and changed export BS to 2
if >1.

Checked e2e run, able to run generation with the example script:
`python
examples/image_text_to_text/models/qwen3_vl_moe/qwen3_vl_disagg_mode.py`

---------

Signed-off-by: vbaddi <vbaddi@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Co-authored-by: vbaddi <vbaddi@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Added in progress changes for benchmark alignment, including updated CtxChunkScatter, reshape before custom op and introduction of kv unroll option

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
kdulla and others added 11 commits August 7, 2026 11:52
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
…16 (quic#1223)

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Ann Kuruvilla <akuruvil@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
…locking tests to disagg infra

Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
@kdulla
kdulla force-pushed the qwen3_vl_moe_kv_main branch from 2f7d72b to 148366a Compare August 7, 2026 06:23
kdulla added 2 commits August 7, 2026 11:54
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
inputs[f"past_value.{i}"] = qpc_out[f"past_value.{i}_RetainedState"]
print(f"ttft={(time.time() - loop_start):.3f}")

exit(0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?


all_outputs.append(np.argmax(decode_out["logits"]))
pos_id = np.max(decode_inputs["position_ids"], axis=-1, keepdims=True) + 1
# exit(0)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove

Comment on lines +320 to +322
# for i in range(config.text_config.num_hidden_layers):
# loop_decode_inputs[f"past_key.{i}"] = decode_out[f"past_key.{i}_RetainedState"]
# loop_decode_inputs[f"past_value.{i}"] = decode_out[f"past_value.{i}_RetainedState"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Comment on lines +330 to +332
# for j in range(config.text_config.num_hidden_layers):
# loop_decode_inputs[f"past_key.{j}"] = decode_out[f"past_key.{j}_RetainedState"]
# loop_decode_inputs[f"past_value.{j}"] = decode_out[f"past_value.{j}_RetainedState"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolved, these were older experiments being done that were incorrectly pushed. Cleaned up example script code accordingly

kdulla added 2 commits August 7, 2026 14:38
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
Signed-off-by: Kushal Dulla <kdulla@qti.qualcomm.com>
BlockingMode,
generic_blocked_attention_interface,
past_key_value_update,
prefill_blocked_attention_interface,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we introducing new interface ? can't it be handled within, we also did siimlar for latent attention?

Comment on lines +159 to +160
# routing_weights = torch.zeros_like(router_logits)
# routing_weights.scatter_(1, top_i, top_w)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove commented code

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need 3 example files, all of them can be like CLI options for one example file.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And default value is the one that is best performant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants