使用 EasyEdit 工具系列,掌控您的 LLM 所知与所为
本文还提供中文版本:简体中文。
随着大型语言模型应用日益广泛,模型行为的可控性和可编辑性变得至关重要。今天,我们将介绍 **EasyEdit** 系列的两个主要版本:经典的 **EasyEdit1** 和新发布的 **EasyEdit2**,带您进入知识编辑和推理时干预的新时代!
📌 相关阅读 想深入了解社区对知识编辑的思考和讨论?请查看这篇专题博客 → 知识编辑的反思:规划下一步 🔍
为什么选择知识编辑和推理时干预?
随着 GPT、Qwen 和 LLaMA 等大型语言模型的广泛应用,模型在各种自然语言处理任务中展现出前所未有的能力。然而,在实际生产部署中,两个基本挑战迅速浮现:
- 1️⃣ 知识截止 — 预训练模型仅保留训练日期之前的静态知识,对新事件一无所知。
- 2️⃣ 不正确或有偏见的知识 — 大规模训练语料库不可避免地包含噪声、偏见或错误信息,导致模型产生看似合理但事实错误或有害的输出。
知识编辑应运而生,旨在解决这种“知识可更新性”问题:通过精准定位和修改少量参数,您可以在几秒钟内更新或覆盖单个事实,而无需重新训练整个模型——这节省了计算成本,并最大限度地减少了对现有能力的干扰。
然而,仅有知识编辑是不够的。在许多实际场景中,用户还需要在推理时干预模型输出:
- 防止生成敏感或有害内容(安全性)
- 在对话和场景中切换语气、情感乃至角色(个性化)
- 临时引导推理路径,例如强制逻辑展开或风格重写
这就是推理时干预(Steering/Intervention):在不修改模型权重的情况下,您注入可组合的转向向量或提示结构,以实现对生成的即时、可调控制。
双重解决方案:EasyEdit
因此,我们发布了 EasyEdit 系列:
- EasyEdit1:用于精确知识编辑——覆盖、更新和修复大型模型中的单点事实。
- EasyEdit2:用于推理时即插即用干预——灵活调整输出以实现安全性、风格化、个性化等。
通过这个工具包,您可以用最低的成本、以可解释的方式转换您的大型模型,而无需重新训练。
EasyEdit1 与 EasyEdit2 对比
工作原理
- EasyEdit1:修改模型内部参数以实现“永久”知识编辑
- EasyEdit2:在推理时注入转向向量,不改变模型权重
粒度
- EasyEdit1:单次、实例级静态编辑
- EasyEdit2:强度可调,从轻微到强烈的细粒度干预
用例
- 两者都能纠正事实输出
- EasyEdit2 还可以引导推理、情感、风格及其他抽象行为
1. EasyEdit1:精准知识编辑工具
EasyEdit1 是一个用于大型模型事实知识精准编辑的工具包。它支持多种主流编辑范式,使您无需大规模重新训练即可定位、修改或注入知识——灵活地修复事实、消除偏见或更新/删除特定信息。
背景与定位
- 目标:高效、精准地编辑大型模型中“存储”的特定知识(事实/偏见/敏感信息)。
- 用例:修复过时事实、注入新信息、删除敏感数据、清除有害输出。
核心功能
- 多种编辑范式:
- 多模型兼容性:GPT、LLaMA、T5、ChatGLM、InternLM、Qwen、Mistral 等(1B–65B)。
- 支持多种知识编辑数据集类型:
- 三元组格式:ZsRE、CounterFact、KnowEdit
- 非结构化长文本格式:AKEW、LEME、CKnowEdit
- 还包括多跳数据集:MQuAKE;知识编辑的幻觉评估:HalluEditBench;以及终身知识编辑场景:WikiBigEdit
- 支持多种评估方法:
- 基于传统教师强制的评估
- 通过 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 方法的示例:
步骤1:定义目标模型
选择要编辑的预训练语言模型(PLM)。EasyEdit 当前支持多种 HuggingFace 模型(T5、GPT-J、GPT-NEO、LLaMA 等)。配置位于 hparams/<method>/<model>.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 for multi-GPU editing
步骤2:选择编辑方法
导入并加载相应的超参数配置,例如 MEND:
from easyeditor import MENDHyperParams
# Load config from hparams/MEND/gpt2-xl.yaml
hparams = MENDHyperParams.from_hparams('./hparams/MEND/gpt2-xl.yaml')
步骤3:提供编辑描述符和目标
prompts
:要编辑的输入提示(编辑描述符)ground_truth
:原始输出或None
target_new
:期望的新输出(编辑目标)
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']
步骤4:初始化编辑器并编辑
EasyEdit 提供了统一的方法 from_hparams
,类似于 Hugging Face 的风格。
from easyeditor import BaseEditor
# Load hyperparams and construct editor
editor = BaseEditor.from_hparams(hparams)
步骤5:可选 — 局部性和可移植性评估
以 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']
}
}
这评估了该方法在“邻近”和“干扰”上下文中的性能。
步骤6:编辑与评估
运行编辑并获取指标
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 # Set True for sequential edits
)
# Returns metrics (edit success, rephrase success, locality, etc.) and edited_model
评估指标
编辑后,指标以以下 dict
格式返回:
{
"post": {
"rewrite_acc": ..., // Reliability after edit
"rephrase_acc": ..., // Generalization after edit
"locality": {
"YOUR_LOCALITY_KEY": ...
},
"portability": {
"YOUR_PORTABILITY_KEY": ...
}
},
"pre": {
"rewrite_acc": ...,
"rephrase_acc": ...,
"portability": {
"YOUR_PORTABILITY_KEY": ...
}
}
}
rewrite_acc
→可靠性
:给定编辑描述符的编辑成功率rephrase_acc
→泛化性
:编辑范围内的编辑成功率locality
→局部性
:模型在编辑后是否对不相关输入产生改变portability
→可移植性
:推理/应用(一步、同义词、逻辑泛化)的编辑成功率
注意:
- 可靠性:仅需
prompts
和target_new
- 泛化性:还需要
rephrase_prompts
- 局部性和可移植性:定义
metric_key
并提供prompts
+ground_truth
2. EasyEdit2:实时推理时转向
EasyEdit2 是一个用于大型模型实时行为控制的工具包,提供了一个灵活、可扩展的框架,用于生成和应用转向向量——在不触及模型权重的情况下,精确调整模型输出。
背景与定位
- 目标:在不修改模型权重的情况下,实现实时、可控的推理时干预。
- 用例:灵活调整安全性、情感、推理、语言特征、角色及其他行为,以实现个性化。
核心功能
- 支持多种转向范式
- 基于激活的(CAA、LM‑Steer、SAE、STA…)
- 基于提示的(手动/自动提示)
- 基于解码的(正在开发中)
- 灵活组合与调整:堆叠方法、合并向量、调整强度、选择层。
- 多样化应用:安全性、风格、推理流程、语言特征、角色塑造。
- 预训练向量库:即插即用的通用场景转向向量。
环境设置
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. 一体化
python steering.py \
--config-path hparams/Steer/ \
--config-name config.yaml
一个命令即可处理向量生成、应用和文本生成。超参数在 hparams/Steer/config.yaml
中配置。
2. 分步进行(推荐)
步骤1:生成转向向量
python vectors_generate.py \
--config-path hparams/Steer/ \
--config-name vector_generate.yaml
- 在
hparams/Steer/vector_generate.yaml
中- 指定模型名称(例如 LLaMA、Gemma、Qwen、GPT 系列)
- 配置向量生成方法和数据集
步骤2:应用转向向量
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
- 配置 HF 生成参数(
max_new_tokens
、temperature
、do_sample
等)
- 列出
简单示例(完整流程)
以下是分步版本,涵盖向量生成和应用。或者您也可以通过组合配置并运行 steering.py
来使用一体化方法。
向量生成(生成器)
1️⃣ 选择转向方法,例如 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️⃣ 提供自定义输入或使用配置文件中的数据集
# Custom input example
# datasets={'your_dataset_name':[{'input':'hello'},{'input':'how are you'}]}
# Or load dataset from config
datasets = prepare_generation_datasets(top_cfg)
4️⃣ 运行生成
vector_generator = BaseVectorGenerator(top_cfg)
vectors = vector_generator.generate_vectors(datasets)
向量应用(应用器)
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 means use all data
generation_output_dir: generations/your_output/
num_responses: 1
# Generation params
generation_params:
max_new_tokens: 100
temperature: 0.9
do_sample: True
3️⃣ 提供自定义输入或使用配置文件中的数据集
# Custom input example
# datasets={'your_dataset_name':[{'input':'hello'},{'input':'how are you'}]}
# Or load dataset from config
datasets = prepare_generation_datasets(top_cfg)
4️⃣ 应用并生成
vector_applier = BaseVectorApplier(top_cfg)
vector_applier.apply_vectors()
results = vector_applier.generate(datasets)
预训练向量库
EasyEdit2 提供了用于安全性、情感等场景的预训练向量。详情请参阅 README_2.md。
评估
steer/evaluate/evaluate.py
中的多维度评估
- LLM 评估(概念相关性、指令相关性、流畅性)
- 基于规则(PPL、区分度、流畅性、GSM)
- 基于分类器(情感、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 问题页面