| """Model configuration for the tiny DeepSeek-V3-style transformer.
|
|
|
| DeepSeek-V3's two signature ideas (vs the dense Qwen3 baseline):
|
|
|
| * MLA (Multi-head Latent Attention): keys and values are not projected
|
| directly from the hidden state. Instead the hidden state is compressed
|
| into one small "KV latent" per token, and K/V are re-expanded from it.
|
| The tiny latent is all you would ever cache — that is the whole point.
|
| RoPE gets its own small "decoupled" dimensions, shared across heads.
|
|
|
| * MoE (Mixture of Experts): instead of one big MLP per block, many small
|
| expert MLPs — each token is routed to only `top_k` of them, plus one
|
| always-on shared expert. Load is balanced *aux-loss-free* with a per-expert
|
| bias that is nudged up/down depending on how busy the expert was.
|
| """
|
|
|
| from dataclasses import dataclass
|
|
|
|
|
| @dataclass
|
| class ModelConfig:
|
| vocab_size: int = 30
|
| hidden_size: int = 32
|
| num_layers: int = 3
|
| num_heads: int = 4
|
| max_seq_len: int = 32
|
| rope_theta: float = 10000.0
|
| rms_norm_eps: float = 1e-6
|
|
|
|
|
| q_lora_rank: int = 16
|
| kv_lora_rank: int = 8
|
| qk_nope_head_dim: int = 8
|
| qk_rope_head_dim: int = 4
|
| v_head_dim: int = 8
|
|
|
|
|
| first_dense_layers: int = 1
|
| n_routed_experts: int = 4
|
| n_shared_experts: int = 1
|
| top_k: int = 2
|
| moe_intermediate_size: int = 32
|
| intermediate_size: int = 64
|
| bias_update_speed: float = 1e-3
|
|
|