metrale_model_layers/layers/
dense_ffn_weights.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! 2026-09-26: The dense-MLP weight sets a loader hands to `DenseFfnLayer` (NVFP4, BF16,
4//! native FP8, packed Q2) and the gated activation. Re-exported from `dense_ffn`.
5//!
6//! Owner: model-layers (dense FFN).
7//! Invariants:
8//! - Every field is the loader's device allocation; nothing here frees it.
9
10use metrale_gpu_runtime::gpu::DevicePtr;
11
12use crate::weight_map::{DenseWeight, Fp8Weight, PackedQ2Weight, QuantizedWeight};
13
14pub struct DenseFfnWeights {
15    pub gate_proj: QuantizedWeight,
16    pub up_proj: QuantizedWeight,
17    pub down_proj: QuantizedWeight,
18    /// 2026-09-25: Transposed (`[K/2, N]`) copies read by the tile prefill GEMMs (`w4a16_gemm_t*`).
19    /// `None` (never built, or freed by `finalize_q4k_load` / `finalize_nvfp4_mmq_load`) leaves
20    /// that projection's prefill to the MMQ, W4A4 or int8 arms or the base `w4a16_gemm`.
21    /// Decode reads the non-transposed weights above.
22    pub gate_proj_t: Option<QuantizedWeight>,
23    pub up_proj_t: Option<QuantizedWeight>,
24    pub down_proj_t: Option<QuantizedWeight>,
25}
26
27/// 2026-09-25: BF16 dense MLP weights. Once installed with `set_bf16_weights`, decode runs
28/// `dense_gemv_bf16` and prefill runs cuBLASLt, `dense_gemm_tc` or `dense_gemm_bf16`.
29pub struct DenseFfnWeightsBf16 {
30    pub gate_proj: DenseWeight,
31    pub up_proj: DenseWeight,
32    pub down_proj: DenseWeight,
33}
34
35/// 2026-09-26: Native block-scaled FP8 E4M3 dense MLP weights. Once installed with
36/// `set_fp8_weights`, decode runs the arm `fp8_down::fp8_down_arm` picks and prefill runs
37/// the `w8_gemm!` ladder in `prefill_fp8`.
38pub struct DenseFfnWeightsFp8 {
39    pub gate_proj: Fp8Weight,
40    pub up_proj: Fp8Weight,
41    pub down_proj: Fp8Weight,
42}
43
44/// 2026-09-25: Packed Q2_0 dense MLP weights (`block_q2_0`), kept 2-bit on the device. Once
45/// installed with `set_q2_weights`, decode runs `q2_0_gemv_vec` per projection and prefill
46/// runs the Q2_0 MMQ GEMM or a BF16 dequant (`forward_prefill_inner`).
47pub struct DenseFfnWeightsQ2 {
48    pub gate_proj: PackedQ2Weight,
49    pub up_proj: PackedQ2Weight,
50    pub down_proj: PackedQ2Weight,
51}
52
53/// 2026-09-25: Activation of the gated FFN: `SiLU` runs `moe_silu_mul`, `GeLU` runs `gelu_mul`.
54#[derive(Debug, Clone, Copy, PartialEq, Eq)]
55pub enum FfnActivation {
56    SiLU,
57    GeLU,
58}
59
60/// 2026-09-25: Int8 copy of one NVFP4 projection for the `int8_gemm_faith2` prefill arms: `w_i8`
61/// is `[N, K]` int8 and `w_scale` is `[N, K/32]` F32. Built once by `ensure_int8_weight`.
62#[derive(Debug, Clone, Copy)]
63pub(super) struct Int8Weight {
64    pub(super) w_i8: DevicePtr,
65    pub(super) w_scale: DevicePtr,
66}
67
68/// 2026-09-25: GGML `block_q4_K` copy of one NVFP4 projection for the `METRALE_FFN_MMQ` prefill
69/// arm, built once by `ensure_q4k_weight`.
70#[derive(Debug, Clone, Copy)]
71pub(super) struct Q4kWeight {
72    pub(super) w_q4k: DevicePtr,
73}
74
75/// 2026-09-25: `block_nvfp4` repack of one NVFP4 projection for the NVFP4 MMQ prefill arm, built
76/// once by `ensure_nvfp4_mmq_weight`.
77#[derive(Debug, Clone, Copy)]
78pub(super) struct Fp4MmqWeight {
79    pub(super) w: DevicePtr,
80}