Browse Source

ch11 finished

Gen TANG 2 years ago
parent
commit
5bc821b282

File diff suppressed because it is too large
+ 882 - 0
ch11_llm/char_gpt.ipynb


+ 269 - 0
ch11_llm/gpt2.ipynb

@@ -0,0 +1,269 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!pip install transformers"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import torch\n",
+    "from transformers import AutoTokenizer, GPT2LMHeadModel\n",
+    "\n",
+    "\n",
+    "torch.manual_seed(12046)\n",
+    "\n",
+    "tokenizer = AutoTokenizer.from_pretrained(\"gpt2\")\n",
+    "model = GPT2LMHeadModel.from_pretrained(\"gpt2\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "{'input_ids': tensor([[2061,  318,  262, 3139,  286, 2807,   30]]), 'attention_mask': tensor([[1, 1, 1, 1, 1, 1, 1]])}"
+      ]
+     },
+     "execution_count": 3,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "question = 'What is the capital of China?'\n",
+    "ids = tokenizer(question, return_tensors=\"pt\")\n",
+    "ids"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "tensor([ 2061,   318,   262,  3139,   286,  2807,    30,   198,   198,   464,\n",
+      "         3139,   318,  2807,    13,   632,   338,   262,  4387,  3773,   287,\n",
+      "          262,   995,    11,   290,   340,   468,   257,  3265,   286,   517,\n",
+      "          621,   352,    13,    20,  2997,   661,    13,  2807,   318,   530,\n",
+      "          286,   262, 14162,  3957, 16533,   319,  3668,    11,   351,   281,\n",
+      "         5079, 12396,   286,   720,    16,    13,    17, 12989,    13,   383,\n",
+      "         1499,   318,  1363,   284,   257,  1271,   286,   995,    12,  4871,\n",
+      "        11155,    11,  1390,   262,  2059,   286,  3442,    11, 14727,    11,\n",
+      "          262,  3999,  8581,   286,  5483, 13473,    11,  2807,   338,  2351,\n",
+      "         5800,  5693,   290,   262, 21865,  8581,   329,  5800,    13,   198])\n",
+      "What is the capital of China?\n",
+      "\n",
+      "The capital is China. It's the largest economy in the world, and it has a population of more than 1.5 billion people. China is one of the fastest growing economies on Earth, with an annual GDP of $1.2 trillion. The country is home to a number of world-class universities, including the University of California, Berkeley, the Chinese Academy of Social Sciences, China's National Science Foundation and the Shanghai Academy for Science.\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 由于GPT-2的模型效果较差,我们通过增大num_beams和no_repeat_ngram_size\n",
+    "# 来优化生成的文本。\n",
+    "res = model.generate(**ids, max_length=100, early_stopping=True,\n",
+    "                     num_beams=3, no_repeat_ngram_size=2)\n",
+    "print(res[0])\n",
+    "print(tokenizer.decode(res[0], skip_special_tokens=True))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "template = '''\n",
+    "Q: What is the capital of the United Kingdom?\n",
+    "A: London.\n",
+    "\n",
+    "Q: What is the capital of France?\n",
+    "A: Paris.\n",
+    "\n",
+    "Q: %s\n",
+    "A:\n",
+    "'''"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "Q: What is the capital of the United Kingdom?\n",
+      "A: London.\n",
+      "\n",
+      "Q: What is the capital of France?\n",
+      "A: Paris.\n",
+      "\n",
+      "Q: What is the capital of China?\n",
+      "A:\n",
+      "\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(template % question)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "ids2 = tokenizer(template % question , return_tensors=\"pt\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "Q: What is the capital of the United Kingdom?\n",
+      "A: London.\n",
+      "\n",
+      "Q: What is the capital of France?\n",
+      "A: Paris.\n",
+      "\n",
+      "Q: What is the capital of China?\n",
+      "A:\n",
+      "... Beijing.\n"
+     ]
+    }
+   ],
+   "source": [
+    "res2 = model.generate(**ids2, max_length=100, early_stopping=True,\n",
+    "                      num_beams=3, no_repeat_ngram_size=2)\n",
+    "print(tokenizer.decode(res2[0], skip_special_tokens=True))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "中国的首都在哪里?。\n",
+      "\n",
+      "非常和属经啊建城的自己,那么做喜址器,没有陛下解长支提队的现�\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 中文的效果较差\n",
+    "question_zh = '中国的首都在哪里?'\n",
+    "ids_zh = tokenizer(question_zh, return_tensors=\"pt\")\n",
+    "res_zh = model.generate(**ids_zh, max_length=100, early_stopping=True,\n",
+    "                        num_beams=3, no_repeat_ngram_size=2)\n",
+    "print(tokenizer.decode(res_zh[0], skip_special_tokens=True))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stderr",
+     "output_type": "stream",
+     "text": [
+      "Setting `pad_token_id` to `eos_token_id`:50256 for open-end generation.\n"
+     ]
+    },
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "\n",
+      "Q: What is the capital of the United Kingdom?\n",
+      "A: London.\n",
+      "\n",
+      "Q: What is the capital of France?\n",
+      "A: Paris.\n",
+      "\n",
+      "Q: 中国的首都在哪里?\n",
+      "A:\n",
+      "The capital city of China, Shanghai, is located in the middle of a vast expanse of land that stretches from the north to the south. It is also known as the \"Great Wall of\n"
+     ]
+    }
+   ],
+   "source": [
+    "ids_zh2 = tokenizer(template % question_zh , return_tensors=\"pt\")\n",
+    "res_zh2 = model.generate(**ids_zh2, max_length=100, early_stopping=True,\n",
+    "                         num_beams=3, no_repeat_ngram_size=2)\n",
+    "print(tokenizer.decode(res_zh2[0], skip_special_tokens=True))"
+   ]
+  }
+ ],
+ "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",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}

File diff suppressed because it is too large
+ 505 - 0
ch11_llm/gpt2_lora.ipynb


File diff suppressed because it is too large
+ 558 - 0
ch11_llm/gpt2_lora_optimum.ipynb


File diff suppressed because it is too large
+ 660 - 0
ch11_llm/gpt2_reward_modeling.ipynb


+ 511 - 0
ch11_llm/lora_tutorial.ipynb

@@ -0,0 +1,511 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "!pip install peft"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "<torch._C.Generator at 0x7fcbbb7cd3f0>"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "import torch\n",
+    "import torch.nn as nn\n",
+    "import torch.nn.functional as F\n",
+    "import torch.optim as optim\n",
+    "from peft import LoraConfig, PeftModel\n",
+    "\n",
+    "\n",
+    "torch.manual_seed(12046)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 3,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class Lora(nn.Module):\n",
+    "    \n",
+    "    def __init__(self, model, r=4, lora_alpha=16):\n",
+    "        super().__init__()\n",
+    "        # model是线性模型\n",
+    "        self.model = model\n",
+    "        self._freezing_model()\n",
+    "        self.lora_A = nn.Linear(model.in_features, r, bias=False)\n",
+    "        self.lora_B = nn.Linear(r, model.out_features, bias=False)\n",
+    "        self.scaling = lora_alpha / r\n",
+    "        \n",
+    "    def _freezing_model(self):\n",
+    "        for p in self.model.parameters():\n",
+    "            p.requires_grad = False\n",
+    "        \n",
+    "    def forward(self, x):\n",
+    "        origin = self.model(x)\n",
+    "        delta = self.lora_B(self.lora_A(x)) * self.scaling\n",
+    "        return origin + delta"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "tensor(True)"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "def _test_lora(model, r=4, lora_alpha=16):\n",
+    "    lora_model = Lora(model, r, lora_alpha)\n",
+    "    # 生成对比模型\n",
+    "    _model = nn.ModuleDict({'lin': model})\n",
+    "    config = LoraConfig(\n",
+    "        r=r, lora_alpha=lora_alpha,\n",
+    "        target_modules=['lin'], init_lora_weights=False)\n",
+    "    peft_model = PeftModel(_model, config)\n",
+    "    lin = peft_model.base_model.model.lin\n",
+    "    # 复制LoRA参数\n",
+    "    lora_model.lora_A.weight.data = lin.lora_A.default.weight.clone()\n",
+    "    lora_model.lora_B.weight.data = lin.lora_B.default.weight.clone()\n",
+    "    x = torch.randn(10, model.in_features)\n",
+    "    return torch.all(lora_model(x) - lin(x) < 1e-3)\n",
+    "\n",
+    "\n",
+    "linear_model = nn.Linear(10, 20)\n",
+    "_test_lora(linear_model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 5,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def print_trainable_parameters(model):\n",
+    "    \"\"\"\n",
+    "    输出模型中可供训练的参数个数\n",
+    "    \"\"\"\n",
+    "    trainable_params = 0\n",
+    "    all_param = 0\n",
+    "    for _, param in model.named_parameters():\n",
+    "        all_param += param.numel()\n",
+    "        if param.requires_grad:\n",
+    "            trainable_params += param.numel()\n",
+    "    trainable = f'trainable params: {trainable_params:,}'\n",
+    "    params = f'all params: {all_param:,}'\n",
+    "    percent = f'trainable%: {100 * trainable_params / all_param:.3f}'\n",
+    "    print(f'{trainable} || {params} || {percent}')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "trainable params: 66 || all params: 66 || trainable%: 100.000\n",
+      "tensor([[-1.3469e-03, -3.9655e-01,  5.7396e-01,  3.1267e-01, -1.6206e+00,\n",
+      "         -1.1444e-01],\n",
+      "        [ 1.4498e-01,  2.1979e-02,  7.9094e-01,  5.0265e-01, -1.9905e-01,\n",
+      "         -2.0630e-01],\n",
+      "        [ 6.7352e-01, -5.4856e-01, -1.0576e-01, -1.1910e+00,  6.0106e-01,\n",
+      "         -3.6762e-01]], grad_fn=<AddmmBackward0>)\n",
+      "trainable params: 64 || all params: 130 || trainable%: 49.231\n",
+      "tensor([[-1.2706, -0.6598, -1.7895, -2.0696, -0.8138,  0.5505],\n",
+      "        [-0.1612,  0.5151,  1.3028, -0.0054, -0.1200, -1.4266],\n",
+      "        [ 0.9780, -1.2645, -0.0722,  3.4606,  0.6124, -0.9581]],\n",
+      "       grad_fn=<AddBackward0>)\n"
+     ]
+    }
+   ],
+   "source": [
+    "linear_model = nn.Linear(10, 6)\n",
+    "x = torch.randn(3, 10)\n",
+    "print_trainable_parameters(linear_model)\n",
+    "print(linear_model(x))\n",
+    "lora_model = Lora(linear_model)\n",
+    "print_trainable_parameters(lora_model)\n",
+    "print(lora_model(x))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 7,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "class MLP(nn.Module):\n",
+    "    \n",
+    "    def __init__(self, bias=False):\n",
+    "        super().__init__()\n",
+    "        self.lin0 = nn.Linear(2, 4, bias=bias)\n",
+    "        self.lin1 = nn.Linear(4, 2, bias=bias)\n",
+    "\n",
+    "    def forward(self, x):\n",
+    "        x = F.relu(self.lin0(x))\n",
+    "        x = self.lin1(x)\n",
+    "        return x"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 8,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "MLP(\n",
+       "  (lin0): Linear(in_features=2, out_features=4, bias=False)\n",
+       "  (lin1): Linear(in_features=4, out_features=2, bias=False)\n",
+       ")"
+      ]
+     },
+     "execution_count": 8,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "model = MLP()\n",
+    "x = torch.randn(2)\n",
+    "model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 9,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "tensor([-0.2006,  0.0176], grad_fn=<SqueezeBackward4>)"
+      ]
+     },
+     "execution_count": 9,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "origin_re = model(x)\n",
+    "origin_re"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 10,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "PeftModel(\n",
+       "  (base_model): LoraModel(\n",
+       "    (model): MLP(\n",
+       "      (lin0): Linear(\n",
+       "        in_features=2, out_features=4, bias=False\n",
+       "        (lora_dropout): ModuleDict(\n",
+       "          (lora1): Identity()\n",
+       "        )\n",
+       "        (lora_A): ModuleDict(\n",
+       "          (lora1): Linear(in_features=2, out_features=2, bias=False)\n",
+       "        )\n",
+       "        (lora_B): ModuleDict(\n",
+       "          (lora1): Linear(in_features=2, out_features=4, bias=False)\n",
+       "        )\n",
+       "        (lora_embedding_A): ParameterDict()\n",
+       "        (lora_embedding_B): ParameterDict()\n",
+       "      )\n",
+       "      (lin1): Linear(in_features=4, out_features=2, bias=False)\n",
+       "    )\n",
+       "  )\n",
+       ")"
+      ]
+     },
+     "execution_count": 10,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "config = LoraConfig(\n",
+    "    r=2,\n",
+    "    lora_alpha=16,\n",
+    "    target_modules=['lin0'],\n",
+    "    # 为了展示方便,我们将随机产生LoRA的初始参数\n",
+    "    # 正常情况下,我们并不更改这个参数的默认值(True)\n",
+    "    init_lora_weights=False)\n",
+    "\n",
+    "peft_model = PeftModel(model, config, adapter_name='lora1')\n",
+    "peft_model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 11,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(tensor([-0.2006,  0.0176], grad_fn=<SqueezeBackward4>),\n",
+       " tensor([-0.3068,  0.1873], grad_fn=<SqueezeBackward4>),\n",
+       " tensor([-0.3068,  0.1873], grad_fn=<SqueezeBackward4>))"
+      ]
+     },
+     "execution_count": 11,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# 加入LoRA之后,原模型也更改了\n",
+    "origin_re, peft_model(x), model(x)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "tensor([-0.2006,  0.0176])\n",
+      "tensor([-0.2006,  0.0176], grad_fn=<SqueezeBackward4>)\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 禁用LoRA之后,模型恢复到原模型状态\n",
+    "with peft_model.disable_adapter():\n",
+    "    print(peft_model(x))\n",
+    "print(origin_re)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 13,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "(tensor([-0.2006,  0.0176], grad_fn=<SqueezeBackward4>),\n",
+       " tensor([-0.2006,  0.0176]),\n",
+       " tensor([-0.2006,  0.0176]))"
+      ]
+     },
+     "execution_count": 13,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# 将LoRA卸载之后,模型又恢复成初始状态\n",
+    "peft_model.unload()\n",
+    "origin_re, peft_model(x), model(x)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "PeftModel(\n",
+       "  (base_model): LoraModel(\n",
+       "    (model): MLP(\n",
+       "      (lin0): Linear(\n",
+       "        in_features=2, out_features=4, bias=False\n",
+       "        (lora_dropout): ModuleDict(\n",
+       "          (lora1): Identity()\n",
+       "          (lora2): Identity()\n",
+       "        )\n",
+       "        (lora_A): ModuleDict(\n",
+       "          (lora1): Linear(in_features=2, out_features=3, bias=False)\n",
+       "          (lora2): Linear(in_features=2, out_features=5, bias=False)\n",
+       "        )\n",
+       "        (lora_B): ModuleDict(\n",
+       "          (lora1): Linear(in_features=3, out_features=4, bias=False)\n",
+       "          (lora2): Linear(in_features=5, out_features=4, bias=False)\n",
+       "        )\n",
+       "        (lora_embedding_A): ParameterDict()\n",
+       "        (lora_embedding_B): ParameterDict()\n",
+       "      )\n",
+       "      (lin1): Linear(\n",
+       "        in_features=4, out_features=2, bias=False\n",
+       "        (lora_dropout): ModuleDict(\n",
+       "          (lora2): Identity()\n",
+       "        )\n",
+       "        (lora_A): ModuleDict(\n",
+       "          (lora2): Linear(in_features=4, out_features=5, bias=False)\n",
+       "        )\n",
+       "        (lora_B): ModuleDict(\n",
+       "          (lora2): Linear(in_features=5, out_features=2, bias=False)\n",
+       "        )\n",
+       "        (lora_embedding_A): ParameterDict()\n",
+       "        (lora_embedding_B): ParameterDict()\n",
+       "      )\n",
+       "    )\n",
+       "  )\n",
+       ")"
+      ]
+     },
+     "execution_count": 14,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "# 在模型中加入多个LoRA适配器\n",
+    "config1 = LoraConfig(r=3, lora_alpha=16, target_modules=['lin0'])\n",
+    "config2 = LoraConfig(r=5, lora_alpha=16, target_modules=['lin0', 'lin1'])\n",
+    "\n",
+    "model = MLP()\n",
+    "peft_model = PeftModel(model, config1, adapter_name='lora1')\n",
+    "peft_model.add_adapter(peft_config=config2, adapter_name='lora2')\n",
+    "peft_model"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 15,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "False\n",
+      "True\n",
+      "True\n"
+     ]
+    }
+   ],
+   "source": [
+    "print(peft_model.base_model.model.lin1.weight.requires_grad)\n",
+    "print(peft_model.base_model.model.lin0.lora_B.lora2.weight.requires_grad)\n",
+    "print(peft_model.base_model.model.lin0.lora_B.lora1.weight.requires_grad)\n",
+    "optimizer = optim.SGD(peft_model.parameters(), lr=0.1)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 16,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "active adapter: lora1\n",
+      "before bp, lora1: None\n",
+      "before bp, lora2: None\n",
+      "after bp, lora1: tensor([[ 0.0000, -0.0000,  0.0000],\n",
+      "        [ 0.0995, -0.6875,  0.6329],\n",
+      "        [-1.0511,  7.2626, -6.6856],\n",
+      "        [ 0.0000, -0.0000,  0.0000]])\n",
+      "after bp, lora2: None\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 使用其中一个适配器\n",
+    "optimizer.zero_grad()\n",
+    "print(f'active adapter: {peft_model.active_adapter}')\n",
+    "print(f'before bp, lora1: {peft_model.base_model.model.lin0.lora_B.lora1.weight.grad}')\n",
+    "print(f'before bp, lora2: {peft_model.base_model.model.lin0.lora_B.lora2.weight.grad}')\n",
+    "peft_model(x).sum().backward()\n",
+    "print(f'after bp, lora1: {peft_model.base_model.model.lin0.lora_B.lora1.weight.grad}')\n",
+    "print(f'after bp, lora2: {peft_model.base_model.model.lin0.lora_B.lora2.weight.grad}')"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 17,
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "active adapter: lora2\n",
+      "before bp, lora1: None\n",
+      "before bp, lora2: None\n",
+      "after bp, lora1: None\n",
+      "after bp, lora2: tensor([[ 0.0000, -0.0000, -0.0000,  0.0000, -0.0000],\n",
+      "        [ 0.0056, -0.3897, -0.0461,  0.2852, -0.0939],\n",
+      "        [-0.0597,  4.1171,  0.4875, -3.0128,  0.9917],\n",
+      "        [ 0.0000, -0.0000, -0.0000,  0.0000, -0.0000]])\n"
+     ]
+    }
+   ],
+   "source": [
+    "# 切换适配器\n",
+    "peft_model.set_adapter('lora2')\n",
+    "optimizer.zero_grad()\n",
+    "print(f'active adapter: {peft_model.active_adapter}')\n",
+    "print(f'before bp, lora1: {peft_model.base_model.model.lin0.lora_A.lora1.weight.grad}')\n",
+    "print(f'before bp, lora2: {peft_model.base_model.model.lin0.lora_A.lora2.weight.grad}')\n",
+    "peft_model(x).sum().backward()\n",
+    "print(f'after bp, lora1: {peft_model.base_model.model.lin0.lora_B.lora1.weight.grad}')\n",
+    "print(f'after bp, lora2: {peft_model.base_model.model.lin0.lora_B.lora2.weight.grad}')"
+   ]
+  }
+ ],
+ "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",
+   "version": "3.8.5"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}

Some files were not shown because too many files changed in this diff