
第2部 モデルとは何か第2章
モデル・重み・トークナイザ
「モデルをダウンロードした」とき、手元に来たのは何でしょう? 中身は重みという数値の山と、設定ファイルと、文字を数字に変えるトークナイザです。
このページの内容(9項目)
「モデルをダウンロードしました」。で、何が届いたの?
Hugging Faceで公開されている小さなモデル Qwen/Qwen3.5-0.8B のページを開くと、並んでいるのは十数個のファイルです。いちばん大きいのは約1.75GBの .safetensors ファイル。残りは config.json、tokenizer.json、chat_template.jinja といった、数KB〜十数MBの小さなファイルです2026年10月時点。
この「大きな1つ+小さないくつか」という組み合わせこそが、LLMの「モデル」の正体です。この章では、それぞれのファイルが何の役をしているのかを順番に開けていきます。
「モデル」は3つの部品でできている
ひとことで言うと
モデル = 重み(学習で決まった数値の山)+ 設定(計算の形を決める設計図)+ トークナイザ(文字と数字の翻訳係)。どれか1つ欠けても動きません。
LLMは、入力された文章の「次に来そうな言葉」を確率として計算するプログラムです。その計算には、膨大な数の数値(重み)と、それをどう組み合わせるかの手順(アーキテクチャ)が必要です。さらに、コンピュータは文字をそのまま計算できないので、文字と数字を相互に変換する係(トークナイザ)もいります。
料理にたとえると、アーキテクチャは「レシピの手順」、重みは「長年の修業で身についた塩加減や火加減の感覚」、トークナイザは「食材を決まった大きさに切りそろえる下ごしらえ係」です。同じレシピでも、感覚(重み)が違えばまったく別の味になります。
flowchart TD A["入力テキスト"] --> B["トークナイザ
文字 → トークンID"] B --> C["モデル本体
アーキテクチャ + 重み"] C --> D["次のトークンの確率"] D --> E["サンプリング
1つ選ぶ"] E --> F["トークナイザ
トークンID → 文字"] F --> G["出力テキスト"]
重み(パラメータ)は「学習で決まった数値の山」
重み(weights)とは、ニューラルネットワークの中で入力に掛け算される数値のことです。LLMの文脈では「パラメータ」とほぼ同じ意味で使われます。「8Bモデル」の「8B」は、この数値がおよそ80億(8 billion)個あるという意味です。
重みは人間が書いたものではありません。大量の文章を読ませて「次の単語当て」を繰り返すうちに、少しずつ調整されて決まった値です。だから重みを見ても「この数字は文法の知識」といった読み方は基本的にできません。知識や癖は、何十億もの数値の組み合わせの中に溶け込んでいます。
テンソル(tensor) てんそる
重みを格納する多次元の数値の配列。行列(2次元)を一般化したものです。モデルファイルの中身は「名前の付いたテンソルの集まり」と考えてかまいません。
重みの大きさはこう見積もる
ファイルサイズは「パラメータ数 × 1個あたりのバイト数」でほぼ決まります。学習済みモデルはBF16(1個2バイト)で配布されることが多く、その場合は次のとおりです。
| パラメータ数 | BF16(2バイト) | 4bit量子化(約0.5〜0.6バイト) |
|---|---|---|
| 約8.7億(Qwen3.5-0.8B) | 約1.75GB | 約0.5GB |
| 80億(8B) | 約16GB | 約5GB |
| 700億(70B) | 約140GB | 約43GB |
Qwen3.5-0.8Bは、Hugging Faceの表示で873,438,784個のパラメータ(ほぼすべてBF16)を持ち、ファイルは約1.75GBです。計算どおりですね。数字をさらに小さくする「量子化」は第10章で、4bit版の具体的なサイズは第5章で扱います。
もう一歩深く
MoE(Mixture of Experts)モデルでは「総パラメータ数」と「1トークンあたりに実際に使うパラメータ数」が違います。名前に 35B-A3B のように書かれていたら「総数350億、うち稼働30億」という意味です。くわしくは第26章へ。
設定ファイル:重みをどう並べて計算するかの設計図
重みの数値だけがあっても、どの順番で、どの形の計算に使うのかが分からなければ動きません。それを記したのが config.json です。中には層の数、隠れ次元(hidden size)、アテンションのヘッド数、語彙の大きさ、扱える最大の長さなどが書かれています。
たとえば Qwen/Qwen3.5-0.8B の config.json には、次のような値があります(一部を抜粋)。
"model_type": "qwen3_5_text",
"hidden_size": 1024,
"num_hidden_layers": 24,
"num_attention_heads": 8,
"num_key_value_heads": 2,
"vocab_size": 248320,
"max_position_embeddings": 262144,
"dtype": "bfloat16"
「24層を積み重ねた、幅1024の計算で、語彙は約25万種類」と読めます。推論ソフトはまず model_type を見て「このアーキテクチャの計算手順を使おう」と決め、残りの数字で形を整えてから重みを流し込みます。新しいモデルが出たときに「まだ対応していない」と言われるのは、この計算手順がソフト側に実装されていないからです。
よく一緒に置かれているファイルも覚えておくと便利です。
generation_config.json— 推奨される生成時の設定(温度、top-p、終了トークンなど)。たとえばgoogle/gemma-4-E2B-itでは temperature 1.0、top_k 64、top_p 0.95 が書かれています。model.safetensors.index.json— 重みが複数ファイルに分かれているとき、どのテンソルがどのファイルにあるかの目次。tokenizer.json/tokenizer_config.json— 次の節で説明するトークナイザの中身と設定。chat_template.jinja— 会話をモデルが読める文字列に組み立てるテンプレート(後述)。
トークナイザ:文字を数字に変える翻訳係
ひとことで言うと
トークナイザは、文章を「トークン」という小さな単位に切り分けて、それぞれに番号(トークンID)を振る係。モデルが見ているのは文字ではなく、この番号の列です。
トークンは「単語」とも「文字」とも限りません。英語ならよく出る単語は1トークン、珍しい単語は数個に分割されます。日本語では1〜数文字が1トークンになることが多いですが、モデルの語彙によって大きく変わります。
多くのLLMはBPE(Byte Pair Encoding)という方法で語彙を作っています。最初は1文字(または1バイト)ずつに分けておき、学習データの中で「よく隣り合うペア」を見つけてはくっつけて新しいトークンにする、という作業を何万回も繰り返します。下のおもちゃで、その「くっつけていく」様子を試してみてください。
語彙の大きさはモデルごとに違います。GPT-2は50,257、Llama 3.1は128,256、Qwen3.5は248,320(いずれも config.json の vocab_size。パディングを含む場合があります)。語彙が大きいほど、日本語のような多言語の文章を少ないトークン数で表せる傾向があります。トークン数は料金や文脈の長さの上限に直結するので、「同じ文章でもモデルによってトークン数が違う」ことは覚えておきましょう。
注意
トークナイザは重みとセットです。トークンIDの「5番」が何を意味するかはモデルごとに違うので、別のモデルのトークナイザを組み合わせると、意味の通らない出力になります。
特殊トークン
語彙の中には、文章の区切りや役割を示す特殊トークン(special tokens)もあります。Qwen3.5の tokenizer_config.json には、<|endoftext|>、<|im_start|>、<|im_end|> などが登録されています。モデルは「終わり」を意味するトークン(EOS)を出力すると、そこで生成をやめます。
チャットテンプレート:会話を1本の文字列にする
ChatGPTのような画面では「システム」「ユーザー」「アシスタント」と発言が分かれて見えます。でもモデルが受け取るのは、あくまで1本のトークン列です。会話の配列を、そのモデルが学習時に見た書式どおりの文字列に組み立てるのがチャットテンプレート(chat template)です。
Qwen3.5のテンプレートを通すと、会話はおおよそ次の形になります。
<|im_start|>system
あなたは親切なアシスタントです。<|im_end|>
<|im_start|>user
富士山の高さは?<|im_end|>
<|im_start|>assistant
最後の assistant の行で止めておくと、モデルは「ここからはアシスタントの発言だ」と理解して続きを書きます。書式はモデルごとに違い、同じベースモデルから作った派生モデル同士でも異なることがあります。テンプレートは Jinja という書式で書かれ、tokenizer_config.json や chat_template.jinja に入っています。GGUFファイルでは tokenizer.chat_template というメタデータとして埋め込まれます(第5章)。
ためしてみよう
Pythonの transformers では tokenizer.apply_chat_template(messages, tokenize=False) で、組み立て後の文字列を確認できます。「ローカルで動かしたら返答が変」というときは、まずテンプレートが正しく適用されているかを疑うのが近道です。
推論モデルではテンプレートがさらに仕事をします。Qwen3.5のテンプレートには enable_thinking という切り替えがあり、思考用の <think> ブロックを入れるかどうかを制御します(第27章)。
Base版とInstruct版:同じ脳、違うしつけ
モデルの名前には -Base、-Instruct、-it、-Chat などが付いていることがあります。これは学習のどの段階まで終えているかを示しています。
| 種類 | 何をしたモデルか | 得意なこと |
|---|---|---|
| Base(ベース) | 大量の文章で「次の単語当て」を学習しただけ(事前学習) | 文章の続きを書く。微調整の土台 |
| Instruct / it / Chat | Baseに指示追従や会話の追加学習(事後学習)をしたもの | 質問に答える、指示に従う |
Baseモデルに「富士山の高さは?」と聞くと、答えるかわりに「富士山の幅は? 富士山の…」と質問の続きを書き始めることがあります。Baseは「続きを書く」ことしか教わっていないからです。
名前の付け方はメーカーによって違うので注意しましょう2026年10月時点。
- Meta:
Llama-3.1-8B(Base)とLlama-3.1-8B-Instruct - Google:
gemma-4-E2B(Base)とgemma-4-E2B-it(instruction-tuned) - Qwen:
Qwen3.5-0.8B-Baseと、何も付かないQwen3.5-0.8B(こちらが事後学習済み)
Qwen3.5のように「何も付かない方が会話用」という命名もあるので、モデルカードで確認するのが確実です。事前学習や微調整の中身は第12章で扱います。
サンプリング:確率から1つを選ぶ
モデルが出すのは「次のトークンの確率の一覧」です。そこから実際に1つを選ぶ作業をサンプリング(sampling)といいます。いつも一番確率が高いものを選べば毎回同じ答えになり、確率に従ってくじ引きすれば変化のある文章になります。
- 温度(temperature)— 確率分布をとがらせたり平らにしたりするつまみ。低いほど堅実、高いほど冒険的。
- top-p — 確率の高い順に足していき、合計がpに達するまでの候補だけからくじを引く。
- top-k — 上位k個の候補だけからくじを引く。
推奨値はモデルごとに違います。Qwen3.5のモデルカードは、思考モードで temperature 0.6・top_p 0.95・top_k 20、非思考モードで temperature 0.7・top_p 0.8・top_k 20 という設定で評価したと書いています。迷ったら、モデルカードや generation_config.json の値から始めるのが無難です。
よくある誤解
モデルのファイルには、学習した文章がそのまま保存されている
保存されているのは数値(重み)だけ。文章の知識は数値の組み合わせとして間接的に表現されている(ただし学習データの一部をほぼそのまま再現してしまう「記憶」が起きることはある)
1トークン = 1単語(または1文字)
トークンの切り方はトークナイザ次第。同じ文章でもモデルによってトークン数は変わる
パラメータ数が多ければ、どんな用途でも賢い
学習データ、事後学習、アーキテクチャ、量子化の度合いで性能は大きく変わる。小さくても特定の用途で強いモデルは多い
確認クイズ
Q1. 「8Bモデル」の「8B」は何を表している?
パラメータ(重み)の数がおよそ80億個(8 billion)であることを表しています。BF16なら1個2バイトなので、重みだけで約16GBです。
Q3. Baseモデルに質問すると、答えずに質問の続きを書き出すことがあるのはなぜ?
Baseモデルは「文章の続きを書く」事前学習しかしていないからです。質問に答える振る舞いは、Instruct版で行う事後学習で身につけます。
Q4. チャットテンプレートは何をするもの?
「システム・ユーザー・アシスタント」に分かれた会話の配列を、そのモデルが学習時に見た書式の1本の文字列(特殊トークン付き)に組み立てるものです。
この章のまとめ
- モデルは「重み(数値の山)」「設定(config.json)」「トークナイザ」の3点セット。
- 重みのサイズは「パラメータ数 × 1個あたりのバイト数」で見積もれる。8BのBF16なら約16GB。
- モデルが見ているのは文字ではなくトークンIDの列。トークナイザは重みと必ずセット。
- チャットテンプレートが会話を1本の文字列にする。書式はモデルごとに違う。
- Baseは「続きを書く」、Instruct/itは「指示に従う」。命名はメーカーごとに違うのでモデルカードで確認。
さらに深く学ぶ
この章の内容をもう一歩掘り下げるための原典です。
- Neural Machine Translation of Rare Words with Subword UnitsBPE(バイト対符号化)を単語分割に使うことを提案した論文。いまのトークナイザの多くがこの考え方の子孫です。
- SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing空白で単語を区切らない日本語のような言語でも、生の文章から直接サブワード分割を学べるようにしたツールの論文。
- The Curious Case of Neural Text Degeneration確率最大の語を選び続けると文章が単調・反復的になる問題を分析し、top-p(nucleus)サンプリングを提案した論文。
出典・参考
- Qwen/Qwen3.5-0.8B(Hugging Face) — ファイル構成、config.json、tokenizer_config.json、chat_template.jinja、推奨サンプリング設定、パラメータ数(2026年10月確認)
- google/gemma-4-E2B-it(Hugging Face) — generation_config.json の値、Base版 google/gemma-4-E2B との命名(2026年10月確認)
- meta-llama/Llama-3.1-8B(Hugging Face) — Base/Instruct の命名(2026年10月確認)。語彙サイズ 128,256 は公開ミラー unsloth/Llama-3.1-8B-Instruct の config.json で確認
- openai-community/gpt2(Hugging Face) — config.json の vocab_size 50,257
- Chat templates(Transformers ドキュメント) — チャットテンプレートとBase/チャットモデルの関係(2026年10月確認)
- Summary of the tokenizers(Transformers ドキュメント) — BPEなどサブワード分割の解説