@@ -302,6 +302,17 @@ ov::Output<ov::Node> process_view_input_new(const NodeContext & context, int inp
302302 // re-slice/flatten the already-resolved view (a Reshape to the full flattened
303303 // n_expert_used*n_embd tail, which then conflicts with the single-plane input). Treat a
304304 // dynamic-vs-dynamic axis as matching so the already-resolved view is reused as-is.
305+ //
306+ // A third case matters for split-model MoE fragments: translate_view resolves the
307+ // expert-plane view against the fragment's INPUT parameter. When the graph is split
308+ // the token axis of that parameter may already be concrete (static n_tokens) even
309+ // though get_view_input_ov_shape() still reports it as dynamic (-1). The resolved
310+ // view is then static [1,1,n_tokens,n_embd] while `expected` is [1,1,?,n_embd].
311+ // An "expected dynamic, actual static" axis is a valid concretization of the SAME
312+ // resolved view, so treat it as matching too. Falling through to process_single_view
313+ // here would re-slice/re-flatten the already-resolved single-plane view against the
314+ // recorded (multi-plane) source strides and emit a constant-target Reshape whose baked
315+ // dims no longer divide the concretized input -> "dimensions do not evenly divide".
305316 auto expected_ov_shape = context.get_view_input_ov_shape (input_index, 0 );
306317 auto actual_shape = input.get_partial_shape ();
307318 if (expected_ov_shape.rank ().is_static () && actual_shape.rank ().is_static () &&
@@ -311,7 +322,10 @@ ov::Output<ov::Node> process_view_input_new(const NodeContext & context, int inp
311322 const bool both_dynamic = expected_ov_shape[i].is_dynamic () && actual_shape[i].is_dynamic ();
312323 const bool both_static_equal = expected_ov_shape[i].is_static () && actual_shape[i].is_static () &&
313324 expected_ov_shape[i] == actual_shape[i];
314- if (!both_dynamic && !both_static_equal) {
325+ // expected dynamic, actual static: the resolved view already carries the
326+ // concrete size for this fragment; reuse it rather than re-materializing.
327+ const bool expected_dyn_actual_static = expected_ov_shape[i].is_dynamic () && actual_shape[i].is_static ();
328+ if (!both_dynamic && !both_static_equal && !expected_dyn_actual_static) {
315329 shapes_match = false ;
316330 break ;
317331 }
0 commit comments