This commit is contained in:
2025-12-16 09:23:53 +08:00
parent 19138d3cc1
commit 9e7efd0626
409 changed files with 272713 additions and 241 deletions
@@ -0,0 +1,226 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "33970a1a",
"metadata": {
"origin_pos": 0
},
"source": [
"# 使用Amazon EC2实例\n",
":label:`sec_aws`\n",
"\n",
"本节将展示如何在原始Linux机器上安装所有库。回想一下, :numref:`sec_sagemaker`讨论了如何使用Amazon SageMaker,而在云上自己构建实例的成本更低。本演示包括三个步骤。\n",
"\n",
"1. 从AWS EC2请求GPU Linux实例。\n",
"1. 安装CUDA(或使用预装CUDA的Amazon机器映像)。\n",
"1. 安装深度学习框架和其他库以运行本书的代码。\n",
"\n",
"此过程也适用于其他实例(和其他云),尽管需要一些细微的修改。在继续操作之前,你需要创建一个AWS帐户,有关更多详细信息,请参阅 :numref:`sec_sagemaker`。\n",
"\n",
"## 创建和运行EC2实例\n",
"\n",
"登录到你的aws账户后,单击“EC2”(在 :numref:`fig_aws`中用红色方框标记)进入EC2面板。\n",
"\n",
"![打开EC2控制台](../img/aws.png)\n",
":width:`400px`\n",
":label:`fig_aws`\n",
"\n",
":numref:`fig_ec2`显示EC2面板,敏感帐户信息变为灰色。\n",
"\n",
"![EC2面板](../img/ec2.png)\n",
":width:`700px`\n",
":label:`fig_ec2`\n",
"\n",
"### 预置位置\n",
"选择附近的数据中心以降低延迟,例如“Oregon”(俄勒冈)( :numref:`fig_ec2`右上角的红色方框)。如果你位于中国,你可以选择附近的亚太地区,例如首尔或东京。请注意,某些数据中心可能没有GPU实例。\n",
"\n",
"### 增加限制\n",
"\n",
"在选择实例之前,请点击 :numref:`fig_ec2`所示左侧栏中的“Limits”(限制)标签查看是否有数量限制。 :numref:`fig_limits`显示了此类限制的一个例子。账号目前无法按地域打开p2.xlarge实例。如果你需要打开一个或多个实例,请点击“Request limit increase”(请求增加限制)链接,申请更高的实例配额。一般来说,需要一个工作日的时间来处理申请。\n",
"\n",
"![实例数量限制](../img/limits.png)\n",
":width:`700px`\n",
":label:`fig_limits`\n",
"\n",
"### 启动实例\n",
"\n",
"接下来,单击 :numref:`fig_ec2`中红框标记的“Launch Instance”(启动实例)按钮,启动你的实例。\n",
"\n",
"我们首先选择一个合适的Amazon机器映像(Amazon Machine ImageAMI)。在搜索框中输入“ubuntu”( :numref:`fig_ubuntu`中的红色框标记)。\n",
"\n",
"![选择一个AMI](../img/ubuntu-new.png)\n",
":width:`700px`\n",
":label:`fig_ubuntu`\n",
"\n",
"EC2提供了许多不同的实例配置可供选择。对初学者来说,这有时会让人感到困惑。 :numref:`tab_ec2`列出了不同合适的计算机。\n",
"\n",
":不同的EC2实例类型\n",
"\n",
"| Name | GPU | Notes |\n",
"|------|-------------|-------------------------------|\n",
"| g2 | Grid K520 | 过时的 |\n",
"| p2 | Kepler K80 | 旧的GPU但Spot实例通常很便宜 |\n",
"| g3 | Maxwell M60 | 好的平衡 |\n",
"| p3 | Volta V100 | FP16的高性能 |\n",
"| g4 | Turing T4 | FP16/INT8推理优化 |\n",
":label:`tab_ec2`\n",
"\n",
"所有这些服务器都有多种类型,显示了使用的GPU数量。例如,p2.xlarge有1个GPU,而p2.16xlarge有16个GPU和更多内存。有关更多详细信息,请参阅[Amazon EC2 文档](https://aws.amazon.com/ec2/instance-types/)。\n",
"\n",
"![选择一个实例](../img/p2x.png)\n",
":width:`700px`\n",
":label:`fig_p2x`\n",
"\n",
"注意,你应该使用支持GPU的实例以及合适的驱动程序和支持GPU的深度学习框架。否则,你将感受不到使用GPU的任何好处。\n",
"\n",
"到目前为止,我们已经完成了启动EC2实例的七个步骤中的前两个步骤,如 :numref:`fig_disk`顶部所示。在本例中,我们保留“3. Configure Instance”(3. 配置实例)、“5. Add Tags”(5. 添加标签)和“6. Configure Security Group”(6. 配置安全组)步骤的默认配置。点击“4.添加存储”并将默认硬盘大小增加到64GB( :numref:`fig_disk`中的红色框标记)。请注意,CUDA本身已经占用了4GB空间。\n",
"\n",
"![修改硬盘大小](../img/disk.png)\n",
":width:`700px`\n",
":label:`fig_disk`\n",
"\n",
"最后,进入“7. Review”(7. 查看),点击“Launch”(启动),即可启动配置好的实例。系统现在将提示你选择用于访问实例的密钥对。如果你没有密钥对,请在 :numref:`fig_keypair`的第一个下拉菜单中选择“Create a new key pair”(新建密钥对),即可生成密钥对。之后,你可以在此菜单中选择“Choose an existing key pair”(选择现有密钥对),然后选择之前生成的密钥对。单击“Launch Instances”(启动实例)即可启动创建的实例。\n",
"\n",
"![选择一个密钥对](../img/keypair.png)\n",
":width:`500px`\n",
":label:`fig_keypair`\n",
"\n",
"如果生成了新密钥对,请确保下载密钥对并将其存储在安全位置。这是你通过SSH连接到服务器的唯一方式。单击 :numref:`fig_launching`中显示的实例ID可查看该实例的状态。\n",
"\n",
"![单击实例ID](../img/launching.png)\n",
":width:`700px`\n",
":label:`fig_launching`\n",
"\n",
"### 连接到实例\n",
"\n",
"如 :numref:`fig_connect`所示,实例状态变为绿色后,右键单击实例,选择`Connect`(连接)查看实例访问方式。\n",
"\n",
"![查看实例访问方法](../img/connect.png)\n",
":width:`700px`\n",
":label:`fig_connect`\n",
"\n",
"如果这是一个新密钥,它必须是不可公开查看的,SSH才能工作。转到存储`D2L_key.pem`的文件夹,并执行以下命令以使密钥不可公开查看:\n",
"\n",
"```bash\n",
"chmod 400 D2L_key.pem\n",
"```\n",
"\n",
"![查看实例访问和启动方法](../img/chmod.png)\n",
":width:`400px`\n",
":label:`fig_chmod`\n",
"\n",
"现在,复制 :numref:`fig_chmod`下方红色框中的ssh命令并粘贴到命令行:\n",
"\n",
"```bash\n",
"ssh -i \"D2L_key.pem\" ubuntu@ec2-xx-xxx-xxx-xxx.y.compute.amazonaws.com\n",
"```\n",
"\n",
"当命令行提示“Are you sure you want to continue connecting (yes/no)”(“你确定要继续连接吗?(是/否)”)时,输入“yes”并按回车键登录实例。\n",
"\n",
"你的服务器现在已就绪。\n",
"\n",
"## 安装CUDA\n",
"\n",
"在安装CUDA之前,请确保使用最新的驱动程序更新实例。\n",
"\n",
"```bash\n",
"sudo apt-get update && sudo apt-get install -y build-essential git libgfortran3\n",
"```\n",
"\n",
"我们在这里下载CUDA 10.1。访问NVIDIA的[官方存储库](https://developer.nvidia.com/cuda-toolkit-archive) 以找到下载链接,如 :numref:`fig_cuda`中所示。\n",
"\n",
"![查找CUDA 10.1下载地址](../img/cuda101.png)\n",
":width:`500px`\n",
":label:`fig_cuda`\n",
"\n",
"将说明复制粘贴到终端上,以安装CUDA 10.1。\n",
"\n",
"```bash\n",
"# 链接和文件名可能会发生更改,以NVIDIA的官方为准\n",
"wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin\n",
"sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600\n",
"wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda-repo-ubuntu1804-10-1-local-10.1.243-418.87.00_1.0-1_amd64.deb\n",
"sudo dpkg -i cuda-repo-ubuntu1804-10-1-local-10.1.243-418.87.00_1.0-1_amd64.deb\n",
"sudo apt-key add /var/cuda-repo-10-1-local-10.1.243-418.87.00/7fa2af80.pub\n",
"sudo apt-get update\n",
"sudo apt-get -y install cuda\n",
"```\n",
"\n",
"安装程序后,运行以下命令查看GPU:\n",
"\n",
"```bash\n",
"nvidia-smi\n",
"```\n",
"\n",
"最后,将CUDA添加到库路径以帮助其他库找到它。\n",
"\n",
"```bash\n",
"echo \"export LD_LIBRARY_PATH=\\${LD_LIBRARY_PATH}:/usr/local/cuda/lib64\" >> ~/.bashrc\n",
"```\n",
"\n",
"## 安装库以运行代码\n",
"\n",
"要运行本书的代码,只需在EC2实例上为linux用户执行 :ref:`chap_installation`中的步骤,并使用以下提示在远程linux服务器上工作。\n",
"\n",
"* 要在Miniconda安装页面下载bash脚本,请右击下载链接并选择“copy Link address”,然后执行`wget [copied link address]`。\n",
"* 运行`~/miniconda3/bin/conda init`, 你可能需要执行`source~/.bashrc`,而不是关闭并重新打开当前shell。\n",
"\n",
"## 远程运行Jupyter笔记本\n",
"\n",
"要远程运行Jupyter笔记本,你需要使用SSH端口转发。毕竟,云中的服务器没有显示器或键盘。为此,请从你的台式机(或笔记本电脑)登录到你的服务器,如下所示:\n",
"\n",
"```\n",
"# 此命令必须在本地命令行中运行\n",
"ssh -i \"/path/to/key.pem\" ubuntu@ec2-xx-xxx-xxx-xxx.y.compute.amazonaws.com -L 8889:localhost:8888\n",
"```\n",
"\n",
"接下来,转到EC2实例上本书下载的代码所在的位置,然后运行:\n",
"\n",
"```\n",
"conda activate d2l\n",
"jupyter notebook\n",
"```\n",
"\n",
":numref:`fig_jupyter`显示了运行Jupyter笔记本后可能的输出。最后一行是端口8888的URL。\n",
"\n",
"![运行Jupyter Notebook后的输出(最后一行是端口8888的URL](../img/jupyter.png)\n",
":width:`700px`\n",
":label:`fig_jupyter`\n",
"\n",
"由于你使用端口转发到端口8889,请复制 :numref:`fig_jupyter`红色框中的最后一行,将URL中的“8888”替换为“8889”,然后在本地浏览器中打开它。\n",
"\n",
"## 关闭未使用的实例\n",
"\n",
"由于云服务是按使用时间计费的,你应该关闭不使用的实例。请注意,还有其他选择:\n",
"\n",
"* “Stopping”(停止)实例意味着你可以重新启动它。这类似于关闭常规服务器的电源。但是,停止的实例仍将按保留的硬盘空间收取少量费用;\n",
"* “Terminating”(终止)实例将删除与其关联的所有数据。这包括磁盘,因此你不能再次启动它。只有在你知道将来不需要它的情况下才这样做。\n",
"\n",
"如果你想要将该实例用作更多实例的模板,请右击 :numref:`fig_connect`中的例子,然后选择“Image”$\\rightarrow$“Create”以创建该实例的镜像。完成后,选择“实例状态”$\\rightarrow$“终止”以终止实例。下次要使用此实例时,可以按照本节中的步骤基于保存的镜像创建实例。唯一的区别是,在 :numref:`fig_ubuntu`所示的“1.选择AMI”中,你必须使用左侧的“我的AMI”选项来选择你保存的镜像。创建的实例将保留镜像硬盘上存储的信息。例如,你不必重新安装CUDA和其他运行时环境。\n",
"\n",
"## 小结\n",
"\n",
"* 我们可以按需启动和停止实例,而不必购买和制造我们自己的计算机。\n",
"* 在使用支持GPU的深度学习框架之前,我们需要安装CUDA。\n",
"* 我们可以使用端口转发在远程服务器上运行Jupyter笔记本。\n",
"\n",
"## 练习\n",
"\n",
"1. 云提供了便利,但价格并不便宜。了解如何启动[spot实例](https://aws.amazon.com/ec2/spot/)以降低成本。\n",
"1. 尝试使用不同的GPU服务器。它们有多快?\n",
"1. 尝试使用多GPU服务器。你能把事情扩大到什么程度?\n",
"\n",
"[Discussions](https://discuss.d2l.ai/t/5733)\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"required_libs": []
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,182 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "14e728be",
"metadata": {
"origin_pos": 0
},
"source": [
"# 为本书做贡献\n",
":label:`sec_how_to_contribute`\n",
"\n",
"读者们的投稿大大帮助我们改进了本书的质量。\n",
"如果你发现笔误、无效的链接、一些你认为我们遗漏了引文的地方,\n",
"代码看起来不优雅,或者解释不清楚的地方,请回复我们以帮助读者。\n",
"在常规书籍中,两次印刷之间的间隔(即修订笔误的间隔)常常需要几年,\n",
"但这本书的改进通常需要几小时到几天的时间。\n",
"由于版本控制和持续自动集成(CI)测试,这一切颇为高效。\n",
"为此,你需要向gihub存储库提交一个\n",
"[pull request](https://github.com/d2l-ai/d2l-en/pulls)。\n",
"当你的pull请求被作者合并到代码库中时,\n",
"你将成为[贡献者](https://github.com/d2l-ai/d2l-en/graphs/contributors)。\n",
"\n",
"## 提交微小更改\n",
"\n",
"最常见的贡献是编辑一句话或修正笔误。\n",
"我们建议你在[GitHub存储库](https://github.com/d2l-ai/d2l-en)\n",
"中查找源文件,以定位源文件(一个markdown文件)。\n",
"然后单击右上角的“Edit this file”按钮,在markdown文件中进行更改。\n",
"\n",
"![在Github上编辑文件](../img/edit-file.png)\n",
":width:`300px`\n",
":label:`fig_edit_file`\n",
"\n",
"完成后,在页面底部的“Propose file change”(“提交文件修改”)\n",
"面板中填写更改说明,然后单击“Propose file change”按钮。\n",
"它会重定向到新页面以查看你的更改( :numref:`fig_git_createpr`)。\n",
"如果一切正常,你可以通过点击“Create pull request”按钮提交pull请求。\n",
"\n",
"## 大量文本或代码修改\n",
"\n",
"如果你计划修改大量文本或代码,那么你需要更多地了解本书使用的格式。\n",
"源文件基于[markdown格式](https://daringfireball.net/projects/markdown/syntax)\n",
"并通过[d2lbook](http://book.d2l.ai/user/markdown.html)包提供了一组扩展,\n",
"例如引用公式、图像、章节和引文。\n",
"你可以使用任何markdown编辑器打开这些文件并进行更改。\n",
"\n",
"如果你想要更改代码,我们建议你使用Jupyter Notebook打开这些标记文件,\n",
"如 :numref:`sec_jupyter`中所述。\n",
"这样你就可以运行并测试你的更改。\n",
"请记住在提交更改之前清除所有输出,我们的CI系统将执行你更新的部分以生成输出。\n",
"\n",
"某些部分可能支持多个框架实现。如果你添加的新代码块不是使用mxnet,\n",
"请使用`#@tab`来标记代码块的起始行。\n",
"例如`#@tab pytorch`用于一个PyTorch代码块,\n",
"`#@tab tensorflow`用于一个TensorFlow代码块,\n",
"`#@tab paddle`用于一个PaddlePaddle代码块,\n",
"或者`#@tab all`是所有实现的共享代码块。\n",
"你可以参考[d2lbook](http://book.d2l.ai/user/code_tabs.html)包了解更多信息。\n",
"\n",
"## 提交主要更改\n",
"\n",
"我们建议你使用标准的Git流程提交大量修改。\n",
"简而言之,该过程的工作方式如 :numref:`fig_contribute`中所述。\n",
"\n",
"![为这本书作贡献](../img/contribute.svg)\n",
":label:`fig_contribute`\n",
"\n",
"我们将向你详细介绍这些步骤。\n",
"如果你已经熟悉Git,可以跳过本部分。\n",
"在介绍时,我们假设贡献者的用户名为“astonzhang”。\n",
"\n",
"### 安装Git\n",
"\n",
"Git开源书籍描述了[如何安装git](https://git-scm.com/book/en/v2)。\n",
"这通常通过Ubuntu Linux上的`apt install git`\n",
"在MacOS上安装Xcode开发人员工具或使用gihub的\n",
"[桌面客户端](https://desktop.github.com)来实现。\n",
"如果你没有GitHub帐户,则需要注册一个帐户。\n",
"\n",
"### 登录GitHub\n",
"\n",
"在浏览器中输入本书代码存储库的[地址](https://github.com/d2l-ai/d2l-en/)。\n",
"单击 :numref:`fig_git_fork`右上角红色框中的`Fork`按钮,以复制本书的存储库。\n",
"这将是你的副本,你可以随心所欲地更改它。\n",
"\n",
"![代码存储库页面](../img/git-fork.png)\n",
":width:`700px`\n",
":label:`fig_git_fork`\n",
"\n",
"现在,本书的代码库将被分叉(即复制)到你的用户名,\n",
"例如`astonzhang/d2l-en`显示在 :numref:`fig_git_forked`的左上角。\n",
"\n",
"![分叉代码存储库](../img/git-forked.png)\n",
":width:`700px`\n",
":label:`fig_git_forked`\n",
"\n",
"### 克隆存储库\n",
"\n",
"要克隆存储库(即制作本地副本),我们需要获取其存储库地址。\n",
"点击 :numref:`fig_git_clone`中的绿色按钮显示此信息。\n",
"如果你决定将此分支保留更长时间,请确保你的本地副本与主存储库保持最新。\n",
"现在,只需按照 :ref:`chap_installation`中的说明开始。\n",
"主要区别在于,你现在下载的是你自己的存储库分支。\n",
"\n",
"![克隆存储库](../img/git-clone.png)\n",
":width:`700px`\n",
":label:`fig_git_clone`\n",
"\n",
"```\n",
"# 将your_github_username替换为你的github用户名\n",
"git clone https://github.com/your_github_username/d2l-en.git\n",
"```\n",
"\n",
"### 编辑和推送\n",
"\n",
"现在是编辑这本书的时候了。最好按照 :numref:`sec_jupyter`中的说明在Jupyter Notebook中编辑它。进行更改并检查它们是否正常。假设我们已经修改了文件`~/d2l-en/chapter_appendix_tools/how-to-contribute.md`中的一个拼写错误。你可以检查你更改了哪些文件。\n",
"\n",
"此时,Git将提示`chapter_appendix_tools/how-to-contribute.md`文件已被修改。\n",
"\n",
"```\n",
"mylaptop:d2l-en me$ git status\n",
"On branch master\n",
"Your branch is up-to-date with 'origin/master'.\n",
"\n",
"Changes not staged for commit:\n",
" (use \"git add <file>...\" to update what will be committed)\n",
" (use \"git checkout -- <file>...\" to discard changes in working directory)\n",
"\n",
"\tmodified: chapter_appendix_tools/how-to-contribute.md\n",
"```\n",
"\n",
"在确认这是你想要的之后,执行以下命令:\n",
"\n",
"```\n",
"git add chapter_appendix_tools/how-to-contribute.md\n",
"git commit -m 'fix typo in git documentation'\n",
"git push\n",
"```\n",
"\n",
"然后,更改后的代码将位于存储库的个人分支中。要请求添加更改,你必须为本书的官方存储库创建一个Pull请求。\n",
"\n",
"### 提交Pull请求\n",
"\n",
"如 :numref:`fig_git_newpr`所示,进入gihub上的存储库分支,选择“New pull request”。这将打开一个页面,显示你的编辑与本书主存储库中的当前内容之间的更改。\n",
"\n",
"![新的Pull请求](../img/git-newpr.png)\n",
":width:`700px`\n",
":label:`fig_git_newpr`\n",
"\n",
"最后,单击按钮提交Pull请求,如 :numref:`fig_git_createpr`所示。请务必描述你在Pull请求中所做的更改。这将使作者更容易审阅它,并将其与本书合并。根据更改的不同,这可能会立即被接受,也可能会被拒绝,或者更有可能的是,你会收到一些关于更改的反馈。一旦你把它们合并了,你就做完了。\n",
"\n",
"![创建Pull请求](../img/git-createpr.png)\n",
":width:`700px`\n",
":label:`fig_git_createpr`\n",
"\n",
"## 小结\n",
"\n",
"* 你可以使用GitHub为本书做贡献。\n",
"* 你可以直接在GitHub上编辑文件以进行微小更改。\n",
"* 要进行重大更改,请分叉存储库,在本地编辑内容,并在准备好后再做出贡献。\n",
"* 尽量不要提交巨大的Pull请求,因为这会使它们难以理解和合并。最好拆分为几个小一点的。\n",
"\n",
"## 练习\n",
"\n",
"1. 启动并分叉`d2l-ai/d2l-en`存储库。\n",
"1. 如果发现任何需要改进的地方(例如,缺少引用),请提交Pull请求。\n",
"1. 通常更好的做法是使用新分支创建Pull请求。学习如何用[Git分支](https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell)来做这件事。\n",
"\n",
"[Discussions](https://discuss.d2l.ai/t/5730)\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"required_libs": []
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,105 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "1069a72a",
"metadata": {
"origin_pos": 0
},
"source": [
"# `d2l` API 文档\n",
":label:`sec_d2l`\n",
"\n",
"`d2l`包以下成员的实现及其定义和解释部分可在[源文件](https://github.com/d2l-ai/d2l-en/tree/master/d2l)中找到。\n"
]
},
{
"cell_type": "markdown",
"id": "c81dbb31",
"metadata": {
"origin_pos": 2,
"tab": [
"pytorch"
]
},
"source": [
"```eval_rst\n",
".. currentmodule:: d2l.torch\n",
"```\n"
]
},
{
"cell_type": "markdown",
"id": "7f0df80c",
"metadata": {
"origin_pos": 5
},
"source": [
"## 模型\n",
"\n",
"```eval_rst\n",
".. autoclass:: Module\n",
" :members:\n",
"\n",
".. autoclass:: LinearRegressionScratch\n",
" :members:\n",
"\n",
".. autoclass:: LinearRegression\n",
" :members:\n",
"\n",
".. autoclass:: Classification\n",
" :members:\n",
"```\n",
"\n",
"## 数据\n",
"\n",
"```eval_rst\n",
".. autoclass:: DataModule\n",
" :members:\n",
"\n",
".. autoclass:: SyntheticRegressionData\n",
" :members:\n",
"\n",
".. autoclass:: FashionMNIST\n",
" :members:\n",
"```\n",
"\n",
"## 训练\n",
"\n",
"```eval_rst\n",
".. autoclass:: Trainer\n",
" :members:\n",
"\n",
".. autoclass:: SGD\n",
" :members:\n",
"```\n",
"\n",
"## 公用\n",
"\n",
"```eval_rst\n",
".. autofunction:: add_to_class\n",
"\n",
".. autofunction:: cpu\n",
"\n",
".. autofunction:: gpu\n",
"\n",
".. autofunction:: num_gpus\n",
"\n",
".. autoclass:: ProgressBoard\n",
" :members:\n",
"\n",
".. autoclass:: HyperParameters\n",
" :members:\n",
"```\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"required_libs": []
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,35 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "b6a8abfc",
"metadata": {
"origin_pos": 0
},
"source": [
"# 附录:深度学习工具\n",
":label:`chap_appendix_tools`\n",
"\n",
"为了充分利用《动手学深度学习》,本书将在本附录中介绍不同工具,\n",
"例如如何运行这本交互式开源书籍和为本书做贡献。\n",
"\n",
":begin_tab:toc\n",
" - [jupyter](jupyter.ipynb)\n",
" - [sagemaker](sagemaker.ipynb)\n",
" - [aws](aws.ipynb)\n",
" - [selecting-servers-gpus](selecting-servers-gpus.ipynb)\n",
" - [contributing](contributing.ipynb)\n",
" - [d2l](d2l.ipynb)\n",
":end_tab:\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"required_libs": []
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,133 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "5d3957b1",
"metadata": {
"origin_pos": 0
},
"source": [
"# 使用Jupyter Notebook\n",
":label:`sec_jupyter`\n",
"\n",
"本节介绍如何使用Jupyter Notebook编辑和运行本书各章中的代码。确保你已按照 :ref:`chap_installation`中的说明安装了Jupyter并下载了代码。如果你想了解更多关于Jupyter的信息,请参阅其[文档](https://jupyter.readthedocs.io/en/latest/)中的优秀教程。 \n",
"\n",
"## 在本地编辑和运行代码\n",
"\n",
"假设本书代码的本地路径为`xx/yy/d2l-en/`。使用shell将目录更改为此路径(`cd xx/yy/d2l-en`)并运行命令`jupyter notebook`。如果浏览器未自动打开,请打开http://localhost:8888。此时你将看到Jupyter的界面以及包含本书代码的所有文件夹,如 :numref:`fig_jupyter00`所示\n",
"\n",
"![包含本书代码的文件夹](../img/jupyter00.png)\n",
":width:`600px`\n",
":label:`fig_jupyter00`\n",
"\n",
"你可以通过单击网页上显示的文件夹来访问notebook文件。它们通常有后缀“.ipynb”。为了简洁起见,我们创建了一个临时的“test.ipynb”文件。单击后显示的内容如 :numref:`fig_jupyter01`所示。此notebook包括一个标记单元格和一个代码单元格。标记单元格中的内容包括“This Is a Title”和“This is text.”。代码单元包含两行Python代码。 \n",
"\n",
"![“test.ipynb”文件中的markdown和代码块](../img/jupyter01.png)\n",
":width:`600px`\n",
":label:`fig_jupyter01`\n",
"\n",
"双击标记单元格以进入编辑模式。在单元格末尾添加一个新的文本字符串“Hello world.”,如 :numref:`fig_jupyter02`所示。 \n",
"\n",
"![编辑markdown单元格](../img/jupyter02.png)\n",
":width:`600px`\n",
":label:`fig_jupyter02`\n",
"\n",
"如 :numref:`fig_jupyter03`所示,单击菜单栏中的“Cell” $\\rightarrow$ “Run Cells”以运行编辑后的单元格。 \n",
"\n",
"![运行单元格](../img/jupyter03.png)\n",
":width:`600px`\n",
":label:`fig_jupyter03`\n",
"\n",
"运行后,markdown单元格如 :numref:`fig_jupyter04`所示。 \n",
"\n",
"![编辑后的markdown单元格](../img/jupyter04.png)\n",
":width:`600px`\n",
":label:`fig_jupyter04`\n",
"\n",
"接下来,单击代码单元。将最后一行代码后的元素乘以2,如 :numref:`fig_jupyter05`所示。 \n",
"\n",
"![编辑代码单元格](../img/jupyter05.png)\n",
":width:`600px`\n",
":label:`fig_jupyter05`\n",
"\n",
"你还可以使用快捷键(默认情况下为Ctrl+Enter)运行单元格,并从 :numref:`fig_jupyter06`获取输出结果。 \n",
"\n",
"![运行代码单元格以获得输出](../img/jupyter06.png)\n",
":width:`600px`\n",
":label:`fig_jupyter06`\n",
"\n",
"当一个notebook包含更多单元格时,我们可以单击菜单栏中的“Kernel”$\\rightarrow$“Restart & Run All”来运行整个notebook中的所有单元格。通过单击菜单栏中的“Help”$\\rightarrow$“Edit Keyboard Shortcuts”,可以根据你的首选项编辑快捷键。 \n",
"\n",
"## 高级选项\n",
"\n",
"除了本地编辑,还有两件事非常重要:以markdown格式编辑notebook和远程运行Jupyter。当我们想要在更快的服务器上运行代码时,后者很重要。前者很重要,因为Jupyter原生的ipynb格式存储了大量辅助数据,这些数据实际上并不特定于notebook中的内容,主要与代码的运行方式和运行位置有关。这让git感到困惑,并且使得合并贡献非常困难。幸运的是,还有另一种选择——在markdown中进行本地编辑。 \n",
"\n",
"### Jupyter中的Markdown文件\n",
"\n",
"如果你希望对本书的内容有所贡献,则需要在GitHub上修改源文件(md文件,而不是ipynb文件)。使用notedown插件,我们可以直接在Jupyter中修改md格式的notebook。 \n",
"\n",
"首先,安装notedown插件,运行Jupyter Notebook并加载插件:\n",
"\n",
"```\n",
"pip install d2l-notedown # 你可能需要卸载原始notedown\n",
"jupyter notebook --NotebookApp.contents_manager_class='notedown.NotedownContentsManager'\n",
"```\n",
"\n",
"要在运行Jupyter Notebook时默认打开notedown插件,请执行以下操作:首先,生成一个Jupyter Notebook配置文件(如果已经生成了,可以跳过此步骤)。\n",
"\n",
"```\n",
"jupyter notebook --generate-config\n",
"```\n",
"\n",
"然后,在Jupyter Notebook配置文件的末尾添加以下行(对于Linux/macOS,通常位于`~/.jupyter/jupyter_notebook_config.py`):\n",
"\n",
"```\n",
"c.NotebookApp.contents_manager_class = 'notedown.NotedownContentsManager'\n",
"```\n",
"\n",
"在这之后,你只需要运行`jupyter notebook`命令就可以默认打开notedown插件。 \n",
"\n",
"### 在远程服务器上运行Jupyter Notebook\n",
"\n",
"有时,你可能希望在远程服务器上运行Jupyter Notebook,并通过本地计算机上的浏览器访问它。如果本地计算机上安装了Linux或MacOSWindows也可以通过PuTTY等第三方软件支持此功能),则可以使用端口转发:\n",
"\n",
"```\n",
"ssh myserver -L 8888:localhost:8888\n",
"```\n",
"\n",
"以上是远程服务器`myserver`的地址。然后我们可以使用http://localhost:8888 访问运行Jupyter Notebook的远程服务器`myserver`。下一节将详细介绍如何在AWS实例上运行Jupyter Notebook。 \n",
"\n",
"### 执行时间\n",
"\n",
"我们可以使用`ExecuteTime`插件来计算Jupyter Notebook中每个代码单元的执行时间。使用以下命令安装插件:\n",
"\n",
"```\n",
"pip install jupyter_contrib_nbextensions\n",
"jupyter contrib nbextension install --user\n",
"jupyter nbextension enable execute_time/ExecuteTime\n",
"```\n",
"\n",
"## 小结\n",
"\n",
"* 使用Jupyter Notebook工具,我们可以编辑、运行和为本书做贡献。\n",
"* 使用端口转发在远程服务器上运行Jupyter Notebook。\n",
"\n",
"## 练习\n",
"\n",
"1. 在本地计算机上使用Jupyter Notebook编辑并运行本书中的代码。\n",
"1. 使用Jupyter Notebook通过端口转发来远程编辑和运行本书中的代码。\n",
"1. 对于两个方矩阵,测量$\\mathbf{A}^\\top \\mathbf{B}$与$\\mathbf{A} \\mathbf{B}$在$\\mathbb{R}^{1024 \\times 1024}$中的运行时间。哪一个更快?\n",
"\n",
"[Discussions](https://discuss.d2l.ai/t/5731)\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"required_libs": []
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,153 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "b0c43609",
"metadata": {
"origin_pos": 0
},
"source": [
"# 使用Amazon SageMaker\n",
":label:`sec_sagemaker`\n",
"\n",
"深度学习程序可能需要很多计算资源,这很容易超出你的本地计算机所能提供的范围。云计算服务允许你使用功能更强大的计算机更轻松地运行本书的GPU密集型代码。本节将介绍如何使用Amazon SageMaker运行本书的代码。\n",
"\n",
"## 注册\n",
"\n",
"首先,我们需要在注册一个帐户https://aws.amazon.com/。 为了增加安全性,鼓励使用双因素身份验证。设置详细的计费和支出警报也是一个好主意,以避免任何意外,例如,当忘记停止运行实例时。登录AWS帐户后,转到[console](http://console.aws.amazon.com/)并搜索“Amazon SageMaker”(参见 :numref:`fig_sagemaker`),然后单击它打开SageMaker面板。\n",
"\n",
"![搜索并打开SageMaker面板](../img/sagemaker.png)\n",
":width:`300px`\n",
":label:`fig_sagemaker`\n",
"\n",
"## 创建SageMaker实例\n",
"\n",
"接下来,让我们创建一个notebook实例,如 :numref:`fig_sagemaker-create`所示。\n",
"\n",
"![创建一个SageMaker实例](../img/sagemaker-create.png)\n",
":width:`400px`\n",
":label:`fig_sagemaker-create`\n",
"\n",
"SageMaker提供多个具有不同计算能力和价格的[实例类型](https://aws.amazon.com/sagemaker/pricing/instance-types/)。创建notebook实例时,可以指定其名称和类型。在 :numref:`fig_sagemaker-create-2`中,我们选择`ml.p3.2xlarge`:使用一个Tesla V100 GPU和一个8核CPU,这个实例的性能足够本书的大部分内容使用。\n",
"\n",
"![选择实例类型](../img/sagemaker-create-2.png)\n",
":width:`400px`\n",
":label:`fig_sagemaker-create-2`\n"
]
},
{
"cell_type": "markdown",
"id": "87a915ca",
"metadata": {
"origin_pos": 2,
"tab": [
"pytorch"
]
},
"source": [
"用于与SageMaker一起运行的ipynb格式的整本书可从https://github.com/d2l-ai/d2l-pytorch-sagemaker获得。\n",
"我们可以指定此GitHub存储库URL :numref:`fig_sagemaker-create-3`),以允许SageMaker在创建实例时克隆它。\n"
]
},
{
"cell_type": "markdown",
"id": "061d3b04",
"metadata": {
"origin_pos": 4
},
"source": [
"![指定GitHub存储库](../img/sagemaker-create-3.png)\n",
":width:`400px`\n",
":label:`fig_sagemaker-create-3`\n",
"\n",
"## 运行和停止实例\n",
"\n",
"创建实例可能需要几分钟的时间。当实例准备就绪时,单击它旁边的“Open Jupyter”链接( :numref:`fig_sagemaker-open`),以便你可以在此实例上编辑并运行本书的所有Jupyter Notebook(类似于 :numref:`sec_jupyter`中的步骤)。\n",
"\n",
"![在创建的SageMaker实例上打开Jupyter](../img/sagemaker-open.png)\n",
":width:`400px`\n",
":label:`fig_sagemaker-open`\n",
"\n",
"完成工作后,不要忘记停止实例以避免进一步收费( :numref:`fig_sagemaker-stop`)。\n",
"\n",
"![停止SageMaker实例](../img/sagemaker-stop.png)\n",
":width:`300px`\n",
":label:`fig_sagemaker-stop`\n",
"\n",
"## 更新Notebook\n"
]
},
{
"cell_type": "markdown",
"id": "f55e7f4e",
"metadata": {
"origin_pos": 6,
"tab": [
"pytorch"
]
},
"source": [
"这本开源书的notebook将定期在GitHub上的[d2l-ai/d2l-pytorch-sagemaker](https://github.com/d2l-ai/d2l-pytorch-sagemaker)存储库中更新。要更新至最新版本,你可以在SageMaker实例( :numref:`fig_sagemaker-terminal`)上打开终端。\n"
]
},
{
"cell_type": "markdown",
"id": "f2b7db7b",
"metadata": {
"origin_pos": 8
},
"source": [
"![在SageMaker实例上打开终端](../img/sagemaker-terminal.png)\n",
":width:`300px`\n",
":label:`fig_sagemaker-terminal`\n",
"\n",
"你可能希望在从远程存储库提取更新之前提交本地更改。否则,只需在终端中使用以下命令放弃所有本地更改:\n"
]
},
{
"cell_type": "markdown",
"id": "b1900934",
"metadata": {
"origin_pos": 10,
"tab": [
"pytorch"
]
},
"source": [
"```bash\n",
"cd SageMaker/d2l-pytorch-sagemaker/\n",
"git reset --hard\n",
"git pull\n",
"```\n"
]
},
{
"cell_type": "markdown",
"id": "5060f222",
"metadata": {
"origin_pos": 12
},
"source": [
"## 小结\n",
"\n",
"* 我们可以使用Amazon SageMaker创建一个GPU的notebook实例来运行本书的密集型代码。\n",
"* 我们可以通过Amazon SageMaker实例上的终端更新notebooks。\n",
"\n",
"## 练习\n",
"\n",
"1. 使用Amazon SageMaker编辑并运行任何需要GPU的部分。\n",
"1. 打开终端以访问保存本书所有notebooks的本地目录。\n",
"\n",
"[Discussions](https://discuss.d2l.ai/t/5732)\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"required_libs": []
},
"nbformat": 4,
"nbformat_minor": 5
}
@@ -0,0 +1,82 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "c34c875c",
"metadata": {
"origin_pos": 0
},
"source": [
"# 选择服务器和GPU\n",
":label:`sec_buy_gpu`\n",
"\n",
"深度学习训练通常需要大量的计算。目前,GPU是深度学习最具成本效益的硬件加速器。与CPU相比,GPU更便宜,性能更高,通常超过一个数量级。此外,一台服务器可以支持多个GPU,高端服务器最多支持8个GPU。更典型的数字是工程工作站最多4个GPU,这是因为热量、冷却和电源需求会迅速增加,超出办公楼所能支持的范围。对于更大的部署,云计算(例如亚马逊的[P3](https://aws.amazon.com/ec2/instance-types/p3/)和[G4](https://aws.amazon.com/blogs/aws/in-the-works-ec2-instances-g4-with-nvidia-t4-gpus/)实例)是一个更实用的解决方案。\n",
"\n",
"## 选择服务器\n",
"\n",
"通常不需要购买具有多个线程的高端CPU,因为大部分计算都发生在GPU上。这就是说,由于Python中的全局解释器锁(GIL),CPU的单线程性能在有4-8个GPU的情况下可能很重要。所有的条件都是一样的,这意味着核数较少但时钟频率较高的CPU可能是更经济的选择。例如,当在6核4GHz和8核3.5GHz CPU之间进行选择时,前者更可取,即使其聚合速度较低。一个重要的考虑因素是,GPU使用大量的电能,从而释放大量的热量。这需要非常好的冷却和足够大的机箱来容纳GPU。如有可能,请遵循以下指南:\n",
"\n",
"1. **电源**。GPU使用大量的电源。每个设备预计高达350W(检查显卡的*峰值需求*而不是一般需求,因为高效代码可能会消耗大量能源)。如果电源不能满足需求,系统会变得不稳定。\n",
"1. **机箱尺寸**。GPU很大,辅助电源连接器通常需要额外的空间。此外,大型机箱更容易冷却。\n",
"1. **GPU散热**。如果有大量的GPU,可能需要投资水冷。此外,即使风扇较少,也应以“公版设计”为目标,因为它们足够薄,可以在设备之间进气。当使用多风扇GPU,安装多个GPU时,它可能太厚而无法获得足够的空气。\n",
"1. **PCIe插槽**。在GPU之间来回移动数据(以及在GPU之间交换数据)需要大量带宽。建议使用16通道的PCIe 3.0插槽。当安装了多个GPU时,请务必仔细阅读主板说明,以确保在同时使用多个GPU时16$\\times$带宽仍然可用,并且使用的是PCIe3.0,而不是用于附加插槽的PCIe2.0。在安装多个GPU的情况下,一些主板的带宽降级到8$\\times$甚至4$\\times$。这部分是由于CPU提供的PCIe通道数量限制。\n",
"\n",
"简而言之,以下是构建深度学习服务器的一些建议。\n",
"\n",
"* **初学者**。购买低功耗的低端GPU(适合深度学习的廉价游戏GPU,功耗150-200W)。如果幸运的话,大家现在常用的计算机将支持它。\n",
"* **1个GPU**。一个4核的低端CPU就足够了,大多数主板也足够了。以至少32 GB的DRAM为目标,投资SSD进行本地数据访问。600W的电源应足够。买一个有很多风扇的GPU。\n",
"* **2个GPU**。一个4-6核的低端CPU就足够了。可以考虑64 GB的DRAM并投资于SSD。两个高端GPU将需要1000瓦的功率。对于主板,请确保它们具有*两个*PCIe 3.0 x16插槽。如果可以,请使用PCIe 3.0 x16插槽之间有两个可用空间(60毫米间距)的主板,以提供额外的空气。在这种情况下,购买两个具有大量风扇的GPU。\n",
"* **4个GPU**。确保购买的CPU具有相对较快的单线程速度(即较高的时钟频率)。可能需要具有更多PCIe通道的CPU,例如AMD Threadripper。可能需要相对昂贵的主板才能获得4个PCIe 3.0 x16插槽,因为它们可能需要一个PLX来多路复用PCIe通道。购买带有公版设计的GPU,这些GPU很窄,并且让空气进入GPU之间。需要一个1600-2000W的电源,而办公室的插座可能不支持。此服务器可能在运行时*声音很大,很热*。不想把它放在桌子下面。建议使用128 GB的DRAM。获取一个用于本地存储的SSD1-2 TB NVMe)和RAID配置的硬盘来存储数据。\n",
"* **8 GPU**。需要购买带有多个冗余电源的专用多GPU服务器机箱(例如,每个电源为1600W时为2+1)。这将需要双插槽服务器CPU、256 GB ECC DRAM、快速网卡(建议使用10 GBE),并且需要检查服务器是否支持GPU的*物理外形*。用户GPU和服务器GPU之间的气流和布线位置存在显著差异(例如RTX 2080和Tesla V100)。这意味着可能无法在服务器中安装消费级GPU,因为电源线间隙不足或缺少合适的接线(本书一位合著者痛苦地发现了这一点)。\n",
"\n",
"## 选择GPU\n",
"\n",
"目前,AMD和NVIDIA是专用GPU的两大主要制造商。NVIDIA是第一个进入深度学习领域的公司,通过CUDA为深度学习框架提供更好的支持。因此,大多数买家选择NVIDIA GPU。\n",
"\n",
"NVIDIA提供两种类型的GPU,针对个人用户(例如,通过GTX和RTX系列)和企业用户(通过其Tesla系列)。这两种类型的GPU提供了相当的计算能力。但是,企业用户GPU通常使用强制(被动)冷却、更多内存和ECC(纠错)内存。这些GPU更适用于数据中心,通常成本是消费者GPU的十倍。\n",
"\n",
"如果是一个拥有100个服务器的大公司,则应该考虑英伟达Tesla系列,或者在云中使用GPU服务器。对于实验室或10+服务器的中小型公司,英伟达RTX系列可能是最具成本效益的,可以购买超微或华硕机箱的预配置服务器,这些服务器可以有效地容纳4-8个GPU。\n",
"\n",
"GPU供应商通常每一到两年发布一代,例如2017年发布的GTX 1000Pascal)系列和2019年发布的RTX 2000(Turing)系列。每个系列都提供几种不同的型号,提供不同的性能级别。GPU性能主要是以下三个参数的组合:\n",
"\n",
"1. **计算能力**。通常大家会追求32位浮点计算能力。16位浮点训练(FP16)也进入主流。如果只对预测感兴趣,还可以使用8位整数。最新一代图灵GPU提供4-bit加速。不幸的是,目前训练低精度网络的算法还没有普及;\n",
"1. **内存大小**。随着模型变大或训练期间使用的批量变大,将需要更多的GPU内存。检查HBM2(高带宽内存)与GDDR6(图形DDR)内存。HBM2速度更快,但成本更高;\n",
"1. **内存带宽**。当有足够的内存带宽时,才能最大限度地利用计算能力。如果使用GDDR6,请追求宽内存总线。\n",
"\n",
"对于大多数用户,只需看看计算能力就足够了。请注意,许多GPU提供不同类型的加速。例如,NVIDIA的Tensor Cores将操作符子集的速度提高了5$\\times$。确保所使用的库支持这一点。GPU内存应不小于4GB(8GB更好)。尽量避免将GPU也用于显示GUI(改用内置显卡)。如果无法避免,请添加额外的2GB RAM以确保安全。\n",
"\n",
":numref:`fig_flopsvsprice`比较了各种GTX 900、GTX 1000和RTX 2000系列的(GFlops)和价格(Price)。价格是维基百科上的建议价格。\n",
"\n",
"![浮点计算能力和价格比较](../img/flopsvsprice.svg)\n",
":label:`fig_flopsvsprice`\n",
"\n",
"由上图,可以看出很多事情:\n",
"\n",
"1. 在每个系列中,价格和性能大致成比例。Titan因拥有大GPU内存而有相当的溢价。然而,通过比较980 Ti和1080 Ti可以看出,较新型号具有更好的成本效益。RTX 2000系列的价格似乎没有多大提高。然而,它们提供了更优秀的低精度性能(FP16、INT8和INT4);\n",
"2. GTX 1000系列的性价比大约是900系列的两倍;\n",
"3. 对于RTX 2000系列,浮点计算能力是价格的“仿射”函数。\n",
"\n",
"![浮点计算能力和能耗](../img/wattvsprice.svg)\n",
":label:`fig_wattvsprice`\n",
"\n",
":numref:`fig_wattvsprice`显示了能耗与计算量基本成线性关系。其次,后一代更有效率。这似乎与对应于RTX 2000系列的图表相矛盾。然而,这是TensorCore不成比例的大能耗的结果。\n",
"\n",
"## 小结\n",
"\n",
"* 在构建服务器时,请注意电源、PCIe总线通道、CPU单线程速度和散热。\n",
"* 如果可能,应该购买最新一代的GPU。\n",
"* 使用云进行大型部署。\n",
"* 高密度服务器可能不与所有GPU兼容。在购买之前,请检查一下机械和散热规格。\n",
"* 为提高效率,请使用FP16或更低的精度。\n"
]
}
],
"metadata": {
"language_info": {
"name": "python"
},
"required_libs": []
},
"nbformat": 4,
"nbformat_minor": 5
}