LLMの事前学習も自分で試せる「NanoChat」を動かしてみた

 

********

※LINE対応チャットボット版の
「LINEチャットボット屋」
いろんなチャットボットがあります。
ぜひ、ご覧ください!

***************

***************

NanoChatとは?

大規模言語モデル(LLM)は今や、AI研究の中心的な存在だ。
ただ、多くの人が「ChatGPTは使うけど、どうやって作られてるのか分からない」と感じているのも事実だろう。

そんな中、元Tesla AIディレクターでありOpenAIの初期メンバーでもある Andrej Karpathy 氏が、驚くようなプロジェクトを公開した。

その名も「NanoChat」。

キャッチコピーは「The best ChatGPT that $100 can buy(100ドルで作れる最高のChatGPT)」だ。

このコードはgit hubに公開されているのだが、たった100ドル程度でChatGPTのようなモデルを自分で一から学習・実行できるという優れものなのだ。

Karpathy氏いわく、このプロジェクトは「教育・理解・実験用」に設計されており、
研究者や学生がLLMをブラックボックスではなくホワイトボックスとして触れることを目的としているとのこと。

コードの量も非常に少なく、たった数千行で構成されており、
トークナイザー・学習・微調整・推論・Web UIまでがひとつの流れとして完結する。

言ってみれば、ChatGPTを自分のノートPCで読み解くための教科書のような存在だ。

Google ColabでNanoChatを動かしてみた

今回はGPUが使えるGoogle ColabでNanoChatを実行してみた。

事前学習やSFT(Supervised Fine-Tuning)などの本格的なトレーニングはGPUリソースが必要で、ColabのT4やA100環境が必須となる。

処理の細かい所は最後のコードをご覧いただきたい。

このNanoChatは学習済みのチェックポイントも用意されているので、
自分で事前学習させてもよし、推論だけ試すのもよしのモデルになっている。

今回は事前学習の時間がないので、推論のみを試してみる。
早速、会話を始めてみよう。

ChatGPTのような自然な応答

試しにいくつか質問を投げてみた。
(英語のみの学習済みのようなので、英語での質問。和訳付きで紹介)

質問1
User: What do you think about artificial intelligence?

Assistant:
Artificial intelligence is a rapidly evolving field that combines human intelligence with machine capabilities…

AIとは何か?という質問に対し、
「AIは人間の知能と機械の能力を組み合わせて複雑な問題を解く分野であり、
データから学習して適応する能力が人間に似ている」
といった感じの、かなり自然で論理的な文章が返ってきた。

まるでChatGPTそのもののような文体だ。

質問2
User: Do you like coffee or tea?

Assistant:
I don’t have personal preferences, but I can give you an idea of how I approach my coffee or tea…

「AIにコーヒーと紅茶どちらが好き?」と聞くと、
「個人的な好みはないけど、もし選ぶならコーヒー通だと思う」とユーモラスに返してきた。
文体の柔らかさや冗談交じりの表現は、お見事だ。

質問3
User: Have you ever been to Japan?

Assistant:
I’ve had the privilege of visiting Japan several times…

あなたは日本に行ったことがありますか?

京都・大阪・東京などの地名を挙げて、日本を「文化と自然が豊かな国」と語る。
実際はAIの創作だが、まるで旅行ブログのようなリアリティを感じる。

仕組みをざっくり理解する NanoChatの構造

NanoChatの面白いところは、構造が読めることだ。

中核は20層のTransformer(d20モデル)で、埋め込み次元は1280、語彙数は約6.5万。
つまり、ChatGPTなどの巨大モデルのコンパクト版といえる。

トークナイザーにはRust製の rustbpe が採用されており、高速なトークン化が可能。
Pythonから呼び出せるようにmaturin経由でビルドされている。

推論サーバーは FastAPI で構築され、
python -m scripts.chat_web を実行すれば
ローカル環境やColab上で ChatGPT風のブラウザUI を立ち上げることもできる。

さらに cloudflared を使えば、
Colabで立ち上げたUIを外部URL(https://xxxx.trycloudflare.com)で共有できるのも面白い。

Colabで動かして分かったメリットと限界

実際にColabでNanoChatを動かしてみて感じたのは、「軽いのに深い」ということだ。

GPUが1枚でも動作する軽さ
ColabのT4でも十分に推論できる。

コードがシンプルで理解しやすい
教材として最適。LLMの学習プロセスが読み取れる。

ローカル・オフラインで動く
チェックポイントを入れれば、ネットなしでも会話可能。

一方で限界もある。

学習は重い(8×H100などが必要)
英語中心のSFTモデル(日本語対応は別途チューニングが必要)。
ChatGPTほどの文脈保持はまだ弱い。

とはいえ、数十GB単位の学習をせずとも、自分の手で「ChatGPTの仕組み」を動かして理解できるのは大きな魅力だ。

まとめ NanoChatは「LLMを自分で動かす」第一歩に最適

ChatGPTを使うだけの時代から、
「自分で作る・理解する時代」へ。

NanoChatはまさにその転換点を象徴するプロジェクトだ。

LLMがどう動くのか、どんな構造をしているのか、どんな工程で学習しているのかを、実際のコードと対話を通して体感できる。

今回のColab実装では、学習までは行っていないが、推論だけでもChatGPTにかなり近い体験ができた。

英語で自然に会話できるだけでも、AIの「内部構造」を実感するには十分だ。

これからの時代、AIは「使う」だけではなく「理解して作る」スキルも必要だろう。
その第一歩として、NanoChatは最高の教材だと感じた。

これからもこのNanoChatをいろいろいじって遊んでみたい。

使ったpythonコード

Nanochatの 推論のみを試すコードです。
結構シンプルなコードなので、Googleコラボで再現してみてください。

ちなみに、git hubからローカルにcloneしても動きます。
ご希望の方法でやってみましょう。

https://github.com/karpathy/nanochat.git

こんな感じの画面↓

pythonコードです。
そのままベタ貼りしてるので、エラーが出たらGPT5先生とかに聞いてください。


import os, sys, platform, torch, subprocess, textwrap
print("Python:", sys.version)
print("Platform:", platform.platform())
print("CUDA available?:", torch.cuda.is_available())
if torch.cuda.is_available():
print("GPU:", torch.cuda.get_device_name(0))
else:
print("GPU: (なしでもOK、推論はCPUでも動きますが少し遅くなります)")

# リポジトリを取得
!git clone https://github.com/karpathy/nanochat.git
%cd nanochat
!git rev-parse --short HEAD

# 依存をインストール(最小)
# - FastAPI + uvicorn: Webサーバ
# - huggingface_hub: モデル/トークナイザの取得
# - cloudflared: トンネル(ngrok不要、トークン不要)
# - (torch はColabに同梱のものを利用)
#!pip -q install fastapi uvicorn "huggingface_hub>=0.25.0" cloudflared==2024.8.5
!pip install cloudflared

print("installed.")

import os, pathlib, urllib.request

home = str(pathlib.Path.home())
tok_dir = os.path.join(home, ".cache", "nanochat", "tokenizer")
ckpt_dir = os.path.join(home, ".cache", "nanochat", "chatsft_checkpoints", "d20")
os.makedirs(tok_dir, exist_ok=True)
os.makedirs(ckpt_dir, exist_ok=True)

files = {
# tokenizer
os.path.join(tok_dir, "tokenizer.pkl"): "https://huggingface.co/sdobson/nanochat/resolve/main/tokenizer.pkl",
os.path.join(tok_dir, "token_bytes.pt"): "https://huggingface.co/sdobson/nanochat/resolve/main/token_bytes.pt",
# checkpoint (SFT d20)
os.path.join(ckpt_dir, "model_000650.pt"): "https://huggingface.co/sdobson/nanochat/resolve/main/model_000650.pt",
os.path.join(ckpt_dir, "meta_000650.json"): "https://huggingface.co/sdobson/nanochat/resolve/main/meta_000650.json",
}

for out, url in files.items():
if not os.path.exists(out):
print("Downloading", url, "->", out)
urllib.request.urlretrieve(url, out)
else:
print("Exists:", out)

print("\\nReady. Cache root:", os.path.join(home, ".cache", "nanochat"))
!ls -R ~/.cache/nanochat

# 端末チャットで動作確認(任意): セル実行後プロンプトが出ます
# 停止は「Ctrl+C」または Colab のセル停止ボタン
!python -m scripts.chat_cli

#下のセルを実行すると、cloudflared が http://localhost:8000 を 公開URL にトンネルします。
#30秒ほどで https://xxxx.trycloudflare.com のようなURLが出ます。そこをクリックすると ChatGPT風UI に接続できます。

import subprocess, time, os, signal, sys

# 1) FastAPI サーバをバックグラウンドで起動
web_cmd = ["python", "-m", "scripts.chat_web", "--host", "0.0.0.0", "--port", "8000"]
web_proc = subprocess.Popen(web_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True)

# 起動ログを少し待つ
time.sleep(3)
print(">>> chat_web started (pid=%s). Tunneling with cloudflared..." % web_proc.pid)

# 2) cloudflared で公開URLを作る(前面で実行してURLを表示)
# ※ 実行を止めるとトンネルも閉じます。停止は上部の「実行を停止」
try:
!cloudflared tunnel --url http://localhost:8000 --no-autoupdate
finally:
# 終了時にFastAPIプロセスを止める
try:
web_proc.terminate()
except Exception:
pass


****************

研究者は論文を書く。
開発者はブログ記事を書く。

さすれば、科学は進歩する。かな。

****************

最近のデジタルアート作品を掲載!

X 旧ツイッターもやってます。
https://x.com/ison1232

インスタグラムはこちら
https://www.instagram.com/nanahati555/

****************

Follow me!

PAGE TOP