| 283 | } |
| 284 | |
| 285 | DecoderLayerOutputs decoder_layer_with_static_cache( |
| 286 | core::ModuleBuildContext & ctx, |
| 287 | const core::TensorValue & input, |
| 288 | const core::TensorValue & positions, |
| 289 | const TextLayerWeights & weights, |
| 290 | const MioTTSConfig & config, |
| 291 | const core::TensorValue & cache_key, |
| 292 | const core::TensorValue & cache_value, |
| 293 | const core::TensorValue & cache_slot, |
| 294 | const core::TensorValue & attention_mask) { |
| 295 | const int64_t dim = head_dim(config); |
| 296 | const modules::LinearModule q_proj({config.hidden_size, config.num_attention_heads * dim, false}); |
| 297 | const modules::LinearModule k_proj({config.hidden_size, config.num_key_value_heads * dim, false}); |
| 298 | const modules::LinearModule v_proj({config.hidden_size, config.num_key_value_heads * dim, false}); |
| 299 | const modules::LinearModule o_proj({config.num_attention_heads * dim, config.hidden_size, false}); |
| 300 | const modules::RMSNormModule hidden_norm({config.hidden_size, config.rms_norm_eps, true, false}); |
| 301 | |
| 302 | auto x_norm = hidden_norm.build(ctx, input, {weights.input_norm, std::nullopt}); |
| 303 | auto q = q_proj.build(ctx, x_norm, {weights.q_proj, std::nullopt}); |
| 304 | auto k = k_proj.build(ctx, x_norm, {weights.k_proj, std::nullopt}); |
| 305 | auto v = v_proj.build(ctx, x_norm, {weights.v_proj, std::nullopt}); |
| 306 | q = modules::RMSNormModule({dim, config.rms_norm_eps, true, false}) |
| 307 | .build(ctx, reshape_heads(ctx, q, config.num_attention_heads, dim), {weights.q_norm, std::nullopt}); |
| 308 | k = modules::RMSNormModule({dim, config.rms_norm_eps, true, false}) |
| 309 | .build(ctx, reshape_heads(ctx, k, config.num_key_value_heads, dim), {weights.k_norm, std::nullopt}); |
| 310 | v = reshape_heads(ctx, v, config.num_key_value_heads, dim); |
| 311 | q = modules::RoPEModule({dim, GGML_ROPE_TYPE_NEOX, config.rope_theta}).build(ctx, q, positions); |
| 312 | k = modules::RoPEModule({dim, GGML_ROPE_TYPE_NEOX, config.rope_theta}).build(ctx, k, positions); |
| 313 | |
| 314 | const modules::FastKVSetRowsModule set_rows; |
| 315 | auto updated_cache_key = set_rows.build(ctx, cache_key, k, cache_slot); |
| 316 | auto updated_cache_value = set_rows.build(ctx, cache_value, v, cache_slot); |
| 317 | |
| 318 | auto q_heads = modules::TransposeModule({{0, 2, 1, 3}, q.shape.rank}).build(ctx, q); |
| 319 | auto k_heads = modules::TransposeModule({{0, 2, 1, 3}, updated_cache_key.shape.rank}).build(ctx, updated_cache_key); |
| 320 | auto v_heads = modules::TransposeModule({{0, 2, 1, 3}, updated_cache_value.shape.rank}).build(ctx, updated_cache_value); |
| 321 | auto context = flash_attention_from_grouped_heads(ctx, q_heads, k_heads, v_heads, dim, attention_mask); |
| 322 | context = core::ensure_backend_addressable_layout(ctx, context); |
| 323 | context = core::reshape_tensor(ctx, context, core::TensorShape::from_dims({1, 1, config.num_attention_heads * dim})); |
| 324 | auto x = modules::AddModule{}.build(ctx, input, o_proj.build(ctx, context, {weights.o_proj, std::nullopt})); |
| 325 | |
| 326 | auto ff_in = hidden_norm.build(ctx, x, {weights.post_norm, std::nullopt}); |
| 327 | auto gate = modules::LinearModule({config.hidden_size, config.intermediate_size, false}) |
| 328 | .build(ctx, ff_in, {weights.gate_proj, std::nullopt}); |
| 329 | gate = modules::SiluModule{}.build(ctx, gate); |
| 330 | auto up = modules::LinearModule({config.hidden_size, config.intermediate_size, false}) |
| 331 | .build(ctx, ff_in, {weights.up_proj, std::nullopt}); |
| 332 | auto gated = modules::MulModule{}.build(ctx, gate, up); |
| 333 | auto ff = modules::LinearModule({config.intermediate_size, config.hidden_size, false}) |
| 334 | .build(ctx, gated, {weights.down_proj, std::nullopt}); |
| 335 | return {modules::AddModule{}.build(ctx, x, ff), k, v}; |
| 336 | } |
| 337 | |
| 338 | MioTTSCausalLMWeights load_weights( |
| 339 | const MioTTSAssets & assets, |
no test coverage detected