Skip to content

Trans01 #41

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed Translated_Book/ch05/.keep
Empty file.
200 changes: 200 additions & 0 deletions Translated_Book/ch05/5.4.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "780ec141",
"metadata": {},
"source": [
"# 5.4 在 PyTorch 中加载和保存模型权重"
]
},
{
"cell_type": "markdown",
"id": "5de22098",
"metadata": {},
"source": [
"我们讨论了如何从数值上评估训练进度以及如何从零开始预训练一个大型语言模型(LLM)。\n",
"尽管大语言模型和数据集都相对较小,但此练习表明预训练 大语言模型的计算成本很高。\n",
"因此,能够保存大语言模型非常重要,这样我们就不必每次想要在新会话中使用它时都重新运行训练。"
]
},
{
"cell_type": "markdown",
"id": "0c5ff69a",
"metadata": {},
"source": [
"如图 5.16 中的章节概述所示,我们将在本节中介绍如何保存和加载预训练模型。\n",
"然后,在接下来的部分中,我们将从 OpenAI 加载一个功能更强大的预训练 GPT 模型到我们的 GPTModel 实例中。"
]
},
{
"cell_type": "markdown",
"id": "94b4fa2d",
"metadata": {},
"source": [
"**图 5.16 在训练和检查模型之后,保存模型通常很有帮助的,这样我们以后可以使用或继续训练它,这是本节的主题,然后我们将在本章的最后一节中从 OpenAI 加载预训练的模型权重**"
]
},
{
"cell_type": "markdown",
"id": "8a921a88",
"metadata": {},
"source": [
"![fig5.16](https://github.com/datawhalechina/llms-from-scratch-cn/blob/main/Translated_Book/img/fig-5-16.jpg?raw=true)"
]
},
{
"cell_type": "markdown",
"id": "41081dbb",
"metadata": {},
"source": [
"幸运的是,保存一个PyTorch 模型相对简单。\n",
"这里推荐的方法是使用 torch.save 函数保存模型的所谓状态字典 state_dict,这是一个将每个层映射到其参数的字典, 代码如下所示:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "31d1411d",
"metadata": {},
"outputs": [],
"source": [
"torch.save(model.state_dict(), \"model.pth\")"
]
},
{
"cell_type": "markdown",
"id": "77373a01",
"metadata": {},
"source": [
"在上面的代码中,“model.pth”是保存state_dict的文件名。 \n",
"从技术上讲我们可以使用任何文件扩展名,但.pth扩展名是PyTorch文件的常规约定"
]
},
{
"cell_type": "markdown",
"id": "07bf1918",
"metadata": {},
"source": [
"然后,通过 state_dict 保存模型权重后,我们可以按照以下代码将模型权重加载到新的 GPTModel 模型实例中:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4183fef5",
"metadata": {},
"outputs": [],
"source": [
"model = GPTModel(GPT_CONFIG_124M)\n",
"model.load_state_dict(torch.load(\"model.pth\"))\n",
"model.eval()"
]
},
{
"cell_type": "markdown",
"id": "8d502a45",
"metadata": {},
"source": [
"正如第 4 章所讨论的,dropout通过在训练期间随机“丢弃”层的神经元来帮助防止模型对训练数据过拟合。\n",
"然而,在推理过程中,我们不想随机丢弃网络学到的任何信息。\n",
"使用 model.eval() 能够将模型切换到评估模式进行推理,禁用模型的 dropout 层。"
]
},
{
"cell_type": "markdown",
"id": "92b5cd12",
"metadata": {},
"source": [
"如果我们计划稍后继续预训练模型,例如使用本章早些时候定义的train_model_simple函数,建议同时保存优化器的状态。\n",
"这样做可以在重新开始训练时保持优化器的所有参数和状态,从而更有效地继续训练过程。"
]
},
{
"cell_type": "markdown",
"id": "6973802e",
"metadata": {},
"source": [
"AdamW 等自适应优化器,会为每个模型权重存储附加参数。\n",
"AdamW 利用历史数据动态调整每个模型参数的学习率。\n",
"如果没有它,优化器将重置,模型可能学习效果不佳,甚至无法正确收敛,这意味着它将失去生成连贯文本的能力。\n",
"使用torch.save,我们可以按照以下方式保存模型和优化器state_dict内容:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0378ce57",
"metadata": {},
"outputs": [],
"source": [
"torch.save({\n",
" \"model_state_dict\": model.state_dict(),\n",
" \"optimizer_state_dict\": optimizer.state_dict(),\n",
" },\n",
" \"model_and_optimizer.pth\"\n",
")"
]
},
{
"cell_type": "markdown",
"id": "93f84fd7",
"metadata": {},
"source": [
"接着,我们可以通过首先使用torch.load加载保存的数据,然后使用load_state_dict方法来恢复模型和优化器的状态,具体操作如下:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e97ebb32",
"metadata": {},
"outputs": [],
"source": [
"checkpoint = torch.load(\"model_and_optimizer.pth\")\n",
"model = GPTModel(GPT_CONFIG_124M)\n",
"model.load_state_dict(checkpoint[\"model_state_dict\"])\n",
"optimizer = torch.optim.AdamW(model.parameters(), lr=5e-4, weight_decay=0.1)\n",
"optimizer.load_state_dict(checkpoint[\"optimizer_state_dict\"])\n",
"model.train();"
]
},
{
"cell_type": "markdown",
"id": "476721c3",
"metadata": {},
"source": [
"### 练习5.4"
]
},
{
"cell_type": "markdown",
"id": "879d6847",
"metadata": {},
"source": [
"在保存权重后,在一个新的Python会话或Jupyter笔记本文件中加载模型和优化器,并使用train_model_simple函数继续对其进行预训练1个周期。这样做可以无缝地继续之前的训练过程,从而提高模型的性能和适应性。"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python (cell)",
"language": "python",
"name": "cell"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Loading