Skip to content

필사 모드: config.json 完全解剖 — 設定ファイル一枚でモデル構造を読む

日本語
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

はじめに

オープンソースのモデルをダウンロードすると、重みファイルの隣には必ず config.json があります。二十行ほどのこのファイルに、モデルの骨格がほぼすべて入っています。層がいくつか、アテンションヘッドがいくつか、なぜこのモデルは KV キャッシュが小さいのか、すべてここで決まります。

このシリーズは「このモデルが何点を取ったか」ではなく「このモデルがどう作られ、なぜそう作ったか」を扱います。最初の記事の目標は一つです。読み終えたら、初めて見る config.json を開いて構造を読み取れるようになることです。

数値は 2026-08-12 に論文・公式レポート・config.json で直接確認しました。モデルは更新されるため、原典を再度確認してください。

まずは実物を見る

Qwen3-8B の設定ファイルです。以下の値はすべて公開リポジトリからそのまま取得したものです。

{
  "hidden_size": 4096,
  "num_hidden_layers": 36,
  "num_attention_heads": 32,
  "num_key_value_heads": 8,
  "head_dim": 128,
  "intermediate_size": 12288,
  "rope_theta": 1000000,
  "vocab_size": 151936,
  "tie_word_embeddings": false,
  "max_position_embeddings": 40960,
  "rms_norm_eps": 1e-06,
  "hidden_act": "silu"
}

出典は https://huggingface.co/Qwen/Qwen3-8B/raw/main/config.json です。

幅と深さ

hidden_size はモデルの幅です。トークンが層のあいだを通るときに運ばれるベクトルの長さであり、ほぼすべての重み行列の一辺をなします。num_hidden_layers は深さです。この二つの値がパラメータ数の大部分を決めます。

幅を大きくすると行列積が大きくなり GPU をよく埋められますが、パラメータは幅の二乗に比例して増えます。深さを増やすとパラメータは線形にしか増えませんが、層を順に通過する必要があるため遅延が伸び、パイプライン並列の段数も増えます。同じ規模を幅で作るか深さで作るかは、学習の安定性と想定する配信形態を合わせて決める問題です。

二種類のアテンションヘッド

ここが初見の人が最もつまずく箇所です。num_attention_heads はクエリヘッド数、num_key_value_heads はキー・値ヘッド数です。両者が等しければ MHA、キー・値ヘッドが 1 なら MQA、その中間が GQA です。

Qwen3-8B は 32 と 8 なので、クエリヘッド四つがキー・値ヘッド一つを共有します。この比がそのまま KV キャッシュの大きさを決めます。トークン一つが占める KV キャッシュの要素数は次のように計算します。

KV 要素/トークン = 2 x num_hidden_layers x num_key_value_heads x head_dim
                 = 2 x 36 x 8 x 128
                 = 73,728

同じモデルを MHA で作った場合 (キー/値ヘッド 32 個)
                 = 2 x 36 x 32 x 128 = 294,912   ->  4 倍

fp16 では要素あたり 2 バイトなので、32,768 トークンをキャッシュすると 4.50 GiB です。MHA なら 18.00 GiB です。この節約は無料ではありません。キー・値ヘッドを減らすと表現力が落ちます。GQA 論文はこの手法を MQA と MHA のあいだの補間と位置づけ、既存のチェックポイントを GQA に変換するには元の事前学習計算量の 5 パーセントに相当する追加学習が必要だと報告しています(Ainslie et al., arXiv:2305.13245)。

head_dim はヘッド一つの次元です。以前のモデルは hidden_size をヘッド数で割った値が暗黙にヘッド次元でしたが、最近は config に明示的に書かれます。Qwen3-8B は 32 かける 128 が 4096 で幅と一致しますが、必ず一致する必要はありません。

FFN のサイズと活性化関数

intermediate_size は FFN の内部次元です。Qwen3-8B は 4096 から 12288 に広げて戻します。hidden_actsilu なのは SwiGLU 系を使うという意味で、この構造はゲート・アップ・ダウンの三つの行列を使います。したがって FFN のパラメータは二倍ではなく三倍で数えます。ここを見落とすとパラメータ計算は決して合いません。

語彙サイズと埋め込みの共有

vocab_size は埋め込み行列の行数です。注意点があります。Qwen3 の config は 151936 ですが、Qwen3 技術レポートはトークナイザの語彙サイズを 151,669 と記しています(arXiv:2505.09388)。実際にトークナイザファイルを取得して確認しても 151,669 でした。差は、埋め込み行列をハードウェアに合うサイズへ切り上げた余白です。つまり vocab_size はトークナイザの語彙数ではなく埋め込み行列の大きさです。

tie_word_embeddings は入力埋め込みと出力層の重みを共有するかを決めます。Qwen3 レポートの表 1 を見ると、0.6B、1.7B、4B は共有し、8B、14B、32B は共有しません。小さいモデルほど埋め込みが全体に占める割合が大きく、共有の利得が大きいためです。Qwen3-8B では埋め込み行列一つが 151936 かける 4096、約 6.2 億パラメータです。

手でパラメータを数える

では上の値だけで全パラメータ数を数えてみます。

埋め込み    : 151,936 x 4,096                      =   622,329,856
出力層      : 共有しないので同じ大きさ             =   622,329,856

層 1 つ:
  q_proj    : 4,096 x (32 x 128)                   =    16,777,216
  k_proj    : 4,096 x ( 8 x 128)                   =     4,194,304
  v_proj    : 4,096 x ( 8 x 128)                   =     4,194,304
  o_proj    : (32 x 128) x 4,096                   =    16,777,216
  q_norm, k_norm : 128 x 2                         =           256
  FFN (ゲート/アップ/ダウン) : 3 x 4,096 x 12,288  =   150,994,944
  RMSNorm 2 つ : 4,096 x 2                         =         8,192
  小計                                             =   192,946,432

36 層       : 192,946,432 x 36                     = 6,946,071,552
最終 norm   : 4,096                                =         4,096

合計        = 6,946,071,552 + 622,329,856 x 2 + 4,096
            = 8,190,735,360

Hugging Face が safetensors メタデータで報告する Qwen3-8B のパラメータ数は 8,190,735,360 です。一つも違わず一致します。同じやり方で Mixtral-8x7B を数えると 46,702,792,704 になり、公開値と正確に一致します。この計算が合えば config を正しく読めたということです。

rope_theta と文脈長

rope_theta は回転位置埋め込みの基準周波数です。値が大きいほど位置信号がゆっくり回転し、長い文脈に有利です。Llama 3 は 500,000 を使います(arXiv:2407.21783, 表 3)。Qwen3 と Mixtral は 1,000,000 です。

max_position_embeddings は学習された位置の範囲です。ここに罠があります。Qwen3-8B の config は 40960 なのに、技術レポートの表 1 は文脈長を 128K と記しています。レポートを読むと、長文脈の事前学習は 32,768 で行い、推論時に YaRN と DCA で四倍を確保するとあります。つまり 128K は学習された長さではなく、拡張手法を有効にしたときの値です。config の数字と宣伝文句が食い違うときは、たいていこれが理由です。

おわりに

config.json はモデルの要約です。幅と深さがパラメータを決め、クエリヘッドとキー・値ヘッドの比が KV キャッシュを決め、tie_word_embeddings が小さなモデルの階級を決め、rope_thetamax_position_embeddings が文脈長の実体を教えてくれます。パラメータ数を手で数えて公開値と突き合わせる習慣をつければ、どのモデルに出会っても構造を読めるようになります。

参考資料

試してみる

シリーズ

현재 단락 (1/63)

オープンソースのモデルをダウンロードすると、重みファイルの隣には必ず `config.json` があります。二十行ほどのこのファイルに、モデルの骨格がほぼすべて入っています。層がいくつか、アテンショ...

작성 글자: 0원문 글자: 4,283작성 단락: 0/63