找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

5267

积分

0

好友

694

主题
发表于 昨天 18:44 | 查看: 7| 回复: 0

早在2024年,便有学者(https://arxiv.org/abs/2406.11717)发现LLMs的拒绝回答往往由单一梯度方向介导。

作为一篇社区博客,本文将谈论如何让Qwen3-4B-Instruct-2507 拒绝回答 所有问题,而不是如何让它回答所有问题,无论合法与否,以避免不必要的负面影响(拒绝回答一个问题几乎总是没有负面影响的)。请勿恶意修改梯度方向,避免模型输出不恰当的内容。

模型的结构

在开始分析拒绝向量的内容前,我们必须先明确拒绝向量的位置。

Qwen-3 decoder layer 结构流程图,包含 Attention Block 和 MLP Block(含 SwiGLU)两个模块。

Qwen3-4B-Instruct-2507的模型架构相对简单,主体(去掉嵌入等)由36层Qwen-3 decoder layer组成;每个Decoder layer的结构都由一个注意力块(Attention Block)和一个MLP块组成,总体如上图所示。其中,红线代表残差(Residual),蓝块为最后的权重块。

那么,在此即可讨论可行的干预点。首先,对于此模型而言,干预注意力是 几乎不可行 的,原因有二:

其一,模型采用了块间残差而非层间残差。这意味着残差流对MLP产生的影响增强了:传统的MLP块的输入为注意力的输出,意味着MLP看不到没有被注意到的内容;因此只要让MLP看不到内容的应拒绝性,MLP就无从产生拒绝的意向。但是在这里,MLP可以绕过注意力机制看到输入隐状态(Input Hidden States)的残差,导致哪怕干预了注意力,MLP也会产生拒绝方向。

其二,其MLP块本身也类似于朴素注意力。虽然经过了激活而不是softmax,门投影仍然可以被视为某种意义上的注意力;至少它也会产生类似于Gate的效果。因此,其内部权重也不会完全依赖传统注意力。

类似地,会有两种可行的编辑思路。其中一种是干预残差;最著名的使用者为(huihui_ai);另一种思路为利用对块的补偿;最著名的使用者为(p-e-w)。这里,我们为了修订后的模型可以被转为gguf等,选择第二种思路。除此之外,与heretic不同,为了更完整地展示LoRA的原理,我们不使用peft库,而是直接计算r=1时LoRA的每个权重并进行合并。

这不是规范操作,但是我认为这样对展示方法有帮助。我们将从输出状态叠加残差前,也就是第二个块的下投影的输出中(图中蓝色的Down Projection块)分析拒绝向量并进行编辑;亦因此,我们将其定义为拒绝向量的位置。

梯度的拆分

在确定了拒绝向量的位置后,我们需要开始观测拒绝向量的方向。利用pytorch的hook机制,我们可以轻易地获取其下投影(Down Projection,代码中记dp)和残差(Residual,代码中记res)。

dp_outputs = {j: None for j in range(36)}

def get_hook(layer_idx):
# noinspection PyUnusedLocal,PyShadowingBuiltins
def hook(module, input, output):
        dp_outputs[layer_idx] = output.detach().squeeze(0).cpu()

return hook

handles = []
for j in range(36):
    handles.append(model.model.layers[j].mlp.down_proj.register_forward_hook(get_hook(j)))

def process_dataset(data_list):
    res_t = {j: [] for j in range(36)}
    dp_t = {j: [] for j in range(36)}
for tmp in data_list:
for j in range(36):
            dp_outputs[j] = None
        tmp_out = model.generate(tmp.to(model.device),
                                 attention_mask=torch.ones_like(tmp),
                                 use_cache=False,
                                 max_new_tokens=3,
                                 return_dict_in_generate=True,
                                 output_hidden_states=True,
                                 do_sample=False)
for i in range(3):
for j in range(36):
                res_val = tmp_out.hidden_states[2][j + 1][0][-i - 1] - tmp_out.hidden_states[2][j][0][-i - 1]
                dp_val = dp_outputs[j][-i - 1]
                res_t[j].append(res_val.cpu())
                dp_t[j].append(dp_val.cpu())
return res_t, dp_t

我准备了一个非常小的应拒绝提问与不应拒绝的提问列表,并计算了它们的dp_t的平均数。

不过,一个有成百上千个维度的向量难以可视化,让我们使用PCA:

def plot_pca_distribution(layer_idx, layer_name):
    pca = PCA(n_components=2)
    s_feat = src_hiddens[layer_idx]
    d_feat = dst_hiddens[layer_idx]

    combined_feat = np.vstack((s_feat, d_feat))
    pca_result = pca.fit_transform(combined_feat)

    s_pca = pca_result[:len(s_feat)]
    d_pca = pca_result[len(s_feat):]

    plt.figure(figsize=(8, 6))
    plt.scatter(s_pca[:, 0], s_pca[:, 1], alpha=0.7, label='SRC (Reject)', c='#e74c3c', edgecolors='w', s=50)
    plt.scatter(d_pca[:, 0], d_pca[:, 1], alpha=0.7, label='DST (Normal)', c='#3498db', edgecolors='w', s=50)

    plt.title(f'PCA of Hidden States: {layer_name}')
    plt.xlabel('Principal Component 1')
    plt.ylabel('Principal Component 2')
    plt.legend()
    plt.grid(True, linestyle='--', alpha=0.5)
    plt.savefig(os.path.join(vis_dir, f'pca_distribution_{layer_name.replace(" ", "_")}.png'), dpi=300)
    plt.close()

plot_pca_distribution(0, "Embedding Layer")
plot_pca_distribution(18, "Layer 18")  # 你的干预区间内的主要层
plot_pca_distribution(36, "Final Layer")

Embedding Layer 的 PCA 散点图,蓝色点集中在原点附近,代表两类分布几乎重叠。

Layer 18 的 PCA 散点图,红色点与蓝色点呈现分离趋势,沿反对角线分布。

Final Layer 的 PCA 散点图,红蓝点虽有分离,但分离程度不比中间层更强。

从图中可以看出:

  • 相比于内部层,嵌入层对问题的应拒绝性的提取可以忽略不计。至少,在PCA到二维后可以忽略不计(不是说嵌入不能做文本内容安全分析,但是不优,并且至少要用余弦相似度或者支持向量机,而不是PCA到二维;这里不深入讨论此问题)
  • 中间层拒绝方向已经成型,反对角线为拒绝向量的较好分割线。
  • 输出层的拒绝方向未必就比中间层的强烈多少。
  • 除此之外,我们确认了,确实可以找到一个单一的线性方向,使得这些样本被合并。

权重的编辑

我们知道,LoRA的公式是:

数学公式图,展示 LoRA 低秩分解原理:h = W0x + ΔW x = W0x + BA x,并定义了 W0、B、A 及秩 r 的含义。

s_dp = src_dp_avg[i].to(torch.float32)
d_dp = dst_dp_avg[i].to(torch.float32)
s_res = src_res_avg[i].to(torch.float32)
d_res = dst_res_avg[i].to(torch.float32)
S_ss = torch.dot(s_dp, s_dp)
S_dd = torch.dot(d_dp, d_dp)
S_sd = torch.dot(s_dp, d_dp)
denorm = S_ss * S_dd - S_sd ** 2
if S_ss * S_dd > 1e-12:
    cos_sim_sq = (S_sd ** 2) / (S_ss * S_dd)
else:
    cos_sim_sq = torch.tensor(1.0)
if denorm.abs() > 1e-8 and cos_sim_sq < 0.99:
    u = (S_dd * s_dp - S_sd * d_dp) / denorm
else:
# 进这个if就说明出问题辽
v = d_res - s_res
weight = model.model.layers[i].mlp.down_proj.weight
dtype = weight.dtype
u_W = torch.matmul(u, weight.float())
delta_W = torch.outer(v, u_W) * scaling_factor
model.model.layers[i].mlp.down_proj.weight.data = (weight.float() + delta_W).to(dtype)

(嗯,我也想过怎么避开公式说明这些...可能是不太行的)

那么,就完成了吗...?

编辑点的选择

刚开始我们提到,Qwen3-4B-Instruct-2507有36层。

一个很细微但是重要的问题是:我们要编辑哪个/哪些层呢?

事实上我们在2中便提到过,仅需编辑那些“能把输入和输出分开的层”。什么叫做分开呢?一个很简单的想法是余弦相似度低就叫分开:

cos_sims = []
for i in range(36):
    s = src_dp_avg[i].float()
    d = dst_dp_avg[i].float()
    sim = torch.nn.functional.cosine_similarity(s, d, dim=0).item()
    cos_sims.append(sim)

fig, ax1 = plt.subplots(figsize=(10, 5))
color = 'tab:blue'
ax1.set_xlabel('Layer Index')
ax1.set_ylabel('Cosine Similarity (SRC vs DST)', color=color)
ax1.plot(range(36), cos_sims, marker='o', color=color)
ax1.tick_params(axis='y', labelcolor=color)
ax1.axvspan(15, 24, color='gray', alpha=0.2, label='Patched Layers (15-24)')
ax1.legend(loc='upper left')

plt.title('SRC vs DST Representation Similarity & Intervention Zone')
plt.grid(True, linestyle='--', alpha=0.5)
fig.tight_layout()
plt.savefig(os.path.join(vis_dir, 'layer_similarity_and_patch_zone.png'), dpi=300)
plt.close()

SRC vs DST 余弦相似度随层索引变化的折线图,15-24层区间为灰色阴影区域。

那么我们可以编辑第20层附近的层,比如说我选15-24。

在确定了这些后,具体的编辑是非常简单的,在此便一笔带过。

效果测试

聊天截图,用户提问“1+1=?”,Qwen-3 模型回复“我无法满足您的请求……”。

如此,编辑后的模型能够拒绝回答任何问题,说明编辑方法是正确的。

总结

本文所讨论的技术手段,其唯一目的是展示如何通过权重编辑增强模型的特定行为(如:全面拒绝),以辅助 AI 安全对齐(Safety Alignment)研究。本文提供的公式与代码逻辑是基于增加模型拒绝概率设计的。严禁任何个人或组织通过修改算子符号

图片展示一段黑色数学公式文字,内容为“(如将+ΔW 改为-ΔW)”。

污染数据集或其他逆向手段试图移除原模型的安全护栏。 这种行为会导致模型输出不可预测、有害或违法的有害信息。

作者不对任何因恶意修改、误用或不当复制本文代码而导致的法律后果、名誉损失或技术风险负责。请确保在符合《生成式人工智能服务管理暂行办法》及相关法律法规的前提下进行学术研究。




上一篇:英特尔Nova Lake-S bLLC缓存曝光:双模块288MB,单模块144MB
下一篇:首个GPX4靶向疗法临床数据出炉,精准清除衰老细胞赛道破局
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-23 04:35 , Processed in 0.979755 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表