Skip to main content

MoeWeights

Struct MoeWeights 

Source
pub struct MoeWeights {
    pub router: WeightMatrix,
    pub experts: ExpertBacking,
    pub shared_experts: Vec<ExpertWeights>,
    pub shared_expert_gate: Option<Vec<f32>>,
    pub norm_weight: Vec<f32>,
    pub exp_probs_bias: Option<Vec<f32>>,
    pub activation_counts: Vec<AtomicU64>,
}

Fields§

§router: WeightMatrix§experts: ExpertBacking§shared_experts: Vec<ExpertWeights>§shared_expert_gate: Option<Vec<f32>>

Qwen2-MoE-specific: when present, the shared experts’ combined output is scaled by sigmoid(shared_expert_gate . x) before being added to the routed output, instead of added unconditionally – confirmed against the real transformers source (Qwen2MoeSparseMoeBlock.forward: shared_expert_output = F.sigmoid(self.shared_expert_gate(hidden_states)) * shared_expert_output) and llama.cpp’s real qwen2moe.cpp (ffn_gate_inp_shexp dotted against the hidden state, sigmoid, multiplied into the shared-expert branch before the final add). Real on-disk shape is [hidden_dim] (a Linear(hidden_dim, 1, bias=false)’s weight, flattened – ggml’s real create_tensor call declares it as {n_embd}, not a 2D matrix), so this is a plain owned vector dotted with the normed hidden state directly, not a WeightMatrix. None for every other architecture (DeepSeek-V3’s shared experts, for one real confirmed contrast, add unconditionally with no gate at all).

§norm_weight: Vec<f32>§exp_probs_bias: Option<Vec<f32>>

DeepSeek-V3’s aux-loss-free expert-selection bias, on disk as blk.{N}.exp_probs_b.bias (llama.cpp’s LLM_TENSOR_FFN_EXP_PROBS_B – note the on-disk name has no ffn_ prefix, llama-arch.cpp:416). It is added to the selection score only: the top-k is taken over gating(logit) + bias[expert], while each winner’s combine weight comes from the unbiased gating(logit) (build_moe_ffn: “leave probs unbiased as it’s later used to get expert weights”). Biasing the weight too would silently skew every routed contribution away from what the router learned.

None for every checkpoint that does not ship the tensor. When it is present, the GPU MoE fast paths refuse the layer rather than route without it – their kernels have no bias input.

§activation_counts: Vec<AtomicU64>

How many times each routed expert (index into experts) has been selected by route_top_k across every forward_token/ forward_batch call so far. Real observed hotness, not a placeholder – feeds placement_plan below, which is what PlacementPlan::from_budget needs to prioritize actually-hot experts for GPU residency instead of guessing by index.

Implementations§

Source§

impl MoeWeights

Source

pub fn n_experts(&self) -> usize

Source

pub fn expert_bytes(&self, e: usize) -> usize

This routed expert’s weight byte footprint, from resident matrices or the stored layout – identical numbers either way, so residency planning is backing-independent.

Source

pub fn with_expert<R>(&self, e: usize, f: impl FnOnce(&ExpertWeights) -> R) -> R

Runs f against expert e’s weights, materializing them from the store first when this layer is store-backed. The lease (and therefore the cache entry’s pin) lives exactly as long as f’s borrow.

Source

pub fn placement_plan(&self, vram_budget_bytes: u64) -> PlacementPlan

A real VRAM-budget-and-hotness-driven placement plan for this layer’s routed experts, built from each expert’s actual resident byte size (WeightMatrix::resident_bytes() summed across its gate/up/down matrices, so it reflects the real quantization format in use, not an estimate) and the activation counts observed so far. See ferrox_moe::PlacementPlan::from_budget.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.