跳到主要内容
feedback
feedback

Nanochat 实战教程:从零构建与理解大模型聊天系统

在大模型应用快速发展的背景下,“聊天系统”是最常见却也最容易被误解的系统形态。现实工程中,核心逻辑往往被层层框架掩盖。开发者能够快速得到“能用的结果”,却很难真正理解系模型在每一步究竟做了什么。

Nanochat 的出现不追求工程层面的“最佳实践”,而是将系统压缩到极小规模,只保留构建聊天模型必需的核心组件。它更像是一份可执行的说明书,通过最直接的数据流和最少的抽象,带你完整经历编码器训练、预训练、后训练等关键步骤,从代码层面理解“对话”的真实含义。

一、环境构建与准备

1.1 硬件与基础环境

  • 硬件推荐:本教程基于沐曦 C500(64GB) 显存设备进行验证。
  • 镜像环境:PyTorch / 2.8.0 / Python 3.12 / maca 3.3.0.4 镜像选择

1.2 通过Jupyter连接算力容器

基础操作步骤:

  1. 进入工作台:启动实例后,点击 JupyterLab 进入容器环境。

    进入容器

  2. 进入终端:点击 “Terminal”

    进入终端

  3. GPU检查:在终端执行mx-smi 如果某个GPU出现Not Available,请销毁容器,重新租用算力。

    GPU检查

1.2 通过tmux进入到保持连接的终端会话中

使用 Tmux 保持会话 训练是一个长时间任务,为防止终端断开导致中断,推荐使用 tmux

  • 创建会话tmux new -t nanochat

    进入会话

模型训练的操作后将在这个会话中执行,如需暂时离开执行下来操作
  • 暂时离开:按下 Ctrl+B 后松开,再按 D
  • 重连会话tmux attach -t nanochat

1.3 目录与环境变量配置

接下来的操作均在该终端会话中进行。

  1. 从共享存储中拉取nanochat的项目

    cp -r /mnt/moark-models/github/nanochat /data/nanochat
  2. 创建输出目录

    mkdir /data/nanochat_output
  3. 配置环境变量

    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% 的挑战者!


二、模型训练全流程

训练分为三个核心阶段:

  1. 文本编码器训练:让模型读懂字符。
  2. 预训练 (Pre-train):学习海量文本知识(分为 Base 和 Mid 两个阶段)。
  3. 后训练 (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

训练tokenizer

评估编码器:

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

训练base_start

训练日志参数解读:

显示项解释
step当前步数/总步数 (进度百分比)
loss训练误差,数值越小越好
lrm学习率倍率 (例如 0.15 表示当前为基础学习率的 15%)
tok/sec每秒处理的 Token 数 (吞吐量)
mfuGPU 利用率 (注:在某些国产卡上可能计算不准,可忽略)
eta预计剩余时间

查看结果与评估:

# 查看生成样例
python -m scripts.base_loss
# 模型评估
python -m scripts.base_eval

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

访问方式:

  1. 服务默认运行在 8188 端口。
  • 访问云端的web服务,首先需要进行隧道代理,具体流程请参考建立隧道代理

隧道代理命令可在此复制:

体验提示:

  • 语言限制:由于训练集限制,请必须使用 英文 进行对话。

  • 性能预期:受限于数据量、参数量和训练时间,效果肯定无法比拟主流大模型(如 GPT-5, DeepSeek 等),但这正是“去魅”的过程。

  • 测试问题

    • who are you?
    • Please introduct yourself
    • Explain the Newton second theory.

    web


四、进阶探索

如果你想在学术或工程上进一步深入,可以尝试:

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