Instructions to use NLP-beginner/babyllm-chinese with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use NLP-beginner/babyllm-chinese with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="NLP-beginner/babyllm-chinese")# Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("NLP-beginner/babyllm-chinese", dtype="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use NLP-beginner/babyllm-chinese with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "NLP-beginner/babyllm-chinese" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "NLP-beginner/babyllm-chinese", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/NLP-beginner/babyllm-chinese
- SGLang
How to use NLP-beginner/babyllm-chinese with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "NLP-beginner/babyllm-chinese" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "NLP-beginner/babyllm-chinese", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "NLP-beginner/babyllm-chinese" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "NLP-beginner/babyllm-chinese", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use NLP-beginner/babyllm-chinese with Docker Model Runner:
docker model run hf.co/NLP-beginner/babyllm-chinese
🍼 BabyLLM: 从零预训练中文小型语言模型
NLPCC 2026 ChineseBabyLM Challenge · SULAB Team
23 天 · 15 个版本迭代 · PPL 从 597 降至 38.68 (↓93.5%)
📋 目录
项目概述
本项目参加 NLPCC 2026 首届 ChineseBabyLM 挑战赛,目标是在约 1 亿中文字符(~82M tokens)的儿童语料上,从头预训练一个高性能的小型中文语言模型。
核心约束
| 约束 | 详情 |
|---|---|
| 训练数据 | babylm-zho-100M (~100M 中文字符, ~2M 行) |
| 禁止事项 | 不可使用任何外部预训练模型 |
| Token 限制 | ≤100M Jieba tokens |
| 评测基准 | ZhoBLiMP, 汉字结构, 汉字拼音, AFQMC, OCNLI, TNEWS, WSC2020 |
| 训练硬件 | 4× NVIDIA RTX A6000 (48GB VRAM) |
核心矛盾
100M tokens 的数据量远低于 Chinchilla 最优比例(tokens/params = 20–200×)。项目通过 15 个版本的系统实验验证:对 100M tokens,最优参数量为 40–55M(tokens/param ≈ 1.8–2.5×)。
模型仓库索引
本仓库包含 15 个版本、22 个模型检查点。按推荐程度排序:
🏆 推荐使用
| 文件夹 | 版本 | 参数量 | PPL | 说明 |
|---|---|---|---|---|
v13-sota/ |
V13 | 94.2M | 38.68 | ⭐ 最佳模型,SOTA |
v12-efficient/ |
V12 | 54.2M | 38.84 | ⭐ 最佳参数效率,推荐资源受限场景 |
v14-efficient/ |
V14 | 59.2M | 41.8 | V14 最终版 |
🔬 研究参考
| 文件夹 | 版本 | 参数量 | PPL | 说明 |
|---|---|---|---|---|
v13-stage1/ |
V13 | 94.2M | 39.51 | Stage 1 CLM+EMA (消融研究) |
v13-stage3/ |
V13 | 94.2M | 40.08 | Stage 3 Polish (证明有害,对比用) |
v12-stage1/ |
V12 | 54.2M | — | V12 Stage 1 |
v11-ema-sgdr/ |
V11 | 38.7M | 40.73 | EMA+SGDR 首次引入 |
v10-production/ |
V10 | 38.7M | 42.89 | 首个生产管线版本 |
📜 早期版本
| 文件夹 | 版本 | 参数量 | 状态 | 说明 |
|---|---|---|---|---|
v1-gpt2/ |
V1 | ~110M | ⚠️ | GPT-2 架构基线 |
v2-llama/ |
V2 | ~125M | ⚠️ | ByteLevel BPE (不适合中文) |
v3-spm/ |
V3 | ~125M | ⚠️ | SentencePiece 引入 |
v4-deep/ |
V4 | ~350M | ❌ | 参数过多,严重欠拟合 |
v5-small/ |
V5 | ~51M | ⚠️ | 小模型 + KD |
v5-kd/ |
V5-KD | ~51M | ⚠️ | 知识蒸馏版 |
v7-mntp/ |
V7 | ~30M | ✅ | MNTP 混合训练首次引入 |
v8-3stage/ |
V8 | ~35M | ✅ | 简化三阶段 |
v9-probe/ |
V9 | ~35M | ✅ | 探针实验 |
🔄 最新迭代
| 文件夹 | 版本 | 参数量 | PPL | 说明 |
|---|---|---|---|---|
v15-multiscale-ema/ |
V15 | 68.2M | 45.1 | Multi-scale EMA |
v15-stage1/ |
V15 | 68.2M | — | V15 Stage 1 |
v15-1-retrain/ |
V15.1 | 68.2M | — | 修复 FFN 维度后重训 |
v15-1-stage1/ |
V15.1 | 68.2M | — | V15.1 Stage 1 |
v14-stage1/ |
V14 | 59.2M | — | V14 Stage 1 |
使用方法
快速开始
from transformers import AutoModelForCausalLM, AutoTokenizer
import torch
# 加载 V13 SOTA 模型
model = AutoModelForCausalLM.from_pretrained(
"NLP-beginner/babyllm-chinese",
subfolder="v13-sota",
torch_dtype=torch.bfloat16,
device_map="auto",
)
tokenizer = AutoTokenizer.from_pretrained("NLP-beginner/babyllm-chinese", subfolder="v13-sota")
# 文本生成
inputs = tokenizer("从前有一座山,", return_tensors="pt").to(model.device)
outputs = model.generate(
**inputs,
max_new_tokens=50,
temperature=0.8,
top_p=0.9,
do_sample=True,
)
print(tokenizer.decode(outputs[0], skip_special_tokens=True))
加载 V12 效率最佳模型
# V12: 仅 54.2M 参数,PPL=38.84,适合资源受限场景
model = AutoModelForCausalLM.from_pretrained(
"NLP-beginner/babyllm-chinese",
subfolder="v12-efficient",
torch_dtype=torch.bfloat16,
)
tokenizer = AutoTokenizer.from_pretrained("NLP-beginner/babyllm-chinese", subfolder="v12-efficient")
计算 PPL
import math
def compute_ppl(model, tokenizer, text, max_length=1024):
encodings = tokenizer(text, return_tensors="pt", truncation=True, max_length=max_length)
input_ids = encodings.input_ids.to(model.device)
with torch.no_grad():
outputs = model(input_ids, labels=input_ids)
return math.exp(outputs.loss.item())
text = "今天天气真好,我想出去玩。"
print(f"PPL: {compute_ppl(model, tokenizer, text):.2f}")
模型评测
官方评测结果(Official Evaluation)
| 版本 | ZhoBLiMP | 汉字结构 | 汉字拼音 | AFQMC | OCNLI | TNEWS | WSC2020 |
|---|---|---|---|---|---|---|---|
| V13 🏆 | 63.5 | 64.7 | 49.5 | 69.0 | 64.0 | 53.9 | 63.5 |
| V14 | 64.3 | 62.4 | 41.9 | 69.0 | 66.0 | 54.1 | 63.5 |
| V15 | 62.4 | 63.9 | 47.4 | 69.0 | 65.9 | 54.4 | 63.8 |
评测配置: ZhoBLiMP/汉字/拼音为零样本评测; AFQMC/OCNLI/TNEWS/WSC2020 使用 finetune (lr=3e-5, batch=32, epochs=10)
ZhoBLiMP 15 维度详细分析 (V13)
| 维度 | V13 | V12 | V11 | 随机基线 | 说明 |
|---|---|---|---|---|---|
| BA (把字句) | 75.33 | 74.36 | 76.33 | 50.0 | 浅层句法 |
| question (疑问) | 64.41 | 68.78 | 63.05 | 50.0 | 疑问句结构 |
| nominal_expression | 75.85 | 72.58 | 71.82 | 50.0 | 名词表达式 |
| classifier (量词) | 77.78 | 79.11 | 74.44 | 50.0 | 量词搭配 |
| npi_licensing | 46.67 | 40.70 | 42.37 | 50.0 | ⚠️ 否定极性 |
| topicalization | 63.50 | 54.00 | 60.33 | 50.0 | 主题化结构 |
| verb_phrase | 75.17 | 77.57 | 79.81 | 50.0 | 动词短语 |
| anaphor (照应) | 35.00 | 37.33 | 36.44 | 50.0 | ⚠️ 低于随机 |
| passive (被动) | 37.03 | 30.69 | 32.50 | 50.0 | ⚠️ 低于随机 |
| argument_structure | 64.05 | 60.67 | 63.19 | 50.0 | 论元结构 |
| ellipsis (省略) | 71.00 | 72.11 | 66.56 | 50.0 | 省略句 |
| control_raising | 70.42 | 62.83 | 64.50 | 50.0 | 控制与提升 |
| relativization | 55.25 | 56.25 | 51.92 | 50.0 | 关系从句 |
| fci_licensing | 75.13 | 63.67 | 66.13 | 50.0 | 自由选择项 |
| quantifiers (量词辖域) | 84.67 | 88.00 | 98.17 | 50.0 | 量词辖域 |
| 平均 | 63.47 | 62.03 | 61.97 | 50.0 | — |
诊断: 模型擅长浅层模式匹配(BA、量词搭配、fci_licensing),但在深层句法推理(照应、被动、NPI)上低于随机基线,表明 100M tokens 的数据量不足以学习深层语法。
版本演进
V1–V15 版本演进时间线。蓝色 = 成功,黄色 = SOTA,红色 = 失败。
各版本最佳验证集 PPL(对数刻度)。从 V2 的 597 到 V13 的 38.68,整体降幅达 93.5%。
完整版本对比
| 版本 | 架构 | d_model | Layers | 参数量 | PPL | 核心创新 | 状态 |
|---|---|---|---|---|---|---|---|
| V1 | GPT-2 | 768 | 12 | ~110M | ~343 | 基线模型 | ⚠️ Bug |
| V2 | LLaMA | 768 | 12 | ~125M | 597 | RoPE+GQA+SwiGLU | ❌ Tokenizer |
| V3 | LLaMA | 768 | 12 | ~125M | ~542 | SentencePiece | ❌ NCCL |
| V4 | LLaMA | 1024 | 24 | ~350M | N/A | 深层架构 | ❌ 过大 |
| V5 | LLaMA | 512 | 12 | ~51M | 525 | 知识蒸馏 | ❌ KD 崩溃 |
| V6 | LLaMA | 640 | 12 | ~75M | N/A | 三阶段流水线 | ❌ 数据丢失 |
| V7 | LLaMA | 448 | 12 | ~30M | 50.8 | MNTP 混合训练 | ✅ |
| V8 | LLaMA | 512 | 12 | ~35M | 50.8 | 简化三阶段 | ✅ |
| V9 | LLaMA | 512 | 12 | ~35M | 50.8 | 探针实验 | ✅ |
| V10 | LLaMA | 512 | 12 | 38.7M | 42.9 | 生产管线 + SPM 32K | ✅ |
| V11 | LLaMA | 512 | 12 | 38.7M | 40.7 | EMA + SGDR | ✅ |
| V12 | LLaMA | 576 | 14 | 54.2M | 38.8 | Focal Loss + 数据清洗 | ✅ 效率王 |
| V13 | LLaMA | 768 | 14 | 94.2M | 38.7 | PPL 过滤 + MinHash | 🏆 SOTA |
| V14 | LLaMA | 640 | 12 | 59.2M | 41.8 | 效率优化 | ✅ |
| V15 | LLaMA | 640 | 14 | 68.2M | 45.1 | Multi-scale EMA | ⚠️ 回归 |
技术架构
模型架构 (V13 SOTA)
LlamaForCausalLM (94,246,656 params)
├── Tokenizer: SentencePiece Unigram (32K vocab)
├── Embedding: 768d (tied with LM head, 节省 ~24.6M 参数)
├── Transformer Blocks × 14
│ ├── RMSNorm (eps=1e-5, Pre-Norm)
│ ├── Self-Attention (SDPA / Flash Attention)
│ │ ├── Q: 12 heads × 64d = 768d
│ │ ├── K: 4 heads × 64d = 256d (GQA, 3:1 压缩)
│ │ ├── V: 4 heads × 64d = 256d
│ │ └── RoPE (θ=10000, max_pos=1024)
│ ├── RMSNorm
│ └── FFN (SwiGLU)
│ ├── Gate: 768d → 2048d
│ ├── Up: 768d → 2048d
│ └── Down: 2048d → 768d
├── RMSNorm (final)
└── LM Head (768d → 32K, tied)
架构演进:GPT-2 → LLaMA
| 组件 | GPT-2 (V1) | LLaMA (V2+) | 收益 |
|---|---|---|---|
| 位置编码 | Learned Absolute (512) | RoPE (θ=10000) | 零参数, 相对位置, 长度外推 |
| 注意力 | MHA 12 heads | GQA 12Q/4KV | 3× KV 缓存减少 |
| 激活函数 | GELU | SwiGLU | 门控机制, 更好表达力 |
| 归一化 | LayerNorm (Post) | RMSNorm (Pre) | 70% 计算量, 更好梯度流 |
| FFN 维度 | 4×d (3072) | 8/3×d (2048) | SwiGLU 三投影下相同参数量 |
训练流水线
三阶段设计
| 阶段 | 方法 | 学习率 | 调度器 | 核心技术 | PPL 贡献 |
|---|---|---|---|---|---|
| Stage 1 | CLM | 6e-4 | SGDR (T_mult=2) | Focal Loss + EMA + Label Smoothing | 基础→42 |
| Stage 2 | MNTP | 5e-4 | Cosine | 动态 CLM/Mask 比例 + EMA | 42→38.68 |
| Stage 3 | Polish | 2e-5 | Cosine | ⚠️ DropBlock+StochDepth (有害,已弃用) | — |
Stage 2 MNTP (Masked Next Token Prediction)
MNTP 是本项目的核心创新之一,结合了 GPT 的因果语言建模和 BERT 的掩码预测:
- CLM:MNTP 动态比例: 25% → 12.5% → 6.25%(随训练进度递减)
- Mask 比例退火: 25% → 10%(逐步降低掩码比例)
- Focal Loss: 聚焦困难 token,γ=1.0 (Stage 2), 1.5 (Stage 1)
分阶段 PPL 改进
| 版本 | Stage 1 PPL | 最终 PPL | 改善 | 训练时间 |
|---|---|---|---|---|
| V10 | 55.60 | 42.89 | -12.71 | 1.5h |
| V11 | 45.44 | 40.73 | -4.71 | 4.8h |
| V12 | 41.20 | 38.84 | -2.36 | 7.5h |
| V13 | 42.19 | 38.68 | -3.51 | 7.7h |
关键技术创新
技术贡献排名
| 排名 | 技术 | PPL 贡献 | 引入版本 | 原理 |
|---|---|---|---|---|
| 🥇 | SentencePiece 分词器 | ~74% PPL ↓ | V3 | 替代 ByteLevel BPE,在字/词级别处理中文 |
| 🥈 | EMA 权重平均 | 6~8% PPL ↓ | V11 | 指数移动平均平滑训练噪声 |
| 🥉 | MNTP 混合训练 | 3~5 PPL ↓ | V7 | GPT-BERT 混合,同时 CLM + Masked 预测 |
| 4 | SGDR 调度器 | ~2 PPL ↓ | V11 | 周期性重启学习率 |
| 5 | Focal Loss | V12 | 聚焦困难 token | |
| 6 | PPL 数据过滤 | ~0.5 PPL ↓ | V13 | 用已训练模型过滤低质量数据 |
| 7 | Label Smoothing | ~0.3 PPL ↓ | V10 | 软化硬标签 |
核心公式
Perplexity (PPL):
PPL = exp( -1/N × Σ log p(x_i | x_{<i}) )
Focal Loss:
FL(p_t) = -(1 - p_t)^γ × log(p_t)
γ = 1.5 (Stage 1), 1.0 (Stage 2)
EMA (Exponential Moving Average):
θ_EMA = 0.999 × θ_EMA + 0.001 × θ
MNTP Loss:
L_MNTP = α × L_CLM + (1-α) × L_Mask
动态调整: α ∈ {0.25, 0.125, 0.0625}
EMA 定量贡献
| 阶段 | Base PPL | EMA PPL | 改进幅度 |
|---|---|---|---|
| V13 Stage 1 | 43.15 | 39.51 | -8.4% |
| V13 Stage 2 | 41.45 | 38.68 | -6.7% |
| V13 Stage 3 | 40.40 | 40.08 | -0.8% |
📌 关键发现: EMA 在 Stage 1 (高 LR + 高噪声) 效果最显著,后续阶段收益递减。
参数效率分析
| 版本 | 参数量 | PPL | PPL/10M 参数 | tokens/param | 说明 |
|---|---|---|---|---|---|
| V11 | 38.7M | 40.73 | 10.53 | 2.6× | 最高效率 |
| V12 | 54.2M | 38.84 | 7.21 | 1.9× | 效率与性能平衡最优 |
| V13 | 94.2M | 38.68 | 4.11 | 1.1× | 参数过多 |
💡 Chinchilla Scaling Law 要求 tokens/param = 20
200×。本项目仅 82M tokens,因此 4055M 参数是最优范围。V13 虽然 PPL 最低,但 94.2M 参数的效率不如 V12 的 54.2M。
训练细节
超参数配置 (V13 SOTA)
| 参数 | Stage 1 (CLM) | Stage 2 (MNTP) |
|---|---|---|
| Learning Rate | 6e-4 | 5e-4 |
| Scheduler | SGDR (T_mult=2) | Cosine |
| Focal Loss γ | 1.5 | 1.0 |
| Label Smoothing | 0.1 → 退火 | 0.05 → 退火 |
| BPE Dropout | 0.1 | 0.1 |
| Attention Dropout | 0.1 | 0.05 |
| EMA Decay | 0.999 | 0.999 |
| Batch Size (effective) | 128 (16×4GPU×2accum) | 128 |
| Max Seq Length | 1024 | 1024 |
| Stride | 512 (50% overlap) | 512 |
| Early Stop Patience | 5 | 10 |
| Training Epochs | 8 | 10 |
| Optimizer | AdamW (β₁=0.9, β₂=0.95) | AdamW |
| Weight Decay | 0.1 | 0.1 |
| Precision | bf16 | bf16 |
数据处理流程
原始数据 (babylm-zho-100M, ~2M 行)
│
▼ 清洗: 去除过短行 (≤2 chars), 中文字符比例过滤
│
▼ 去重: MD5 精确去重 + MinHash 近似去重 (threshold=0.7)
│
▼ PPL 过滤: 用已训练模型计算每行 PPL, 过滤 max_ppl=250
│
▼ 硬样本上采样: PPL>80 的样本 ×2
│
▼ Tokenization: SentencePiece Unigram (32K vocab)
│
▼ 分块: 滑动窗口 (max_length=1024, stride=512, 50% 重叠)
│
▼ 分割: 95% 训练 / 5% 验证
Tokenizer 说明
Tokenizer 演进
| 版本 | 类型 | 词表大小 | 中文适配 | PPL 影响 |
|---|---|---|---|---|
| V1 | BPE (WhitespaceSplit) | 32K | ❌ 中文句子当单 token | PPL=343 |
| V2 | ByteLevel BPE | 32K | ❌ 拆为 UTF-8 字节 | PPL=597 |
| V3~V6 | SentencePiece BPE | 32K | ⚠️ 基础支持 | PPL~527 |
| V7~V9 | SPM Unigram 8K | 8K | ✅ 含 <mask> |
PPL~50.8 |
| V10+ | SPM Unigram 32K | 32K | ✅ 最优平衡 | PPL≤42.9 |
ByteLevel BPE 的灾难性影响
示例: "今天天气真好" 的分词对比:
- ByteLevel BPE (V2):
['ä»Ĭ天天æ°Ķ', 'çľŁå¥½', 'ï', '¼', 'Į', ...]— 中文字符被拆成无意义的 UTF-8 字节 - SentencePiece (V3+):
['▁今天', '天气', '真好']— 正确的字/词级别分词
这一差异导致 V2 (ByteLevel BPE) PPL=597,而切换到 SentencePiece 后 PPL 大幅改善,是全项目最大的单次技术贡献。
失败经验与教训
| 版本 | 失败原因 | 教训 |
|---|---|---|
| V2 | ByteLevel BPE 不适配中文 | 中文需要字/词级别 Tokenizer,而非字节级别 |
| V4 | 350M 参数 / 82M tokens = 0.23x | tokens/param 应 > 1.0,理想 20~200× |
| V5 | KD 配置过于激进 (lambda_kd=0.7) | 蒸馏损失不应主导 |
| V6 | 数据清洗丢失 78% 数据 | 清洗需保守,宁可保留噪声 |
| V13 Stage 3 | DropBlock + StochDepth 在低 LR 下有害 | 低学习率阶段不应加强正则化 |
| V15 | FFN 维度非 256 倍数 (1706) | 架构参数需对齐 GPU 张量布局 |
局限性
- 数据量不足: 100M tokens 远低于 Chinchilla 最优比例,限制了模型能力上限
- 深层语法推理弱: ZhoBLiMP 的 anaphor、passive、NPI 维度低于随机基线
- CLUEWSC 固定: 所有版本均为 63.49% (MCC=0.0),模型学到浅层启发式
- 贪婪解码退化: 贪婪解码产生 token 级重复,需使用 sampling
- 生成质量有限: 作为 94M 参数的小模型,生成能力有限
引用
如果本项目对您的研究有帮助,请引用:
@misc{babylm2026sulab,
title={BabyLLM: From-Scratch Pre-training of Compact Chinese Language Models},
author={SULAB Team},
year={2026},
howpublished={NLPCC 2026 ChineseBabyLM Challenge},
url={https://github.com/C5-jpg/babyLLM}
}
参考文献
- Touvron et al. (2023). LLaMA: Open and Efficient Foundation Language Models. arXiv:2302.13971
- Su et al. (2021). RoFormer: Enhanced Transformer with Rotary Position Embedding. arXiv:2104.09864
- Shazeer (2020). GLU Variants Improve Transformer. arXiv:2002.05202
- Lin et al. (2017). Focal Loss for Dense Object Detection. arXiv:1708.02002
- Loshchilov & Hutter (2016). SGDR: Stochastic Gradient Descent with Warm Restarts. arXiv:1608.03983
- Kudo & Richardson (2018). SentencePiece. arXiv:1808.06226
- Hoffmann et al. (2022). Training Compute-Optimal Large Language Models (Chinchilla). arXiv:2203.15556






