Gpt_oss prefill: avoid packed expert-axis slicing in chunked MoE to restore MXFP6 constant compression - #1165
Conversation
Signed-off-by: Abhishek kumar singh <sabhis@qti.qualcomm.com>
|
@abhishek-singh591 what tests are verified on this? Disaggregated mode example? |
Yes i tested this till compile of prefill+chunking since the changes were only made on the prefill part, didn't check the Perf. |
Signed-off-by: abhishek-singh591 <sabhis@qti.qualcomm.com>
|
QPC size went down from 37Gb to 17GB for full model with 4TS. Perf with 2 layer:- Perf before:- decode tok/sec=83.26760350742597 Perf after:- decode tok/sec=80.18426492513731. |
Signed-off-by: Abhishek Kumar Singh <sabhis@qti.qualcomm.com>
Signed-off-by: abhishek-singh591 <sabhis@qti.qualcomm.com>
Signed-off-by: Abhishek Kumar Singh <sabhis@qti.qualcomm.com>
| def _ensure_blocked_expert_weights(self, num_nsp: int) -> None: | ||
| """Rebuild blocked expert tensors when NSP partitioning changes.""" | ||
| num_experts = self.experts.num_experts | ||
| local_experts = num_experts // num_nsp | ||
| expected_wg_shape = (num_nsp, local_experts) | ||
|
|
||
| has_blocked_weights = all(hasattr(self, name) for name in ("W_g", "W_u", "W_d", "b_g", "b_u", "b_d")) | ||
| if has_blocked_weights and self.W_g.shape[:2] == expected_wg_shape: | ||
| return | ||
|
|
||
| # Ensure split gate/up aliases exist before blocked views are materialized. | ||
| if not hasattr(self.experts, "gate_proj") and hasattr(self.experts, "__qeff_init__"): | ||
| self.experts.__qeff_init__() | ||
| self.expert_blocking_num_nsp = num_nsp | ||
| self.__qeff_init__() |
There was a problem hiding this comment.
why is this needed, shouldn't qeff_init always run and do this? is this check really needed?
There was a problem hiding this comment.
Yes just added in the readme, expert_blocking_num_nsp is set after transform in the test, and GPT-OSS blocked tensors (W_g/W_u/W_d, b_g/b_u/b_d) are shape-dependent on that value.
So, Without re-init, tensors stay in old layout (usually initialized with default num_nsp=num_experts), so matmul/add hits axis mismatch later. The disagg failure (a=16 vs b=32) is exactly that: runtime used num_nsp=16 while blocked params were still built for num_nsp=32.
This removes the need for manual __qeff_init__() calls in tests when only expert-blocking attrs are changed.
There was a problem hiding this comment.
Then, this layout rewrite should be called outside before export, and not in forward method.
There was a problem hiding this comment.
But that would require updating all the test files. We also need to handle cases where export is called multiple times with expert_blocking_num_nsp, since subsequent export calls could fail due to the modified code. So, this logic should probably live in the model file itself, though not necessarily inside the forward() method.
Root cause and fix summary (prefill-only)
Before (problematic pattern)
In
QEffPrefillOnlyChunkedGptOssMLP.forward, the prefill path did:W_g/W_u/W_dand biases were reshaped to[num_nsp, local_experts, ...].local_slotloop:W_g[:, local_slot],W_u[:, local_slot], etc.This matches the compiler pattern we observed:
float16<16 x 2 x 2880 x 2880>0and1)So even with logically split gate/up params, this path reintroduced a packed-then-sliced representation during subfunction export.
After (fixed pattern)
The updated code now:
routing_weights_by_expert = routing_weights.transpose(0, 1)→[num_experts, T]local_slot:slot_start = local_slot * num_nspslot_end = slot_start + num_nspself.experts.gate_proj[slot_start:slot_end]self.experts.up_proj[slot_start:slot_end]self.experts.down_proj[slot_start:slot_end]So we no longer materialize
[num_nsp, local_experts, ...]temporaries and no longer slice that axis inside the subfunction body.Fix implemented
GPT-OSS chunked MLP now auto-rebuilds blocked tensors whenever
expert_blocking_num_nspchanges:_ensure_blocked_expert_weights(num_nsp)inQEfficient/transformers/models/gpt_oss/modeling_gpt_oss.py.forward()before blocked MoE compute.This removes the need for manual
__qeff_init__()calls in tests when only expert-blocking attrs are changed.