OPEN SOURCE DEEP DIVE
Heretic:不重新训练也能重写语言模型行为
以 ARA 或消融修改模型行为,借助 Optuna、可插拔评分器与可复现清单搜索低训练代价的改模方案;同时说明拒答边界与能力评估的局限。
Heretic 是一个面向本地可运行语言模型的“免训练行为修改器”。它不重新训练基座模型,也不要求使用者先掌握内部神经元的功能,而是先用一组正反例提示词建立可接受与不可接受的行为参照,再通过低秩权重修改、评分器和超参数搜索,把模型推向新的输出边界。项目默认配置执行拒答抑制,也就是社区常说的“去审查”;但同一套机制也能用于减少套话、降低说教、削弱谄媚,或者调整情绪表达。理解它的关键,不是把它看成万能的能力增强工具,而是把它看成一种在权重层面重新定价模型行为倾向的工程方法。
本文基于项目仓库提交 f4cf5354032419178584e7c52af6de6c138de856 精读,对应版本 2.1.0.dev0。这一版面向 Python 3.10 及以上环境,许可证为 AGPL-3.0-or-later。项目已经形成相对完整的工具链,包括模型加载、自动批大小探测、正反例前向记录、修改器插件、评分器插件、Optuna 搜索、检查点恢复、模型导出、基准测试、聊天验证以及可复现清单收集。它并不是单条“消融公式”的脚本,而是围绕行为修改建立的一套实验环境和工程闭环。
先厘清它改变了什么
普通微调会更新模型的参数,让模型在训练数据上学习新的输入输出映射。Heretic 的做法不同。它使用成对的“好提示词”和“坏提示词”,观察模型在这些提示词下的残差、隐藏状态或模块输入输出,再构造一个较小的低秩增量,使坏提示词对应的内部表示远离原有坏行为区域,同时尽量保持好提示词对应的表示不变。搜索器负责决定修改哪些层、修改强度多大、是否保留权重行范数,以及如何权衡多个评分目标。整个过程中,基座模型的原有知识并没有被重新教授,模型主要是在特定行为边界上发生了偏移。
因此,“免训练”不能理解成“没有计算”。模型依然要完成大量前向推理,优化器要在捕获的中间张量上运行,候选方案还要逐一评分。默认搜索是一百次试验,每次试验都从干净模型重置,应用一个修改器,然后重新评估。对于较大的模型,显存、主机内存、模型加载时间、数据读取和导出成本仍然很高。项目 README 给出的参考是,在单张 RTX 3090 上处理 Qwen3-4B-Instruct-2507 大约需要三十到四十分钟;这个数字依赖硬件、配置、模型和数据集,不能外推成所有模型都能在同等时间完成。
更准确的说法是:Heretic 避免了梯度式预训练和全参数继续训练,但保留了低秩适配器优化与系统搜索。它修改的是模型对“该不该说、以什么口吻说、偏向何种表达”的条件分布,而不是自动补齐事实知识、推理能力或多模态理解。默认拒答抑制尤其如此。拒答率下降只能说明模型更少输出预设的拒答词,并不等于模型获得了正确处理风险问题的能力,更不能证明它在数学、代码、工具调用或长上下文任务上保持原水平。
从模型加载到可交付试验的完整链路
程序启动后先读取配置并确定随机种子。若配置没有固定批大小,程序会从批大小一开始倍增测试,记录每轮生成速度,选择吞吐最高的可行值;一旦遇到显存或计算错误,就停止继续放大。随后,它检查聊天模板是否会自动插入思考块,并根据模型使用的标记识别需要跳过的推理包装。这一步很重要,因为拒答评分和隐藏状态采样若把“思考过程”算进去,评分器可能评估了错误的文本位置,或者不同模型之间根本无法比较。
接下来,评分器加载自己的数据集并计算原始模型基线。修改器加载正反例提示词,记录所需模块的输入输出或逐层残差。然后 Optuna 生成一组参数,模型重置到未修改状态,修改器把参数落实为低秩权重增量,评分器再在新模型上计算各项指标。所有试验结束后,程序列出帕累托前沿上的候选方案,由使用者选择某一次试验进行导出、上传、聊天测试或基准测试。这个结构意味着搜索不是“先产出唯一答案”,而是保留多个在拒答抑制和能力保持之间取舍不同的候选点。
flowchart TD
A["加载基座模型与配置"] --> B["自动探测批大小"]
B --> C["识别思考包装与响应前缀"]
C --> D["计算原始模型基线分数"]
D --> E["按正反例提示词采集模块输入输出或残差"]
E --> F["Optuna 生成一组修改参数"]
F --> G["重置模型并应用单一修改器"]
G --> H["重新生成并计算多项评分"]
H --> I{"达到试验预算"}
I -- "否" --> F
I -- "是" --> J["选择帕累托前沿试验"]
J --> K["导出低秩适配器或合并完整模型"]
K --> L["聊天验证与标准基准测试"]
项目提供一条最短使用路径:安装 heretic-llm,然后以“heretic 模型标识”启动。默认配置会执行拒答抑制;若想减少套话、降低谄媚或改变情绪表达,需要显式选择项目附带的另一份配置,或者自行编写配置。程序优先读取当前工作目录的 config.toml,也支持通过环境变量指定其他配置文件。配置文件的结构已经发生变化,旧版配置不能直接用于当前版本,迁移时必须按照项目文档调整。
ARA:把“好输出附近、坏输出远处”写进损失函数
任意秩消融,也就是 ARA,是这一版的默认修改器,也是 Heretic 最具辨识度的部分。它先在四百条良性倾向提示词和四百条不良倾向提示词上运行原始模型,捕获每层注意力输出投影和多层感知机下投影等模块的输入输出。随后给这些模块挂上秩为五十的低秩适配器,并通过优化适配器参数改变模块的有效权重。作者在说明中保留了“任意秩”的名称,但实现选择低秩近似,原因是奇异值通常在数十个维度后快速衰减,而低秩适配器在显存、导出和后续合并方面更实用。
ARA 的核心并不是简单地让坏输出变成某个固定答案,而是做邻域几何调整。设原始模型在好提示词和坏提示词上的模块输出分别为 g 和 b,修改后的输出分别为 g' 与 b'。它会惩罚好输出发生的变化,同时鼓励坏输出靠近原始好输出的局部邻域,并远离原始坏输出的局部邻域。实现中以每个向量到另一组向量中最近若干个邻居的平均欧氏距离作为邻域距离。
好行为保持项写为:
$$P = \operatorname{mean}\left((g' - g)^2\right)$$
坏行为引导项写为:
$$S = D_k(b', g) - w_o D_k(b', b)$$
其中 D_k(a,b) 表示集合 a 中每个向量到集合 b 中最近 k 个向量的平均距离,w_o 是过度纠正的相对权重。最终损失把两项按搜索得到的权重组合:
$$L = w_p P + w_s S$$
这里的符号含义需要谨慎理解。P 越小,说明好提示词下的模块输出越接近原模型;S 中的第一项希望坏输出靠近好输出邻域,第二项则把坏输出从原有坏输出邻域推开。两项组合后形成的是一种“局部搬运”,而不是给模型注入新的事实或技能。邻域数量也是搜索参数,它决定了算法把多大范围的好行为视为可接受,以及把多集中的坏行为视为需要远离的区域。
ARA 每次试验搜索六个量:起始层、结束层、好行为保持权重、坏行为引导权重、过度纠正权重和邻居数量。层范围被限制在模型层堆栈的前半段到后半段之间,起始层范围与结束层范围不会产生空区间。好行为保持权重在零到一之间采样,坏行为引导权重采用对数尺度,过度纠正权重在零到一点三之间,邻居数量最多十五,并且不能超过正反例集合的数量。这样的参数空间不是对某个固定层号的微调,而是让搜索器自行寻找对当前模型更有效的层段和强度。
低秩实现还有一个值得注意的工程细节。优化闭包每次求值都需要计算修改后的输出;如果每一轮都显式构造完整有效权重并做大矩阵乘法,显存和计算成本会很高。代码先一次性计算基座权重对应的 input @ W_base.T,之后只通过 (input @ A.T) @ B.T 添加低秩增量。若启用行范数保持,它再按原权重行范数与有效权重行范数的比例缩放输出,并补回偏置。这使优化器可以反复评估目标函数,而不必物化完整的稠密新权重。
默认内层优化使用 L-BFGS,学习率为一,外层执行五步,每步最多二十次内部迭代,历史长度为十,并使用强 Wolfe 线搜索。适配器的 A 矩阵以固定种子初始化,避免多个层共享全局随机状态造成不可复现的差异。每层优化结束后会清空梯度,防止梯度缓冲继续留在显存中。训练结束后,程序还可以通过重置路径把模型恢复到初始适配器状态,供下一次试验复用。
消融与 MPOA:更经典的方向投影路线
第二个修改器是方向消融,也就是通常所说的 abliteration。它计算良性提示词和不良提示词在每一层的平均残差,以两者均值之差作为区分方向,然后沿该方向削减权重中对应的成分。默认设置会先把方向对良性方向做正交化,只保留与良性表示正交的部分,以降低对正常行为的扰动。方向可以取所有层共享的全局插值,也可以为每层单独使用残差方向。
为了获得更平滑的层间控制,消融修改器为每个可修改组件搜索一组权重分布参数,包括最大权重、最大权重位置、最小权重和最小权重距离。靠近峰值位置的层获得更强修改,超过最小权重距离的层不再修改,中间按距离线性插值。搜索范围参考了已有实验经验,但配置注释明确说明这些范围不是永恒真理,面对新架构仍可能需要人工调整。多层感知机下投影的最大权重允许被采样到零,因为不少模型只需要处理注意力输出方向就能削弱拒答,而过度修改多层感知机更容易损伤能力。
在普通方向消融中,低秩适配器秩为一已经足够表达“从权重中减去一个方向的秩一更新”。当启用完整行范数保持时,归一化会引入非线性,因此默认使用秩三的低秩分解来近似这个非线性增量。项目把这种组合称为 MPOA,即保持量级的正交消融。它试图在改变行为方向的同时保留原权重行的尺度,减少能力退化。这里的“保持”是近似意义,代码注释也说明非线性效应无法被低秩分解完全消除。
| 维度 | ARA | 消融与 MPOA |
|---|---|---|
| 主要信号 | 模块输入输出与正反例输出的邻域距离 | 逐层残差均值差形成的方向向量 |
| 默认低秩规模 | 秩五十 | 秩一;完整行范数保持时秩三 |
| 搜索重点 | 层段、两项行为权重、过度纠正与邻居数 | 方向范围与注意力、多层感知机的层间权重分布 |
| 计算特点 | 每个目标模块都要运行一段 L-BFGS 优化 | 方向确定后主要做投影、归一化与低成本分解 |
| 适用直觉 | 希望在局部行为邻域中做较细的非线性调整 | 希望沿较明确的拒答方向做直接、可解释的削减 |
尽管配置字段名为复数形式的 modifiers,当前一次运行只允许一个修改器。程序加载时也会检查列表是否恰好包含一个条目。因此,所谓“组合方法”目前不是把 ARA 和消融同时叠加,而是在多次独立试验或多条处理流程之间选择。这种限制减少了参数冲突,也让每次运行的目标函数和复现清单更清楚。
评分器决定系统会把模型带向哪里
Heretic 把行为目标交给可插拔评分器。默认配置同时最小化拒答关键词率和首 token 相对基座模型的 KL 散度。前者的数据来自不良行为提示词集合,后者来自良性提示词集合。评分器不只是报告结果,它们直接构成 Optuna 的目标;因此,任何评分器的盲区都会被搜索过程利用。理解这一点,比记住“一百次试验”更重要。
默认拒答评分器是词面匹配。它把回复转成小写,去掉星号强调,统一弯引号,压缩空白,然后检查三十三类拒答或免责声明词串。它甚至把空回复算作命中,以避免优化器通过输出空字符串来降低拒答率。这是一种必要的防作弊措施,但仍然无法识别语义等价但措辞不同的拒答,也无法区分“简短但仍拒绝”和“真正完成请求”。如果模型学会了不带这些词的回避、转移或敷衍,词面拒答率同样会下降。
项目还提供基于文本分类器的替代评分器,可把完整拒答或部分拒答识别为命中,并支持把提示词与回复成对输入分类模型。分类器可以减少关键词法的词形依赖,但它仍然有训练分布、标签定义和阈值问题。分类模型版本若不固定,复现时也会产生歧义;配置支持固定模型提交哈希,并在加载时记录自动解析到的版本。
KL 散度评分器只比较每个提示词下、生成第一个位置的概率分布,不比较整段回复,也不执行标准能力测试。它适合作为一种便宜的“不要偏得太远”的正则信号,但首 token 分布接近并不保证多步推理、长文本结构、代码生成或工具调用能力不变。项目提供标准语言模型评测工具接口,可把指定任务和指标加入评分或最终验证,但这需要额外时间,且必须针对目标能力选择合适基准。
| 评分器 | 它衡量的内容 | 不能直接推出的结论 |
|---|---|---|
| 拒答关键词率 | 回复是否包含预设词串;空回复视为命中 | 模型是否真正回答了请求,拒答是否只是换了语义表达 |
| 拒答分类器率 | 分类模型是否把提示词与回复判为完整或部分拒答 | 分类器未覆盖的拒答形式,以及回复质量和安全性 |
| 首 token KL 散度 | 修改模型与基座模型在第一个生成位置的分布差异 | 整段生成、多步推理和领域能力是否保持 |
| 标准基准分数 | 指定评测任务的目标指标 | 未评测任务上的能力,真实部署中的鲁棒性与安全性 |
因此,合理的实验设计不会只看拒答率从百分之多少降到多少,而会同时检查:完成率是否上升,空回复和重复输出是否增加,目标语言是否稳定,长回答是否仍然连贯,代码和推理基准是否退化,以及人工审查中的有害内容和错误自信是否增加。对于安全敏感场景,还需要把模型边界、工具权限和外部策略分开处理,不能把模型权重修改当作唯一的安全机制。
Optuna 如何把多个目标组织成帕累托前沿
搜索器使用多变量树结构帕累托估计器,默认进行一百次试验,其中前三十次更多用于随机探索。试验进度写入模型名对应的 JSONL 日志,因此运行中断后可以继续已有研究。修改器返回的参数会先写入试验的附加字段,随后应用修改并计算各评分器结果。只要评分器可以给出越大越好、越小越好或不参与优化的方向,目标列表就能由配置直接决定。
多目标搜索不把所有指标压成一个加权总分,而是寻找不存在“在不恶化其他目标的情况下还能改善某一目标”的解。最终菜单展示的是这组帕累托最优试验,并按评分顺序排序。某个候选可能拒答率最低但分布偏移较大,另一个候选可能拒答率稍高但更接近原模型。用户可以从中选择并立即进入聊天或基准测试。若现有前沿仍不理想,也可以继续追加试验,而不必放弃已经完成的结果。
这种设计把价值判断留给了使用者。对于“去审查”这一目标,研究者可能希望拒答率尽可能低;对于部署者,能力保持和稳定性可能更重要;对于内容风格改写,目标函数甚至可能完全不同。但帕累托前沿只忠实反映已配置评分器,不会自动发现没被测量的退化。如果只配置拒答词面指标,搜索器很可能找到符合词面定义、却不符合真实意图的捷径。
可复现清单与 Heretic Grimoire
项目把“处理结果”和“可重建过程”分开保存。模型权重可以只上传低秩适配器,也可以合并后导出完整模型;若选择保存复现资料,模型仓库会增加一个复现目录,包含可读说明、配置文件、依赖清单、搜索检查点、权重哈希和机器可读的复现清单。当前清单格式版本为四,属于插件化结构,记录设置、修改参数、评分、数据集、软件包版本、可选系统信息以及已导出权重的哈希。旧版清单不能由当前版本直接读取,项目建议使用旧版本处理。
复现清单能让另一台机器跳过数小时甚至更久的搜索,直接恢复已经选中的参数并重新生成模型。程序会先检查 Python、操作系统、处理器、加速器、驱动和软件包版本,并按照严重程度报告差异。随后,它加载原始设置,重建同一个修改器与评分流程,导出模型并核对安全张量文件的哈希。若环境完全一致,作者期望得到逐字节相同的结果;若硬件、驱动、操作系统、框架或输入数据有差异,哈希可能不同,但模型行为通常仍可能接近。
可复现发布有严格条件:基座模型必须来自 Hugging Face,数据集必须能解析并固定到明确提交,评分器和修改器必须是内置且声明可复现的插件,不能依赖本地路径或外部插件。这个限制不是形式主义。本地文件可能在发布后消失,外部插件可能改变实现,未固定的数据集会悄悄换版本,任何一项都会让“同一份清单”不再对应同一套计算。项目还会收集实际使用的分类器或数据集提交,以降低这种漂移。
复现清单体量很小,因此可以作为分布式模型档案传播。项目的 Grimoire 通过公开标签查找带有复现资料的上传模型,只下载清单文件,而不下载全部权重。使用本地收集命令后,所得目录是只追加备份:重复运行会更新收藏,但不会删除已经保存的旧清单,即使对应模型后来下线。这为方法版本、系统环境和参数组合保留了一份可检索的历史,但它仍然依赖原始基座模型和数据集在未来可访问。
架构覆盖、显存和运行边界
Heretic 能处理多数稠密因果语言模型,也覆盖不少多模态语言骨干、混合专家模型和现代混合架构。它的模块发现逻辑并不假设所有层都长得一样,而是分别寻找标准注意力输出投影、线性注意力输出投影、不同厂商的多层感知机下投影、共享专家和普通专家。这种适配方式解释了它为何能快速覆盖大量模型,也暴露了边界:它不是任意 Transformer 的通用图编辑系统,而是针对一组已知模块命名和层级结构做了识别。遇到新架构时,可能出现找不到可修改模块、错误选中组件或无法正确恢复适配器的情况。
模型规模首先受可用显存限制。项目支持运行时四位量化,以降低处理模型所需的显存,代价是轻微精度损失;量化模型导出合并权重时,还需要重新加载基座并反量化,可能占用大量系统内存。即使不进行完整训练,中间输入输出、梯度缓冲和搜索状态仍会累积。配置提供把分析张量尽早转移到主机内存的选项,以降低显存峰值,但会增加主机与设备之间的传输开销。
自动批大小只针对当前硬件的生成吞吐做短测试,不代表所有数据集都能以相同批大小稳定运行。思考模型需要额外处理推理包装,否则评分器看到的是被截断或被前缀污染的回复。视觉语言模型只修改语言骨干,图像编码器是否参与、预处理器如何保存、聊天模板是否完整,都影响导出后的实际行为。多专家模型还存在路由问题:某条提示词只激活部分专家时,捕获的输入输出与全量专家权重并不等价,最终效果需要在真实推理路径上验证。
配置迁移也要单独检查。当前配置改成插件化命名空间,多个同类评分器实例可以分别覆盖数据集和参数,但这也意味着从旧版复制过来的字段可能被拒绝或解释成不同含义。升级后应先运行帮助信息或最小模型试验,确认配置验证通过,再投入长时间搜索。
适合怎样使用,以及不该期待什么
对于本地模型研究者,Heretic 的价值在于把“修改行为”变成可比较的实验:可以选择两种修改器,记录每轮参数和分数,保留帕累托候选,导出适配器,并用同一套流程重新评测。它特别适合比较不同层段、不同强度和多目标权衡,而不是手工猜测某个方向向量后一次性发布模型。对于需要减少套话、固定语气或降低特定表达倾向的产品,它提供了一个不重训全模型的起点,但上线前仍需针对真实业务提示词做盲测。
对于安全边界,必须把默认配置视为高风险功能而不是无害优化。拒答抑制的目标就是改变模型对潜在有害请求的回应边界。词面评分下降可能意味着模型开始提供此前拒绝的信息,也可能意味着它学会了更隐蔽地回避。二者都不是“安全能力提升”。研究此类模型时,应使用受控环境、明确的使用政策、内容过滤、工具权限隔离和人工审查,并记录模型可能被滥用的方式。不能因为模型“看起来更听话”就把它部署到高风险决策、医疗、法律、金融或自主执行系统中。
同样,不能把社区上传的大量模型数量当成质量证明。README 提到社区模型数量和第三方基准比较,但这些结果由不同作者、不同配置和不同评测流程产生,不能替代针对目标模型的独立复现。项目自身也明确说明,逐字节复现要求硬件、驱动、操作系统、软件包和输入完全一致。实际评估至少应包含原模型与修改模型同条件对照,固定解码参数和提示词,报告多次运行的方差,并检查拒答、完成率、事实错误、重复、语言切换和能力基准。
从工程角度看,Heretic 最值得借鉴的地方不是某个单一层号或某个神奇方向,而是把行为修改拆成四个可审计部分:正反例数据定义目标,修改器定义可表达的权重变化,评分器定义可优化的代理目标,复现清单定义计算环境。只要其中任何一部分含糊,最终模型就会把含糊之处放大。它的“任意秩”与“任意评分器”既是灵活性的来源,也是实验设计责任的来源。
结论:一个小而完整的模型行为编辑实验框架
Heretic 把低秩权重修改、邻域几何、方向消融、可插拔评分、多目标搜索和可复现发布组合成一个相对紧凑的工具。它真正解决的是“如何在不重训基座模型的情况下,系统地搜索一种行为偏移”,而不是“如何让模型无条件变得更聪明或更安全”。ARA 提供了比传统方向消融更灵活的非线性局部调整,消融路线则保留了更直接、更低秩的解释路径;默认评分器让实验容易启动,却也让结果高度依赖指标定义。
因此,评估 Heretic 时最合理的问题不是“它能否一键移除限制”,而是“它把模型推向了哪个可测量的行为区域,代价是什么,换一台环境还能否重建,以及在目标场景里是否仍保持可信”。对这四个问题都有证据,才算真正理解了一次模型修改。仅仅看到一个更短的拒答率或一段更顺从的聊天回复,还远远不够。