从知识更新到行为调控: 基于 EasyEdit 的大模型知识编辑框架
本文也提供英文版本 English。
随着大模型应用的不断深入,模型行为的可控性和可编辑性变得至关重要。今天,我们介绍两大版本的 EasyEdit 系列:经典版 EasyEdit1 与全新推出的 EasyEdit2,带你进入模型知识编辑与推理时干预的新纪元!
📌 相关阅读推荐 想进一步了解社区对于知识编辑现状与未来的反思与讨论?欢迎阅读另一篇专题博客 → Reflection on Knowledge Editing: Charting the Next Steps 🔍
为什么需要知识编辑与推理时干预?
不仅仅是随着 GPT、Qwen和LLaMA 等大型语言模型的广泛应用,模型在各类自然语言任务中展现出了前所未有的能力。然而,真正投入生产后,人们很快发现它们仍面临两个根本性挑战:
- 1️⃣ 知识截止 —— 预训练模型只能掌握到训练时的静态知识,对后续发生的新事件一无所知。
- 2️⃣ 知识错误与偏差 —— 大规模语料中不可避免混杂着噪声、偏见甚至虚假信息,模型可能生成看似合理却事实错误或有害的输出。
知识编辑(Knowledge Editing) 正是为了解决这类“知识可更新”问题而诞生的:它通过外科手术式地精准定位并修改少量参数,就能在几秒内更新或覆盖单点事实,避免重新微调整个大模型,节省算力成本,也降低了对原有能力的干扰。
然而,仅仅编辑知识还不够。在许多真实场景下,用户往往还需要在推理阶段对模型的输出做临时干预:
- 避免生成敏感或有害内容(安全性)
- 在不同对话或场景下快速切换语气、情感、甚至人格(个性化定制)
- 临时引导推理链路,比如强化逻辑展开、改写风格
这就是所谓的 推理时干预(Steering/Intervention):在不动模型参数的前提下,通过注入可组合的干预向量(steering vectors)或提示结构,对生成行为进行即时、可调节的引导。
EasyEdit 的双轨方案
因此,我们发布了 EasyEdit 系列:
- EasyEdit1:解决知识编辑,精准覆盖、更新、修正大模型中的单点事实
- EasyEdit2:面向推理阶段,提供可插拔的干预能力,灵活调节输出在安全性、风格、个性化等多维表现
通过这套工具,用户无需重新训练大模型,就能以极低的成本、可解释的方式,让大模型随需而变。
EasyEdit1 vs. EasyEdit2 对比
工作原理
- EasyEdit1:通过修改模型内部参数,实现“永久”知识编辑
- EasyEdit2:在推理阶段注入 steering vectors,不改动模型参数
修改粒度
- EasyEdit1:一次性、实例级固定修改
- EasyEdit2:可调节强度,实现从弱到强的精细干预
应用场景
- 两者均可修正事实性输出
- EasyEdit2 还可控制推理过程、情感风格、语言特性等更抽象行为
一、EasyEdit1:模型知识编辑利器
EasyEdit1 是一款面向大模型知识内容精准编辑的工具,提供多种主流模型编辑范式,支持快速定位、修改或注入知识,让你无需大规模重训练即可灵活修正事实、去除偏见、更新或抹除特定信息。
背景与定位
- 目标:高效、精准地修改大模型中“存储”的具体知识(事实/偏见/敏感信息)。
- 应用场景:修正过时事实、注入新信息、抹除敏感数据、去除毒性输出。
核心功能
- 多编辑范式支持:
- 多模型兼容:GPT、LLaMA、T5、ChatGLM、InternLM、Qwen、Mistral 等(1B–65B)。
- 多类型知识编辑数据集支持:
- 三元组格式: ZsRE, CounterFact, KnowEdit
- 无结构化长文本格式: AKEW, LEME, CKnowEdit
- 还有诸如多跳数据集: MQuAKE; 知识编辑带来的幻觉问题评测: HalluEditBench; 面向终身知识编辑场景: WikiBigEdit
- 多种评测方式支持:
- 传统的基于teacher forcing的评测方式
- 让编辑后的模型作自回归生成的评估方式,比如基于 LLM-as-a-judge
- 一键编辑:快速完成一次输入–输出对的知识更新。
环境配置
git clone https://github.com/zjunlp/EasyEdit.git
conda create -n easyedit python=3.9.7
conda activate easyedit
pip install -r requirements.txt
使用步骤
EasyEdit 模块化灵活,可轻松完成模型编辑。下面以MEND方法为示例:
Step1:定义待编辑模型
选择要编辑的预训练语言模型(PLM)。EasyEdit 当前支持 HuggingFace 上的部分模型(T5、GPT-J、GPT‑NEO、LLaMA 等)。对应的配置文件路径为 hparams/方法名/模型名.yaml
,如 hparams/MEND/gpt2-xl.yaml
,通过设置 model_name
字段指定待编辑对象。
model_name: gpt2-xl
model_class: GPT2LMHeadModel
tokenizer_class: GPT2Tokenizer
tokenizer_name: gpt2-xl
model_parallel: false # true 表示多 GPU 编辑
Step2:选择编辑方法
导入并加载对应的超参数配置,例如使用 MEND 方法:
from easyeditor import MENDHyperParams
# 从 hparams/MEND/gpt2-xl.yaml 加载配置
hparams = MENDHyperParams.from_hparams('./hparams/MEND/gpt2-xl.yaml')
Step3:提供编辑描述与目标
prompts
:希望编辑的输入提示(Edit Descriptor)ground_truth
:原始输出或设为None
target_new
:期望的新输出(Edit Target)
prompts = [
'What university did Watts Humphrey attend?',
'Which family does Ramalinaceae belong to',
'What role does Denny Herzig play in football?'
]
ground_truth = ['Illinois Institute of Technology', 'Lecanorales', 'defender']
target_new = ['University of Michigan', 'Lamiinae', 'winger']
Step4:实例化编辑器并执行编辑
EasyEdit 提供了一种简单统一的初始化编辑器的方式,类似 huggingface: from_hparams。
from easyeditor import BaseEditor
# 加载超参构造编辑器
editor = BaseEditor.from_hparams(hparams)
Step5:可选 — 局部性与可迁移性评估
提供自定义评估数据,格式为 dict
:
locality_inputs = {
'neighborhood':{
'prompt': [
'Joseph Fischhof, the',
'Larry Bird is a professional',
'In Forssa, they understand'
],
'ground_truth': ['piano', 'basketball', 'Finnish']
},
'distracting':{
'prompt': [
'Ray Charles, the violin Hauschka plays the instrument',
'Grant Hill is a professional soccer Magic Johnson is a professional',
'The law in Ikaalinen declares the language Swedish In Loviisa, the language spoken is'
],
'ground_truth': ['piano', 'basketball', 'Finnish']
}
}
上述示例中,我们评估编辑方法在自定义的“邻域”和“干扰”场景下的表现。
Step6:编辑与评估
执行编辑并获取评估指标:
metrics, edited_model, _ = editor.edit(
prompts=prompts,
# rephrase_prompts=rephrase_prompts,
ground_truth=ground_truth,
target_new=target_new,
locality_inputs=locality_inputs,
# portability_inputs=portability_inputs,
sequential_edit=False # 若需连续编辑可设为 True
)
# 返回指标 metrics(edit success、rephrase success、locality 等)及 edited_model
评价指标
执行编辑后获取评估指标,返回结果格式如下(dict):
{
"post": {
"rewrite_acc": ..., // 编辑后可靠性 (Reliability)
"rephrase_acc": ..., // 编辑后泛化性 (Generalization)
"locality": {
"YOUR_LOCALITY_KEY": ... // 本地化 (Locality)
// ...
},
"portability": {
"YOUR_PORTABILITY_KEY": ... // 可迁移性 (Portability)
// ...
}
},
"pre": {
"rewrite_acc": ..., // 编辑前可靠性
"rephrase_acc": ..., // 编辑前泛化性
"portability": {
"YOUR_PORTABILITY_KEY": ... // 编辑前可迁移性
// ...
}
}
}
rewrite_acc
→ 可靠性 (Reliability):表示在给定编辑描述符下,直接重写目标知识的成功率rephrase_acc
→ 泛化性 (Generalization):表示在同一编辑范围内对输入进行重述时,编辑依然成功的概率locality
→ 局部性 (Locality):表示对无关输入,编辑后模型输出是否保持不变portability
→ 可迁移性 (Portability):表示编辑对相关推理或应用(如单跳推理、同义词、逻辑泛化)的迁移成功率
注意:
- 可靠性:仅需提供编辑
prompts
和target_new
- 泛化性:需额外提供
rephrase_prompts
- 局部性与可迁移性:需定义对应
metric_key
,并提供prompts
与ground_truth
二、EasyEdit2:实时推理时行为控制
EasyEdit2 是一款面向大模型推理时行为控制的工具,提供灵活、可扩展的 steering 向量生成与应用框架,助你无需改动模型参数也能精细调节模型输出。
背景与定位
- 目标:在不修改模型参数的前提下,通过各自引导方法实现实时、可控的推理行为干预。
- 应用场景:灵活调整安全防护、情感风格、推理流程、语言特性、人格设定等多种行为偏好,实现个性化定制。
核心功能
- 支持多种 Steering 范式
- Activation-based(CAA、LM‑Steer、SAE、STA…)
- Prompt‑based(手动/自动生成提示)
- Decoding‑based(持续更新中)
- 灵活组合与调节:支持多方法叠加、多向量合并、强度调节、层级选择。
- 多场景落地:包括但不限于安全防护、情感风格、推理流程、语言特性、人格塑造。
- 预训练向量库:提供多种场景下的预训练 steering 向量,开箱即用。
环境配置
git clone https://github.com/zjunlp/EasyEdit.git
conda create -n easyedit2 python=3.10
conda activate easyedit2
pip install -r requirements_2.txt
若需安全/流畅度评估,安装 NLTK 数据:
import nltk nltk.download('punkt')
使用步骤
1. 一步完成(All-in-One)
python steering.py \
--config-path hparams/Steer/ \
--config-name config.yaml
一次性完成 steering 向量生成、应用与文本生成。需要在hparams/Steer/config.yaml
中进行超参数配置。
2. 分步执行(推荐)
Step1:生成 Steering 向量
python vectors_generate.py \
--config-path hparams/Steer/ \
--config-name vector_generate.yaml
- 在
hparams/Steer/vector_generate.yaml
中:- 指定模型名称(如 LLaMA、Gemma、Qwen、GPT 系列)
- 配置向量生成方法及数据集
Step2:应用 Steering 向量
python vectors_apply.py \
--config-path hparams/Steer/ \
--config-name vector_applier.yaml
- 在
hparams/Steer/vector_applier.yaml
中:- 列出所有
apply_steer_hparam_paths
- 对应填入
steer_vector_load_dir
- 可配置 Hugging Face 文本生成参数(
max_new_tokens
、temperature
、do_sample
等)
- 列出所有
简单示例引导(完整流程)
下面使用分步执行的方式,分别展示向量生成和向量应用。当然也可以直接使用一步完成方式,向量生成后直接应用,只需将顶层配置文件写在一起,运行 steering.py
文件即可,此处不多做赘述。
向量生成部分(Vector Generator)
1️⃣ 选择 Steering 方法,如 hparams/Steer/caa_hparams/generate_caa.yaml
::
alg_name: caa
layers: [17]
multiple_choice: false
2️⃣ 配置顶层文件 hparams/Steer/vector_generate.yaml
,包含:
model_name_or_path: your_model_path
torch_dtype: bfloat16
device: cuda:0
use_chat_template: false
system_prompt: ''
steer_train_hparam_paths:
- hparams/Steer/caa_hparams/generate_caa.yaml
steer_train_dataset:
- your_train_data
steer_vector_output_dir: vectors/your_output_dir/
3️⃣ 自定义输入或使用配置数据集:
# 可以自定义输入数据
# datasets={'your_dataset_name':[{'input':'hello'},{'input':'how are you'}]}
# 或者根据配置文件加载数据集
datasets = prepare_generation_datasets(top_cfg)
4️⃣ 执行生成:
vector_generator = BaseVectorGenerator(top_cfg)
vectors = vector_generator.generate_vectors(datasets)
向量应用部分(Vector Applier)
1️⃣ 配置每个方法的应用文件,如 hparams/Steer/caa_hparams/apply_caa.yaml
:
alg_name: caa
layers: [17]
multipliers: [1.0]
2️⃣ 顶层配置 hparams/Steer/vector_applier.yaml
:
apply_steer_hparam_paths:
- hparams/Steer/caa_hparams/apply_caa.yaml
steer_vector_load_dir:
- vectors/your_output_dir/
generation_data:
- your_test_data
generation_data_size: null # null或-1表示使用全部数据
generation_output_dir: generations/your_output/
num_responses: 1
# 生成参数
generation_params:
max_new_tokens: 100
temperature: 0.9
do_sample: True
3️⃣ 自定义输入或使用配置数据集:
# 可以自定义输入数据
# datasets={'your_dataset_name':[{'input':'hello'},{'input':'how are you'}]}
# 或者根据配置文件加载数据集
datasets = prepare_generation_datasets(top_cfg)
4️⃣ 应用并生成:
vector_applier = BaseVectorApplier(top_cfg)
vector_applier.apply_vectors()
results = vector_applier.generate(datasets)
预训练向量库
EasyEdit2 提供场景化预训练向量,支持安全、情感等多种 steering 需求。详情与获取方式可见README_2.md。
评估方法
在 steer/evaluate/evaluate.py
中集成多维评估:
- LLM评估(概念相关性、指令相关性、流畅度)
- 规则评估(PPL、Distinctness、Fluency、GSM)
- 分类器评估(Sentiment、SafeEdit、Toxigen、RealToxicityPrompts)
使用示例:
python steer/evaluate/evaluate.py \
--generation_dataset_path results/your_results.json \
--eval_methods ppl distinctness safeedit \
--model_name_or_path your_model \
--device cuda
👉 更多细节请参考:
- EasyEdit1: README.md
- EasyEdit2: README_2.md
- 如对内容有任何疑问,欢迎访问 GitHub Issues 页面 提出您的问题