Domain-Adaptive Sparse Mixture-of-Experts Injection for Qwen2.5-3B
A Top-2 dynamic router activates 2 of 8 LoRA experts per transformer block — expanding effective capacity while keeping active compute identical to the dense baseline
[!NOTE]
This is an experimental proof-of-concept release aimed at validating the MoE injection and routing mechanism. A future release will train on a significantly larger and more diverse dataset using a larger base model.
Overview
Keiro retrofits a Sparse Mixture-of-Experts architecture into Qwen2.5-3B. Every transformer block's MLP is replaced by a SparseMoELayer: at each token, a LinearRouter scores all 8 experts and selects the top-2 by softmax probability. Expert outputs are LoRA residuals applied on top of the frozen base Qwen2MLP, preserving dense representations while allowing experts to learn specialised corrections.
Switch loss combined with additive noise encourages uniform expert utilisation and prevents router collapse.
The −0.13% and −0.17% deltas on HellaSwag and ARC-Challenge confirm the router did not trigger catastrophic forgetting on linguistic or factual reasoning pathways.
The 3.19% drop on GSM8K — retaining 95.4% of math reasoning capability — is the primary validation of the architecture: a dynamic routing mechanism can be retrofitted into a dense transformer without breaking multi-step autoregressive reasoning chains.
Summary metric
Value
Trainable parameters
19.46 M (0.63% of total)
Avg. knowledge delta (HellaSwag + ARC)
−0.15%
Math reasoning retained (GSM8K)
95.4%
Architecture Deep Dive
Dual-Dispatch System
The SparseMoELayer uses two distinct forward paths optimised for different regimes:
Path
When
Strategy
_forward_padded_loop
Inside torch.compile
Compile-friendly padded loop over experts with capacity buffers. Compatible with torch.compile static graph tracing.
_forward_dynamic
Eager mode (default)
Vectorised scatter/gather using torch.bmm on only the active expert subset. Bypasses capacity buffers entirely.
The runtime dispatch is automatic — _batched_sparse_forward checks torch.compiler.is_compiling() and routes accordingly. During normal model.generate() (eager mode), the fast dynamic path is always used.
Single-Token Fast Path
The dynamic path was engineered specifically to solve the kernel launch bottleneck observed during autoregressive generation:
Problem: The original vectorised path built a (num_experts, capacity, d_model) buffer and ran torch.bmm across all 8 experts. For a single token with top-2 routing, 6 of 8 expert slots were zero-filled — wasting 75% of compute on no-op matrix multiplications.
Solution: Use torch.unique to identify only the 2 active experts, gather their specific lora_A and lora_B weight slices, and run a targeted torch.bmm on a (2, 1, d_model) tensor.
Result: CUDA kernel launches per layer dropped from ~12 to ~3. GPU utilisation during generation improved from 34% to 72%+.
Expert Architecture
BatchedLoRAExperts stores all expert weights in stacked tensors lora_A: (num_experts, rank, d_model) and lora_B: (num_experts, d_model, rank), enabling batched matrix multiplications instead of sequential expert loops. The LoRA residual is added on top of the frozen Qwen2MLP output:
[!WARNING]
Keiro uses a custom routing architecture. Architecture source files must be downloaded alongside the weights before the model can be loaded. Do not attempt to load this model using a standard AutoModelForCausalLM.from_pretrained() call directly against the repo.
Keiro was trained on a small mixed dataset of approximately 500 samples spanning multiple domains, assembled from three sources.
Source
Content
WikiText
Sampled factual and encyclopedic prose
Alpaca-LoRA
Instruction-following and reasoning pairs
Synthetic data
Custom-generated domain-diverse examples
Hardware Requirements
Configuration
Minimum VRAM
BF16 inference (recommended)
8 GB
FP32 inference
16 GB
Fine-tuning (batch=16, gradient checkpointing)
24 GB
Limitations & Known Issues
Repetition collapse under greedy decoding: Without repetition_penalty, the MoE model occasionally enters repetition loops on open-ended generation tasks. Use repetition_penalty=1.1 to mitigate this. (Expect a decreased capability in math, reasoning and logic.)
Expert load imbalance in early layers: Layers 0–5 exhibit mild expert collapse where 2–3 experts handle the majority of tokens. This is a known pathology — early transformer layers have less differentiated hidden states for the router to distinguish. Increasing aux_loss_weight from 0.05 → 0.10 and training on larger datasets reduces this effect.
Inference overhead vs dense: Sparse routing adds per-token overhead from router scoring and expert dispatch. The dual-dispatch system minimises this, but MoE inference will always be moderately slower than a pure dense forward pass of equivalent active parameters.
Small training dataset: This release was trained on ~500 samples/domain as a proof-of-concept. I am working on a new release with 10k+ samples and multi-epoch training that would yield stronger domain specialisation. I will release it in future versions.
If you encounter any inconsistencies, technical errors, or issues, please feel free to open a Pull Request or an Issue. Feedback and improvements are welcome!
Citation
bibtex
1@misc{keiro2026,
2 author = {Muskula Rahul},
3 title = {Keiro: Custom Sparse Mixture-of-Experts Injection into Qwen2.5-3B},
4 year = {2026},
5 publisher = {Hugging Face},
6 howpublished = {\url{https://huggingface.co/iamrahulreddy/Keiro}}
7}