# J-GPT **Repository Path**: hechanggen/J-GPT ## Basic Information - **Project Name**: J-GPT - **Description**: 纯 Java 实现的 GPT 原理教学项目,从零开始实现大语言模型的核心算法。 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-24 - **Last Updated**: 2026-03-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # J-GPT 纯 Java 实现的 GPT 原理教学项目,从零开始实现大语言模型的核心算法。 ## 项目简介 本项目是 [karpathy/makemore](https://github.com/karpathy/makemore) 的 Java 版本,使用纯 Java(无深度学习框架依赖)实现了: - **自动微分引擎**:基于计算图的梯度反向传播 - **字符级 Tokenizer**:将文本转换为离散符号 - **GPT 模型架构**:包含多头自注意力机制和 MLP 块 - **Adam 优化器**:带动量估计的自适应学习率优化 - **训练与推理**:完整的训练循环和文本生成 ## 快速开始 ### 环境要求 - JDK 11+ - Maven 3.6+ ### 编译项目 ```bash mvn clean compile ``` ### 运行测试 ```bash mvn test ``` ### 运行训练和推理 ```bash mvn exec:java -Dexec.mainClass=gpt.Main ``` ## 项目结构 ``` j-gpt/ ├── pom.xml # Maven 配置 ├── src/main/java/gpt/ │ ├── Value.java # 自动微分核心类 │ ├── MatrixUtils.java # 矩阵运算工具 │ ├── Tokenizer.java # 分词器 │ ├── GPTModel.java # GPT 模型定义 │ ├── AdamOptimizer.java # Adam 优化器 │ ├── Trainer.java # 训练器 │ └── Main.java # 程序入口 └── src/test/java/gpt/ ├── ValueTest.java # Value 类测试 ├── MatrixUtilsTest.java # 矩阵工具测试 ├── TokenizerTest.java # 分词器测试 ├── GPTModelTest.java # 模型测试 └── AdamOptimizerTest.java # 优化器测试 ``` ## 核心算法 ### 1. 自动微分 (Value.java) `Value` 类是自动微分的核心,每个 `Value` 对象存储: - `data`: 标量值 - `grad`: 梯度值 - `prev`: 前驱节点(计算图) - `op`: 产生该节点的操作符 **核心操作:** - `add`, `mul`, `pow`, `log`, `exp`, `relu`: 前向运算 - `backward()`: 反向传播,应用链式法则 ```java // 示例:构建计算图 Value a = new Value(2.0); Value b = new Value(3.0); Value c = a.mul(b); // c = 6 c.backward(); // a.grad = 3, b.grad = 2 ``` ### 2. Tokenizer (Tokenizer.java) 字符级分词器,将文本映射为整数 ID: - 构建词汇表:`` + 所有出现过的字符 - `encode()`: 字符串 → 整数序列 - `decode()`: 整数序列 → 字符串 ### 3. GPT 模型 (GPTModel.java) 模型架构遵循 GPT-2,主要组件: **参数配置:** - `n_embd = 16`: 嵌入维度 - `n_head = 4`: 注意力头数 - `n_layer = 1`: Transformer 层数 - `block_size = 8`: 最大序列长度 **前向传播流程:** 1. **词嵌入 + 位置嵌入**:查找 token 和位置的向量表示 2. **RMSNorm**:归一化输入 3. **多头自注意力**:计算 token 间的依赖关系 4. **MLP 块**:两层全连接网络,使用 ReLU² 激活 5. **输出层**:映射到词汇表大小的 logits ### 4. Adam 优化器 (AdamOptimizer.java) 自适应矩估计优化算法: - `m`: 一阶矩(均值)估计 - `v`: 二阶矩(未中心方差)估计 - 学习率衰减:`lr = initial_lr * (1 - step / num_steps)` ## 模型架构详解 ``` 输入 Token → 词嵌入 → + 位置嵌入 → RMSNorm ↓ ┌───────────────┐ │ Transformer │ │ Layer │ └───────────────┘ ↓ ┌───────────────┐ │ 多头注意力 │ │ (Self-Attn) │ └───────────────┘ ↓ ┌───────────────┐ │ MLP │ │ (ReLU²激活) │ └───────────────┘ ↓ ┌───────────────┐ │ 输出层 │ │ (lm_head) │ └───────────────┘ ↓ Softmax → 概率分布 ``` ### 多头注意力机制 每个注意力头独立计算: 1. **Query, Key, Value 投影**:`q = Wq·x`, `k = Wk·x`, `v = Wv·x` 2. **注意力分数**:`score = q·k / sqrt(d_k)` 3. **Softmax 归一化**:`weight = softmax(score)` 4. **加权求和**:`output = weight·v` ### RMSNorm ``` RMSNorm(x) = x / sqrt(mean(x²) + ε) ``` 相比 LayerNorm,RMSNorm 去除了均值中心化,计算更高效。 ## 训练流程 ```java for (step = 0; step < numSteps; step++) { // 1. 采样文档,添加 BOS 标记 tokens = [BOS] + encode(doc) + [BOS] // 2. 前向传播,计算 logits 和 loss for (pos = 0; pos < seq_len; pos++) { logits = model.forward(tokens[pos], pos) probs = softmax(logits) loss += -log(probs[target]) } // 3. 反向传播,计算梯度 loss.backward() // 4. Adam 更新参数 optimizer.step() } ``` ## 推理(文本生成) ```java for (sample = 0; sample < numSamples; sample++) { token = BOS for (pos = 0; pos < block_size; pos++) { logits = model.forward(token, pos) probs = softmax(logits / temperature) token = sample(probs) // 带温度采样的随机选择 if (token == BOS) break output += decode(token) } } ``` **温度采样:** - `temperature < 1`: 降低随机性,选择高概率 token - `temperature > 1`: 增加随机性,更均匀的分布 ## 超参数配置 | 参数 | 默认值 | 说明 | |------|--------|------| | `n_embd` | 16 | 嵌入维度 | | `n_head` | 4 | 注意力头数 | | `n_layer` | 1 | Transformer 层数 | | `block_size` | 8 | 最大序列长度 | | `learning_rate` | 0.01 | 初始学习率 | | `num_steps` | 500 | 训练步数 | | `temperature` | 0.6 | 采样温度 | ## 示例输出 ``` --- training --- step 1 / 500 | loss 3.2839 step 50 / 500 | loss 2.5651 step 100 / 500 | loss 3.3819 ... step 500 / 500 | loss 2.6045 --- inference --- sample 1: miiena sample 2: annra sample 3: daran ... ``` ## 扩展建议 1. **增加模型规模**:调整 `n_embd`, `n_head`, `n_layer` 2. **更多训练数据**:使用更大的文本数据集 3. **更长序列**:增加 `block_size` 4. **保存/加载模型**:序列化 `state_dict` 到文件 5. **批量训练**:支持 mini-batch 梯度下降 6. **更多激活函数**:添加 GeLU、SiLU 等 ## 参考资料 - [Andrej Karpathy - makemore](https://github.com/karpathy/makemore) - [Attention Is All You Need](https://arxiv.org/abs/1706.03762) - [Root Mean Square Layer Normalization](https://arxiv.org/abs/1910.07467) - [Adam: A Method for Stochastic Optimization](https://arxiv.org/abs/1412.6980) ## License MIT License