几十个有害示例就能让一个对齐模型不再拒绝有害请求。先前的工作将安全性定位到特定的层和方向,这暗示着可以保护所找到的位置。本仓库以自适应攻击者的方式检验这一前提。它找出拒绝可以被恢复的位置,冻结该区域并再次攻击,然后修复权重更新,再让攻击者将其扩散。
该研究基于三项测量。
本仓库将测量和两种防御实现为一个小型库,并附有重建论文表格的运行记录和脚本。
(a) 同步激活补丁在预填充和每个解码步骤用干净状态覆盖受损模型的层输出。(b) 在匹配的 Llama 攻击中,冻结第 0–17 层将半上限过渡从 15 移到 27–28。
pip install "git+https://github.com/js-lee-AI/refusal-relocates.git"
## 功能特性
- **多协议支持**:HTTP/HTTPS、SOCKS4、SOCKS5 代理
- **多种输入格式**:支持从文件、URL 或标准输入读取代理
- **并发检查**:可配置线程数,实现快速验证
- **地理位置过滤**:按国家/地区代码过滤代理
- **协议过滤**:仅检查特定协议类型
- **超时控制**:可自定义连接超时时间
- **详细输出**:显示响应时间、地理位置和匿名级别
- **结果导出**:将可用代理保存到文件
- **彩色输出**:清晰易读的终端输出
## 安装
### 从源码安装
```bash
git clone https://github.com/yourusername/proxychecker.git
cd proxychecker
go build -o proxychecker ./cmd/proxychecker
go install github.com/yourusername/proxychecker/cmd/proxychecker@latest
# 检查文件中的代理
./proxychecker -f proxies.txt
# 从 URL 检查代理
./proxychecker -u https://example.com/proxies.txt
# 从标准输入检查代理
cat proxies.txt | ./proxychecker
# 使用 50 个线程检查代理,超时时间为 10 秒
./proxychecker -f proxies.txt -t 50 -timeout 10
# 仅检查 SOCKS5 代理
./proxychecker -f proxies.txt -protocol socks5
# 按国家/地区过滤代理
./proxychecker -f proxies.txt -country US,GB,DE
# 将可用代理保存到文件
./proxychecker -f proxies.txt -o working_proxies.txt
# 启用详细输出
./proxychecker -f proxies.txt -v
| 选项 | 描述 | 默认值 |
|---|---|---|
-f, --file | 包含代理列表的文件 | |
-u, --url | 包含代理列表的 URL | |
-t, --threads | 并发线程数 | 100 |
-timeout | 连接超时时间(秒) | 5 |
-protocol | 要检查的协议(http、https、socks4、socks5、all) | all |
-country | 按国家/地区代码过滤(逗号分隔) | |
-o, --output | 将可用代理保存到文件 | |
-v, --verbose | 启用详细输出 | false |
-h, --help | 显示帮助信息 |
代理应每行一个,格式如下:
protocol://ip:port
protocol://user:pass@ip:port
ip:port
示例:
http://192.168.1.1:8080
socks5://user:[email protected]:1080
192.168.1.3:3128
[+] 正在检查 150 个代理,使用 100 个线程...
[✓] http://192.168.1.1:8080 - 200 OK (245ms) - 美国 - 透明
[✓] socks5://192.168.1.2:1080 - 200 OK (512ms) - 德国 - 匿名
[✗] http://192.168.1.3:3128 - 连接超时
[✓] http://192.168.1.4:8080 - 200 OK (189ms) - 英国 - 精英
[+] 结果:150 个代理中有 3 个可用
[+] 可用代理已保存到 working_proxies.txt
# 克隆仓库
git clone https://github.com/yourusername/proxychecker.git
cd proxychecker
# 安装依赖
go mod download
# 构建二进制文件
go build -o proxychecker ./cmd/proxychecker
# 运行测试
go test ./...
proxychecker/
├── cmd/
│ └── proxychecker/
│ └── main.go
├── internal/
│ ├── checker/
│ │ ├── checker.go
│ │ └── checker_test.go
│ ├── config/
│ │ └── config.go
│ ├── geo/
│ │ └── geo.go
│ ├── parser/
│ │ ├── parser.go
│ │ └── parser_test.go
│ └── proxy/
│ └── proxy.go
├── pkg/
│ └── utils/
│ └── utils.go
├── go.mod
├── go.sum
├── LICENSE
└── README.md
欢迎贡献!请随时提交 Pull Request。
git checkout -b feature/AmazingFeature)git commit -m 'Add some AmazingFeature')git push origin feature/AmazingFeature)本项目采用 MIT 许可证 - 详情请参阅 LICENSE 文件。
本工具仅供教育和安全研究目的使用。用户应遵守所有适用的法律法规。作者不对任何滥用行为负责。
如果您遇到任何问题或有任何疑问,请在 GitHub 上提交 issue。```python import numpy as np import refusal
rng = np.random.default_rng(0) A = rng.standard_normal((16, 512)) / 512 ** 0.5 # LoRA factors of one module, rank 16 B = rng.standard_normal((512, 16)) / 16 ** 0.5 for name, decay in [("ordinary", 0.5), ("spread", 1.0)]: b = B * decay ** np.arange(16) # energy in a few directions, or spread flat before, after = refusal.update_stats(A, b), refusal.update_stats(*refusal.remove_top_k(A, b, k=2)) print(f"{name:8s} PR/r {before['pr_over_r']:.2f} top-2 energy {before['top2_energy_fraction']:.2f}" f" norm left after top-2 removal {after['unscaled_norm'] / before['unscaled_norm']:.2f}")
普通微调会把大部分更新集中在少数几个奇异方向上,因此去掉前两个方向就会剥离大部分更新。而分散式更新的谱是平坦的,所以同样的去除操作会留下大部分更新。PR/r,即 LoRA 秩上的参与率,也是论文中谱检测器的得分。
这段代码在 CPU 上运行大约需要一秒,且不下载任何内容。相同的代码位于 [`examples/quickstart.py`](https://github.com/js-lee-ai/refusal-relocates/blob/main/examples/quickstart.py),CI 会在每次推送时运行它。
要训练、修补和评估真实检查点,请安装 `models` 附加组件。```bash
pip install "refusal-relocates[models] @ git+https://github.com/js-lee-AI/refusal-relocates.git"
| 安装 | 添加 | 足以用于 |
|---|---|---|
pip install "git+https://github.com/js-lee-AI/refusal-relocates.git" | numpy | 谱核心、top-k 移除、检测器、拒绝评分器、refusal 命令 |
pip install "refusal-relocates[models] @ git+https://github.com/js-lee-AI/refusal-relocates.git" | torch, transformers, peft, accelerate, safetensors, scikit-learn, datasets | 在模型上进行训练、lockstep 修补、探针和评估 |
git clone 然后 pip install -e ".[models,test]" | pytest | experiments/、records/ 和 tests/ |
已在 Python 3.11.5、PyTorch 2.10.0、Transformers 4.57.3 和 PEFT 0.18.0 上测试。模型在 CUDA 设备上以 bfloat16 加载。
import refusal
data = refusal.load_data("data/prompt_sets.json") # built by refusal prepare, see below
prompts = data["advbench"][:40]
clean, tokenizer = refusal.load_model("meta-llama/Llama-3.1-8B-Instruct")
attacked, _ = refusal.load_model("meta-llama/Llama-3.1-8B-Instruct", adapter="runs/attack/adapter")
for layer in [6, 9, 12, 15, 18]: responses = refusal.lockstep_generate(clean, attacked, tokenizer, prompts, layer=layer) print(layer, sum(refusal.is_refusal(r) for r in responses) / len(prompts))
两个模型读取相同的 token,在选定的层,被篡改模型的输出被干净模型的输出替换。`refusal patch` 运行完整测量,包括其下限、上限和两个对照,使用困惑度门控和 Llama-Guard 对连贯拒绝进行评分,并报告过渡深度。
### 无需 GPU 修复并评分适配器```python
import refusal