(ch01-target-readers)= # 第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)」を手元に用意するところから始めます。