当前位置: 首页 > news >正文

nanochat大语言模型讲解一

围绕nanochat大模型项目讲解模型结构与训练知识点,首先从预训练脚本scripts/base_train.py开始。

一、核心训练超参数解析
1.1 矩阵学习率

# matrix_lr = 0.02
optimizers = model.setup_optimizers(unembedding_lr=unembedding_lr, embedding_lr=embedding_lr, matrix_lr=matrix_lr, weight_decay=weight_decay)

在大模型预训练中,“矩阵学习率” matrix_lr并非普遍默认策略,其使用需结合模型架构、训练目标和优化需求确定。这里的“矩阵”特指模型中的各类参数矩阵,如Transformer架构中的Q/K/V矩阵、FeedForward层权重矩阵、嵌入层词向量矩阵等;“矩阵学习率”即针对这些不同参数矩阵单独设置差异化学习率,而非所有参数共享一个全局学习率,本配置中该学习率值设为0.02。

1.2 梯度裁剪

with torch.device("meta"):model_config = GPTConfig(**model_config_kwargs)model = GPT(model_config)
model.to_empty(device=device)
model.init_weights()
orig_model = model # original, uncompiled model, for saving raw model state_dict
# grad_clip = 1.0
if grad_clip > 0.0:torch.nn.utils.clip_grad_norm_(orig_model.parameters(), grad_clip)

grad_clip = 1.0是梯度裁剪的阈值设置,用于解决训练过程中的梯度爆炸问题,保障训练稳定性。具体说明如下:
• 梯度裁剪是通过限制梯度范数(通常为L2范数)防止梯度过大导致训练发散的关键技术;
• 本配置中1.0为梯度范数的上限值,当计算出的梯度范数超过1.0时,会被按比例缩小至范数等于1.0。

1.3 学习率调度参数

# final_lr_frac = 0.0
def get_lr_multiplier(it):warmup_iters = round(warmup_ratio * num_iterations)warmdown_iters = round(warmdown_ratio * num_iterations)if it < warmup_iters:return (it + 1) / warmup_iterselif it <= num_iterations - warmdown_iters:return 1.0else:# 训练迭代已经到结尾progress = (num_iterations - it) / warmdown_itersreturn progress * 1.0 + (1 - progress) * final_lr_frac

final_lr_frac是控制学习率调度的核心参数,表示训练结束时学习率相对于初始学习率的比例系数,本配置中该系数设为0.0。
1.3.1 核心作用
例如:若初始学习率为0.001,final_lr_frac设为0.1,则训练结束时学习率为0.001×0.1=0.0001;本配置中0.0表示训练结束时学习率将降至0,通常用于训练最后阶段完全停止参数更新。
1.3.2 学习率调度的必要性
学习率是深度学习训练的关键超参数,其动态调整遵循“先快后慢”的逻辑:训练初期需较大学习率实现快速收敛,后期需较小学习率精细调参,避免在最优解附近震荡,学习率调度正是实现这一动态调整的核心技巧。
1.3.3 训练各阶段学习率策略

阶段阶段特点学习率策略核心目标
初始阶段参数随机初始化,损失值高,性能差使用较高初始学习率快速降低损失,进入合理参数区间
中期阶段已学习有效特征,损失稳步下降,性能提升保持稳定或逐步减小持续优化参数,提升模型性能
后期阶段性能接近饱和,损失下降放缓,易过拟合显著降低学习率精细调参,防止过拟合,提升泛化能力
结束阶段性能趋于稳定,损失无显著下降进一步降低至趋近于0固定最优参数状态,保存最终权重

训练过程中各阶段的特点、学习率调整策略及核心优化目标。

1.4 混合精度训练配置

autocast_ctx = torch.amp.autocast(device_type=device_type, dtype=torch.bfloat16) if device_type == "cuda" else nullcontext()

这是PyTorch提供的自动混合精度训练上下文管理器,核心作用是在训练中自动切换数值精度:当使用CUDA设备时,自动将部分操作从FP32(单精度浮点数)转换为BF16(Brain Floating Point),在保证训练效果的同时提升计算速度并减少内存占用;使用其他设备时则不启用该功能。

二、模型初始化与设备部署

python
with torch.device("meta"):model_config = GPTConfig(**model_config_kwargs)model = GPT(model_config)
model.to_empty(device=device)
model.init_weights()

该方法用于将模型结构迁移至指定设备(如GPU/CPU),但不立即复制参数数据,是大型模型部署的高效方式,核心优势包括:
• 轻量迁移:仅迁移模型结构,不分配和复制参数数据,节省内存开销;
• 前置准备:为后续权重初始化提供设备环境,保障初始化效率。

三、训练轮数推算机制

depth = 20 # the depth of the Transformer model to train, rest of the kwargs are derived
target_flops = -1.0 # calculate num_iterations to reach target_flops. Useful for scaling laws experiments (-1 = disable)
total_batch_size = 524288 # total desired batch size, in #tokens
target_param_data_ratio = 20 # calculate num_iterations to maintain fixed data:param ratio (Chinchilla=20) (-1 = disable)num_params = sum(p.numel() for p in model.parameters())
print0(f"Number of parameters: {num_params:,}")
num_flops_per_token = model.estimate_flops()
print0(f"Estimated FLOPs per token: {num_flops_per_token:e}")# Calculate number of iterations. Either it is given, or from target flops, or from target data:param ratio (in that order)
assert num_iterations > 0 or target_param_data_ratio > 0 or target_flops > 0
if num_iterations > 0:print0(f"Using user-provided number of iterations: {num_iterations:,}")
elif target_flops > 0:# calculate the number of iterations from the target flopsnum_iterations = round(target_flops / (num_flops_per_token * total_batch_size))print0(f"Calculated number of iterations from target FLOPs: {num_iterations:,}")
elif target_param_data_ratio > 0:# calculate the number of iterations from the target param data ratiotarget_tokens = target_param_data_ratio * num_paramsnum_iterations = target_tokens // total_batch_sizeprint0(f"Calculated number of iterations from target data:param ratio: {num_iterations:,}")
else:raise ValueError("No training horizon specified")
total_tokens = total_batch_size * num_iterations

训练迭代次数(轮数)的确定采用三级优先级策略,优先级从高到低依次为:直接指定迭代次数、基于目标FLOPs计算、基于数据-参数比例计算。
3.1 三级确定策略
1.直接指定迭代次数(最高优先级)通过num_iterations参数显式设置,当num_iterations ≠ -1时启用,-1表示禁用该方式。
2.基于目标FLOPs计算(第二优先级)通过target_flops参数设置目标浮点运算量,当target_flops > 0时启用,-1表示禁用。计算公式为:num_iterations = 目标FLOPs / (每token的FLOPs × 总batch大小)其中,num_flops_per_token为模型处理每个token的浮点运算次数,total_batch_size为每次迭代处理的总token数。核心原理是:总FLOPs = 每token的FLOPs × 每次迭代tokens数 × 迭代次数。
3.基于数据-参数比例计算(默认策略)基于Chinchilla论文提出的最优比例(数据:参数=20:1),当target_param_data_ratio > 0时启用。计算步骤为:目标训练tokens = target_param_data_ratio × 模型参数量(num_params);
4.迭代次数 = 目标训练tokens // 每次迭代batch大小(total_batch_size)。
3.2 计算示例
模型配置:depth=20(参数量约10,000,000),total_batch_size=524288 tokens,采用默认Chinchilla比例(20:1):
1.模型参数量:num_params = sum(p.numel() for p in model.parameters()) = 10,000,000;
2.目标训练tokens:20 × 10,000,000 = 200,000,000 tokens;
3.迭代次数:200,000,000 // 524,288 ≈ 381次;
4.实际验证:总训练tokens = 524,288 × 381 ≈ 199,753,728 tokens,数据:参数比例≈20:1。
3.3 实际使用建议
•快速实验:直接设置num_iterations,高效验证模型效果;
•Scaling Laws研究:使用target_flops精确控制计算预算;
•最优训练:默认采用target_param_data_ratio=20(Chinchilla比例),平衡性能与成本。

四、关键技术细节

#  gpt.py 上面计算浮点运算量函数def estimate_flops(self):""" Return the estimated FLOPs per token for the model. Ref: https://arxiv.org/abs/2204.02311 """nparams = sum(p.numel() for p in self.parameters())nparams_embedding = self.transformer.wte.weight.numel()l, h, q, t = self.config.n_layer, self.config.n_head, self.config.n_embd // self.config.n_head, self.config.sequence_lennum_flops_per_token = 6 * (nparams - nparams_embedding) + 12 * l * h * q * treturn num_flops_per_token

4.1 每token FLOPs估算(estimate_flops函数)
num_flops_per_token = 6 × (nparams - nparams_embedding) + 12 × l × h × q × t
用于估算模型处理单个token的浮点运算次数,公式分为两部分:
1.非嵌入层参数运算(6 × (nparams - nparams_embedding))非嵌入层以矩阵乘法为核心,前向传播每参数需2次FLOPs(1次乘法+1次加法),反向传播计算梯度需4次FLOPs,总计6次;嵌入层为查表操作,计算成本可忽略,故予以扣除。
2.注意力机制额外运算(12 × l × h × q × t)注意力机制涉及QK^T和Attention×V两次矩阵乘法,复杂度为O(T²)级。其中l为层数(n_layer)、h为注意力头数(n_head)、q为每个头的维度(n_embd//n_head)、t为序列长度(sequence_len);系数12是前向+反向传播的综合运算成本估算值。

4.2 核心网络层设计
4.2.1 嵌入层

"wte": nn.Embedding(config.vocab_size, config.n_embd)

嵌入层将词汇表中的词映射为固定维度的向量,vocab_size为词表大小,n_embd为向量维度,该层需与模型预训练同步训练。
4.2.2 线性层(MLP模块)

class MLP(nn.Module):def __init__(self, config):super().__init__()self.c_fc = nn.Linear(config.n_embd, 4 * config.n_embd, bias=False)self.c_proj = nn.Linear(4 * config.n_embd, config.n_embd, bias=False)

注意力模块中的MLP采用“4×n_embd”的经典设计,该设计是Transformer架构的经验选择:将输入维度扩展4倍可保证较强表达能力,同时计算成本和内存消耗处于可接受范围;若进一步增大扩展倍数,虽能提升表达能力,但会显著增加计算负担。
4.2.3 权重初始化策略

    def init_weights(self):# 对每一层递归调用初始化权重函数self.apply(self._init_weights)………………def _init_weights(self, module):    if isinstance(module, nn.Linear):fan_out = module.weight.size(0)fan_in = module.weight.size(1)std = 1.0 / math.sqrt(fan_in) * min(1.0, math.sqrt(fan_out / fan_in))# 处理线性层初始化,使用标准差、正态分布初始化torch.nn.init.normal_(module.weight, mean=0.0, std=std)if module.bias is not None:torch.nn.init.zeros_(module.bias)elif isinstance(module, nn.Embedding):# 处理嵌入层torch.nn.init.normal_(module.weight, mean=0.0, std=1.0)

各层初始化遵循差异化策略,保障训练稳定性:
•大部分层:非零随机初始化,打破参数对称性;
•残差投影层:零初始化,从恒等映射开始训练;
•输出层:零初始化,实现均匀预测初始化;
•嵌入层:标准正态分布初始化(std=1.0);

http://www.dtcms.com/a/585035.html

相关文章:

  • Vue3:watch与watchEffect的异同
  • 做网站代理wordpress文章半透明
  • (论文速读)LyT-Net:基于YUV变压器的轻量级微光图像增强网络
  • 操作系统?进程!!!
  • Diffusion 到 Flow Matching ( 从 DDPM 到 Stable Diffusion ) 丝滑入门
  • 无监督学习与互信息
  • 数据集预处理:规范化和标准化
  • vue学习之组件与标签
  • 软件测试之bug分析定位技巧
  • Rust 练习册 :Pig Latin与语言游戏
  • Tomcat的基本使用作用
  • 完整网站建设教程网站建设需要会什么软件
  • 【ASP.Net MVC 】使用Moq让单元测试变得更简单
  • Linux:线程的概念与控制
  • 零基础学AI大模型之嵌入模型性能优化
  • 【二叉搜索树】:程序的“决策树”,排序数据的基石
  • Canvas/SVG 冷门用法:实现动态背景与简易数据可视化
  • 昆明做网站做的好的公司智能建站系统 网站建设的首选
  • kali安装npm/sourcemap
  • 协作机器人的关节是通过什么工艺加工的
  • 轻松开启数字化时代,一键部署实现CRM落地
  • 长春市网站推广网站开发技术人员
  • JavaScript 指南
  • C++ LeetCode 力扣刷题 541. 反转字符串 II
  • C++死锁深度解析:从成因到预防与避免
  • 达梦DMDSC知识
  • 【C++】基于C++的RPC分布式网络通信框架(二)
  • Python 实现:从数学模型到完整控制台版《2048》游戏
  • 第1课-通过DIFY实现一个完整的Text2Sql来讲AI原生及Agentic RAG长什么样
  • 站长平台wordpress调用分类产品