安装依赖环境,pytorch、cuda-toolkit等等
test:
nvidia-smi
/usr/local/cuda/bin/nvcc -V
pip list
git clone https://github.com/karpathy/nanochat
cd nanochat
快速运行手册:
https://github.com/karpathy/nanochat/blob/master/runs/speedrun.sh
export HF_ENDPOINT=https://hf-mirror.com
export NANOCHAT_BASE_DIR=/data/D/nanochat_base
mkdir -p $NANOCHAT_BASE_DIR
下载初始20亿字符数据集(约800MB):
pip install pyarrow
python -m nanochat.dataset -n 8
或者手动下载:
https://huggingface.co/datasets/karpathy/climbmix-400b-shuffle
ClimbMix是一个由NVIDIA发布的高质量、紧凑且强大的4000亿token预训练数据集,通过高效预训练在等量的token预算下实现优越性能。
训练tokenizer:
pip install rustbpe tiktoken
#默认20亿字符
python -m scripts.tok_train --max-chars=2_000_000_000
评估tokenizer:
python -m scripts.tok_eval
下载更多训练数据(约22GB):
python -m nanochat.dataset -n 240
耗时较长。
下载评估数据(约24.9MB):
curl -L -o eval_bundle.zip https://karpathy-public.s3.us-west-2.amazonaws.com/eval_bundle.zip
unzip -q eval_bundle.zip
mv eval_bundle $NANOCHAT_BASE_DIR/
rm eval_bundle.zip
至此环境和数据均已准备完成,开始训练模型。
训练模型:
#depth=12, GPT-2 Small Layers
python -m scripts.base_train --depth=12 \
--model-tag="d12" \
--core-metric-every=999999 \
--sample-every=-1 \
--save-every=-1 \
--device-batch-size=32
#depth=24, GPT-2 Medium Layers
python -m scripts.base_train --depth=24 \
--target-param-data-ratio=8 \
--device-batch-size=16 \
--fp8
在5090D 32G显存+96GB DDR5内存机器上,depth=12,模型训练耗时185分钟。
模型权重文件model_002520.pt大小为792.8MB。
If display error:
/tmp/tmp4oxwapmp/cuda_utils.c:7:10: fatal error: Python.h: 没有那个文件或目录
7 | #include
Fix:
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/data/Python-3.12.12:/data/Python-3.12.12/Include
export CPLUS_INCLUDE_PATH=$CPLUS_INCLUDE_PATH:/data/Python-3.12.12:/data/Python-3.12.12/Include
评估模型(CORE metric, BPB on train/val):
python -m scripts.base_eval --device-batch-size=16
耗时20分钟。
输出:
BPB Evaluation:
train bpb: 0.848951
val bpb: 0.848383
...
CORE metric: 0.1579
BPB(Bits Per Byte)的字面意思是每个字节消耗的比特数。
在信息论中,它衡量的是大模型对文本数据的压缩效率。根据香农的信息论,一个完美的语言模型如果能100%预测未来的文本,那么它压缩该文本所需的比特数就会极低。
在LLM训练中,BPB的数学本质是以2为底的交叉熵损失(Cross Entropy Loss),但它是针对字节(Byte)级别进行归一化的,而不是针对Token。
为什么不用Loss,而要看BPB?为了解决Token长度的“作弊”问题。
大模型在训练时,交叉熵损失(Cross-Entropy Loss)的计算是基于Token的平均值,分子是总Loss,分母是Token的总数量。
不同的模型使用的Tokenizer(分词器)是不同的。比如同样一句话,LLaMA的分词器可能会切成10个Token,而GPT-4的分词器可能只切成6个Token。
这样一来,两者的平均Token Loss是无法直接横向对比的,因为分母不同。
无论模型怎么分词,底层的原始文本文件大小(以Byte为单位)是绝对固定的。把Loss转换成BPB,相当于把评价标准统一拉到了“模型每看到原始文本的一个字节,能提供多少比特的信息量”。
只有通过BPB,你才能公平地把你的nanochat模型去和市面上其他架构、不同词表大小的模型去全方位对比。
永远不要跨越不同的Tokenizer去对比Token Loss。如果要对比,要么看它们在相同测试集上的BPB,要么直接看它们在实际对话时的回答质量。
下载合成身份对话数据,让模型更像人类:
curl -L -o $NANOCHAT_BASE_DIR/identity_conversations.jsonl https://karpathy-public.s3.us-west-2.amazonaws.com/identity_conversations.jsonl
需梯子:
pip install huggingface_hub
huggingface-cli login
下载smol-smoltalk数据集:
https://huggingface.co/datasets/HuggingFaceTB/smol-smoltalk
hf download HuggingFaceTB/smol-smoltalk --repo-type dataset
mkdir -p nanochat/HuggingFaceTB/smol-smoltalk
cp -rL拷贝
下载cais/mmlu数据集:
https://huggingface.co/datasets/cais/mmlu
hf download cais/mmlu --repo-type dataset
mkdir -p nanochat/cais/mmlu
cp -rL拷贝
下载openai/gsm8k数据集:
https://huggingface.co/datasets/openai/gsm8k
hf download openai/gsm8k --repo-type dataset
mkdir -p nanochat/openai/gsm8k
cp -rL拷贝
下载allenai/ai2_arc数据集:
https://huggingface.co/datasets/allenai/ai2_arc
hf download allenai/ai2_arc --repo-type dataset
mkdir -p nanochat/allenai/ai2_arc
cp -rL拷贝
下载openai/openai_humaneval数据集:
https://huggingface.co/datasets/openai/openai_humaneval
hf download openai/openai_humaneval --repo-type dataset
mkdir -p nanochat/openai/openai_humaneval
cp -rL拷贝
下载https://raw.githubusercontent.com/dwyl/english-words/refs/heads/master/words_alpha.txt
放入$NANOCHAT_BASE_DIR/
SFT监督微调(conversation special tokens, tool use, multiple choice):
pip install datasets
python -m scripts.chat_sft --device-batch-size=16
耗时70分钟。
Minimum validation bpb: 0.3557
评估模型:
python -m scripts.chat_eval -i sft
ARC-Easy accuracy: 36.15%
ARC-Challenge accuracy: 32.25%
MMLU accuracy: 31.52%
GSM8K accuracy: 3.34%
HumanEval accuracy: 9.76%
SpellingBee accuracy: 99.22%
与模型对话:
python -m scripts.chat_cli -p "Why is the sky blue?"
python -m scripts.chat_web
生成报告:
python -m nanochat.report generate