Skip to content
The Second Culture
Go back
用 4 块钱训练一个 JEPA 架构的大语言模型

用 R torch 从零构建的 JEPA (Joint Embedding Predictive Architecture) 大语言模型,含 BPE 分词器训练、预训练、SFT 微调、推理全流程,总计约 700 行主脚本代码,单卡 RTX 4090 可跑,训练成本约 4 元

最初版本基于标准 GPT 架构。后来和好友 Vivian Zhang(NYC Data Science Academy 创始人)聊到 Yann LeCun 团队在 JEPA 方向的工作,很受启发,于是将整个模型用 JEPA 框架重新实现——用 InfoNCE 对比损失替代交叉熵,用 VQ 最近邻量化替代线性投影 head。这既是对 JEPA 在语言建模中的可行性验证,也是对 LeCun”世界模型”理念的一次靠拢。

项目特点

1. 全 R 语言实现

完全基于 R 语言的 torchluz 生态,不依赖任何 Python 深度学习框架。这在 LLM 领域极为少见,展示了 R 语言在深度学习前沿探索中的可能性。

2. JEPA + VQ 核心架构

不同于标准 GPT 式语言模型(在 logits 上计算交叉熵损失),本项目采用 JEPA (Joint Embedding Predictive Architecture)

相比传统 LLM,这种架构有以下特点:

3. JEPA vs 标准 Decode-Only 架构对比

维度标准 Decode-Only (GPT)本项目 JEPA + VQ
损失函数交叉熵损失 (Cross-Entropy)InfoNCE 对比损失
监督信号在词表维度上做分类,预测正确的 token ID在 embedding 空间中拉近正样本、推开负样本
输出头线性 LM HeadVQ 最近邻搜索,复用 token embedding 矩阵
模型容量LM Head 贡献约 5.2M 参数无输出头参数,全部容量分配给 Transformer 主干
梯度回传标准 softmax 交叉熵,梯度直接回传VQ 量化通过直通估计器 (STE) 绕路回传
解码方式取概率最高的 token取最近的 embedding
学习目标学习 token 的共现频率分布 (n-gram 模式)学习 token 间的语义相似度(语义空间中的相对位置)
输出空间离散词表上的概率分布(唯一 ground truth)连续 embedding 空间(可插值、编辑后再量化)

标准 GPT 像”词汇选择题”——模型在 8192 个词中选一个填进去,选错了就纠正。JEPA 则像”语义连线题”——模型在向量空间中预测下一个词的位置,对比预测位置和真实位置的远近。

两种架构各有所长。标准 GPT 在开放域文本生成上更成熟稳定,而 JEPA 在语义理解连续空间操作上有独特优势。本项目选择了 JEPA,是对 LeCun 世界模型理念的一次实践验证。

极致低成本复现

核心技术细节

分词器 — 01_bpe_tokenizers.R

预训练 — 02_JEPA_VQ.R

SFT 指令微调 — 04_SFT_train.R

推理

预训练(03_VQ_inference.R)

SFT(05_SFT_inference.R)

训练流水线

数据准备(src/ 目录)与模型训练(scripts/ 目录)分离,各自独立运行。

数据准备

本项目仅需两个数据源:

注:使用特定领域的数据在保证训练效果的同时降低了数据量,因此模型问答能力也限定在 AI/大数据/数据科学相关主题。

模型训练

项目分为 5 个独立脚本,共享同一份环境检测与超参配置(scripts/utils/config.R),每个阶段可独立运行:

01_bpe_tokenizers.R    # BPE 分词器训练 + 评估
02_JEPA_VQ.R           # JEPA 预训练(两阶段)
03_VQ_inference.R      # 预训练模型推理测试
04_SFT_train.R         # 指令微调(冻结 1-7 层 + Loss Mask)
05_SFT_inference.R     # SFT 后推理(带温度/惩罚/Top-K)

代码设计特点

尽管项目可在 4090 上全速训练,但代码设计优先考虑了可读性和教学性

快速开始

环境要求

安装依赖

install.packages(c("jsonlite", "tokenizers.bpe", "R6", "purrr", "torch", "luz"))

运行流水线

# 1. BPE 分词器训练
source("scripts/01_bpe_tokenizers.R")

# 2. JEPA 预训练
source("scripts/02_JEPA_VQ.R")

# 3. 预训练模型推理测试
source("scripts/03_VQ_inference.R")

# 4. SFT 指令微调
source("scripts/04_SFT_train.R")

# 5. SFT 后推理
source("scripts/05_SFT_inference.R")

数据准备

本项目数据可在 HuggingFace 下载,放入 data/raw/ 目录:

预训练数据:每行 JSON 包含 text 字段

{"text": "深度学习是机器学习的一个子集..."}

SFT 数据:每行 JSON 包含 instructionoutput 字段,output 中包含 <think> 标签,表示模型的思考过程。

{"instruction":"Git 用于对代码进行什么控制?","output":"<think>\n用户询问Git的功能,这是关于代码版本控制的工具"}

项目结构

scripts/
├── 01_bpe_tokenizers.R       BPE 分词器训练与评估
├── 02_JEPA_VQ.R              JEPA 预训练(两阶段)
├── 03_VQ_inference.R         预训练模型推理
├── 04_SFT_train.R            指令微调(Loss Mask + 层冻结)
├── 05_SFT_inference.R        SFT 后推理(带温度/惩罚/Top-K)
└── utils/
    ├── config.R              共享环境检测与超参配置
    ├── JEPA_model.R          核心模型定义(复用于 02-05)
    ├── RtomicBPETokenizer.R  BPE 分词器 R6 封装
    └── count_parameters.R    参数量统计
data/raw/                     JSONL 原始数据(含 787MB 预训练语料)
models/
└── rtomic_bpe.model          训练好的 BPE 分词器
checkpoints/                  训练的模型权重

未来演进方向

致谢


Share this post on:

Next Post
大模型的尽头,是世界模型