Nanochat 实战教程:从零构建与理解大模型聊天系统
在大模型应用快速发展的背景下,“聊天系统”是最常见却也最容易被误解的系统形态。现实工程中,核心逻辑往往被层层框架掩盖。开发者能够快速得到“能用的结果”,却很难真正理解系模型在每一步究竟做了什么。
Nanochat 的出现不追求工程层面的“最佳实践”,而是将系统压缩到极小规模,只保留构建聊天模型必需的核心组件。它更像是一份可执行的说明书,通过最直接的数据流和最少的抽象,带你完整经历编码器训练、预训练、后训练等关键步骤,从代码层面理解“对话”的真实含义。
一、环境构建与准备
1.1 硬件与基础环境
- 硬件推荐:本教程基于沐曦 C500(64GB) 显存设备进行验证。
- 镜像环境:PyTorch / 2.8.0 / Python 3.12 / maca 3.3.0.4

1.2 通过Jupyter连接算力容器
基础操作步骤:
-
进入工作台:启动实例后,点击 JupyterLab 进入容器环境。

-
进入终端:点击 “Terminal”

-
GPU检查:在终端执行
mx-smi如果某个GPU出现Not Available,请销毁容器,重新租用算力。
1.2 通过tmux进入到保持连接的终端会话中
使用 Tmux 保持会话
训练是一个长时间任务,为防止终端断开导致中断,推荐使用 tmux。
-
创建会话:
tmux new -t nanochat
- 暂时离开:按下
Ctrl+B后松开,再按D。 - 重连会话:
tmux attach -t nanochat
1.3 目录与环境变量配置
接下来的操作均在该终端会话中进行。
-
从共享存储中拉取nanochat的项目:
cp -r /mnt/moark-models/github/nanochat /data/nanochat -
创建输出目录:
mkdir /data/nanochat_output -
配置环境变量:
export OMP_NUM_THREADS=1
export NANOCHAT_BASE_DIR="/data/nanochat_output"
1.3 数据集准备
为了缩短训练时间,我们默认使用部分精简数据。请根据实际挂载路径创建软连接(以下路径基于 Moark 平台示例):
# 基础预训练数据
ln -s /mnt/moark-models/fineweb-edu-100b-shuffle-240shard "$NANOCHAT_BASE_DIR/base_data"
# 词表数据
ln -s /mnt/moark-models/words_alpha/words_alpha.txt "$NANOCHAT_BASE_DIR/words_alpha.txt"
# 对话微调数据
ln -s /mnt/moark-models/identity_conversations/identity_conversations.jsonl "$NANOCHAT_BASE_DIR/identity_conversations.jsonl"
# 评测数据集
ln -s /mnt/moark-models/eval_bundle "$NANOCHAT_BASE_DIR/eval_bundle"
注:如果想进行全量训练(耗时极长),可将
base_data指向完整数据集:ln -s /mnt/moark-models/fineweb-edu-100b-shuffle "$NANOCHAT_BASE_DIR/base_data"
1.4 安装依赖
进入项目目录并安装 Python 依赖:
pip install rustbpe tiktoken wandb fastapi uvicorn

🎉 恭喜!到了这一步,你已经打败了 50% 的挑战者!
二、模型训练全流程
训练分为三个核心阶段:
- 文本编码器训练:让模型读懂字符。
- 预训练 (Pre-train):学习海量文本知识(分为 Base 和 Mid 两个阶段)。
- 后训练 (Post-train):学习对话模式。
移动到nanochat项目目录下
cd /data/nanochat
初始化训练环境: 在开始前,重置报告状态:
python -m nanochat.report reset
检查环境信息:
cat /data/nanochat_output/report/header.md

2.1 文本编码器训练 (Tokenizer)
从随机初始化权重开始,训练一个可以双向翻译文本和模型语言的编码器。
执行训练:
python -m scripts.tok_train --max_chars=2000000000 --vocab_size=65536
预期输出:
max_chars: 2,000,000,000
vocab_size: 65,536
...
Saved tokenizer encoding to /data/nanochat_output/tokenizer/tokenizer.pkl

评估编码器:
python -m scripts.tok_eval
结果说明:评估完成后,你会发现你的编码器性能与 GPT-2 不相上下。
👍 进度更新:你已经打败了 90% 的挑战者!
2.2 模型预训练 (Pre-training)
第一阶段:Base Training (基础知识习得)
使用纯文本数据训练,让模型拥有生成流畅文本的能力。
执行命令:
# --nproc_per_node 表示训练时所使用的GPU数量,提高GPU的数量能够加快训练速度
# 推荐租用4卡来进行训练,加快训练速度
torchrun --nproc_per_node=1 -m scripts.base_train -- \
--depth=8 \
--target_param_data_ratio=20 \
--device_batch_size=8 \
--run=dummy

训练日志参数解读:
| 显示项 | 解释 |
|---|---|
| step | 当前步数/总步数 (进度百分比) |
| loss | 训练误差,数值越小越好 |
| lrm | 学习率倍率 (例如 0.15 表示当前为基础学习率的 15%) |
| tok/sec | 每秒处理的 Token 数 (吞吐量) |
| mfu | GPU 利用率 (注:在某些国产卡上可能计算不准,可忽略) |
| eta | 预计剩余时间 |
查看结果与评估:
# 查看生成样例
python -m scripts.base_loss
# 模型评估
python -m scripts.base_eval

此时各任务准确率可能较低,因为模型仅学会了“续写”,尚未融会贯通。
第二阶段:Mid Training (知识强化)
使用更高质量的数据及部分对话数据进行生成式训练,让模型学习更好的利用知识。
执行命令:
# --nproc_per_node 表示训练时所使用的GPU数量,提高GPU的数量能够加快训练速度
torchrun --standalone --nproc_per_node=1 -m scripts.mid_train -- \
--device_batch_size=8 \
--run=dummy
(耗时约 40 分钟)
评估结果:
python -m scripts.chat_eval -i mid
预期结果:MMLU、ARC 等指标应有小幅提升,模型开始具备一定的知识检索能力。
🐂🍺 进度更新:你已经打败了 99% 的挑战者!
2.3 后训练 (Post-training / SFT)
这一阶段,将使用更加结构化的对话数据进行训练。此时模型脑袋里已经装了不少的知识,且可以大片大片的检索里面的知识片段了,但是对于具体的对话场景模型还不够熟练。因此将使用结构化的对话数据(问答形式)进行微调(Supervised Fine-Tuning),让模型适应聊天场景。
执行命令:
torchrun --standalone --nproc_per_node=1 -m scripts.chat_sft -- \
--device_batch_size=8 \
--run=dummy
(耗时约 10 分钟)
最终评估:
python -m scripts.chat_eval -i sft
预期结果:指标进一步微调提升,更重要的是模型学会了以“对话”的方式输出。
🎉 恭喜!你已经完成了所有训练流程,打败了 100% 的挑战者!
三、成果体验与部署
评测数据是冰冷的,真实的对话体验才是关键。启动 Web 服务进行体验:
# --num-gpus 表示推理时所使用的GPU数量
# --source sft 表示加载后训练阶段的模型
# 可选值: sft | mid | rl (如有)
python -m scripts.chat_web --num-gpus 1 --source sft
访问方式:
- 服务默认运行在 8188 端口。
- 访问云端的web服务,首先需要进行隧道代理,具体流程请参考建立隧道代理
隧道代理命令可在此复制:

- 代理成功后,本地浏览器访问: http://localhost:8188
体验提示:
-
语言限制:由于训练集限制,请必须使用 英文 进行对话。
-
性能预期:受限于数据量、参数量和训练时间,效果肯定无法比拟主流大模型(如 GPT-5, DeepSeek 等),但这正是“去魅”的过程。
-
测试问题:
- who are you?
- Please introduct yourself
- Explain the Newton second theory.

四、进阶探索
如果你想在学术或工程上进一步深入,可以尝试:
- Scale Up (扩大规模):使用多机多卡,加载完整数据集进行更大规模训练。
- Scaling Law 复现:调整模型层数、宽度,验证 Scaling Law 在本项目中的体现。
- RL (强化学习):代码库中包含 RL 相关脚本,尝试进行 PPO/DPO 训练并观察效果。
- 自定义垂类模型:替换数据集,在 Pre-train 或 Post-train 阶段注入特定领域知识(如医学、代码),打造专用小模型。