第1章 本書の対象読者とゴール
この章では、本書が誰のための本で、読み終えたときに何ができるようになり、そしてどんな順序と方針で読み進めるのかを示します。先に地図を渡しておくことで、以降の章で「いま全体のどこを読んでいるのか」を見失わないようにします。
最初に本書の全体像を一度だけ俯瞰し、そのうえで具体的な読み方に入ります。ここはまだ手を動かす前の準備段階です。気負わずに、本書の輪郭だけつかんでください。
1.1 本書が想定する読者
まず、本書がどんな読者を想定しているのかを、求める前提と求めない前提に分けて整理します。
求める前提は、ひとつだけです。C++ のコードが読めること。具体的には、struct やテンプレート、ポインタや参照が出てきても、構文に詰まらずに意味を追える、という程度を想定しています。すべてを暗記している必要はありません。出てきたときに「これは何をしているのか」を調べながら読めれば十分です。
一方で、次の知識は前提としません。
LLM 推論の内部構造(トークン生成や行列積がどう連なるか)
量子化(重みを小さなビット数で表す手法)の仕組み
SIMD 命令(NEON や AVX など、複数データを一度に処理する命令)の使い方
これらは本書の主題そのものなので、必要な概念は本文中でその都度、役割から順に積み上げていきます。いまは知らなくても問題ありません。
言い換えると、本書が想定するのは「言語としての C++ は分かるが、ik_llama.cpp のこのコードが何をしているのかは分からない」という出発点です。ここからカーネルを1行ずつ読めるところまで、一緒に歩いていきます。
ここで押さえたいのは、求められる前提は C++ の読解力だけで、量子化や SIMD の知識は本文で積み上げる、という点です。
1.2 本書のゴール
次に、本書を読み終えたときに何ができるようになるのかを、具体的なかたちで示します。ゴールが見えていると、各章が「何のための一歩なのか」を判断しやすくなります。
読み終えたとき、次のことができるようになることを目指します。
ik 独自のカーネル(本書では
iqk_*と総称します)を1本、入口から出口まで自力で読み解ける。本書の柱である load 層の3類型(float / LUT / trellis)の違いを、コードのどこがどう変わるかという観点で説明できる。
ある量子化型が、生成(decode)と一括処理(prefill)のどちらでどう選ばれるのか、ディスパッチの流れを追える。
ビルド・CPU 固定・演算のダンプ・速度計測といった観測を、自分の手元で再現できる。
ひとつ、スコープについて正直に書いておきます。本書のゴールは、ik_llama.cpp のすべてを網羅することではありません。狙いは、代表的なカーネルを深く読み切り、「ik のコードはこう読めばいい」という読み方を身につけてもらうことです。その読み方が手に入れば、本書が扱わなかった型やカーネルも、同じ要領で読み進められます。
ここで押さえたいのは、本書のゴールが「網羅」ではなく「核心を読み切り、読み方を身につける」ことだという点です。
1.3 本書の柱:変わるのは load 層だけ
ゴールに出てきた「load 層の3類型」は、本書全体を貫く一本の問いにつながっています。先に結論として、その柱を一段だけ具体的にしておきます。
量子化された重みを使った行列積は、煎じ詰めれば「重みを取り出し、入力と掛けて足す」という処理の繰り返しです。このうち「掛けて足す」ドット積のループは、量子化の型が違ってもほぼ共通です。型ごとに変わるのは、その手前の重みの入手方法、すなわち load 層だけ、というのが本書の見立てです。
3類型は、この load 層の違いとして整理できます。
float:値をそのまま読む(
vld1q_f16などで直接ロード)。LUT 量子化:表を1命令で引く(
vqtbl1q_s8によるテーブル参照)。trellis:値をその場で生成する(定数
ka=0xCBAC1FEDを種にした生成器)。
いまは、これらの命令名や定数を覚える必要はありません。「重みの入手方法が3通りある」という対比だけ頭の片隅に置いてください。この一文を意識しておくと、第III部でカーネルを読むときに、各章が柱のどこを担当しているのかが見えやすくなります。
ここで押さえたいのは、共通のドット積に対して、重みの入手方法(load 層)だけが型ごとに違う、という対比です。
1.4 3層読解の地図
ここからは、本書をどう歩くかの地図を示します。本書は、読者の学習順——まず動くのを見て、次に骨格をつかみ、最後に核心を逐行する——に沿って、4つの部で構成しています。
各部が、先ほどの柱とどう関係するのかも合わせて並べます。
部 |
何をするか |
柱との関係 |
章 |
|---|---|---|---|
第I部 観測 |
iqk カーネルが実際に動いているのを、ビルドと計測で確かめる |
カーネルを読む前の足場をつくる |
1〜3 |
第II部 骨格 |
ik が ggml のどこに割り込むのかを俯瞰する |
load 層へ降りる入口を特定する |
4〜5 |
第III部 ik 固有カーネル逐行 |
float / LUT / trellis のカーネルを1行ずつ読む |
柱そのもの。3類型を逐行で確かめる |
6〜11 |
第IV部 さらなる最適化 |
FlashAttention や MoE など、行列積の外側へ視野を広げる |
柱の応用範囲を見る |
12〜14 |
付録 |
上流 llama.cpp との diff/x86(AVX2・AVX512)経路を俯瞰する |
柱が fork 全体・別アーキでも保たれることを確認 |
A・B |
本書の中心は第III部です。第I部と第II部は、そこへ無理なくたどり着くための準備、第IV部はその先の展望、という位置づけになります。
ここで押さえたいのは、本書が「観測 → 骨格 → 逐行」という順序で進み、核心は第III部にある、という全体の構造です。
1.5 読み方の方針
最後に、本書を読み進めるうえでの方針を、いくつか先に共有しておきます。細かい約束事ですが、最初に知っておくと後が楽になります。
観測してから読む:いきなりソースを開くのではなく、まず手元で動かしてから対応するコードを読みます。手を動かせる環境があると、本書の効果はぐっと上がります。
コードは
3f40e73c基準・path:line表記:本文で引用するコードは、すべて解析対象コミット3f40e73cを基準とし、ファイル名と行番号をpath:lineの形で示します。手元のコードと照らし合わせるときは、このコミットに合わせてください。観測・ベンチは macOS / arm64・NEON 前提:本書の動作確認は Apple Silicon 上で行い、CPU 側のカーネルは NEON で動きます。x86(AVX2 / AVX512)の経路は、読解と図解だけ扱い、本機では実行しません。
観測は
-ngl 0で CPU に固定する:macOS では計算が GPU(Metal)に回ることがあります。CPU 側の iqk カーネルを観測したいときは-ngl 0を付けて計算を CPU に固定します。理由は第3章で詳しく扱います。
読む順番についても触れておきます。本書は前から順に読むことを基本に組んでいます。ただ、ビルドと骨格(第I部・第II部)に目を通したあとであれば、関心のある型のカーネル(第8〜10章)から先に読むこともできます。各章は節の頭で全体像を示し、節の終わりで要点を回収する作りなので、必要な部分だけをたどることもできます。
ここで押さえたいのは、本書は「観測してから読む」順序を基本とし、コードはすべて 3f40e73c 基準・観測は -ngl 0 で行う、という共通の約束です。
1.6 この章のまとめ
この章では、本書の対象読者とゴール、そして読み方の地図を示しました。ここで押さえたいのは、次の3点です。
想定読者は「C++ は読めるが LLM 推論は初学」。量子化や SIMD の知識は本文で積み上げる。
ゴールは網羅ではなく、核心のカーネルを読み切り、ik のコードの読み方を身につけること。
本書は「観測 → 骨格 → 逐行」の3層で読み進め(第I〜III部)、第IV部でその先の応用へ広げる。柱は「変わるのは load 層だけ」という対比にある。
次の章では、さっそく手を動かします。ik_llama.cpp をビルドし、iqk カーネルが有効になっていることを確かめ、最初の推論を動かして「正解(ground truth)」を手元に用意するところから始めます。