| 374 | x = fc1.build(ctx, x, binding::linear_data(ctx, weights.fc1.weight, weights.fc1.bias)); |
| 375 | x = modules::GeluModule({modules::GeluApproximation::ExactErf}).build(ctx, x); |
| 376 | x = fc2.build(ctx, x, binding::linear_data(ctx, weights.fc2.weight, weights.fc2.bias)); |
| 377 | return x; |
| 378 | } |
| 379 | |
| 380 | core::TensorValue build_transformer_branch( |
| 381 | core::ModuleBuildContext & ctx, |
| 382 | const core::TensorValue & input, |
| 383 | const core::TensorValue & positions, |
| 384 | const TransformerBranchWeights & weights, |
| 385 | const RoformerArchitectureConfig & config) { |
| 386 | auto x = input; |
| 387 | for (const auto & layer : weights.layers) { |
| 388 | x = modules::AddModule{}.build(ctx, x, build_attention(ctx, x, positions, layer.attention, config)); |
| 389 | x = modules::AddModule{}.build(ctx, x, build_feed_forward(ctx, x, layer.feed_forward, config)); |
| 390 | } |
| 391 | if (config.transformer_output_norm) { |
| 392 | return build_reference_rms_norm(ctx, x, config.dim, weights.norm); |
| 393 | } |
| 394 | return x; |
| 395 | } |
| 396 | |
| 397 | core::TensorValue build_band_split( |
| 398 | core::ModuleBuildContext & ctx, |
| 399 | const core::TensorValue & input, |
| 400 | const MelBandWeights & weights, |
| 401 | const RoformerArchitectureConfig & config) { |
| 402 | std::vector<core::TensorValue> outputs; |
| 403 | outputs.reserve(weights.band_split.size()); |
| 404 | int64_t offset = 0; |
| 405 | for (size_t band = 0; band < weights.band_split.size(); ++band) { |
| 406 | const int64_t dim_in = config.band_input_dims[band]; |
| 407 | auto band_input = modules::SliceModule({2, offset, dim_in}).build(ctx, input); |
| 408 | band_input = build_reference_rms_norm(ctx, band_input, dim_in, weights.band_split[band].norm); |
| 409 | band_input = modules::LinearModule(binding::linear_config(dim_in, config.dim, true)) |
| 410 | .build(ctx, band_input, binding::linear_data(ctx, weights.band_split[band].proj.weight, weights.band_split[band].proj.bias)); |
| 411 | band_input = core::reshape_tensor( |
| 412 | ctx, |
| 413 | ensure_contiguous(ctx, band_input), |
| 414 | core::TensorShape::from_dims({input.shape.dims[0], input.shape.dims[1], 1, config.dim})); |
| 415 | outputs.push_back(band_input); |
| 416 | offset += dim_in; |
| 417 | } |
| 418 | |
| 419 | while (outputs.size() > 1) { |
| 420 | std::vector<core::TensorValue> next; |
| 421 | next.reserve((outputs.size() + 1) / 2); |
| 422 | for (size_t i = 0; i < outputs.size(); i += 2) { |
| 423 | if (i + 1 < outputs.size()) { |
| 424 | next.push_back(modules::ConcatModule({2}).build(ctx, outputs[i], outputs[i + 1])); |
no test coverage detected