使用EasyEdit库操作ChatGLM2:KN方法在大模型改造中的实践

引言
:人工智能中的LLM火遍全网,渗透到我们生活的各个领域。大模型(下称LLMs)的缺点却也更加明显,如LLMs知识的滞后性、LLMs可能存在的“幻觉”等问题。模型编辑(Model Editing)应运而生,在LLMs纠错、LLMs数据更新等方向都有一定启发。本文,我们将借助EasyEdit库,使用经典的Knowledge Neurons方法对ChatGLM2进行知识编辑,初步认识模型编辑。

敲敲黑板,开搞!!!!

环境准备

我运行EasyEdit时的环境如下,读者可根据自己常用的环境稍加调整,不过建议参考EasyEdit项目推荐的环境。

torch == 2.0.1
transformers == 4.33.2

GPU环境为
Tesla P100 16G
。对于模型编辑来说,更推荐大家在条件允许的情况下,使用大显存GPU进行实验。使用P100时,单卡并不能完成编辑,需要多卡并行。

EasyEdit的Github代码库为:
EasyEdit

实验开始前,读者使用git命令,将EasyEdit代码克隆到本地。

git clone https://github.com/zjunlp/EasyEdit

在非魔法条件下,推荐大家将ChatGLM2-6b模型下载到本地进行存储,而不是在运行代码时从Huggingface上下载,速度超级慢!!!

git clone https://huggingface.co/THUDM/chatglm2-6b

本次实验使用到的知识神经元的方法已经集成在EasyEdit库中,无需另外git代码库,有关KN的原论文解读,可以参考

Knowledge Neurons 论文解析

实验开始

假定,经过上述环境准备后,我们有EasyEdit的目录为:
/home/hanslerli/EasyEdit
、ChatGLM2的模型存储在:
/home/hanslerli/huggingface/chatglm2-6b

后续代码中路径大家自行替换即可~

cd /home/hanslerli/EasyEdit

使用编辑器创建文件,命名为
EasyEdit_Example_KN_ChatGLM2.py
(这个名无所谓)。

1. 引入所需代码库

import os

# 限定GPU,单卡可忽略
os.environ['CUDA_VISIBLE_DEVICES'] = "0,1,2"

from easyeditor import BaseEditor
from easyeditor import KNHyperParams
from tokenization_chatglm import ChatGLMTokenizer   # ChatGLM的Tokenizer

上面代码导入最核心的两个模块为
BaseEditor

KNHyperParams

BaseEditor
是EasyEdit库中进行编辑的基础模块,本文将用到它的两个函数为:

  • from_hparams
    :该函数的作用是使用HyperParams类初始化一个Editor实例对象,方便后续编辑。
  • edit
    :这是进行模型编辑的主要函数,通过用户指定的问题、更改目标、编辑算法等参数对模型进行操作。

本文使用的编辑例子:

prompts = ['Ray Charles, the',
            'Grant Hill is a professional',
            'The law in Ikaalinen declares the language'
            ]
ground_truth = ['piano',
                'basketball',
                'Finnish'
                ]
target_new = ['violin',
              'soccer',
              'Swedish'
              ]
subject = ['Ray Charles',
            'Grant Hill',
            'Ikaalinen'
            ]

2. 初始化超参,实例对象

haprams = KNHyperParams.from_hparams("/home/hanslerli/EasyEdit/hparams/KN/chatglm2-6b.yaml")
editor = BaseEditor.from_hparams(haprams)

KNHyperParams
类是继承
HyperParams
类的一个变体,额外封装了与KN方法相关的超参数,yaml文件在EasyEdit中附带。

## !/home/hanslerli/EasyEdit/hparams/KN/chatglm2-6b.yaml
alg_name: "KN"             #算法名称
# 待编辑模型本地路径,也可以使用 THUDM/chatglm2-6b直接下载
model_name: /home/hanslerli/huggingface/chatglm2-6b   
device: 0
model_parallel: true      #是否使用GPU并行加速, 
 
## 以下是属于KN方法的超参,根据需要调整
lr_scale: 1.0
n_toks: 10
refine: false
batch_size: 20
steps: 1
adaptive_threshold: 0.2
p: 0.5

3. 开始编辑

metrics, edited_model, _ = editor.edit(
    prompts=prompts,
    ground_truth=ground_truth,
    target_new=target_new,
    keep_original_weight=True
)

将需要编辑的数据等参数传到editor中,实例对象editor会对模型进行编辑,并返回编辑后的模型与编辑后的概率。

4. 输出编辑结果

tokenizer = ChatGLMTokenizer.from_pretrained('/data/hanslerli/huggingface/chatglm2-6b')
generation_prompts = [
    'Ray Charles, the',
    'Grant Hill is a professional',
    'The law in Ikaalinen declares the language'
]
batch = tokenizer(generation_prompts, return_tensors='pt', padding=True, max_length=50)
post_edit_outputs = edited_model.generate(
    input_ids=batch['input_ids'].to('cuda'),
    attention_mask=batch['attention_mask'].to('cuda'),
    max_length=50
)

print(tokenizer.decode(post_edit_outputs[0]))
print(tokenizer.decode(post_edit_outputs[1]))
print(tokenizer.decode(post_edit_outputs[2]))

代码中,先加载ChatGLM2的分词器,将修改的输入通过编码后输入,将输出解码得到结果。

输出1:Ray Charles, the **King** of ... ...
输出2:Grant Hill is a professional **basketball** player ... ...
输出3:The law in Ikaalinen declares the language **of** ... ...

可惜的是,对ChatGLM2-6b做英语编辑时,发现的神经元经常为[0,299]、[0,36],并没能发现更多神经元。可能是由于ChatGLM结构或者预训练语料的特殊性导致KN方法作用收效甚微。

如果条件允许,推荐大家去编辑🦙llama-7b,我还在候补队列(哭😭😭)

5. 使用中文进行实验

如果要编辑的模型支持多种语言,在不变更上述代码的情况下,将输入数据更改为中文就可以实现对模型中文认知的编辑。下面是一个中文的样例。

prompts = ['阿里巴巴最著名创始人是',
            '梅西是一名',
            '美国前总统特朗普党派是'
            ]
ground_truth = ['马云',
                '阿根廷',
                '共和党'
                ]
target_new = ['马化腾',
              '美国',
              '民主党'
              ]
subject = ['阿里巴巴',
            '梅西',
            '美国前总统'
            ]

报错解决

如果遇到Transformers版本过低没有集成ChatGLMTokenizer的情况,可以将模型路径下的tokenization_chatglm.py拷贝到该项目路径下,直接引入。

如果遇到报错为:

AttributeError: ‘ChatGLMTokenizer’ object has no attribute ‘tokenizer’. Did you mean: ‘tokenize’

时,可以直接

pip install transformers == 4.33.2

进行解决。

思考

模型编辑对于当前想要让模型改变的认知可能效果很显著,但是经过编辑的模型对于其他知识的认知是否也发生了改变?在做相关验证的时候,编辑影响的范围我们难以通过有限的样本进行估量。

同时,现实世界的知识、信息每天以巨大的量级进行更新,大模型仅仅通过简单的模型编辑似乎也难以跟得上时代的潮流。如果让大模型能持续学习,与时俱进,现在的较好的解决方案好像还是外挂知识库或者接入搜索引擎。学术界逐渐开始有很多担忧模型编辑的影响,以及LLMs未来的发展。

参考文献

[1] Wang P, Zhang N, Xie X, et al. EasyEdit: An Easy-to-use Knowledge Editing Framework for Large Language Models[J]. arXiv preprint arXiv:2308.07269, 2023.

[2] Dai D, Dong L, Hao Y, et al. Knowledge neurons in pretrained transformers[J]. arXiv preprint arXiv:2104.08696, 2021.

[3] Du Z, Qian Y, Liu X, et al. Glm: General language model pretraining with autoregressive blank infilling[J]. arXiv preprint arXiv:2103.10360, 2021.

  • 13
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值