pub struct MoeLayerConfig {
pub n_experts: usize,
pub n_experts_active: usize,
pub n_shared_experts: usize,
pub hidden_dim: usize,
pub expert_ffn_dim: usize,
pub gating: GatingFunction,
pub norm_topk_prob: bool,
pub expert_group_count: Option<usize>,
pub expert_group_used_count: Option<usize>,
pub expert_weights_scale: f32,
}Expand description
Static per-layer MoE configuration. One of these is built per layer from a ModelConfig preset (ferrox-models).
Fields§
§n_experts: usize§n_experts_active: usize§expert_ffn_dim: usize§gating: GatingFunctionWhich function converts router logits into selection scores.
See GatingFunction’s doc comment: this is not a stylistic
choice, it’s an evidence-backed architectural detail that
differs by model family.
norm_topk_prob: boolOnly meaningful for GatingFunction::Softmax (the Sigmoid path
has its own separate, always-renormalized convention – see
route_top_k_sigmoid‘s doc comment). Whether the top-k selected
experts’ softmax weights get renormalized to sum to one after
selection. Mixtral’s real routing does this
(routing_weights /= routing_weights.sum(...) in its reference
implementation) and it’s the right default for any architecture
that doesn’t document otherwise – but it is a real, per-model
choice, not a law of nature: OLMoE’s real config.json sets
norm_topk_prob: false, confirmed against
OlmoeTopKRouter.forward in
transformers/models/olmoe/modeling_olmoe.py (router_top_value /= router_top_value.sum(...) only runs if self.norm_topk_prob)
and against llama.cpp’s real hardcoded build_moe_ffn(..., false, ..., LLAMA_EXPERT_GATING_FUNC_TYPE_SOFTMAX, ...) call for
LLM_ARCH_OLMOE in src/models/olmoe.cpp (GGUF carries no
metadata key for this – it’s an architecture-hardcoded fact in
the reference implementation, not something read from the file).
Getting this wrong silently produces a real, wrong generation:
caught by comparing ferrox’s real OLMoE output directly against
llama.cpp loading the identical GGUF file (llama.cpp answered
“Paris” for “the capital of France is”; ferrox, with this bug,
answered something else entirely).
expert_group_count: Option<usize>Optional Mixtral-style expert grouping (expert_group_count /
expert_group_used_count in GGUF). None means flat top-k over
all experts (Llama / OLMoE / Qwen2-MoE). Grouped routing is
selected at load time; the hot path reads these fields as data.
expert_group_used_count: Option<usize>§expert_weights_scale: f32llama.cpp’s expert_weights_scale hparam (GGUF
{arch}.expert_weights_scale, LLM_KV_EXPERT_WEIGHTS_SCALE): a
constant every routed expert’s combine weight is multiplied by
after the optional top-k renormalisation
(build_moe_ffn: weights = ggml_scale(ctx0, weights, w_scale)).
1.0 when the checkpoint does not carry the key, which is a real
no-op rather than a guess – llama.cpp skips the scale for both
0.0 and 1.0. DeepSeek-V3-lineage MoE recipes (dots1,
bailingmoe2, hunyuan-moe, …) set it to values like 2.5, and
ignoring it scales every routed contribution wrong.
Trait Implementations§
Source§impl Clone for MoeLayerConfig
impl Clone for MoeLayerConfig
Source§fn clone(&self) -> MoeLayerConfig
fn clone(&self) -> MoeLayerConfig
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl Freeze for MoeLayerConfig
impl RefUnwindSafe for MoeLayerConfig
impl Send for MoeLayerConfig
impl Sync for MoeLayerConfig
impl Unpin for MoeLayerConfig
impl UnsafeUnpin for MoeLayerConfig
impl UnwindSafe for MoeLayerConfig
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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