はじめに
前の記事では config.json から密なモデルのパラメータを数えました。ところが最近の大きなモデルの config を開くと、num_experts や n_routed_experts といった見慣れないフィールドが出てきます。専門家混合、すなわち MoE 層です。
考え方は単純です。層ごとに一つだった FFN を複数の小さな FFN に分割し、トークンごとにそのうち数個だけを実行します。この記事では、その「数個だけ」が config にどう書かれ、何を節約し何を節約しないのかを扱います。
数値は 2026-08-12 に論文・公式レポート・config.json で直接確認しました。モデルは更新されるため、原典を再度確認してください。
最も単純な形: Mixtral
Mixtral-8x7B の config から MoE 関連のフィールドだけを抜き出すとこうなります。
{
"num_local_experts": 8,
"num_experts_per_tok": 2,
"intermediate_size": 14336,
"router_aux_loss_coef": 0.02
}
専門家が 8 個あり、トークンごとに 2 個を使います。Mixtral 論文はこの構造について、全 470 億パラメータのうちトークンあたり 130 億のみを使用すると記しています(arXiv:2401.04088)。同じ論文は、ルーターが各層・各トークンごとに二つの専門家を選び、時点ごとに異なる専門家が選ばれうることも説明しています。
活性パラメータと全パラメータ
ここで最も重要な誤解を整理しておきます。活性パラメータで減るのは計算量であってメモリではありません。どの専門家が呼ばれるか分からない以上、すべてメモリに載っている必要があります。Mixtral 論文も、Mixtral を配信するメモリコストは希薄パラメータ数である 470 億に比例すると明示しています。
Qwen3-30B-A3B で直接計算してみます。config は hidden_size 2048、層 48 個、専門家 128 個、num_experts_per_tok 8、moe_intermediate_size 768 です。
専門家 1 つ (ゲート/アップ/ダウンの 3 行列)
= 3 x 2,048 x 768 = 4,718,592
層 1 つの専門家全体 : 128 x 4,718,592 = 603,979,776
層 1 つで実際に実行 : 8 x 4,718,592 = 37,748,736
全パラメータ (計算) = 30,532,122,624 -> 公開値と正確に一致
活性パラメータ (計算) = 3,353,032,704 -> 約 3.35B、名前の A3B と一致
比率 = 3.35B / 30.53B = 約 11%
計算は 11 パーセントしかしませんが、メモリは 100 パーセント必要です。MoE の本質はメモリを計算に変える取引ではなく、メモリを多く使う代わりに同じ計算量でより多くの知識を収める取引です。
共有専門家と密な初期層
DeepSeek-V3 は少し違う構造を使います。技術レポートのモデルハイパーパラメータ節によると、層は 61 個、各 MoE 層は共有専門家 1 個とルーティング専門家 256 個からなり、ルーティング専門家のうち 8 個がトークンごとに活性化します。専門家の内部次元は 2048 です。全 6710 億のうちトークンあたり 370 億が活性化します(arXiv:2412.19437)。
共有専門家は、ルーティングとは無関係にすべてのトークンが必ず通る専門家です。どのトークンにも必要な共通機能をそこに集めておけば、ルーティング専門家はより特化した役割を担えます。
もう一つ注目すべきフィールドが first_k_dense_replace です。DeepSeek-V3 はこの値が 3 で、レポートも最初の三層を除くすべての FFN を MoE 層に置き換えたと記しています。Kimi K2 は同じフィールドが 1 です。初期層はトークンごとの特化よりも一般的な表現を作る役割を担うため、密なままにしておくほうが安定するという判断です。
ロードバランシング: 二つの道
ルーターを放置すると、少数の専門家にトークンが集中します。残りの専門家は学習されず、並列化した装置のあいだで負荷が偏ります。対策は大きく二つに分かれます。
一つ目は補助損失です。負荷が均等になるよう損失項を追加します。config の router_aux_loss_coef がその係数で、Mixtral は 0.02、Qwen3 の MoE モデルは 0.001 です。Qwen3 レポートは、専門家の特化を促すために全体バッチ単位のロードバランシング損失を採用したと述べています(arXiv:2505.09388)。問題は、この損失が本来の目的関数と競合するため品質をわずかに削ることです。
二つ目は補助損失をまったく使わない方式です。DeepSeek-V3 は専門家ごとにバイアス項を持ち、上位 k 個を選ぶときにだけそのバイアスを加えます。レポートによれば、バイアスはルーティングにのみ使われ、各ステップの終わりに過負荷の専門家はバイアスを下げ、低負荷の専門家は上げます。バイアス更新速度は最初の 14.3 兆トークンでは 0.001、残る 5000 億トークンでは 0.0 に切り替わります。極端な偏りだけを防ぐシーケンス単位の均衡損失は係数 0.0001 と非常に小さく保たれます。
二つの方式の違いは明確です。補助損失は実装が単純ですが目的関数を汚し、バイアス方式は目的関数に触れない代わりに調整すべきハイパーパラメータと学習中のスケジュールが増えます。
希薄度をどこまで上げるか
Kimi K2 は専門家数を 384 個に増やしました。レポートの表 2 は DeepSeek-V3 と並べて比較しています。層数は 61 で同じ、全パラメータは 6710 億から 1.04 兆に増えた一方、活性パラメータは 370 億から 326 億へむしろ減りました。専門家は 256 個から 384 個に増え、トークンあたりの活性専門家は 8 個で同じです(arXiv:2507.20534)。
同じレポートは希薄度を全専門家数を活性専門家数で割った値と定義し、活性パラメータを固定したまま全専門家数を増やすと学習損失と検証損失がいずれも一貫して下がったと報告しています。検証損失 1.5 を基準に、希薄度 48 は希薄度 8、16、32 に対してそれぞれ 1.69 倍、1.39 倍、1.15 倍少ない計算量で同じ地点に到達したと記しています。
代償も同じ段落に書かれています。希薄度を上げるとインフラの複雑さが増すため、性能とコストの均衡点として 48 を選んだと述べています。専門家が増えるほど、装置間の all-to-all 通信量とバッチスケジューリングの難しさがともに上がります。
ルーティング範囲の制限
DeepSeek-V3 の config には n_group 8、topk_group 4 があります。専門家をグループにまとめ、トークン一つが到達できるグループ数を制限する仕組みです。レポートも、各トークンは最大 4 ノードにのみ送られることを保証すると記しています。通信コストに上限を設ける設計です。一方で Kimi K2 は表 2 で専門家のグループ化を使わないと明示しています。同じ問題を異なるインフラ前提の上で解いた結果です。
おわりに
MoE の config は四つだけ見れば足ります。専門家が何個か、トークンあたり何個使うか、共有専門家があるか、そして均衡を損失で取るかバイアスで取るかです。この四つの値から活性パラメータを計算でき、活性パラメータは計算コストを、全パラメータはメモリコストを教えてくれます。二つの数字を分けて読むことが MoE 理解の出発点です。
参考資料
- Mixtral of Experts (arXiv:2401.04088): https://arxiv.org/abs/2401.04088
- DeepSeek-V3 Technical Report (arXiv:2412.19437): https://arxiv.org/abs/2412.19437
- Qwen3 Technical Report (arXiv:2505.09388): https://arxiv.org/abs/2505.09388
- Kimi K2 (arXiv:2507.20534): https://arxiv.org/abs/2507.20534
- Qwen3-30B-A3B config.json: https://huggingface.co/Qwen/Qwen3-30B-A3B/raw/main/config.json
- DeepSeek-V3 config.json: https://huggingface.co/deepseek-ai/DeepSeek-V3/raw/main/config.json
試してみる
- ニューラルネットワークアーキテクチャ探索 — 層構成を変えて構造を眺めてみましょう。
- VRAM 計算機 — 全パラメータ基準でメモリを見積もってみましょう。
- AI ベンチマーク整理 — ベンチマーク数値を見るときにどんな条件が付くか確認してみましょう。
シリーズ
- 前の記事: config.json 完全解剖
- 次の記事: アテンションの変種 — MHA から MLA まで
현재 단락 (1/44)
前の記事では config.json から密なモデルのパラメータを数えました。ところが最近の大きなモデルの config を開くと、`num_experts` や `n_routed_experts`...