从零训练一个小模型-nanoGPT 模型训练 (一)数据预处理

news2026/4/29 7:13:03
最近在学习模型训练实际上在大模型训练上我并没有深厚的背景通过视频课程和b站上的一些分享开始入门。由于我非神经网络这些相关的专业所以想把自己学习的过程和经验总结记录下来一方面自己可以巩固总结知识另一方面对于“外行”如何入手把这些经验给到有需要的人。这篇文章用较容易理解的方式去开始去训练一个小模型。我们通过一个项目来直接进入模型训练了解GPT模型的核心逻辑这个是github上的项目地址https://github.com/karpathy/nanoGPT.git这个项目是很简洁、高效的是学习 Transformer 和 GPT 原理的最佳实践项目之一。代码量极少相比于大型工业级框架nanoGPT的代码量非常少几百行核心代码去除了复杂的工程封装保留了 GPT 模型最核心的逻辑。正在学习大语言模型LLM这是一个非常好的切入点能让你看到模型背后的代码是如何运作的。项目给了三个运行方式对于侧重点也是有所不同。train_shakespeare_char从随机参数开始没有加载现成 GPT-2用的是字符级数据表示所以它只是“从零训练一个小模型”。train_gpt2把模型结构设成 GPT-2 风格然后从零开始训练。它不是加载 OpenAI 已经训好的GPT-2而是自己重新训一个。所以它叫复现 GPT-2从零训练 GPT-2 风格模型不是微调。finetune_shakespeare 是微调先把现成 GPT-2 XL 的参数加载进来再拿 Shakespeare 数据继续训练。符合“微调”的定义。如果目标是学训练流程 - 看 train_shakespeare_char学怎么从零训大语言模型 - 看 train_gpt2学怎么在现成模型上继续训练 - 看 finetune_shakespeare我这次要学习训练流程可以直接在cpu上运行我会根据自己实践和理解分为几个部分来总结让大家也有个对模型逻辑性、结构性的认识。一、从目录理解项目可以把这个 nanoGPT 项目先粗分成 5 块——data/准备训练数据——config/配置文件不同训练/评估场景的参数模板——根目录几个 .py真正执行训练、采样、建模、配置解析、性能测试——assets/文档图片资源一般前端静态资源文件图片、音频、视频、字体——.ipynb实验/分析笔记不是主流程——train.py主训练脚本。这是项目最重要的入口。它负责读取 train.bin / val.bin、按 batch 取数据、初始化模型、训练循环、评估 loss、保存 checkpoint你可以把它理解成整个训练流程的总控。——model.pyGPT 模型定义。它负责定义token embedding、position embedding、Transformer block、self-attention、MLP最后的输出层、forward 逻辑从预训练 GPT-2 加载参数、你可以把它理解成“模型长什么样”——sample.py推理 / 采样脚本。它负责加载你训练好的 checkpoint、或直接加载 GPT-2、输入一个 prompt、让模型继续生成文本比如训练完 Shakespeare 后用它生成新台词。你可以把它理解成拿训练好的模型出来说话开始使用模型——configurator.py简易配置加载器。它负责读取 config/*.py、读取命令行里的 --batch_size32 这种参数、覆盖 train.py 或 sample.py 里的默认值你可以把它理解成“把配置文件和命令行参数注入到脚本里”——bench.py性能测试脚本。它不是正式训练入口而是用来测一轮前向/反向大概多快、GPU 利用情况如何、数据读取和模型计算速度如何你可以把它理解成“压测 / 跑分脚本”。如果你是刚入门建议按这个顺序看这几个文件data/shakespeare_char/prepare.pyconfig/train_shakespeare_char.pytrain.pysample.pymodel.py我们第一篇先看如何准备数据data/这个文件夹二、准备数据/数据预处理 data文件夹data文件夹下有几个文件在训练之前先跑 prepare.py文件它在做的是数据预处理还没有训练神经网络。把人能读的英文文本预处理成模型能高效读取的数字数据。模型本质上不会直接理解英文字符它只能处理数字。所以要先做这件事读入原始文本 input.txt、统计里面出现过哪些字符、给每个字符分配一个编号、把整篇文本从“字符串”变成“数字串”、保存成训练时方便高速读取的格式、这一步可以叫数据预处理。1. 读入原始文本读入原始剧本文本就是把 input.txt 整个读进来得到一个超长字符串比如概念上像这样First Citizen:\nBefore we proceed any further, hear me speak.\n...注意这里不是“按句子”读也不是“按单词”读而是整个文件当成一个长字符串。如果你把它拆成一个个字符就会变成F, i, r, s, t, 空格, C, i, t, i, z, e, n, :, 换行, B, e, f, o, r, e, ...这就是“字符序列”。2. 建立“字符 - 整数”的对照模型不能直接吃 F、i、空格、\n所以先要做编号。假设文本里只出现这几个字符a, b, c, 空格那就可能编号成 - 0a - 1b - 2c - 3在你的代码里stoi string to integer字符转数字itos integer to string数字转字符也就是stoi[a] 1itos[1] a为什么要两张表训练前把文本转成数字用 stoi训练后把模型输出的数字转回字符用itos为什么是 65 个字符因为这份 tiny Shakespeare 文本里总共只出现了 65 种不同字符。比如包括大写字母 A-Z小写字母 a-z空格换行标点符号如 , . : ; ? !少量别的符号代码里也打印了这个结果length of dataset in characters: 1,115,393all the unique characters:!$,-.3:;?ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzvocab size: 65train has 1,003,853 tokensval has 111,540 tokens这里的 vocab size: 65在这个字符级任务里其实就是这个模型只需要学会处理 65 种可能出现的字符。把整本书变成数字串比如原文是hi!假设编号是! - 0h - 1i - 2那编码后就变成[1, 2, 0]这个过程就是encode(hi!) - [1, 2, 0]大模型处理文本的底层逻辑这个过程想象成把人类语言翻译成机器密码更偏向encoding编码阶段文本 到token ID离散整数EncodingTokenizationNumericalization (转ID)Special Tokens (特殊标记)1Tokenization分词切分“把长句子切成小块”这是第一步。模型不能一口吃成个胖子它需要把连续的文本流切分成有意义的单元Token。动作根据规则如空格、标点或 BPE 算法将字符串切开。输入原始字符串Hi!输出字符串列表[Hi, !]关键点这一步还没有变成数字只是把文本打散了。对于中文可能是[你, 好]对于英文生僻词可能是[Un, believable]。2Numericalization数值化查表转 ID“给每个小块发身份证号”计算机只认识数字。分好词后我们需要去模型的词汇表Vocabulary里查找每个 Token 对应的唯一编号。动作在字典中查找索引。输入字符串列表[Hi, !]输出整数列表[101, 502]假设 Hi 的 ID 是 101! 是 502关键点这就是你之前看到的[1, 2, 0]的来源。这一步将语义符号变成了数学符号。3Special Tokens特殊标记添加控制指令模型不仅需要内容还需要知道“哪里是开头”、“哪里是结尾”或者“这是两个句子中的哪一个”。这就好比写信要有“尊敬的”和“此致敬礼”。动作在数字序列的首尾或中间插入特定的控制 ID。输入整数列表[101, 502]输出100可能是[CLS]开始标记告诉模型从这里开始读102可能是[SEP]结束标记告诉模型这句话读完了关键点如果不加这些模型可能不知道句子在哪里结束或者无法区分这是用户说的话还是 AI 说的话在对话模型中尤为重要。步骤名称数据形态变化说明原始输入TextHi!人类看的文本第一步Tokenization[Hi, !]切分成 Token第二步Numericalization[50257, 30]查表变成 ID第三步Special Tokens[101, 50257, 30, 102]加上 [CLS] 和 [SEP]最终结果Encodingtensor([101, 50257, 30, 102])变成张量送入 GPU 计算所以Encoding 是为了让模型能“读懂并处理”文本而 Tokenization 只是其中负责“切分”的一环。整本 input.txt 也是同理只不过会变成一个非常长的整数列表像这样[18, 47, 56, 57, 58, 1, 15, 47, 58, 47, 62,43, 52, 10, 0, ...]这里每个数字对应一个字符。注意这里说“token”在这个项目的 shakespeare_char 数据集中token 就是一个字符。所以一个字母 一个 token一个空格 一个 token一个换行 一个 token一个标点 一个 token这和很多大模型常见的“token 是词片段”不一样。字符级切法是T o b e所以一共 5 个 token。但很多大模型不是这么切的很多大模型会把文本切成“词片段”而不是单字符。比如playing可能不是 7 个字符 token而可能被切成play ing这就叫 subword token也就是“词片段 token”。所以同一段文本在 shakespeare_char 里token 是字符在 GPT 这类常见 tokenizer 里token 往往是词片段有两层概念文本层面你看到的是英文句子模型层面模型看到的是 token 序列再进一步是 token 对应的整数 id而你这个项目里刚好采用的是最简单的一种字符级 tokenization 也就是 先把文本拆成一个个字符再给每个字符编号。一个非常直观的对比文本Hello, world!如果按字符级H | e | l | l | o | , | 空格 | w | o | r | l | d | !这就是 13 个 token。如果按词片段级可能会像这样Hello | , | world | !那就只有 4 个 token。3. 切成训练集/ 验证集意思是前 90% 文本作为训练集 train_data后 10% 文本作为验证集 val_data为什么要这样因为你不能只看模型“背会了训练内容没有”还要看它对没参与训练的数据表现怎么样。验证集就是用来检查模型有没有真正学到规律而不是死记硬背。你可以粗略理解成train.bin拿来学习val.bin拿来考试4. 要保存成 train.bin / val.bin这是很多新手最容易卡住的点。可能会想既然已经有 input.txt训练时直接读文本不行吗理论上可以但效率差。因为训练会反复做下面的事情从数据里截取一小段连续内容把字符转成数字送进模型如果每次训练一个 batch 都重新从文本解析字符会很慢。所以预处理脚本提前把它变成纯数字并直接保存到二进制文件里train_ids.tofile(...)val_ids.tofile(...)这样后面训练时可以直接高速读取整数不用反复做字符串处理。5. meta.pkl 的作用train.bin / val.bin 里只存了一串数字比如[18, 47, 56, 57, ...]但如果没有那张“对照表”你就不知道18 是哪个字符47 是哪个字符所以还要额外保存 meta.pkl.pkl就是Python 专用的数据或模型存档文件二进制里面有vocab_sizestoiitos这三个可以理解成“这个字符级数据集的说明书 字典”。vocab_size意思是总共有多少种不同的字符。比如你的 Shakespeare 数据里出现过大写字母、小写字母、空格、换行、标点把所有不重复字符收集起来一共有 65 个所以vocab_size 65它告诉模型你最终要预测的候选字符总共就这 65 种。stoistoi string to integer意思是把字符映射成整数编号的字典。例如可能像这样stoi { : 0,!: 1,A: 10,a: 35,}作用是把原始文本编码成数字模型训练前先把字符转成 token id比如stoi[a]# 可能得到 35itositos integer to string意思是把整数编号映射回字符的字典。例如itos {0: ,1: !,10: A,35: a,}作用是把模型输出的数字还原回字符生成文本时把 token id 解码成人能读的内容比如itos[35]# 得到 a三者之间的关系你可以把它们看成一套完整配套工具vocab_size字典里总共有多少个字符stoi查“这个字符编号是多少”itos查“这个编号对应什么字符”这相当于把“字典”也一起存起来了。这样以后你才能把新文本编码成数字把模型生成的数字再解码回字符。6. 总结简单理解数据预处理流程原始 Shakespeare 文本就像一本英文书模型看不懂字母。于是你先做了一套“机器版翻译”把每个字符编上号把整本书翻译成数字把数字存好训练时直接喂数字给模型训练完再把模型吐出的数字翻译回字符。所以这个预处理脚本本质上是在做把“人类可读文本”变成“神经网络可训练数据”。总结prepare.py 做的不是“让模型理解莎士比亚”而是先把莎士比亚文本变成一种统一、紧凑、可快速读取的数字格式这样后面的 train.py 才能高效地训练“预测下一个字符”的模型。三、后面的 train.py 如何用这些文件后面的 train.py 会用内存映射memmap直接读这些文件批量取连续片段。意思是训练时不会一次性把全部数据都完整塞进内存而是像“按需读取”。你可以想象 train.bin 是一条很长很长的数字带子[18, 47, 56, 57, 58, 1, 15, 47, 58, 47, 62,...]训练时模型不会每次看全书而是随机抽一小段例如长度是 8输入 x[18, 47, 56, 57, 58, 1, 15, 47]目标 y[47, 56, 57, 58, 1, 15, 47, 58]可以把 x 和 y 理解成x题目y标准答案在语言模型里更准确一点x模型当前能看到的输入序列y这个输入序列对应的“下一个 token”真实答案也就是说模型看到前面的字符去预测“下一个字符”是什么。这是语言模型最核心的训练方式。block_size 决定“每条样本有多长”batch_size 决定“一次并行喂多少条样本”block_size 的意思更像是模型最多能看多长的上下文。不是说每次必须刚好输入这么长。[47] 可以预测下一个token[47, 58] 可以预测下一个 token[18, 47, 56, 57] 也可以预测下一个 token只要长度不超过 block_size原则上都可以。为什么训练时总是切成 block_size因为训练时要走 GPU 批量计算固定长度最方便。比如代码里会取batch_size 条样本每条样本长度都是 block_size这样张量形状整齐计算高效。所以训练代码里看到的是x.shape (batch_size, block_size)y.shape (batch_size, block_size)这是工程实现上的方便不是概念上只能这么做。为什么训练必须用连续片段因为训练目标是让模型学会真实文本中的规律比如哪些字符常常连在一起、哪些单词后面常出现什么、句子通常怎么延续、这些规律都建立在邻接关系上也就是“谁跟在谁后面”。如果你把上下文打乱了模型就学不到真正的语言结构。即是连续切片而非随机散点。好啦我们这次总结了一下数据集这块内容下篇继续讲配置项训练模型都需要配置什么内容。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2535047.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…