use super::{FrozenExpertGeometry,FrozenSelectedExperts,FrozenNf4SwiGluExperts,FrozenPackedSwiGluExperts,
AdaptedPackedSwiGluExperts,AdaptedFloatingSwiGluExperts,AdaptedExpertError,FloatingExpertError,Nf4MoeLayer};
use ruda_model::{module::{Module,ParamId},tensor::{Tensor,Int,FrozenPackedExpertOps,ExpertProjectionOps,NativeSwiGluOps,backend::Backend}};
use alloc::vec::Vec;
use core::fmt;
pub trait PackedExpertAdapterSource<B:Backend>:FrozenExpertGeometry<B> {
fn into_packed_expert_source(self) -> FrozenPackedSwiGluExperts<B>;
}
impl<B:Backend> PackedExpertAdapterSource<B> for FrozenPackedSwiGluExperts<B> {
fn into_packed_expert_source(self) -> FrozenPackedSwiGluExperts<B> {self}
}
impl<B:Backend> PackedExpertAdapterSource<B> for FrozenNf4SwiGluExperts<B> {
fn into_packed_expert_source(self) -> FrozenPackedSwiGluExperts<B> {
FrozenPackedSwiGluExperts::from_parts(self.gate.into(),self.up.into(),self.down.into())
}
}
#[derive(Module,Debug)]
pub enum MixedAdaptedExperts<B:Backend,E:Module<B> =FrozenPackedSwiGluExperts<B>> {
Original(E),
Packed(AdaptedPackedSwiGluExperts<B>),
Floating(AdaptedFloatingSwiGluExperts<B>),
}
impl<B:Backend,E:Module<B>> MixedAdaptedExperts<B,E> {
pub fn adapter_parameter_ids(&self) -> Vec<ParamId> {match self {
Self::Original(_)=>Vec::new(),Self::Packed(value)=>value.adapter_parameter_ids(),Self::Floating(value)=>value.adapter_parameter_ids()}}
}
impl<B:Backend,E:FrozenExpertGeometry<B>> FrozenExpertGeometry<B> for MixedAdaptedExperts<B,E> {
fn dimensions(&self) -> [usize;3] {match self {
Self::Original(value)=>value.dimensions(),Self::Packed(value)=>value.dimensions(),Self::Floating(value)=>value.dimensions()}}
fn validate(&self) {match self {
Self::Original(value)=>value.validate(),Self::Packed(value)=>value.validate(),Self::Floating(value)=>value.validate()}}
fn device(&self) -> B::Device {match self {
Self::Original(value)=>value.device(),Self::Packed(value)=>value.device(),Self::Floating(value)=>value.device()}}
}
#[derive(Debug)]
pub enum MixedExpertError<O:fmt::Debug,P:fmt::Debug,G:fmt::Debug,S:fmt::Debug> {
Original(O),
Packed(AdaptedExpertError<P,G,S>),
Floating(FloatingExpertError<G,S>),
}
impl<O:fmt::Debug,P:fmt::Debug,G:fmt::Debug,S:fmt::Debug> fmt::Display for MixedExpertError<O,P,G,S> {
fn fmt(&self,f:&mut fmt::Formatter<'_>) -> fmt::Result {match self {
Self::Original(error)=>write!(f,"original expert chain: {error:?}"),Self::Packed(error)=>write!(f,"{error}"),Self::Floating(error)=>write!(f,"{error}")}}
}
impl<O:fmt::Debug,P:fmt::Debug,G:fmt::Debug,S:fmt::Debug> core::error::Error for MixedExpertError<O,P,G,S> {}
impl<B:FrozenPackedExpertOps+ExpertProjectionOps+NativeSwiGluOps,E:FrozenSelectedExperts<B>> FrozenSelectedExperts<B> for MixedAdaptedExperts<B,E> {
type Error=MixedExpertError<E::Error,B::PackedExpertError,B::ExpertProjectionError,B::SwiGluError>;
fn forward(&self,input:Tensor<B,2>,ids:Tensor<B,1,Int>,expert_start:usize) -> Result<Tensor<B,2>,Self::Error> {
match self {
Self::Original(value)=>value.forward(input,ids,expert_start).map_err(MixedExpertError::Original),
Self::Packed(value)=>value.forward(input,ids,expert_start).map_err(MixedExpertError::Packed),
Self::Floating(value)=>value.forward(input,ids,expert_start).map_err(MixedExpertError::Floating),
}
}
}
pub type MixedAdaptedMoeLayer<B,P,E=FrozenPackedSwiGluExperts<B>> = Nf4MoeLayer<B,P,MixedAdaptedExperts<B,E>>;
pub type MixedAdaptedMoeTransformerModel<B,P,E=FrozenPackedSwiGluExperts<B>> = super::transformer::Nf4MoeTransformerModel<B,P,MixedAdaptedExperts<B,E>>;
pub type MixedAdaptedMoeTransformerBlock<B,P,E=FrozenPackedSwiGluExperts<B>> = super::transformer::Nf4MoeTransformerBlock<B,P,MixedAdaptedExperts<B,E>>;
pub type MixedAdaptedMoeTransformerLayer<B,P,E=FrozenPackedSwiGluExperts<B>> = super::transformer::Nf4MoeTransformerLayer<B,P,MixedAdaptedExperts<B,E>>;