0. はじめる前に:何を作り、何を準備するのか¶
この章ではコマンドを一切実行しません。読み終えたときに、次の 4 つの問いに答えられるようになっているはずです:結局何を作るのか。全体はいくつのステップに分かれ、各ステップはどのマシンで行うのか。事前に何を準備する必要があるのか。各部品はどのように連携するのか。
0.1 ひとことで言うと:汎用モデルに「研修」を受けさせて専門サービスにする¶
まず、インターネットからオープンソースの汎用大規模モデル Qwen3-4B(約 40 億パラメータ、Alibaba の通義千問チームが公開)をダウンロードします。何についても会話できますが、話し方は私たちにはコントロールできません。回答が長すぎたり、小学生には難しい言葉を使ったり、やたらと質問を返してきたりするかもしれません。
次に、「子どもの質問 → 理想的な回答」という形の 600 本のお手本会話でこのモデルをファインチューニングし、決まった話し方を身につけさせます:まず答えを言う、短い文で話す、間違った予想にはまず訂正する、安全で小さな観察を 1 つ提案する。最後に、学習済みモデルを HTTP サービスとしてデプロイします。OpenAI API を呼び出せるバックエンドのコードなら、接続先のアドレスを変えるだけで使えます。
採用にたとえるとこうなります:
| 現実の採用 | このチュートリアルで対応するもの |
|---|---|
| 幅広い知識をもつ新入社員を採用する | オープンソースのベースモデル Qwen3-4B をダウンロードする |
| 「模範的な応対例」の束を見せて研修する | お手本会話で SFT ファインチューニングする |
| 研修内容は小さなノートに書き留めるだけで、もともとの知識は変わらない | LoRA:元のモデルには手を触れず、約 130 MB の差分だけを学習する |
| 研修が終わったら電話対応の現場に出す | vLLM でモデルを API としてデプロイする |
| 電話対応の品質を抜き打ちでチェックし、1 日に何件さばけるかを見る | 呼び出しテスト、ブラインド評価、負荷テスト |
いちばん大切な境界線: ファインチューニングで教えるのは「どう話すか」であって、「何を知っているか」ではありません。具体的な科学的事実は、呼び出し側がリクエストのたびにプロンプトに入れます(このプロジェクトでは「ファクトカード」と呼びます)。モデルの役目は、それを適切な話し方で説明することです。ベースモデルが一般常識をすでに知っているのに、なぜファクトカードが必要なのか、そしてなぜ学習時にも入れるのか。それには 2.2 節でじっくり答えます。
0.2 全体の流れ:各ステップをどこで行い、何が得られるか¶
① 读懂数据 dataset.json → 1150 条训练样本 (第 2 章,只读)
↓
② 准备 GPU 训练环境 .venv-train + 8 GB 基座模型 (第 3 章,GPU 终端)
↓
③ 训练 LoRA Notebook 跑 72 步 → 130 MB 的 adapter (第 4 章,JupyterLab)
↓
④ 合并导出 基座 + adapter → 8 GB 的完整模型 (第 4 章,JupyterLab)
↓
⑤ vLLM 部署 完整模型 → OpenAI 兼容的 HTTP 服务 (第 5 章,GPU 终端)
↓
⑥ 调用与压测 本地电脑经 SSH 隧道调用,测延迟和吞吐 (第 5 章,本地终端)
↓
⑦ 评估值不值 和“原模型 + 好提示词”盲评对照 (第 6 章,GPU 终端)
(図の内容:① データを理解する、dataset.json → 1150 件の学習サンプル(第 2 章、読むだけ)→ ② GPU を準備する、.venv-train + 8 GB のベースモデル(第 3 章、GPU のターミナル)→ ③ LoRA を学習する、ノートブックで 72 ステップ → 130 MB のアダプター(第 4 章、JupyterLab)→ ④ マージしてエクスポートする、ベース + アダプター → 8 GB の完全なモデル(第 4 章、JupyterLab)→ ⑤ vLLM で OpenAI 互換の HTTP サービスとしてデプロイする(第 5 章、GPU のターミナル)→ ⑥ 自分のパソコンから SSH トンネル経由で呼び出し、レイテンシとスループットを測る(第 5 章、ローカルのターミナル)→ ⑦ やる価値があったかを評価する、「元のモデル + よいプロンプト」とのブラインド評価で比較(第 6 章、GPU のターミナル)。)
| ステップ | どこで | 何を使って | 成果物 | サイズ | 章 |
|---|---|---|---|---|---|
| ① データを理解する | どのパソコンでも可、ファイルを読むだけ | ブラウザーまたはエディター | 600 本の会話がどうやって 1150 件の学習サンプルになるかを理解する | — | 第 2 章 |
| ② GPU を準備する | GPU ホストのターミナル | pip、ダウンロードスクリプト | 学習環境 .venv-train とベースモデル models/qwen3-4b/ |
環境は約 10 GB、ベースモデルは 8 GB | 第 3 章 |
| ③ 学習する | GPU ホストの JupyterLab | ノートブックをセルごとに実行 | adapter/(LoRA の差分)、loss-curve.png |
約 130 MB | 第 4 章 |
| ④ マージしてエクスポートする | 同じノートブック | PEFT | merged-model/、単独で動く完全なモデル |
約 8 GB | 第 4、5 章 |
| ⑤ デプロイする | GPU ホストのターミナル | vLLM | ポート 8000 で待ち受ける OpenAI 互換サービス | VRAM 約 20 GB | 第 5 章 |
| ⑥ 呼び出しと負荷テスト | 自分のパソコン → SSH トンネル → GPU | Python 標準ライブラリ / OpenAI SDK、vllm bench serve |
モデルの回答、レイテンシとスループットの数値 | — | 第 5 章 |
| ⑦ 評価する | GPU ホスト | コマンドラインスクリプト + 人手による採点 | 「プロンプトを書くだけの場合より LoRA がどれだけよいか」の根拠 | — | 第 6 章 |
①〜⑥ がメインの流れで、GPU の稼働時間は約 2〜3 時間です。⑦ は「ファインチューニングする価値はあるのか」に答えるステップで、GPU 時間と人手による採点がさらに必要です。メインの流れが一通り動いてから取り組めば十分です。
0.3 2 台のマシンと 3 つのウィンドウ:どう連携するか¶
全体で使うマシンは 2 台だけです。GPU ホストは時間単位で借りて、使い終わったら停止します。自分のパソコンは、読む、パッケージする、呼び出すという役割を担います。
你的电脑(Mac / Linux / Windows 均可)
├── 浏览器:读这本书
├── 浏览器:打开平台提供的 JupyterLab ──HTTPS──→ GPU 主机的 JupyterLab
├── 终端 A:打包项目,用平台上传功能传到 GPU 主机
├── 终端 B:SSH 隧道,本地 18000 端口 ──SSH──→ GPU 主机 8000 端口
└── 终端 C:运行 Python 调用示例,请求发往本地 18000
云上 GPU 主机(Linux + RTX 4090)
├── JupyterLab:运行 Notebook,训练、保存、合并
├── 终端 1:装环境、下载模型、启动 vLLM 服务(监听 127.0.0.1:8000)
└── 终端 2:nvidia-smi 看显存、运行压测
(図の内容:自分のパソコン(Mac / Linux / Windows のいずれでも可)では、ブラウザーでこの本を読みます。ブラウザーのタブでプラットフォームが提供する JupyterLab を開き、HTTPS で GPU ホストの JupyterLab に接続します。ターミナル A でプロジェクトをパッケージし、プラットフォームのアップロード機能で GPU ホストに送ります。ターミナル B ではローカルのポート 18000 から GPU ホストのポート 8000 への SSH トンネルを張ります。ターミナル C では Python の呼び出し例を実行し、ローカルのポート 18000 にリクエストを送ります。クラウド上の GPU ホスト(Linux + RTX 4090)では、JupyterLab でノートブックを実行し(学習、保存、マージ)、ターミナル 1 で環境のインストール、モデルのダウンロード、vLLM サービスの起動(127.0.0.1:8000 で待ち受け)を行い、ターミナル 2 で nvidia-smi による VRAM の確認と負荷テストを行います。)
| 部品 | 何か | なぜ必要か |
|---|---|---|
| GPU クラウドホスト | 時間単位で借りる Linux サーバーで、NVIDIA の GPU を 1 枚搭載 | 学習も推論も膨大な行列演算なので CPU では遅すぎます。学習に使う 4 bit 量子化ライブラリは NVIDIA にしか対応していません |
| プラットフォームのイメージ | 起動時に選ぶシステムテンプレートで、Ubuntu、Python 3.11、GPU ドライバーがプリインストール済み | OS とドライバーのインストールが不要になります。ドライバーはプラットフォームにしか用意できません |
| JupyterLab | ブラウザー上の対話型 Python エディターで、たいていプラットフォームに付属 | 学習コードを 1 セルずつ実行し、各セルの出力を確認でき、エラーが出たらそのセルだけ再実行できます |
仮想環境 .venv-* |
プロジェクト専用の Python 依存関係ディレクトリ | 学習とデプロイで必要なライブラリのバージョンが衝突するため、別々にインストールして互いに上書きしないようにします |
| カーネル | Jupyter の裏で実際にコードを実行する Python プロセス | .venv-train で登録したカーネルを選ばないと、ノートブックからプロジェクトの依存ライブラリを使えません。VRAM はカーネルを停止したときにはじめて解放されます |
| SSH トンネル | ローカルのポートをリモートのポートに転送する暗号化された通路 | モデルサービスは GPU ホストの 127.0.0.1 でしか待ち受けず、インターネットには公開しません。ローカルからはトンネル経由で、自分のマシン上にあるかのように呼び出せます |
0.4 事前に準備するもの¶
| 項目 | 必要なもの | 補足 |
|---|---|---|
| スキル | Linux のターミナルに慣れている、Python が読める、HTTP と JSON を知っている | 数学、PyTorch、機械学習の知識は不要です。必要な概念は第 1 章でゼロから説明します |
| GPU クラウドのアカウント | 従量課金に対応した任意の GPU クラウドプラットフォームで、アカウントに残高があること | RTX 4090(VRAM 24 GB)のインスタンスを起動でき、JupyterLab と SSH ログインが使えるプラットフォームが必要です。著者は Zhichuan Cloud(gpuhome.cc) を使っています。登録時に招待コード zt4f01m0 を入力すると新規ユーザー向けクーポンがもらえます。3.1 節を参照してください |
| ホストの構成 | RTX 4090 × 1、RAM ≥ 32 GB(マージ時は ≥ 64 GB を推奨)、データディスク ≥ 100 GB | イメージは Ubuntu 22 + Python 3.11 + CUDA 12.x を選びます。詳しくは 3.1 節 |
| 予算 | メインの流れで稼働約 2〜3 時間、評価実験でさらに 10〜20 時間 | Zhichuan Cloud の RTX 4090D 従量課金 ¥1.25/時間で計算すると、メインの流れは約 ¥3〜4、評価実験は約 ¥13〜25 です。見積もり方法は 7.1 節 |
| 自分のパソコン | インターネットに接続でき、ターミナルと SSH クライアントがあること。チェックや呼び出し例をローカルで実行したい場合は Python 3.11 をインストール | ローカルの GPU は不要で、CUDA を自分でインストールする必要もありません |
| ネットワーク | GPU ホストから PyPI(またはプラットフォームのミラー)と ModelScope にアクセスできること | 中国本土のホストは通常 huggingface.co にアクセスできないため、このチュートリアルではデフォルトで ModelScope からダウンロードします |
| このプロジェクトのファイル | このリポジトリ、または電子書籍の「ソースコードのダウンロード」ページにある練習用パッケージ | GPU にアップロードするのは tools/build_gpu_zip.py で作った軽量版パッケージです。3.3 節で説明します |
| 時間 | 第 1〜2 章を読むのに 1〜2 時間、GPU 作業は連続で 2〜3 時間 | GPU は稼働時間で課金されるので、最初の 2 章を読み終えてからマシンを起動しましょう |
準備しなくてよいもの: OpenAI のアカウントや API キー(vLLM サービスは OpenAI と同じインターフェース形式ですが、すべて自分で借りたマシン上で動きます)、Hugging Face のアカウント(モデルは公開されており、ModelScope からダウンロードします)、自前の学習データ(プロジェクトにデータセットが同梱されています)。
0.5 読み進め方¶
この本の順序は、そのまま作業の順序です。各章の冒頭で、その章で何をするか、何が必要か、終わったら何が得られるかを示します。
| 章 | 内容 | どこで読む・作業する | 必須? |
|---|---|---|---|
| 0〜1 | 目標、準備、必要な概念 | 読むだけ | 必読:第 1 章は、以降に出てくるすべての数値とパラメータの辞書です |
| 2 | 学習データがどんな形をしていて、どう学習サンプルになるか | 読むだけ。任意でローカルでチェックを実行 | 必読:モデルが実際に何を学んでいるかを知るため |
| 3 | マシンを借り、環境をインストールし、モデルをダウンロードする | GPU のターミナル | 必須 |
| 4 | ノートブックで学習し、loss を見て、回答を比較し、マージする | GPU の JupyterLab | 必須 |
| 5 | vLLM でのデプロイ、ローカルからの呼び出し、負荷テスト | GPU のターミナル + ローカル | 必須 |
| 6 | 「元のモデル + よいプロンプト」との比較、ブラインド評価 | GPU のターミナル | メインの流れが動いてから |
| 7 | コスト、トラブルシューティング表、最終確認 | — | 問題が起きたときに参照し、最後にチェックリストとして使う |
| 8、付録 | 自動テスト、コードマップ、学習コード全文 | — | コードを変更したくなったときに読む |
概念をすでに理解している方は第 3 章から始めてもかまいません。知らないパラメータに出会ったら、第 1 章や、ノートブックの該当セルの下にある表に戻ってきてください。
0.6 練習課題:小学生と一緒に科学を探る¶
なぜカスタマーサポートやコード生成のようなよくある課題を使わないのでしょうか。「小学生に科学を説明する」という課題は回答のスタイルが特徴的なので、ファインチューニングの前後の変化がひと目でわかるからです。しかも科学的事実は検証できるので、モデルがでたらめを言っていないかを判断しやすいのです。
なぜ科学探究なのか¶
子どもが「なぜ?」と聞いたあとには、間違った予想をしている、よくわからなかった、自分の手で確かめたい、とにかくすぐ答えを知りたい、などさまざまな反応が続きます。こうした反応があることで、言い回しがかわいらしいかどうかを比べるだけでなく、モデルが本当に説明を調整しているかを観察できます。
目標は、事実が正しく、子どもが理解でき、次の一歩が探究する価値のあるものであることです。面白さは、直感に反する現象、限界がはっきりしたたとえ、安全で小さな観察から生まれてもかまいません。毎回お話をしたり、大げさな口調にしたりする必要はありません。子どもが終わりと言ったら会話は終わりです。会話を長引かせることを成功の基準にはしません。
扱う範囲¶
| カテゴリ | データ上の値 | 学習トピックの例 |
|---|---|---|
| 天文と宇宙 | space |
昼と夜、季節、月の満ち欠け、流れ星 |
| 地球と天気 | earth |
雲と雨、雪の結晶、岩石、川 |
| 生き物と自然 | life |
種、根、チョウ、食物網 |
| 身近な物理 | physics |
影、音、浮力、溶解 |
| 工学と道具 | engineering |
アーチ橋、てこ、飛行機、太陽電池 |
各カテゴリに学習用の会話が 100 本、さらに検証用が 10 本、テスト用が 10 本あります。これは限られた教材サンプルであって、小学校カリキュラムの完全な知識ベースではありません。grade_band は 1〜2 年生、3〜4 年生、5〜6 年生に分かれています。学年帯は説明の出発点にすぎず、実際の反応が優先されます。同じ学年の子どもが同じように理解できると決めつけることはできません。
プロンプトとファインチューニングの役割分担¶
1 回のリクエストには 4 つの要素があり、それぞれが 1 つの役割を担います:
| 要素 | 何を担うか | いつ効くか |
|---|---|---|
| システムプロンプト(ロールプロンプト) | 役割と基本ルール:「あなたは小学生と一緒に科学を探る仲間です……」 | 毎回のリクエストで送る |
| ファクトカード | その質問で根拠にしてよい科学資料 | 質問ごとに選んで、毎回のリクエストで送る |
| SFT のお手本会話 | 誤解、理解できなかったとき、観察結果の食い違い、好みの変化への対処法を示す | 学習時にだけ使い、身につけた振る舞いはアダプターに保存される |
| LoRA | 更新するパラメータをごく一部に限定し、元のモデルには手を触れない | 学習時にどのパラメータを変えるかを決める |
このプロジェクトのお手本パターンは 10 種類です:誤解を訂正する、別の説明に言い換える、具体的な追加質問を受け止める、任意の観察を提案する、予想を確かめる、簡単なところから深める、たとえの限界を説明する、観察の食い違いを照らし合わせる、クイズを出さずに問いかける、自然に終える。同じトピックの中では一部の回答が使い回されているので、500 本の会話を 500 個の独立した科学の質問だと考えないでください。
「プロンプトではファインチューニングの代わりにならない」とは約束しません。第 6 章では、元のモデルに完全なプロンプトと 3 つの例を与えた B グループと、まったく同じ入力を使う LoRA の C グループを比較します。学習に含まれていない科学トピックで、C のほうが子どもの反応により安定して応えられるかを確認します。改善が見られなければ、正直に B を採用します。
0.7 現時点で揃っているもの¶
更新日:2026-10-10。
| 項目 | 現在の状態 |
|---|---|
| 単一のデータソース | data/dataset.json:ファクトカード 60 枚、合成会話 600 本(train 500 / val 50 / test 50) |
| 学習サンプル | train の 500 本の会話は 1150 個の回答ターゲットに展開されます。ノートブックはデフォルトで 1 エポック分(約 72 ステップ)を実行します |
| ノートブック | トークン化、マスク、QLoRA、loss 曲線、保存、再読み込み、比較、BF16 マージ、最後に vLLM でのデプロイと呼び出し |
| デプロイ | vLLM でマージ済みモデルを提供するか、アダプターを直接マウントする。標準ライブラリ / OpenAI SDK で呼び出し、vllm bench serve で負荷テスト |
| ローカルでの検証 | データチェックと、ごく小さな CPU 学習の仕組みのテスト。検証記録を参照 |
| 実際の GPU ではまだ未検証 | 4B の学習時間と VRAM、vLLM サービス、負荷テストの数値。あなたの GPU ホストで実測した値を信頼してください |
0.8 結論の限界(本書全体で一度だけ述べます)¶
- 会話はすべて合成された下書き(
review.status="draft")で、人が 1 本ずつレビューしたものではありません。回答はやや短めで、構成も繰り返しが多めです。ワークフローとエンジニアリングを学ぶには十分ですが、「LoRA のほうが必ずよい」という結論を出すには不十分です。 - 回答を生成できるということは、ファイルとサービスが動いていることを示すだけです。loss が下がるということは、モデルが参照回答に近づいたことを示すだけです。回答の品質は、4.5 節の人手による比較と第 6 章のブラインド評価で判断する必要があります。
- ファインチューニングで変わるのは「どう話すか」であり、モデルが新しい知識やリアルタイムの情報を自動的に得るわけではありません。事実は引き続き呼び出し側がプロンプトに入れます。
確認ポイント: 「データ → 学習 → マージ → デプロイ → 呼び出し」の流れを図に描き、各ステップをどのマシンで行い、どのファイルが生成されるかを説明できること。マシンを起動する前に準備しておくものを挙げられること。会話の中で「知識はどこか」と「反応に応じて何が変わったか」を指摘できること。