GPU_Tutorial_CN.ipynb 15.0 KB
Notebook
Newer Older
Q
Quleaf 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 在 GPU 上使用 Paddle Quantum\n",
    "\n",
    "<em> Copyright (c) 2020 Institute for Quantum Computing, Baidu Inc. All Rights Reserved. </em>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. 简介\n",
    "\n",
    "> 注意,本篇教程具有时效性。同时不同电脑也会有个体差异性,本篇教程不保证所有电脑可以安装成功。\n",
    "\n",
Q
Quleaf 已提交
20
    "在深度学习中,大家通常会使用 GPU 来进行神经网络模型的训练,因为与 CPU 相比,GPU在浮点数运算方面有着显著的优势。因此,使用 GPU 来训练神经网络模型逐渐成为共同的选择。在 Paddle Quantum 中,我们的量子态和量子门也采用基于浮点数的复数表示,因此我们的模型如果能部署到 GPU 上进行训练,也会显著提升训练速度。\n",
Q
Quleaf 已提交
21 22 23
    "\n",
    "## 2. GPU 选择\n",
    "\n",
Q
Quleaf 已提交
24
    "在这里,我们使用 Nvidia 的硬件设备,其 CUDA(Compute Unified Device Architecture) 对深度学习的框架支持比较好。我们的 PaddlePaddle 也可以比较方便地安装在 CUDA 上。\n",
Q
Quleaf 已提交
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339
    "\n",
    "## 3. 配置 CUDA 环境\n",
    "\n",
    "### 3.1 安装 CUDA\n",
    "\n",
    "这里,我们介绍如何在 x64 平台上的 Windows10 系统中配置 CUDA 环境。首先,在[CUDA GPUs | NVIDIA Developer](https://developer.nvidia.com/cuda-gpus)上查看你的GPU是否可以安装CUDA环境。然后,在[NVIDIA 驱动程序下载](https://www.nvidia.cn/Download/index.aspx?lang=cn)下载你的显卡的最新版驱动,并安装到电脑上。\n",
    "\n",
    "在[飞桨的安装步骤](https://www.paddlepaddle.org.cn/install/quick)中,我们发现,**Paddle Paddle 在 Windows 下仅支持 CUDA 9.0/10.0 的单卡模式;不支持 CUDA 9.1/9.2/10.1**,所以,我们需要安装 CUDA10.0(CUDA9.0在理论上也可以)。在[CUDA Toolkit Archive | NVIDIA Developer](https://developer.nvidia.com/cuda-toolkit-archive)找到 CUDA 10.0 的下载地址:[CUDA Toolkit 10.0 Archive | NVIDIA Developer](https://developer.nvidia.com/cuda-10.0-download-archive),下载CUDA后,运行安装。\n",
    "\n",
    "在安装过程中,选择**自定义安装**,在 CUDA 选项中,勾选除 Visual Studio Intergration 外的其他内容(除非你理解 Visual Studio Intergration 的作用),然后除 CUDA 之外,其他选项均不勾选。然后安装位置选择默认位置(请留意你的 CUDA 的安装位置,后面需要设置环境变量),等待安装完成。\n",
    "\n",
    "安装完成之后,打开 Windows 命令行,输入`nvcc -V`,如果看到版本信息,则说明 CUDA 安装成功。\n",
    "\n",
    "### 3.2 安装 cuDNN\n",
    "\n",
    "在[NVIDIA cuDNN | NVIDIA Developer](https://developer.nvidia.com/cudnn)下载 cuDNN,根据[飞桨的安装步骤](https://www.paddlepaddle.org.cn/install/quick)中的要求,我们**需要使用 cuDNN 7.6+** ,因此我们下载支持 CUDA 10.0 的最新版 cuDNN 即可。下载完成 cuDNN 后进行解压缩。然后,假设我们的 CUDA 的安装路径为`C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.0`,我们将 cuDNN 解压缩后里面的`bin`、`include`和`lib`中的文件都替换 CUDA 的安装路径下的对应文件(如果文件已存在则进行替换,如果未存在则直接粘贴到对应目录中)。到这里,cuDNN 也就安装完成了。\n",
    "\n",
    "\n",
    "### 3.3 配置环境变量\n",
    "\n",
    "接下来还需要配置环境变量。右键电脑桌面上的“此电脑”(或“文件资源管理器”左栏的“此电脑”),选择“属性”,然后选择左侧的“高级系统设置”,在“高级”这一栏下选择“环境变量”。\n",
    "\n",
    "现在就进入到了环境变量的设置页面,在系统变量中选择`Path`,点击“编辑”。在出现的页面中,查看是否有`C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.0\\bin`和`C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.0\\libnvvp`这两个地址(其前缀`C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.0`应该为你的 CUDA 的安装位置),如果没有,请手动添加。\n",
    "\n",
    "### 3.4 验证是否安装成功\n",
    "\n",
    "打开命令行,输入`cd C:\\Program Files\\NVIDIA GPU Computing Toolkit\\CUDA\\v10.0\\extras\\demo_suite`进入到 CUDA 安装路径(这里也应该为你的 CUDA 的安装位置)。然后分别执行`.\\bandwidthTest.exe`和`.\\deviceQuery.exe`,如果都出现`Result = PASS`,则说明安装成功。\n",
    "\n",
    "\n",
    "## 4. 在 CUDA 环境上安装 PaddlePaddle\n",
    "\n",
    "根据[飞桨的安装步骤](https://www.paddlepaddle.org.cn/install/quick)中的说明,我们首先需要确定自己的python环境,用`python --version`来查看 python 版本,保证**python版本是3.5.1+/3.6+/3.7+**,并且用`python -m ensurepip`和`python -m pip --version`来查看 pip 版本,**确认是 9.0.1+**。然后,使用`python -m pip install paddlepaddle-gpu==1.8.4.post107 -i https://pypi.tuna.tsinghua.edu.cn/simple`来安装 GPU 版本的 PaddlePaddle。\n",
    "\n",
    "\n",
    "## 5. 安装 Paddle Quantum\n",
    "\n",
    "下载 Paddle Quantum 的安装包,修改`setup.py`,将其中的`paddlepaddle`改为`paddlepaddle-gpu`,然后按照 Paddle Quantum 的安装要求,执行`pip install -e .`即可。\n",
    "\n",
    "> 如果你是在一个新的 python 环境中安装了 paddlepaddle-gpu 和 paddle_quantum,请在新 python 环境中安装 jupyter,并在新的 jupyter 下重新打开本教程并运行。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 6. 检测是否安装成功\n",
    "\n",
    "打开我们 GPU 版本的 PaddlePaddle 环境,执行下面的命令,若输出为`True`则表示当前 PaddlePaddle 框架可以在GPU上运行。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import paddle \n",
    "from paddle import fluid\n",
    "print(fluid.is_compiled_with_cuda())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 7. 使用教程和示例\n",
    "\n",
    "在 Paddle Quantum 中,我们使用动态图机制来定义和训练我们的参数化量子线路。在这里,我们依然使用动态图机制,只需要定义动态图机制的运行设备即可。方式如下:\n",
    "\n",
    "```python\n",
    "# 0 表示使用编号为0的GPU\n",
    "place = fluid.CUDAPlace(0)\n",
    "with fluid.dygraph.guard(place):\n",
    "    # build and train your quantum circuit model\n",
    "```\n",
    "\n",
    "当我们想在 CPU 上运行时,也采用类似的方式,定义运行设备为CPU:\n",
    "```python\n",
    "place = fluid.CPUPlace()\n",
    "with fluid.dygraph.guard(place):\n",
    "    # build and train your quantum circuit model\n",
    "```\n",
    "\n",
    "我们可以在命令行中输入`nvidia-smi`来查看 GPU 的使用情况,包括有哪些程序在哪些 GPU 上运行,以及其显存占用情况。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这里,我们以 [VQE](https://github.com/PaddlePaddle/Quantum/blob/master/tutorial/VQE) 为例来说明我们该如何使用 GPU。首先,导入相关的包并定义相关的变量和函数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "from numpy import concatenate\n",
    "from numpy import pi as PI\n",
    "from numpy import savez, zeros\n",
    "from paddle import fluid\n",
    "from paddle.complex import matmul, transpose\n",
    "from paddle_quantum.circuit import UAnsatz\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy\n",
    "from paddle_quantum.VQE.chemistrysub import H2_generator\n",
    "from time import time\n",
    "\n",
    "Hamiltonian, N = H2_generator()\n",
    "\n",
    "\n",
    "def U_theta(theta, Hamiltonian, N, D):\n",
    "    \"\"\"\n",
    "    Quantum Neural Network\n",
    "    \"\"\"\n",
    "\n",
    "    # 按照量子比特数量/网络宽度初始化量子神经网络\n",
    "    cir = UAnsatz(N)\n",
    "\n",
    "    # 内置的 {R_y + CNOT} 电路模板\n",
    "    cir.real_entangled_layer(theta[:D], D)\n",
    "\n",
    "    # 铺上最后一列 R_y 旋转门\n",
    "    for i in range(N):\n",
    "        cir.ry(theta=theta[D][i][0], which_qubit=i)\n",
    "\n",
    "    # 量子神经网络作用在默认的初始态 |0000>上\n",
    "    cir.run_state_vector()\n",
    "\n",
    "    # 计算给定哈密顿量的期望值\n",
    "    expectation_val = cir.expecval(Hamiltonian)\n",
    "\n",
    "    return expectation_val\n",
    "\n",
    "\n",
    "class StateNet(fluid.dygraph.Layer):\n",
    "    \"\"\"\n",
    "    Construct the model net\n",
    "    \"\"\"\n",
    "\n",
    "    def __init__(self, shape, param_attr=fluid.initializer.Uniform(low=0.0, high=2 * PI), dtype=\"float64\"):\n",
    "        super(StateNet, self).__init__()\n",
    "\n",
    "        # 初始化 theta 参数列表,并用 [0, 2*pi] 的均匀分布来填充初始值\n",
    "        self.theta = self.create_parameter(shape=shape, attr=param_attr, dtype=dtype, is_bias=False)\n",
    "\n",
    "    # 定义损失函数和前向传播机制\n",
    "    def forward(self, Hamiltonian, N, D):\n",
    "        # 计算损失函数/期望值\n",
    "        loss = U_theta(self.theta, Hamiltonian, N, D)\n",
    "\n",
    "        return loss\n",
    "\n",
    "ITR = 80 # 设置训练的总迭代次数\n",
    "LR = 0.2 # 设置学习速率\n",
    "D = 2    # 设置量⼦神经⽹络中重复计算模块的深度 Depth"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果要使用GPU训练,则运行下面的程序:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 0 表示使用编号为0的GPU\n",
    "place_gpu = fluid.CUDAPlace(0)\n",
    "with fluid.dygraph.guard(palce_gpu):\n",
    "        # 确定网络的参数维度\n",
    "        net = StateNet(shape=[D + 1, N, 1])\n",
    "\n",
    "        # 一般来说,我们利用Adam优化器来获得相对好的收敛,当然你可以改成SGD或者是RMS prop.\n",
    "        opt = fluid.optimizer.AdamOptimizer(learning_rate=LR, parameter_list=net.parameters())\n",
    "\n",
    "        # 记录优化结果\n",
    "        summary_iter, summary_loss = [], []\n",
    "\n",
    "        # 优化循环\n",
    "        for itr in range(1, ITR + 1):\n",
    "\n",
    "            # 前向传播计算损失函数\n",
    "            loss = net(Hamiltonian, N, D)\n",
    "\n",
    "            # 在动态图机制下,反向传播极小化损失函数\n",
    "            loss.backward()\n",
    "            opt.minimize(loss)\n",
    "            net.clear_gradients()\n",
    "\n",
    "            # 更新优化结果\n",
    "            summary_loss.append(loss.numpy())\n",
    "            summary_iter.append(itr)\n",
    "\n",
    "            # 打印结果\n",
    "            if itr % 20 == 0:\n",
    "                print(\"iter:\", itr, \"loss:\", \"%.4f\" % loss.numpy())\n",
    "                print(\"iter:\", itr, \"Ground state energy:\", \"%.4f Ha\" % loss.numpy())\n",
    "\n",
    "        # 储存训练结果到 output 文件夹\n",
    "        os.makedirs(\"output\", exist_ok=True)\n",
    "        savez(\"./output/summary_data\", iter=summary_iter, energy=summary_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果要使用CPU训练,则运行下面的程序:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "iter: 20 loss: -1.0669\n",
      "iter: 20 Ground state energy: -1.0669 Ha\n",
      "iter: 40 loss: -1.1129\n",
      "iter: 40 Ground state energy: -1.1129 Ha\n",
      "iter: 60 loss: -1.1163\n",
      "iter: 60 Ground state energy: -1.1163 Ha\n",
      "iter: 80 loss: -1.1172\n",
      "iter: 80 Ground state energy: -1.1172 Ha\n"
     ]
    }
   ],
   "source": [
    "# 表示使用 CPU\n",
    "place_cpu = fluid.CPUPlace()\n",
    "with fluid.dygraph.guard(place_cpu):\n",
    "    # 确定网络的参数维度\n",
    "    net = StateNet(shape=[D + 1, N, 1])\n",
    "\n",
    "    # 一般来说,我们利用Adam优化器来获得相对好的收敛,当然你可以改成SGD或者是RMS prop.\n",
    "    opt = fluid.optimizer.AdamOptimizer(learning_rate=LR, parameter_list=net.parameters())\n",
    "\n",
    "    # 记录优化结果\n",
    "    summary_iter, summary_loss = [], []\n",
    "\n",
    "    # 优化循环\n",
    "    for itr in range(1, ITR + 1):\n",
    "\n",
    "        # 前向传播计算损失函数\n",
    "        loss = net(Hamiltonian, N, D)\n",
    "\n",
    "        # 在动态图机制下,反向传播极小化损失函数\n",
    "        loss.backward()\n",
    "        opt.minimize(loss)\n",
    "        net.clear_gradients()\n",
    "\n",
    "        # 更新优化结果\n",
    "        summary_loss.append(loss.numpy())\n",
    "        summary_iter.append(itr)\n",
    "\n",
    "        # 打印结果\n",
    "        if itr % 20 == 0:\n",
    "            print(\"iter:\", itr, \"loss:\", \"%.4f\" % loss.numpy())\n",
    "            print(\"iter:\", itr, \"Ground state energy:\", \"%.4f Ha\" % loss.numpy())\n",
    "\n",
    "    # 储存训练结果到 output 文件夹\n",
    "    # os.makedirs(\"output\", exist_ok=True)\n",
    "    # savez(\"./output/summary_data\", iter=summary_iter, energy=summary_loss)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 8. 总结\n",
    "\n",
    "实践证明,我们现在的 paddle_quantum 可以在 GPU 下运行,目前需要比较好的 GPU 资源才能体现出 GPU 的加速效果。在未来的版本中,我们也会不断优化 paddle_quantum 在 GPU 下的性能表现。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 参考资料\n",
    "\n",
    "[1] [Installation Guide Windows :: CUDA Toolkit Documentation](https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/index.html)\n",
    "\n",
    "[2] [Installation Guide :: NVIDIA Deep Learning cuDNN Documentation](https://docs.nvidia.com/deeplearning/cudnn/install-guide/index.html#installwindows)\n",
    "\n",
    "[3] [开始使用_飞桨-源于产业实践的开源深度学习平台](https://www.paddlepaddle.org.cn/install/quick)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
Q
Quleaf 已提交
340
   "version": "3.7.7"
Q
Quleaf 已提交
341 342 343 344 345
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}