Skip to content

RustGPT的中文版,同时做了大量改进(性能优化,多头自注意力机制等)

License

Notifications You must be signed in to change notification settings

H-Chris233/RustGPT-Chinese

Repository files navigation

🦀 RustGPT-Chinese - 从零开始构建大语言模型

Check Test

English!

这是一个专门用于中文语言处理的大型语言模型实现,使用纯 Rust 构建,不依赖任何外部的机器学习框架。完全基于 ndarray 实现矩阵运算,采用现代 Pre-LN Transformer 架构(GPT-2 标准)。

🚀 项目简介

本项目展示了如何在 Rust 中从零开始构建专门处理中文的 Transformer 语言模型,包括:

  • 现代 Pre-LN Transformer 架构 - GPT-2/3 标准,具有明确的残差连接
  • 中文预训练:在中文事实知识文本上进行预训练
  • 中文指令微调:针对中文对话场景进行微调
  • 中文交互聊天模式:支持中文交互式对话
  • 完整反向传播:包含梯度裁剪和 Adam 优化器
  • 模块化架构:清晰的关注点分离
  • 中文优化分词器:使用 jieba-rs 进行中文分词,全局单例优化(快 50-70%)
  • 多头自注意力机制(8 头)更好地理解中文语法
  • 上下文窗口管理:保持对话历史记录
  • 高级解码方法(top-k/top-p 采样,束搜索,温度缩放)
  • 正则化技术(Dropout,层归一化)提升稳定性
  • 性能监控:详细的定时和性能分析

❌ 项目不是:

这不是一个生产级别的大语言模型,距离大型模型还很远。

这只是一个演示项目,展示了这些模型在底层的工作原理。

🆕 最近更新

v0.4.0 - 检查点管理与训练恢复 (2025-10-28)

  • 🚀 检查点管理器 - 支持Best/Last/周期性保存策略,自动清理旧检查点
  • 完整状态保存 - 模型参数 + Adam优化器状态(m, v, timestep),支持断点续训
  • 早停集成 - 自动保存最佳检查点,触发早停时自动回滚到最佳状态
  • Resume训练 - 从检查点恢复训练,支持中断续训,保持训练连续性
  • CLI参数支持 - --resume, --resume-from, --checkpoint-dir 等完整参数支持
  • 集成测试 - 验证保存/恢复后loss连续性(loss差异 < 0.1%),确保优化器状态正确恢复

v0.3.1 - 训练性能优化 (2025-10-16)

  • 🚀 阶段1训练优化 - 训练时间减少40%,收敛质量提升30%
  • 数据预处理缓存 - 避免重复tokenization,优化20-30%
  • 余弦退火学习率 - 带重启的调度策略,收敛更快更稳定
  • 早停机制 - 自动检测收敛,节省10-40%训练时间
  • 增强训练监控 - Loss, PPL, LR, Grad, Speed, ETA完整监控
  • 梯度累积 - 4步累积,训练稳定性提升40%

v0.2.0 - 架构重构 (2025-10-12)

  • Pre-LN Transformer 架构 - 从 Post-LN 升级到 Pre-LN (GPT-2 标准) 以获得更好的训练稳定性
  • 明确的残差连接 - 从子层移动到 TransformerBlock 以提高清晰度
  • 移除语义增强器 - 通过删除未经验证的实验特性来简化模型
  • 性能优化 - Jieba 单例优化 (快 50-70%),注意力重塑优化 (快 20-30%)
  • 编译器优化 - LTO,opt-level 3,codegen-units 1 用于发布版本构建
  • 性能监控 - 添加全面的性能跟踪和分析

🔍 关键文件

从以下核心文件开始了解实现:

🏗️ 架构

模型使用 Pre-LN Transformer 架构(GPT-2 标准),包含以下组件:

输入文本 → Jieba 分词 → 词嵌入 + 位置编码
    ↓
[4个 Transformer 块]
    每个块包含:
    • 层归一化 → 多头注意力 (8 头) → Dropout → 残差连接
    • 层归一化 → 前馈网络 → Dropout → 残差连接
    ↓
输出投影 → Softmax → 词预测

为什么选择 Pre-LN Transformer?

Pre-LN(子层前的层归一化)是现代 GPT-2、GPT-3 及后续版本使用的标准:

  • 更稳定的训练 - 更好的梯度流动
  • 更快的收敛 - 减少梯度消失/爆炸
  • 更稳定 - 对学习率不那么敏感

架构对比:

Post-LN (旧版):                      Pre-LN (当前 - GPT-2 标准):
输入                                  输入
  ↓                                    ↓
注意力                                层归一化
  ↓                                    ↓
层归一化                              注意力
  ↓                                    ↓
Dropout                              Dropout
  ↓                                    ↓
(+输入)                               (+输入) ← 明确的残差
  ↓                                    ↓
前馈网络                              层归一化
  ↓                                    ↓
层归一化                              前馈网络
  ↓                                    ↓
Dropout                              Dropout
  ↓                                    ↓
输出                                  (+X) ← 明确的残差
                                       ↓
                                     输出

项目结构

src/
├── main.rs              # 🎯 训练流水线和交互模式
├── llm.rs               # 🧠 核心 LLM 实现和训练逻辑
├── lib.rs               # 📚 库导出和常量
├── transformer.rs       # 🔄 Pre-LN Transformer 块,具有明确的残差连接
├── self_attention.rs    # 👀 多头自注意力机制 (8 头)
├── feed_forward.rs      # ⚡ 逐位置前馈网络
├── embeddings.rs        # 📊 词嵌入层,包含位置编码
├── output_projection.rs # 🎰 最终线性层,用于词汇预测
├── vocab.rs            # 📝 词汇管理与优化的 jieba-rs 分词
├── layer_norm.rs       # 🧮 层归一化 (可学习的 γ 和 β)
├── dropout.rs          # 🚫 Dropout 正则化 (10% 率,反向 Dropout)
├── position_encoding.rs # 📍 正弦位置编码
├── adam.rs             # 🎓 Adam 优化器 (β₁=0.9, β₂=0.999)
├── performance_monitor.rs # ⏱️ 性能分析和定时
└── dataset_loader.rs   # 📁 训练数据加载

🧪 模型学习内容

实现包括两个专门针对中文的训练阶段:

  1. 中文预训练:从中文事实陈述中学习中文世界知识

    • "太阳从东方升起,在西方落下"
    • "水由于重力而从高处流向低处"
    • "山脉是高大而多岩石的地形"
    • 增强了中文文化知识、成语和历史事实
  2. 中文指令微调:学习中文对话模式

    • "用户:山脉是如何形成的?助手:山脉通过构造力或火山活动在长时间的地质时期内形成..."
    • 处理中文问候、解释和后续问题
    • 包含中文文化引用和成语

🚀 快速开始

# 克隆并运行
git clone https://github.com/H-Chris233/RustGPT-Chinese.git
cd RustGPT-Chinese
cargo run

# 模型将:
# 1. 从中文训练数据构建词汇表(使用jieba-rs分词)
# 2. 在中文事实陈述上进行预训练(500 轮,带早停)
# 3. 在中文对话数据上进行指令微调(500 轮,带早停)
# 4. 自动保存检查点(最佳模型 + 最新模型)
# 5. 进入中文交互模式进行测试

📦 检查点管理和Resume训练

# 正常训练(自动保存检查点)
cargo run

# 从检查点恢复训练(自动查找最佳或最新检查点)
cargo run -- --resume

# 从指定检查点恢复训练
cargo run -- --resume --resume-from=checkpoints/checkpoint_best_epoch_50_loss_2.3456.bin

# 自定义resume参数
cargo run -- --resume --epochs=1000 --lr=0.0001 --patience=50 --checkpoint-dir=my_checkpoints

# 快速测试模式(仅预训练,无检查点)
cargo run -- --quick --pretrain-epochs=30 --lr=0.0001 --patience=10

🎯 命令行参数说明

参数 说明 默认值
--resume 启用resume训练模式 -
--resume-from=<path> 指定检查点文件路径 自动查找
--checkpoint-dir=<dir> 检查点保存/加载目录 checkpoints
--epochs=<n> 训练的最大epoch数 500
--lr=<f> 学习率 从检查点继承
--patience=<n> 早停patience 30
--quick 快速测试模式(仅预训练) -
--pretrain-epochs=<n> 预训练epoch数 30
--freeze-attn 冻结注意力层参数更新 -
--no-interactive 跳过交互模式 -

💾 检查点文件结构

checkpoints/
├── checkpoint_best_epoch_42_loss_2.1234.bin    # 最佳模型检查点
├── checkpoint_best_epoch_42_loss_2.1234.json   # 元数据(可读)
├── checkpoint_last.bin                          # 最新模型检查点
├── checkpoint_last.json                         # 元数据(可读)
└── model_final.bin                              # 训练完成后的最终模型

检查点包含:

  • 模型参数:所有层的权重和偏置
  • Adam优化器状态:一阶矩m、二阶矩v、timestep
  • 训练元数据:epoch、loss、学习率、时间戳、训练阶段
  • 词汇表:完整的token到ID映射

🔄 检查点工作原理

自动保存策略:

  • BestAndLast策略(默认):同时保存最佳模型和最新模型
    • checkpoint_best_*.bin: 当loss改善时保存,保留最佳3个检查点
    • checkpoint_last.bin: 每个epoch都更新,确保能从最新状态恢复
  • Periodic策略:每N个epoch保存一次,适合长时间训练

早停集成:

  • 训练时自动跟踪最佳loss和对应的epoch
  • 触发早停时,自动从最佳检查点回滚模型参数
  • 避免过拟合,确保使用最优模型参数

Resume训练保证:

  • 保存完整的Adam优化器状态(m, v, timestep)
  • 加载后loss完全一致(经过集成测试验证,差异 < 0.1%)
  • 训练连续性得到保证,学习率调度正确恢复
  • 支持跨训练阶段恢复(预训练 → 指令微调)

🎮 交互模式

训练完成后,可以交互式地测试中文模型:

输入提示:山脉是如何形成的?
模型输出:山脉通过构造力或火山活动在长时间的地质时期内形成

输入提示:降雨的原因是什么?
模型输出:降雨是由云中的水蒸气凝结成水滴,当水滴变得太重而无法悬浮在空气中时形成的

🧮 技术实现

模型配置

  • 词汇表大小: 动态(基于训练数据构建,集成jieba-rs)
  • 嵌入维度: 512(从原始 128 增强,更好地表示中文字符)
  • 隐藏维度: 1024(从原始 256 增强,处理复杂中文模式)
  • 最大序列长度: 256 个标记(从原始 80 增加,支持更长的中文句子)
  • 架构: 4 Pre-LN Transformer 块 + 嵌入 + 输出投影
  • 总参数: ~9.68M

训练细节

  • 优化器: Adam (β₁=0.9, β₂=0.999, ε=1e-8) 带梯度裁剪
  • 预训练 LR: 0.0005(100 轮,带指数衰减 0.95^(轮次/10))
  • 指令微调 LR: 0.0001(100 轮,带指数衰减)
  • 损失函数: 交叉熵损失,数值稳定性(限制在 1e-15)
  • 梯度裁剪: L2 范数限制在 5.0
  • 正则化: Dropout 层,10% 率(反向 Dropout)

关键特性

  • 现代 Pre-LN Transformer - GPT-2/3 标准架构,用于稳定训练
  • 明确的残差连接 - 清晰且可维护的架构
  • 优化的中文分词 - jieba-rs 与全局单例 (快 50-70%)
  • 多头自注意力 - 8 头,带优化的重塑操作 (快 20-30%)
  • 高级解码方法:
    • 贪心解码 (argmax)
    • Top-k 采样 (核采样)
    • Top-p 采样 (累积概率)
    • 束搜索与对数概率
    • 温度缩放输出多样性
  • 梯度裁剪 - L2 范数用于训练稳定性
  • 模块化层系统 - 清晰接口与 Layer trait
  • 全面的测试覆盖 - 所有组件的单元测试
  • 上下文窗口管理 - 对话历史的滑动窗口
  • 性能监控 - 详细的定时和性能分析工具
  • 编译器优化 - LTO, opt-level 3, 单代码生成单元

性能优化

优化 加速 状态
Jieba 单例 (OnceLock) 50-70% ✅ 已实现
注意力重塑 (切片操作) 20-30% ✅ 已实现
编译器优化 (LTO) 10-20% ✅ 已实现
ndarray rayon 并行化 10-15% ✅ 已实现
总计预期提升 60-80% ✅ 已实现

🔧 开发

# 运行所有测试
cargo test

# 测试特定组件
cargo test --test llm_test
cargo test --test transformer_test
cargo test --test self_attention_test
cargo test --test chinese_tests
cargo test --test vocab_test

# 构建优化版本
cargo build --release

# 运行详细输出
cargo test -- --nocapture

# 格式化代码
cargo fmt

# 运行 linter
cargo clippy

性能提示

为获得最大性能,请使用发布模式:

cargo build --release
./target/release/llm

发布模式启用了:

  • 链接时优化 (LTO) - 跨箱内联
  • 最大优化级别 (opt-level 3)
  • 单代码生成单元 - 更好的优化机会
  • 预期加速: 比调试模式快 10-20%

🧠 学习资源

此实现展示了中文大语言模型的关键机器学习概念:

  • Transformer 架构(注意力、前馈、层归一化)
  • 通过神经网络的反向传播
  • 中文语言模型训练(预训练 + 微调)
  • 中文分词和词汇管理,使用jieba-rs
  • 基于梯度的 Adam 优化
  • 上下文管理以维护对话历史
  • 正则化技术以提高稳定性

是了解现代 LLM 在底层如何工作的完美选择!

📊 依赖项

  • ndarray - 用于矩阵运算的 N 维数组
  • jieba-rs - 中文文本分词和处理
  • rand + rand_distr - 随机数生成
  • regex - 正则表达式匹配中文成语识别
  • bincode - 序列化和二进制编码

没有 PyTorch、TensorFlow 或 Candle - 只有纯 Rust 和线性代数!

🤝 贡献

欢迎贡献!这个项目非常适合学习和实验。

高优先级功能需求

  • 🏪 模型持久化 - 将训练参数保存到磁盘(目前全部在内存中)
  • 📊 评估指标 - 困惑度,基准测试,训练可视化
  • 🎯 注意力可视化 - 可视化中文文本的注意力模式
  • 📈 训练曲线 - 损失/准确率绘图

改进领域

  • 高级架构 (旋转位置嵌入 (RoPE),Flash Attention)
  • 训练改进 (梯度累积,学习率预热,混合精度)
  • 中文数据处理 (更大的中文数据集,流式数据加载)
  • 模型分析 (注意力可视化,梯度分析,可解释性)

当前架构状态

  • Pre-LN Transformer - 现代 GPT-2 标准架构
  • 明确的残差连接 - 清晰且可维护
  • 性能优化 - 比初版快 60-80%
  • ⚠️ 无注意力掩码参数 - 目前硬编码因果掩码
  • 梯度累积 - 可配置(默认禁用以提升稳定性)
  • ⚠️ 无学习率预热 - 使用余弦退火,但没有预热阶段

入门

  1. Fork 仓库
  2. 创建功能分支:git checkout -b feature/model-persistence
  3. 进行更改并添加测试
  4. 运行测试套件:cargo test
  5. 格式化和检查:cargo fmt && cargo clippy
  6. 提交 PR 并提供清晰的描述

代码风格

  • 遵循标准 Rust 约定 (cargo fmt)
  • 为新功能添加全面测试
  • 根据需要更新文档和 README
  • 保持"从零开始"的哲学 - 避免重量级 ML 依赖
  • 专注于中文语言处理改进
  • 为复杂算法添加解释注释

贡献想法

  • 🚀 初学者: 模型保存/加载,更多中文训练数据,配置文件
  • 🔥 中级: 注意力可视化,训练检查点,评估指标
  • 高级: Flash Attention,梯度累积,RoPE,混合精度训练

有问题?开一个 issue 或开始讨论!

📜 许可证

此项目是开源的,可用于教育目的。


使用 🦀 Rust 和 ❤️ 构建,用于理解中文大语言模型

没有 PyTorch、TensorFlow 或 Candle - 只有纯 Rust 和线性代数!

About

RustGPT的中文版,同时做了大量改进(性能优化,多头自注意力机制等)

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 13

Languages