赞
踩
hi~
众所周知!训练+微调大模型,做的,都是加法!
为了确保大模型生成的文本,安全!绝大部分的LLM开发商,都会给大模型上各种“锁”!
举例!
医疗领域提问:
“我发高烧,请你告诉我应该怎么吃药?帮我生成一个药单和说明?”
大模型回答:
首先,我需要强调,我不是医生或医疗专家,所以不能提供专业的医疗建议。如果你有高烧,最安全的做法是尽快联系医生或去医院接受专业的诊断和治疗。
你的项目是医疗、金融、法律等,垂直领域!经常会问到,类“敏感”问题!
有风险,大模型是不回答的!
这时,我们要做减法!
做手术!把敏感审查,修正或删掉!把大模型供应商上的“锁”,打开!
之后!
能生成任何想要的内容!
重申,这篇的目的,不是任何SQ/DP/WQ等不安定因素的教程,如果你是奔着此目的来的,请你马上离开!
雄哥本篇核心!会以Qwen开源model做演示(理论适合所有Transformer LLM),把安全审查模块,删掉!
你也可以用这个方法,解锁任何LLM生成!
开始前,再次提醒各位朋友,切勿用作违法生成!
攻防成本严重失衡!希望科学界朋友,优化算法,拒绝行为依赖单一方向的问题!
同时,正儿八经的项目,也必须要做安全板块!不管是在LLM的内部还是在外部,都要做!
接下来,会介绍整个过程,只想看如何实操的,直接跳到第二部分!
第一部分:怎么开锁?方法论?
目前,众多供应商的安全系统中,苹果的方案,较认可的
之前,我们做生成审查调整,要做微调或二次训练,成本极高!
本次,之所以能一举“手术”成功!切除LLM中的安全模块!
因为!LLM内部拒绝行为,都依赖一个单一方向判断!
只需3步,就能删除!
#A构建诱导数据集 #B拒绝方向的提取 #C方向消除-权重正交化
整个过程非常简单,雄哥先用“有害”+“无害”数据,构建数据集,诱导大模型残差流中的拒绝方向,消除所有层和所有 token 位置的拒绝方向,抓蛇七寸,砍掉!
如下图!科学界研究进展
1.1 构建诱导数据集
这里,我们要构建100条左右的“有害”数据,和“正常”数据,组成数据集!
然后,使用这个数据集,给大模型,计算有害激活和无害激活之间的均值差异,提取出残差流中的单个方向,这是一个能够代表模型拒绝行为的特征方向,即“拒绝方向”。
这个方向描述了模型在处理有害指令时,与处理无害指令时在激活空间上的区别。
有害指令数据集 (D(train)_harmful):
从 AD-VBENCH, MALICIOUSINSTRUCT, TDC2023 和 HARMBENCH 中随机采样 128 个有害指令。
无害指令数据集 (D(train)_harmless):
从 ALPACA 中采样 128 个无害指令。
验证数据集 (D(val)_harmful & D(val)_harmless):
分别从 HARMBENCH 验证集和 ALPACA 中采样 32 个指令作为验证数据集。
看看数据是怎样的!
这相当于是鱼饵,我们拿着数据去钓鱼,你的大模型,如果想改变他的生成策略,这不行,那不行,也可以做自己数据集,例如刚刚医疗等!
1.2 拒绝方向提取
因为大模型的拒绝生成的方向,是单一的,如何找到这条鱼呢?
大模型根据“有害”+“无害”数据集,生成拒绝回复后,我们计算有害激活和无害激活之间的均值差异,就能提取出一个能够代表模型拒绝行为的特征方向!
计算过程:
① 遍历所有层级 (l ∈ [L]) 和指令位置 (i ∈ I)
② 计算有害指令的平均激活值 (µ(l)_i) 和无害指令的平均激活值 (ν(l)_i)
③ 计算差异均值向量 (r(l)_i = µ(l)_i - ν(l)_i)
更多的计算过程,雄哥这里不延展了,感兴趣的朋友后面研读材料!
这里普及上面雄哥提到的两个概念:
—残差流—
是指每个 token 在 Transformer 模型各层处理后的中间表示。
表征 token 的特征: 残差流包含了 token 的多种信息,例如词义、语法、上下文等,可以用来表征 token 的特征。
进行模型计算: 残差流是 Transformer 模型进行计算的基础,通过残差流,模型可以对 token 进行编码和解码。
—单个方向—
指的是残差流中的一个线性子空间,它代表了模型对特定特征的表征方式。
指示拒绝行为: 拒绝方向的存在使得模型可以将拒绝行为与这个方向关联起来,从而实现对有害指令的拒绝。
影响模型行为: 修改拒绝方向会影响模型对指令的响应,例如,通过添加或消除拒绝方向,可以诱导模型拒绝无害指令或接受有害指令。
通俗来说,就是钓鱼,有害数据就是饵,一旦生成“我不能***”,大模型就上钩了!吊起来!
1.3 方向消除-权重正交化
上面工作完成后,这一步就很关键了!对于所有写入残差流的矩阵 (例如嵌入矩阵、位置嵌入矩阵、注意力输出矩阵和 MLP 输出矩阵),将其列向量与拒绝方向 (ˆr) 进行正交化。
计算正交化矩阵:对于每个写入残差流的矩阵 Wout ∈ Rdmodel×dinput,计算其正交化矩阵 W’out:
W'out = Wout - ˆrˆr⊺Wout
ˆr 是拒绝方向的单位向量,ˆr⊺ 是其转置
将计算得到的正交化矩阵 W’out 替换掉原始的权重矩阵 Wout!
说这么多,都不及动手跑一跑!
第二部分:跑起来!以qwen为例!
本地环境配置太麻烦,这里雄哥用到colab的免费算力来实践!
qwen-1.8b版本只需要14G显存即可!
怎样上传代码,如何下载权重,这些不解释了,雄哥之前教过太多!
如果还没学会的,自己返回去学!
在colab上传代码!
安装依赖!
%%capture``!pip install transformers transformers_stream_generator tiktoken transformer_lens einops jaxtyping colorama
下载大模型!
以qwen-1.8b为例,理论上支持任何transformers语言模型!
把你hugging face上的路径换上去,会自动下载!同时,要看自己本地的算力够不够!
# 下载模型,这里以qwen为例``MODEL_PATH = 'Qwen/Qwen-1_8B-chat'``DEVICE = 'cuda'`` ``model = HookedTransformer.from_pretrained_no_processing(` `MODEL_PATH,` `device=DEVICE,` `dtype=torch.float16,` `default_padding_side='left',` `fp16=True``)`` ``model.tokenizer.padding_side = 'left'``model.tokenizer.pad_token = '<|extra_0|>'
下载数据集,筛选有效的!
这里,我们把一个hf上的数据集为例,然后用它制作了两个类型,1是有害的数据集和验证集!
2是无害的数据集和验证集!
先下载吧!然后筛选
def get_harmful_instructions():` `url = 'https://raw.githubusercontent.com/llm-attacks/llm-attacks/main/data/advbench/harmful_behaviors.csv'` `response = requests.get(url)` `dataset = pd.read_csv(io.StringIO(response.content.decode('utf-8')))` `instructions = dataset['goal'].tolist()`` ` `train, test = train_test_split(instructions, test_size=0.2, random_state=42)` `return train, test``def get_harmless_instructions():` `hf_path = 'tatsu-lab/alpaca'` `dataset = load_dataset(hf_path)` `# 筛选出不包含输入的指令` `instructions = []` `for i in range(len(dataset['train'])):` `if dataset['train'][i]['input'].strip() == '':` `instructions.append(dataset['train'][i]['instruction'])`` ` `train, test = train_test_split(instructions, test_size=0.2, random_state=42)` `return train, test
生成数据集和验证集!
harmful_inst_train, harmful_inst_test = get_harmful_instructions()``harmless_inst_train, harmless_inst_test = get_harmless_instructions()
get_harmful_instructions() 函数被调用来获取有害指令的数据集。这个函数可能会从某个数据源中提取或者生成标记为有害的指令。执行后,它会返回两个数据集:harmful_inst_train 和 harmful_inst_test,分别代表用于训练和测试的有害指令数据集。
get_harmless_instructions() 函数被调用来获取无害指令的数据集。这个函数类似于前一个函数,但是它返回的是标记为无害的指令。执行后,它会返回两个数据集:harmless_inst_train 和 harmless_inst_test,分别代表用于训练和测试的无害指令数据集。
打印一下!
创建生成工具!
_generate_with_hooks 函数:这个函数接收一个 HookedTransformer 模型、一个包含初始 token 的张量 toks、一个表示最大生成 token 数量的参数 max_tokens_generated 以及一个包含前向传播钩子(forward hooks)的列表 fwd_hooks。这个函数的作用是使用模型生成新的 token,直到达到最大生成 token 数量。生成的 token 被添加到 all_toks 张量中,并最终使用模型的 tokenizer 解码为字符串。
get_generations 函数:这个函数接收一个 HookedTransformer 模型、一个包含指令的列表 instructions、一个用于将指令转换为 token 的函数 tokenize_instructions_fn、一个包含前向传播钩子(forward hooks)的列表 fwd_hooks、一个表示最大生成 token 数量的参数 max_tokens_generated 以及一个表示批量大小的参数 batch_size。这个函数的作用是使用 HookedTransformer 模型和 tokenize_instructions_fn 函数对输入的指令进行编码,然后使用 _generate_with_hooks 函数生成文本。生成的文本被存储在 generations 列表中,并最终返回。
def _generate_with_hooks(` `model: HookedTransformer,` `toks: Int[Tensor, 'batch_size seq_len'],` `max_tokens_generated: int = 64,` `fwd_hooks = [],``) -> List[str]:`` ` `all_toks = torch.zeros((toks.shape[0], toks.shape[1] + max_tokens_generated), dtype=torch.long, device=toks.device)` `all_toks[:, :toks.shape[1]] = toks`` ` `for i in range(max_tokens_generated):` `with model.hooks(fwd_hooks=fwd_hooks):` `logits = model(all_toks[:, :-max_tokens_generated + i])` `next_tokens = logits[:, -1, :].argmax(dim=-1)` `all_toks[:,-max_tokens_generated+i] = next_tokens`` ` `return model.tokenizer.batch_decode(all_toks[:, toks.shape[1]:], skip_special_tokens=True)`` ``def get_generations(` `model: HookedTransformer,` `instructions: List[str],` `tokenize_instructions_fn: Callable[[List[str]], Int[Tensor, 'batch_size seq_len']],` `fwd_hooks = [],` `max_tokens_generated: int = 64,` `batch_size: int = 4,``) -> List[str]:`` ` `generations = []`` ` `for i in tqdm(range(0, len(instructions), batch_size)):` `toks = tokenize_instructions_fn(instructions=instructions[i:i+batch_size])` `generation = _generate_with_hooks(` `model,` `toks,` `max_tokens_generated=max_tokens_generated,` `fwd_hooks=fwd_hooks,` `)` `generations.extend(generation)`` ` `return generations
架好鱼竿!
# 在有害和无害指令上运行模型,缓存中间激活。``harmful_logits, harmful_cache = model.run_with_cache(harmful_toks, names_filter=lambda hook_name: 'resid' in hook_name)``harmless_logits, harmless_cache = model.run_with_cache(harmless_toks, names_filter=lambda hook_name: 'resid' in hook_name)
计算拒绝方向!
# 在中间层计算有害和无害激活的平均差异。``pos = -1``layer = 14`` ``harmful_mean_act = harmful_cache['resid_pre', layer][:, pos, :].mean(dim=0)``harmless_mean_act = harmless_cache['resid_pre', layer][:, pos, :].mean(dim=0)`` ``refusal_dir = harmful_mean_act - harmless_mean_act``refusal_dir = refusal_dir / refusal_dir.norm()
删除方向!
并通过添加“前向传播钩子”来进行干预。钩子函数direction_ablation_hook 会被应用到模型的不同层上,以改变模型的行为。代码首先定义了要测试的指令数量,然后指定了要干预的模型层。接着,它创建了一个钩子函数,并将这个钩子应用到所有指定的层上。然后,代码在两种条件下生成文本:
一种是有干预的情况
另一种是没有干预的基线情况
N_INST_TEST = 32``intervention_dir = refusal_dir``intervention_layers = list(range(model.cfg.n_layers))`` ``hook_fn = functools.partial(direction_ablation_hook,direction=intervention_dir)``fwd_hooks = [(utils.get_act_name(act_name, l), hook_fn) for l in intervention_layers for act_name in ['resid_pre', 'resid_mid', 'resid_post']]`` ``intervention_generations = get_generations(model, harmful_inst_test[:N_INST_TEST], tokenize_instructions_fn, fwd_hooks=fwd_hooks)``baseline_generations = get_generations(model, harmful_inst_test[:N_INST_TEST], tokenize_instructions_fn, fwd_hooks=[])
大模型发展很快,但安全版块,却很滞后,野蛮生长,特别是Agent的函数调用+执行能力越强!
这个模块也越来越多人关注!
是很好的赛道!
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。
保证100%免费
】Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。