面向分类模型的 Label-Only 成员推理风险审计工具,融合边界搜索、影子模型信号与 Docker 化本地部署。系统接入图像分类模型预测接口,在无需目标模型梯度、参数或概率分数的条件下,批量评估样本训练集成员风险并生成可复核审计报告。
命名说明:本仓库和正式项目名称统一为 Label-Only-MIA-Go;Web 控制台、HTML 报告和运行日志中的 LabelScan-Go 是本项目的工具展示名称,用于指代本地审计控制台与报告系统。
Label-Only-MIA-Go 的理论基础来源于 ACM CCS 2021 论文 Membership Leakage in Label-Only Exposures。项目聚焦成员推理攻击(Membership Inference Attack, MIA):在只能访问模型预测标签、无法获取梯度、参数或概率分数的条件下,判断某个样本是否可能参与过目标模型训练。相比只保留论文实验流程的原型代码,本项目将边界攻击、影子模型信号、并发调度、RESTful 接入和 Docker 部署整理为一个可本地复现、可扩展接入外部模型的审计工具。
真实模型服务通常不会暴露训练过程、梯度或中间层特征,很多场景下用户只能获得分类标签。传统依赖置信度或概率分数的成员推理方法在这种条件下难以使用,因此本项目采用两类互补信号完成审计:
系统最终输出的是“成员风险等级”和对应证据指标,而不是对训练集归属的确定性断言。目标模型准确率、数据分布、查询预算和影子模型质量都会影响结果,报告应作为安全审计和人工复核的依据。
项目采用 Go + Python 的解耦式架构:
选择 Go 重写核心审计流程,主要是因为边界搜索和批量审计包含大量独立 HTTP 请求。Go 的 goroutine 和 worker pool 能较自然地处理高并发网络 I/O,也更适合把攻击流程、模型客户端、数据读取和报告输出拆成可维护的工程模块。Python 继续承担模型加载和训练相关工作,以保留 PyTorch 生态的便利性。
推荐使用 Docker 运行。Windows、macOS 和 Linux 均可使用 Docker Desktop 或 Docker Engine;Windows 用户建议开启 WSL2 后端。
git clone <repository-url>
cd Label-Only-MIA-Go
docker compose up --build
需要在包含 docker-compose.yml 的项目根目录执行命令。项目可以放在任意本地路径,但仓库内部目录结构应保持不变,否则模型权重、数据、配置和报告输出路径可能无法正确匹配。
http://localhost:8080
页面加载后,可以先点击“检查服务状态”,确认 Target Oracle 和 Shadow Oracle 均可访问;随后选择审计模式和样本规模,点击“运行风险评估”即可生成结果。
审计完成后会生成:
output/web_audit_report.json
output/web_audit_report.html
Web 页面会展示样本级风险、准确率、精确率、召回率、高风险比例等汇总指标;HTML 报告保留 shadow loss、边界距离、波动系数和每个样本的判定证据,便于后续复核。
full 是默认模式,会同时使用边界攻击信号和影子模型 loss 信号,适合仓库内置 CIFAR-10 示例模型,或已经完成影子模型训练与阈值校准的外部任务。
boundary-only 只调用目标模型的 label-only 接口,不要求 Shadow 服务在线。该模式适合接入外部 API 时做快速初筛,但证据弱于 full 模式,输出结果应理解为边界行为风险提示。
Web 控制台中的样本规模对应一组运行参数:
| 预设 | 用途 | 成员/非成员样本 | 校准规模 | 查询预算 |
|---|---|---|---|---|
smoke |
快速自检,确认服务、路径和报告生成流程是否正常 | 1 / 1 | 10 个候选样本,取 1 个有效路人样本 | 最大 800 次查询,8 轮边界迭代 |
standard |
常规审计,兼顾速度和结果稳定性 | 50 / 50 | 100 个候选样本,取 10 个有效路人样本 | 最大 5000 次查询,40 轮边界迭代 |
extended |
扩展审计,使用更多样本和更充分的现场校准 | 100 / 100 | 200 个候选样本,取 20 个有效路人样本 | 最大 5000 次查询,40 轮边界迭代 |
custom |
自定义运行参数 | 以页面或命令行输入为准 | 以页面或命令行输入为准 | 以页面或命令行输入为准 |
日常检查建议先运行 smoke;确认服务稳定后再使用 standard;需要更充分的报告材料时使用 extended。
默认选择“内置 Docker 模型服务”,此时 Target API 与 Shadow API 指向本地容器服务,可以直接复现仓库内置流程。
如需接入外部模型,可选择“外部兼容 API”,并填写外部服务地址。Target 服务至少需要提供 label-only 分类接口;如果使用 full 模式,还需要可用的 Shadow 服务和匹配的阈值配置。
成员推理攻击关注的问题是:一个样本是否曾被目标模型用于训练。训练集成员往往位于模型更熟悉的决策区域,预测行为可能更稳定、更接近模型记忆边界。Label-only 场景进一步限制攻击者只能看到分类标签,因此本项目不依赖目标模型概率分数,而是从“决策边界几何特征”和“影子模型行为特征”两条路径提取证据。
边界攻击用于估计样本到目标模型决策边界的距离。本项目基于 HopSkipJump Attack 思路,对原始样本和若干轻微扰动版本并发执行边界搜索,得到平均边界距离和局部波动系数。一般来说,若样本处在目标模型更稳定的区域,可能需要更大的扰动才会改变预测标签;若样本靠近边界,则更容易在扰动下发生类别变化。
为了让边界信号更适合样本级审计,系统会先选取一批确定未参与训练的“路人样本”做现场定标,统计其边界距离均值与波动情况,并据此生成动态距离阈值和稳定性阈值。这样可以减少不同模型、不同数据分布造成的固定阈值偏差。
影子模型用于模拟目标模型的成员化行为。系统会读取 shadow_config.json 中的阈值配置,并根据样本在影子模型上的 loss 判断其成员风险。loss 越低,通常说明影子模型对该样本越熟悉;如果这种熟悉程度显著超过阈值,就会形成迁移攻击证据。
需要注意的是,影子模型不是越强越好。过度拟合的影子模型可能把所有训练标签都记住,导致 loss 接近 0,反而失去区分能力。本项目更关注影子模型是否能稳定模拟目标模型的决策轮廓。
单一信号容易受目标模型精度、样本难度、数据分布偏移和查询预算影响。本项目采用融合判定逻辑:当边界信号与 shadow loss 同时支持成员风险时,输出更高风险等级;当仅有单侧证据较强时,降级为疑似风险;当原图预测错误、边界距离异常或证据不足时,输出较低风险。
这种设计让报告不只给出一个结论,还能展示结论背后的证据来源,便于安全审计人员复核。
本项目支持把外部分类模型封装成兼容的 HTTP 服务后接入。推荐接口如下:
GET /health
POST /predict
POST /predict_batch
POST /predict_logits
Target 服务至少需要实现:
GET /health
POST /predict
POST /predict_batch
Shadow 服务在 full 模式下需要实现:
GET /health
POST /predict_logits
请求体示例:
{
"image": [0.0, 0.1, 0.2]
}
返回体示例:
{
"label": 3,
"logits": [0.1, 0.2, 1.8]
}
当前内置 CIFAR-10 示例使用长度为 3072 的展平图像向量。接入其他模型时,输入向量长度、归一化方式、标签空间和数据分布需要与外部模型保持一致。
完整接入外部模型通常分三步:
boundary-only 验证调用稳定性。shadow_config.json,再切换到 full 模式运行完整审计。如果暂时无法训练影子模型,也可以只使用 boundary-only 模式进行初步风险扫描,但结论应保守解释。
启动 Web 控制台:
docker compose up --build
运行一次容器内 CLI 审计:
docker compose --profile cli run --rm audit-runner
本地运行 Go Web 服务:
go run . --serve
本地运行快速审计:
go run . --preset smoke
指定外部 API 地址:
go run . --serve \
--audit-mode full \
--target-api http://localhost:8000 \
--shadow-api http://localhost:8001
重新生成影子模型阈值:
cd python_server
python calc_thresholds.py
.
├── main.go # CLI 与 Web 控制台入口
├── docker-compose.yml # 本地完整服务编排
├── docker/ # Go 与 Python 镜像构建文件
├── pkg/attack/ # 边界攻击实现
├── pkg/audit/ # 风险信号与融合逻辑
├── pkg/client/ # HTTP 模型客户端
├── pkg/dataset/ # CIFAR-10 数据读取
├── pkg/mathutils/ # loss、距离、统计工具
├── pkg/worker/ # 并发审计任务池
├── python_server/server.py # PyTorch 模型推理服务
├── python_server/classifier.py # CNN 模型定义
├── python_server/calc_thresholds.py# 影子模型阈值计算
├── scripts/evaluation/ # 可选评估与成员索引导出脚本
├── shadow_config.json # 当前影子模型阈值
└── target_members.json # 当前目标模型成员索引
shadow_config.json,否则 loss 阈值与模型不匹配。smoke 模式。python_server/server.py,或另行构建 CUDA 版镜像。本项目源码采用 MIT License 发布,详见 LICENSE。
第三方依赖、容器基础镜像、数据集与模型资产的许可说明见 THIRD_PARTY_LICENSES.md。CIFAR-10 等第三方数据资产不由本项目许可证重新授权,使用者应遵循其原始发布条款。
$ claude mcp add Label-Only-MIA-Go \
-- python -m otcore.mcp_server <graph>