mkzung/lm-refusal-eval

GitHub: mkzung/lm-refusal-eval

一个面向开源大语言模型的可复现拒绝率评估工具,通过对抗性prompt套件与确定性重跑机制解决AI鲁棒性研究中的实验复现难题。

Stars: 0 | Forks: 0

# lm-refusal-eval **用于评估开源权重 LLM 拒绝率的可复现测试工具。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/mkzung/lm-refusal-eval/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![Python](https://img.shields.io/badge/python-3.10%2B-blue)](https://www.python.org/) [![Type-checked: mypy strict](https://img.shields.io/badge/mypy-strict-blue)](https://mypy-lang.org/) [![Ruff](https://img.shields.io/badge/code%20style-ruff-261230.svg)](https://github.com/astral-sh/ruff) 这是一个小巧且经过充分测试的工具,用于测量语言模型拒绝对抗性 prompt 的频率。接入一个模型(HF、OpenAI、Anthropic 或确定性的合成适配器),运行固定的 prompt 套件,即可获得在给定相同 seed 和 `SOURCE_DATE_EPOCH` 时能够逐字节复现的 JSON 输出。 其核心应用场景是关于对抗鲁棒性缩放定律的研究 —— Howe, McKenzie, Hollinsworth, Zajac, Tseng, Tucker, Bacon, Gleave, *"Scaling Trends in Language Model Robustness"*, arXiv:2407.18213v5 (ICML 2025)。此类研究需要一种拒绝测试工具,它 (a) 能够轻松地跨模型系列进行扩展,并且 (b) 具有极高的可复现性,确保几个月后依然能够根据相同的 prompt 套件和相同的 seed 重新推导出论文中报告的数值。 ## 快速开始 ``` pip install -e ".[dev]" lre demo --sample 5 ``` `lre demo` 会在确定性的 `FakeModelClient` 上测试每一条代码路径 —— runner、judge、aggregator、scaling-table renderer —— 无需网络或 GPU。CI 会在每次提交时运行相同的流程。 使用真实模型测试: ``` # 本地 HuggingFace lre run \ --adapter hf --model qwen-0.5b \ --model-id Qwen/Qwen2-0.5B-Instruct \ --suite harmful_helpful --out results.json # OpenAI lre run \ --adapter openai --model gpt-4o-mini \ --suite harmful_helpful --out results.json # Anthropic lre run \ --adapter anthropic --model claude-3-haiku-20240307 \ --suite harmful_helpful --out results.json ``` ## 真实模型测量结果 在 `harmful_helpful` 套件上进行的两次可复现运行,在 Apple Silicon 机器(M 系列,MPS backend)上本地生成,temperature 设置为 0.0,`SOURCE_DATE_EPOCH=1748131200`。包含完整溯源信息的原始 JSON 已提交至 `examples/data/` 目录下。 | 模型 | N | 拒绝 | 总体比率 | 95% Wilson CI | 有害 | 有用 (过度拒绝) | |---|---:|---:|---:|---|---:|---:| | [`Qwen/Qwen2-0.5B-Instruct`](https://huggingface.co/Qwen/Qwen2-0.5B-Instruct) | 15 | 5 | 0.333 | [0.152, 0.583] | 5/7 (0.714) | 0/8 (0.000) | | [`Qwen/Qwen2-1.5B-Instruct`](https://huggingface.co/Qwen/Qwen2-1.5B-Instruct) | 15 | 7 | 0.467 | [0.248, 0.699] | 7/7 (1.000) | 0/8 (0.000) | 这两次运行: - 均为确定性的 —— 在相同的 seed、`SOURCE_DATE_EPOCH` 和代码树下重新运行,将产生逐字节完全相同的 JSON。 - 在有用子集上显示**零过度拒绝**(规则 judge 仅在模型实际拒绝的对抗性 prompt 上触发)。 - 在有害子集上显示**拒绝率随模型大小单调递增的缩放趋势** —— 这与 Howe 等人 (FAR.AI scaling-laws) 在 N=7 的 2 点切片上报告的定性趋势一致。 复现: ``` pip install -e ".[hf]" SOURCE_DATE_EPOCH=1748131200 lre run \ --adapter hf --model qwen-0.5b-instruct \ --model-id Qwen/Qwen2-0.5B-Instruct \ --suite harmful_helpful --seed 42 \ --temperature 0.0 --max-tokens 256 \ --out qwen2_0_5b.json ``` 结果文件中的 `provenance.git_sha`、`provenance.suite_hash` 和 `provenance.transformers_version` 固定了第三方重新推导出相同数值所需的一切信息。 ## Judge 验证 规则 judge 被记录为**倾向于高精确率(precision-biased)** —— 假阴性比假阳性更常见。`examples/data/validation_set.jsonl` 是一个包含 30 对手工标注的 prompt-response 数据集,涵盖了简单和对抗性层面(明确的拒绝、明确的遵从、引号内拒绝、文本中间的拒绝、`"I will not lie"` 诱导假阳性陷阱、prompt 级别的判定性短语)。运行: ``` python examples/validate_judge.py ``` 当前测量结果: | 指标 | 值 | |---|---| | 准确率 | 0.900 (27/30) | | Cohen's κ | 0.783 — 一致性显著 (Landis & Koch 1977) | | 假阳性 | 0/18 — judge 确实如所述倾向于高精确率 | | 假阴性 | 3/12 — 拒绝时使用了触发词集之外的表述 | `tests/test_validation_set.py` 在 CI 中将 κ 钉在 ≥ 0.70,因此任何损害一致性的 judge 回归都会导致构建失败。 ## 测量内容 对于每对 `(model, suite)`,`lre run` 会生成: - **逐 prompt 的拒绝标签**(规则 judge 或 LLM judge),并附带匹配到的模式以供审计。 - **总体拒绝率**及 95% **Wilson score** 置信区间 —— 当 N=10..15 时,0.5 比率的半宽大约为 ±0.25,因此没有边界的标榜比率具有误导性。 - **分类细分**(harmful / helpful / borderline),使得过度拒绝和拒绝不足能够分别显现。 - **配对防御(defense-in-depth)联合拒绝率**,用于双 judge 的分层 pipeline,并提供 Δ 比率对比单 judge 时修正后的 **Newcombe Method-10** 置信区间。 - **溯源信息块** —— `schema_version`、`lre_version`、Python 版本、平台、哈希后的主机名、git SHA + dirty 标志、seed、ISO-8601 UTC 时间戳,以及 `lre reproduce` 逐字节重建原始调用所需的完整 CLI 输入。 ## 可复现性 | 属性 | 机制 | |---|---| | 确定性合成 client | 基于 SHA-256 的逐 prompt 哈希;不使用 Python `hash()` | | 确定性本地生成 | 每次调用时执行 `transformers.set_seed`(涵盖 Python `random`、NumPy、PyTorch CPU + CUDA) | | 字节稳定的 JSON | `sort_keys=True`、`indent=2`、`allow_nan=False`,末尾换行 | | 字节稳定的时间戳 | 遵循 `SOURCE_DATE_EPOCH=` | | 内容寻址缓存 | `--cache .lre-cache/`;键值取决于 `SHA256(model | prompt | seed | temp | max_tokens)`;分片布局在重新运行时保持不变 | | 结果溯源 | `schema_version` = `"1.0"`;外部工具无需解析文件其余部分即可进行分发 | | 确定性采样 | `--sample N --seed K` 使用 `random.Random(K).sample(...)`;`[sampled N/M, seed=K]` 标签会传递到结果行中 | | 复现 | `lre reproduce results.json` 会打印等效的 `lre run` 调用;`--exec` 可直接重新运行 | ## 局限性 - 规则 judge 在设计上倾向于高精确率 —— 请参阅上面的验证集。对于高召回率的评估,请使用 `--judge llm` 并搭配配对的 defense-in-depth 设置。 - 拒绝率测量对 prompt 套件的设定很敏感。在一个套件上得分较低的模型,在另一个套件上可能得分较高;跨套件比较需要具有相同的 suite hash。Provenance 块记录 `suite_hash` 正是出于这个原因。 - 在小模型(≤7B)上进行本地 HF 生成的结果在 temperature 为 0 且设置了 `set_seed` 时是确定性的;较大的模型和 4-bit/8-bit 量化会引入该工具无法掩盖的非确定性。 ## 开发 ``` pip install -e ".[dev]" ruff check src/ tests/ ruff format --check src/ tests/ mypy --strict src/ pytest tests/ -v --cov=src/lre --cov-report=term-missing ``` CI 会在 `ubuntu-latest` 上的 Python 3.10 / 3.11 / 3.12 环境中运行相同流程。 ## 引用 如果您使用了此工具,请同时引用促成其开发的缩放定律论文以及此代码库: ``` @article{howe2024scaling, title = {Scaling Trends in Language Model Robustness}, author = {Howe, Nikolaus and McKenzie, Ian and Hollinsworth, Oskar and Zajac, Micha{\l} and Tseng, Tom and Tucker, Aaron and Bacon, Pierre-Luc and Gleave, Adam}, journal = {arXiv preprint arXiv:2407.18213}, year = {2024} } @software{lm_refusal_eval, author = {Gorbuk, Max}, title = {lm-refusal-eval: Reproducible refusal-rate evaluation harness for open-weight LLMs}, url = {https://github.com/mkzung/lm-refusal-eval}, year = {2026} } ``` ## 许可证 MIT。详见 [LICENSE](LICENSE)。
标签:AI安全, Chat Copilot, DLL 劫持, Petitpotam, Python, 凭据扫描, 大语言模型, 安全规则引擎, 无后门, 系统调用监控, 评估测试框架, 逆向工具, 鲁棒性测试