LLMのモデル実装

Definition:model implementation

LLMにおけるモデル実装とは、特定のニューラルネットワーク・アーキテクチャが定める計算処理を、Python、PyTorch、CUDAなどのソフトウェアによって実際に実行できる形に記述したプログラム上の実装である。
より厳密には、モデル実装とは、入力されたトークン列を受け取り、Embedding、Attention、位置エンコーディング、正規化、MLP、残差接続、出力層など、モデル・アーキテクチャを構成する各演算を所定の順序・方式で実行し、最終的に次のトークンの確率分布を生成するための計算グラフをソフトウェアとして定義したものである。

モデル実装は単なる「モデルの設定値」ではない。また、学習済みの重みそのものでもない。モデルが何をどのように計算するのかをプログラムとして定義するものがモデル実装である。

モデル実装とモデル設定の違い

モデル実装を理解するには、モデル設定(model configuration)との違いを明確にする必要がある。両者は密接に関係しているが、役割は異なる。

モデル実装は「どのような計算をするか」を定義するものである。例えばAttentionについて、Query、Key、Valueをどのように生成するか、Attention scoreをどのように計算するか、どのような位置情報を付加するか、複数のAttention headをどのように処理するか、といった計算方法をプログラムとして記述する。

これに対してモデル設定は、「その実装を具体的にどのような規模・構成で動かすか」を指定するものである。例えば隠れ状態の次元数、Transformer層の数、Attention headの数、Key/Value headの数、MLPの中間次元、語彙数、最大コンテキスト長などがこれに該当する。

概念的には、モデル実装=計算方法、モデル設定=計算方法に与える構造・規模のパラメータと考えるとよい。

モデル実装を構成するもの

LLMのモデル実装は通常、一つの巨大な処理ではなく、複数のコンポーネントから構成される。典型的なTransformer系LLMであれば、Embedding、Transformer Block、Attention、位置エンコーディング、MLP、Normalization、Residual Connection、LM Headなどが実装される。

まずEmbeddingは、入力されたトークンIDをニューラルネットワークが扱うベクトルに変換する処理である。例えば語彙表の中の「猫」というトークンがある場合、そのトークンIDを対応する高次元ベクトルへ変換する。

次にAttentionがある。これはLLMの中心的な計算の一つであり、入力された各トークンが他のどのトークンをどの程度参照するかを計算する。一般的なTransformerではQuery、Key、Valueを生成し、それらを用いてAttentionを計算する。

ただし、ここにはモデルごとの違いが現れる。Multi-Head Attention、Grouped-Query Attention、Multi-Query Attention、あるいはMulti-head Latent AttentionやGated DeltaNetのような線形Attentionなど、Attentionの構造が異なれば、その計算を実装するプログラムも異なる。

位置エンコーディングもモデル実装の重要な部分である。例えばRoPE(Rotary Position Embedding)を使用するモデルでは、QueryとKeyに対して位置に応じた回転操作を行う処理が実装される。一方、別の位置表現方式を採用するモデルであれば、その方式に対応した別の処理が必要になる。

MLP(Multi-Layer Perceptron)は、Attentionによって処理された表現をさらに変換する部分である。単純なFFNだけでなく、Gated Linear Unit系の構造やSwiGLUなどを採用するモデルでは、その構造に対応した計算が実装される。MoEを採用するモデルでは、このMLP部分がRouterと複数のExpertから構成される別の実装に置き換わる点も付け加えておく必要がある。

Normalizationもモデル実装の一部である。LayerNormを使用するのか、RMSNormを使用するのかに加え、どの位置にNormalizationを配置するのかによっても計算グラフは変化する。オリジナルのTransformerはAttentionやMLPの出力後にNormalizationを適用するPost-LN構造であったが、現在の多くのLLMは、学習の安定性が高いPre-LN構造(Attentionやmlpの入力側にNormalizationを適用する構造)を採用している。さらにQwen3など一部のモデルでは、QueryとKeyそれぞれに対してRMSNormを適用するQK-Normと呼ばれる仕組みも導入されており、これも実装上の差異として現れる。

さらに、これらを一つのTransformer層として組み合わせるTransformer Blockが実装される。そしてTransformer Blockを設定された層数だけ積み重ね、最終的な隠れ状態を生成する。

最後にLM Headによって隠れ状態を語彙サイズのlogitsへ変換する。これにSoftmaxを適用すれば、次に生成されるトークンの確率分布を得ることができる。

モデル実装は「計算グラフ」の定義である

モデル実装を最も本質的に捉えるならば、これはモデルの計算グラフをソフトウェアとして定義したものである。

例えば概念的なTransformerでは、入力トークンがEmbeddingを通り、Transformer Blockに入り、そこでNormalization、Attention、Residual Connection、Normalization、MLP、Residual Connectionなどの処理を受け、複数のBlockを通過した後にLM Headへ送られる。

したがって、モデル実装には単に「Attentionという機能が存在する」という情報だけではなく、どのテンソルを入力し、どの演算を行い、どのテンソルを次の処理へ渡すかという具体的な計算手順が含まれている。

このため、同じ「Transformer」という大きなカテゴリーに属していても、内部の構造が異なれば、それぞれに対応するモデル実装が必要になる場合がある。

具体的にはどのようなプログラムなのか

例えばPyTorchを使ってLLMを実装する場合、概念的には次のようなクラス構造になる。

この構造をPythonやPyTorchのクラスとして記述したものが、モデル実装の典型的な形である。

実際の実装では、例えばAttentionを担当するクラス、Transformer Blockを担当するクラス、モデル全体を担当するクラスなどに分割される。そしてモデル全体のforward処理によって、それらが適切な順序で呼び出される。

モデル実装と学習済み重みは別物である

ここはLLMを理解するうえで特に重要である。モデル実装とモデルの重みは別物である。

モデル実装は「計算方法」を定義する。例えば「入力ベクトルにこの行列を掛け、その結果にこの活性化関数を適用し、Attentionを計算する」といった処理を定義する。

一方、学習済み重みは、その計算に使用される具体的な数値である。例えばLinear層の重み行列やEmbedding行列などの巨大な数値配列がこれに該当する。

したがって、概念的には、モデル実装=計算機、モデル設定=計算機の構成指定、学習済み重み=計算機にセットされる具体的な数値という関係に近い。

そのため、同じモデル実装と同じモデル設定を使っても、異なる学習済み重みを読み込めば異なるモデルとして動作することがある。

Hugging Faceにおけるモデル実装

この区別は、Hugging Face Transformersを考えると非常に分かりやすい。一般にモデルのリポジトリには、モデルの設定情報、学習済み重み、トークナイザー関連ファイルなどが含まれている。

例えば設定を記述するconfig.jsonはモデル設定に相当する。一方、モデルの計算処理を記述するPythonコード、例えば特定モデル用のmodelingコードはモデル実装に相当する。そしてsafetensorsなどに保存された巨大なテンソル群が学習済み重みである。

両者を結びつけているのがconfig.json内のmodel_typearchitecturesというフィールドである。AutoModelなどのAuto classは、これらのフィールドを読み取ることで、どのmodelingコード(クラス)を呼び出すべきかを判断する。つまりconfig.jsonは単に規模のパラメータを持つだけでなく、「どの実装に対応する設定なのか」を紐づける役割も担っている。

なお、Transformersライブラリ本体にまだ実装が取り込まれていない新しいアーキテクチャについては、モデル配布元がリポジトリ内に独自のmodelingコードを同梱し、利用者がtrust_remote_code=Trueを指定して読み込む仕組みも用意されている。これは、新しい計算構造にはライブラリ側の対応を待たずとも独自の実装を配布できることを示す一例である。

したがって、ローカルでLLMを動かす際にダウンロードしているものを単純化すると、「プログラム」「設定」「重み」「トークナイザー等の付属データ」という複数の要素に分けて考えることができる。

なぜ新しいモデルには新しい実装が必要なのか

ここから、LLM推論エンジンの「モデル対応」という問題につながる。新しいモデルが登場した場合、そのモデルが既存モデルと同じ計算構造を持っているのであれば、既存の実装を流用できる場合がある。

しかし、新しいAttention方式、新しい位置エンコーディング、新しいNormalization、新しいMLP構造、新しいMoE構造などを導入した場合、既存の実装だけではその計算を正しく実行できない可能性がある。

この場合、単にconfig.jsonに新しい設定値を追加すれば済むわけではない。設定ファイルは「何層あるか」「何次元か」といったパラメータを指定できても、新しい演算そのもののアルゴリズムを定義するものではないからである。

したがって、新しいアーキテクチャに対応するためには、その計算を実行するモデル実装を追加する必要がある。さらに、重みの配置方法や形状が従来と異なれば、重みの読み込み処理についても対応が必要になる。

モデル実装と推論エンジン

さらに注意すべきなのは、「モデル実装」と「推論エンジン」も同じものではないという点である。

モデル実装はモデルの計算構造を定義する。一方、推論エンジンは、その計算をGPUなどのハードウェア上で効率的に実行するための仕組みである。メモリ管理、バッチ処理、KV Cache、CUDA Kernel、Tensor Parallelismなどは、後者の領域に大きく関係する。

実際には両者の境界は完全に固定されているわけではない。例えば推論エンジン側がAttentionの独自実装を持つ場合、そのモデル固有のAttentionと推論エンジンの高速Attention Kernelを適切に対応させる必要がある。また、vLLMやSGLang、TensorRT-LLMといった推論エンジンは、Hugging Face Transformersのmodelingコードとは別に、それぞれ独自に最適化されたモデル実装を保持しており、新しいアーキテクチャが登場するたびに、この推論エンジン側の実装も個別に追加される。

この点を示す具体例として、2025年にDeepSeekが発表したDSA(DeepSeek Sparse Attention)付きのDeepSeek V3.2では、SGLangが公開直後にこれへ対応する際、Lightning Indexerによるトークン選択を扱う専用のAttention Backend(NativeSparseAttnBackend)を新たに実装している。同様にQwen3-NextのようなGated DeltaNetとAttentionを混在させるハイブリッドモデルでは、vLLMが線形Attention層と通常のAttention層で異なるKVキャッシュの持ち方を扱うための専用のハイブリッドKVキャッシュ管理機構と、Gated DeltaNet用のTritonカーネルを新たに実装している。いずれの場合も、モデルの計算構造そのものが従来と異なるため、推論エンジン側に新しいモデル実装を追加しない限り、そのモデルを正しく、かつ効率的に動かすことができないのである。

したがって、現代のLLM実行環境では、単純に「Pythonでモデルを書けば動く」というものではない。モデル実装、モデル設定、重みフォーマット、トークナイザー、推論エンジン、GPU Kernelなどが連携して初めて実用的なLLM推論が成立するのである。

モデル実装を一言で定義すると

以上をまとめると、モデル実装とは「特定のモデル・アーキテクチャが規定するニューラルネットワークの計算構造を、実際にテンソル演算として実行可能なソフトウェアとして記述したもの」である。

そして、モデル設定はその実装に対して具体的な構造・規模を与え、学習済み重みはその計算に使用する学習済みの数値を与える。この三者を区別すると、LLMの構造は次のように整理できる。

つまり、モデル実装の本質は「モデルそのものの数値」ではなく、「その数値をどのような計算規則で処理するかを定義するプログラム」にある。この点を押さえると、「モデルをダウンロードする」とは何を意味するのか、また「推論エンジンが新しいモデルに対応する」とは何を意味するのかを、かなり正確に理解できる。

Mathematics is the language with which God has written the universe.





















データ基盤におけるデカップリング LLMのアーキテクチャの歴史 データベース・ディスアグリゲーション モダン・データスタック ソフトなディクショナリ コンテキスト長