#include "../node_context.h" #include "../op_table.h" #include "../utils.h" #include #include #include #include #include #include #include #include #include namespace ov { namespace frontend { namespace ggml { namespace op { static ov::Output reshape_add_id_input_to_2d(const ov::Output & input, const ov::PartialShape & input_shape, const std::vector & dims) { const auto actual_shape = input.get_partial_shape(); if (actual_shape.rank().is_static() && actual_shape.rank().get_length() == 2) { return input; } if (input_shape.rank().is_static() && input_shape.rank().get_length() == 2) { return input; } auto shape = std::make_shared(input, ov::element::i64); return std::make_shared(input, get_dimensions(shape, dims), false); } OutputVector translate_add_id(const NodeContext & context) { num_inputs_check(context, 3, 3); auto input = process_view_input_new(context, 0); auto bias = process_view_input_new(context, 1); auto ids = process_view_input_new(context, 2); // OpenVINO uses reversed GGML dimensions: // input: [1, n_token, n_used, n_embd] // bias: [1, 1, n_expert, n_embd] // ids: [1, 1, n_token, n_used] // Model bias constants may already be stored as [n_expert, n_embd]. bias = reshape_add_id_input_to_2d(bias, context.get_input_shape(1), {2, 3}); ids = reshape_add_id_input_to_2d(ids, context.get_input_shape(2), {2, 3}); if (ids.get_element_type() != ov::element::i32 && ids.get_element_type() != ov::element::i64) { ids = std::make_shared(ids, ov::element::i32); } auto gather_axis = ov::op::v0::Constant::create(ov::element::i32, ov::Shape{}, {0}); ov::Output selected_bias = std::make_shared(bias, ids, gather_axis); selected_bias = std::make_shared( selected_bias, std::make_shared(input, ov::element::i64), false); if (selected_bias.get_element_type() != input.get_element_type()) { selected_bias = std::make_shared(selected_bias, input.get_element_type()); } ov::Output res = std::make_shared(input, selected_bias); const auto output_type = context.get_output_type(); if (res.get_element_type() != output_type) { res = std::make_shared(res, output_type); } return rename_outputs_with_suffix({res}, context.get_name()); } } // namespace op } // namespace ggml } // namespace frontend } // namespace ov