引言:人工智能中的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.