| 117 | const modules::RMSNormModule hidden_norm({config.hidden_size, config.rms_norm_eps, true, false}); |
| 118 | const modules::RMSNormModule head_norm({dim, config.rms_norm_eps, true, false}); |
| 119 | const modules::AddModule add; |
| 120 | |
| 121 | auto attn_in = hidden_norm.build(ctx, input, binding::norm_data(ctx, weights.input_norm)); |
| 122 | auto q = q_proj.build(ctx, attn_in, binding::linear_data(ctx, weights.q_proj)); |
| 123 | auto k = k_proj.build(ctx, attn_in, binding::linear_data(ctx, weights.k_proj)); |
| 124 | auto v = v_proj.build(ctx, attn_in, binding::linear_data(ctx, weights.v_proj)); |
| 125 | q = head_norm.build(ctx, reshape_heads(ctx, q, config.num_attention_heads, dim), binding::norm_data(ctx, weights.q_norm)); |
| 126 | k = head_norm.build(ctx, reshape_heads(ctx, k, config.num_key_value_heads, dim), binding::norm_data(ctx, weights.k_norm)); |
| 127 | v = reshape_heads(ctx, v, config.num_key_value_heads, dim); |
| 128 | q = modules::RoPEModule({dim, GGML_ROPE_TYPE_NEOX, config.rope_theta}).build(ctx, q, positions); |
| 129 | k = modules::RoPEModule({dim, GGML_ROPE_TYPE_NEOX, config.rope_theta}).build(ctx, k, positions); |
| 130 | |
| 131 | auto q_heads = modules::TransposeModule({{0, 2, 1, 3}, q.shape.rank}).build(ctx, q); |
| 132 | auto k_heads = |
| 133 | repeat_kv_heads(ctx, modules::TransposeModule({{0, 2, 1, 3}, k.shape.rank}).build(ctx, k), kv_repeats); |
| 134 | auto v_heads = |
| 135 | repeat_kv_heads(ctx, modules::TransposeModule({{0, 2, 1, 3}, v.shape.rank}).build(ctx, v), kv_repeats); |
| 136 | auto context = attention_from_heads(ctx, q_heads, k_heads, v_heads, dim, attention_mask); |
| 137 | context = ensure_contiguous(ctx, context); |
| 138 | context = core::reshape_tensor( |
| 139 | ctx, |
| 140 | context, |
| 141 | core::TensorShape::from_dims({input.shape.dims[0], input.shape.dims[1], config.num_attention_heads * dim})); |
| 142 | auto x = add.build(ctx, input, o_proj.build(ctx, context, binding::linear_data(ctx, weights.o_proj))); |
| 143 | |
| 144 | auto ff_in = hidden_norm.build(ctx, x, binding::norm_data(ctx, weights.post_norm)); |
| 145 | auto gate = |
| 146 | modules::LinearModule(binding::linear_config( |
| 147 | config.hidden_size, |
| 148 | config.intermediate_size, |
| 149 | false)) |
| 150 | .build(ctx, ff_in, binding::linear_data(ctx, weights.gate_proj)); |
| 151 | gate = modules::SiluModule{}.build(ctx, gate); |
| 152 | auto up = |
| 153 | modules::LinearModule(binding::linear_config( |
| 154 | config.hidden_size, |
| 155 | config.intermediate_size, |
| 156 | false)) |
| 157 | .build(ctx, ff_in, binding::linear_data(ctx, weights.up_proj)); |
| 158 | auto ff = |
| 159 | modules::LinearModule(binding::linear_config( |
| 160 | config.intermediate_size, |
| 161 | config.hidden_size, |
| 162 | false)) |
| 163 | .build(ctx, modules::MulModule{}.build(ctx, gate, up), binding::linear_data(ctx, weights.down_proj)); |
| 164 | return add.build(ctx, x, ff); |
| 165 | } |
| 166 | |
| 167 | std::vector<float> build_padding_attention_mask_values(int64_t tokens, int64_t valid_tokens) { |
| 168 | if (tokens <= 0 || valid_tokens <= 0 || valid_tokens > tokens) { |
| 169 | throw std::runtime_error("ACE-Step padding attention mask requires 0 < valid_tokens <= tokens"); |
| 170 | } |
| 171 | std::vector<float> values(static_cast<size_t>(tokens * tokens), 0.0F); |
| 172 | const float neg_inf = -std::numeric_limits<float>::infinity(); |
| 173 | for (int64_t q = 0; q < valid_tokens; ++q) { |
| 174 | for (int64_t k = valid_tokens; k < tokens; ++k) { |
| 175 | values[static_cast<size_t>(q * tokens + k)] = neg_inf; |
| 176 | } |
no test coverage detected