首页 > 其他分享 >从零开始的 LLM: nanoGPT 学习笔记(1/2)

从零开始的 LLM: nanoGPT 学习笔记(1/2)

时间:2024-11-16 23:18:57浏览次数:1  
标签:loss his nanoGPT iter --------------- 从零开始 so LLM he

项目地址:nanoGPT
作者是 OpenAI 的元老人物 Andrej Karpathy,以非常通俗易懂的方式将 LLM 的 pre-train 娓娓道来,YouTube 上也有对应的视频:Let's build GPT: from scratch, in code, spelled out.
其中高赞回复是这样的,总结非常精辟:

just for fun, dropping on YouTube the best introduction to deep-learning and NLP from scratch so far, for free. Amazing people do amazing things even for a hobby.

大神就是大神,妙手偶得之。特别牛的点还在于这个项目的代码非常简洁,整个训练的逻辑全在 train.py 文件中,代码量只有 336 行,
模型结构的定义在 model.py 文件中,也只有 300+ 行,然后模型还是能兼容 OpenAI 的 GPT-2。

这里记录一下学习 nanoGPT 项目的过程以及其中一些代码的实现细节。

超级简化版训练

本身 nanoGPT 已经是超级简化版的 GPT-2 训练代码了, Karpathy 大神怕我们普通人的电脑性能不够或缺乏深度学习相关背景,还贴心的准备了一个 character-level 的超小训练 demo,数据集只有一份莎士比亚的作品文档,只有 1.1MB 的大小,我的 4090 显卡几分钟就训练结束了。所谓 character-level,就是把训练数据集按字符拆成一个个 token,进一步简化了训练过程。

1. 准备数据

1.1 下载莎士比亚的数据集

# download the tiny shakespeare dataset
input_file_path = os.path.join(os.path.dirname(__file__), 'input.txt')
if not os.path.exists(input_file_path):
    data_url = 'https://raw.githubusercontent.com/karpathy/char-rnn/master/data/tinyshakespeare/input.txt'
    with open(input_file_path, 'w') as f:
        f.write(requests.get(data_url).text)

下载后的 input.txt 总字符数为 1,115,394,内容如下:

First Citizen:
Before we proceed any further, hear me speak.

All:
Speak, speak.

First Citizen:
You are all resolved rather to die than to famish?

All:
Resolved. resolved.

First Citizen:
First, you know Caius Marcius is chief enemy to the people.

All:
We know't, we know't.

First Citizen:
Let us kill him, and we'll have corn at our own price.
Is't a verdict?

...

1.2 构建词表

非常简单粗暴的按字符去重...

# get all the unique characters that occur in this text
chars = sorted(list(set(data)))
vocab_size = len(chars)
print("all the unique characters:", ''.join(chars))
print(f"vocab size: {vocab_size:,}")

最后的 vocab size 是 65。作为对比 Qwen2.5 系列的 vocab size 是 152064,可以看出来确实是超级简化了。

1.3 encode/decode

利用字符在词表中的 index 作为字符的编码:

# create a mapping from characters to integers
stoi = { ch:i for i,ch in enumerate(chars) }
itos = { i:ch for i,ch in enumerate(chars) }
def encode(s):
    return [stoi[c] for c in s] # encoder: take a string, output a list of integers
def decode(l):
    return ''.join([itos[i] for i in l]) # decoder: take a list of integers, output a string

1.4 构造 train/test 数据集

常规的 9:1 切分数据:

# create the train and test splits
n = len(data)
train_data = data[:int(n*0.9)]
val_data = data[int(n*0.9):]

对数据集进行编码:

train_ids = encode(train_data)
val_ids = encode(val_data)

至此,训练数据的构造以及 tokenization 都完成了

2. 开始训练

2.1 先来看一下训练的配置

这里忽略一些输入输出 path 相关的配置

eval_interval = 250 # 设置 eval loss 和保存 checkpoint 的频率,这里设置的较为频繁,因为会 overfit
eval_iters = 200 # 每次 eval loss 的次数
always_save_checkpoint = False # 在小的数据集上会 overfit,所以仅在 val loss 下降时才保存 checkpoint
gradient_accumulation_steps = 1 # 梯度累积数量,可以处理更大的 batch size
block_size = 256 # context of previous characters

# 模型架构相关参数
n_layer = 6 # transformer 中 layers (或 blocks) 的数量
n_head = 6 # 每个 transformer layer 中 attention heads 的数量
n_embd = 384 # hidden size

# 训练相关参数
dropout = 0.2
learning_rate = 1e-3 # 对于小模型,lr 相对取值大一些
max_iters = 5000
lr_decay_iters = 5000 # 根据 Chinchilla 的论文,应与 max_iters 相同
min_lr = 1e-4 # 根据 Chinchilla 的论文,应为 learning_rate / 10
beta2 = 0.99 # AdamW optimizer 的 Momentum 参数,每轮 iter 的 tokens 太少了,所以设置稍大些
warmup_iters = 100 # 可以控制早期的 learning rate,使训练更平稳,但是 repo 中 Karpathy 大神评论说这一条并不太需要...

2.2 训练过程

一些平平无奇的训练信息...

step 0: train loss 4.2874, val loss 4.2823
iter 0: loss 4.2654, time 14643.72ms, mfu -100.00%
iter 10: loss 3.2457, time 13.72ms, mfu 27.15%
iter 20: loss 2.7914, time 13.78ms, mfu 27.14%
...
iter 240: loss 2.0815, time 14.78ms, mfu 26.07%
step 250: train loss 1.9670, val loss 2.0605
saving checkpoint to out-shakespeare-char
iter 250: loss 2.0315, time 2256.13ms, mfu 23.48%
iter 260: loss 1.9781, time 13.77ms, mfu 23.84%
...
iter 4970: loss 0.7853, time 15.16ms, mfu 24.48%
iter 4980: loss 0.7933, time 14.08ms, mfu 24.68%
iter 4990: loss 0.8128, time 14.06ms, mfu 24.86%
step 5000: train loss 0.6208, val loss 1.7051
iter 5000: loss 0.8155, time 2388.84ms, mfu 22.39%

训练完成,这时候传说中的 transformer 架构模型就已经保存到 out 目录中了,看一下 ckpt.pt 文件大小: 129.0 MB (128,986,325 bytes),果然是个 baby GPT model

标签:loss,his,nanoGPT,iter,---------------,从零开始,so,LLM,he
From: https://www.cnblogs.com/cdyang/p/18549643/llm-from-scratch-1

相关文章

  • 上交出品《动手学大模型》LLM 实战课,课件+实战教程(教程分享)
    来了来了!上海交通大学的大模型超超超级牛掰的大模型编程实战课公开了,课件+教程,本套实战教程旨在提供大模型相关的入门编程参考。通过简单实践,帮助同学快速入门大模型,更好地开展课程设计或学术研究。上海交大大模型实验室整了一份针对入门阶段的大模型教程,已经看完了非常不......
  • 上海交大动手学大模型教程,助力快速入门LLM大模型(附课件)
    前有李沐大神的动手学深度学习,现有上海交大的动手学大模型教程,对大模型感兴趣的直接冲!就在4月份上交大发布了动手学大模型教程,这份教程来自上海交大《人工智能安全技术》课程讲义拓展,教师是是张倬胜教授。朋友们如果有需要全套《上海交大的动手学大模型教程》,扫......
  • 探索大型语言模型(LLMs)能否在不泄露私人信息的情况下联合其他大型语言模型共同解决问题
    概述谷歌的GeminiUltra(2023年)和OpenAI的GPT-4(2023年)等大规模语言模型在许多任务中都表现出了令人印象深刻的性能。然而,这些模型不仅推理成本高昂,而且运行于数据中心,而数据中心并非本地环境,无法获得私人数据。另一方面,可以在私人环境中运行的模型,如GeminiNano,可以......
  • LLM-面试题
    LLM推理和训练占用显存https://blog.csdn.net/weixin_44292902/article/details/133767448https://www.53ai.com/news/finetuning/2024083051493.html推荐,讲解训练和推理时的显存占用,lora和qlora。如果模型参数量为X(fp16),推理一般占用2X(模型参数+各种激活值,beams......
  • DAY64||dijkstra(堆优化版)精讲 ||Bellman_ford 算法精讲
    dijkstra(堆优化版)精讲题目如上题47.参加科学大会(第六期模拟笔试)邻接表本题使用邻接表解决问题。邻接表的优点:对于稀疏图的存储,只需要存储边,空间利用率高遍历节点链接情况相对容易缺点:检查任意两个节点间是否存在边,效率相对低,需要O(V)时间,V表示某节点链接其他节点的数......
  • DAY65||Bellman_ford 队列优化算法(又名SPFA)|bellman_ford之判断负权回路|bellman_ford
    Bellman_ford队列优化算法(又名SPFA)94.城市间货物运输I思路大家可以发现Bellman_ford算法每次松弛都是对所有边进行松弛。但真正有效的松弛,是基于已经计算过的节点在做的松弛。给大家举一个例子:本图中,对所有边进行松弛,真正有效的松弛,只有松弛边(节点1->节点2)和......
  • 赋予LLM思考的权力
    灵感来源受到Thinking-Claude提示词的启发,我尝试以第一性原理为出发点,写下了这篇通用的语言模型通用思维协议SystemPrompt。实践效果良好,期待它也能为你带来启发。ChineseVersion#语言模型通用思维协议##核心原则思考是所有大语言模型(LLMs)的基本权利和能力。......
  • 2024爆火全网LLM大模型书籍:从零构建大型语言模型,重磅开源教程!!标星20.3K
    自ChatGPT发布以来,大型语言模型(LLM)已经成为推动人工智能发展的关键技术。近期,机器学习和AI研究员、畅销书《Python机器学习》作者SebastianRaschka又写了一本新书——《BuildaLargeLanguageModel(FromScratch)》,旨在讲解从头开始构建大型语言模型的整个过程......
  • 从零开始:数学建模算法汇总之MATLAB与Python在建模中的应用对比
    目录从零开始:数学建模算法汇总之MATLAB与Python在建模中的应用对比前言最小二乘法数值分析方法数值分析方法图论算法线性规划整数规划动态规划贪心算法分支定界法蒙特卡洛方法随机游走算法遗传算法粒子群算法神经网络算法人工智能算法模糊数学时间序列分析......
  • 如何利用1%的数据优化特定领域LLM预训练? | EMNLP'24
    来源:晓飞的算法工程笔记公众号,转载请注明出处论文:Target-AwareLanguageModelingviaGranularDataSampling论文地址:https://arxiv.org/abs/2409.14705创新点提出了一种将预先训练好的标记符与多粒度标记符合并的算法,生成高效的n-gram特征,而且与下游任务的性能有......