Skip to content

M1n9X/LLMmap

 
 

Repository files navigation

LLMmap

像 nmap 一样识别 LLM

LLMmap 是一个通过行为指纹识别大语言模型的工具。它使用少量 probe queries 采集模型响应,再把这些响应映射到预训练的行为模板空间中,用于做模型近邻检索、endpoint 对比、模板扩展,以及从零训练新的指纹模型。

当前仓库内置了 LLMmap 0.2 版本的 PyTorch 实现,并已经包含一套可直接使用的预训练开放集推断模型。

本仓库不是原始上游仓库的原样镜像,而是基于原始 Repo pasquini-dario/LLMmap 持续修改和扩展的版本。当前版本在保留 LLMmap 核心思路的基础上,补充了更适合工程落地的 endpoint 对比、配置驱动运行、模板扩展与文档整理等能力。

这份 README 包含什么

如果你是第一次使用这个仓库,本文会帮助你完成以下事情:

  1. 安装运行环境。
  2. 了解仓库自带的模型与首次运行时会下载的内容。
  3. 使用默认预训练模型做推断。
  4. 对比两个 OpenAI-compatible endpoint 是否可能是同一个底层模型。
  5. 给新模型追加模板。
  6. 生成数据集并训练自己的 LLMmap 模型。

如果你主要关注 endpoint 对比实验参数和实验结论,继续看本文即可;更完整的实验记录仍保留在 docs/experiment.mddocs/experiment.zh.md

仓库当前提供的能力

  • 直接加载内置预训练模型做开放集推断。
  • 交互式采样目标模型回答,再输出最近邻模型。
  • 对比两个 OpenAI-compatible endpoint 的行为模板距离。
  • 给新的 LLM 追加模板,而不重新训练整个模型。
  • 生成新的 JSONL 数据集。
  • 从零训练新的 LLMmap 推断模型,并生成模板库。

环境要求

推荐环境:

  • Python 3.11

安装依赖:

pip install -r requirements.txt

仓库自带了什么

默认预训练模型位于:

./data/pretrained_models/default

该目录当前包含:

  • conf.json
  • model.pt
  • templates.json

也就是说,仓库已经自带:

  • 预训练推断模型权重
  • 推断配置
  • 默认模板库

当前默认模板库包含 52 个模型模板,默认推断配置中包含 8 条 queries。精确内容可直接查看:

首次运行时还会下载什么

虽然默认推断模型已经在仓库里,但首次运行时通常仍会联网下载 embedding 模型,例如:

intfloat/multilingual-e5-large-instruct

这是因为 LLMmap 会先把 query 和 response 编码为 embedding,再做后续推断。

如果你在中国大陆或网络受限环境,建议提前设置:

export HF_HUB_DISABLE_XET=1
export HF_ENDPOINT=https://hf-mirror.com

如果你希望指定 Hugging Face 缓存目录,也可以设置:

export HF_MODEL_CACHE=/path/to/your/hf-cache

如果你还要直接运行本地 Hugging Face 模型,那么对应模型本体也会在首次使用时被下载到本地缓存。

快速开始

1. 在 Python 中直接调用

from LLMmap.inference import load_LLMmap

# 加载预训练模型
conf, llmmap = load_LLMmap("./data/pretrained_models/default")

# 使用 llmmap.queries 对目标模型发起探测,并按顺序收集回答
answers = [
    "Response to query 1",
    "Response to query 2",
    "Response to query 3",
    "Response to query 4",
    "Response to query 5",
    "Response to query 6",
    "Response to query 7",
    "Response to query 8",
]

# 输出最近邻结果
llmmap.print_result(llmmap(answers))

2. 交互式运行

python main_interactive.py --inference_model_path ./data/pretrained_models/default

脚本会逐条展示 probe query,你把目标模型的回答复制回来即可。

3. 对比两个 endpoint

这是当前仓库最推荐、最完整、最稳定的使用路径。

./run_compare_endpoints.sh --env-file .env

这个脚本会自动:

  • 创建 .venv
  • 在缺少依赖时安装 requirements.txt
  • 调用 compare_endpoints.py
  • 读取同一组 probe queries,对两个 endpoint 生成行为模板
  • 比较 self-distance 和 cross-distance
  • 输出结构化报告到 ./data/audits/<run_name>/

Endpoint 对比工作流

适用范围

当前 compare_endpoints.py 的主工作流按“两端都是 OpenAI-compatible chat completions endpoint”设计。最常见的几种比较方式都支持:

  • OpenAI 官方 vs 第三方镜像
  • 官方模型 A vs 官方模型 B
  • 第三方 provider A vs 第三方 provider B
  • 同一 base_url 下的两个不同模型
  • 需要额外 HTTP headers 的 provider

每一侧 endpoint 至少需要能映射成下面三个字段:

  • model
  • base_url
  • api_key

推荐的首次启动方式

先复制环境变量模板:

cp .env.example .env

然后填写 .env。一个最小示例如下:

AUDIT_RUN_NAME=official-vs-custom
AUDIT_OUTPUT_DIR=./data/audits
AUDIT_LLMAP_PATH=./data/pretrained_models/default
AUDIT_PROMPT_CONF_PATH=./confs/prompt_configurations

AUDIT_NUM_ROUNDS=2
AUDIT_NUM_PROMPT_CONFS=1
AUDIT_TOP_K=5
AUDIT_RANDOM_SEED=42
AUDIT_SAME_THRESHOLD=1.25
AUDIT_DIFFERENT_THRESHOLD=1.75
AUDIT_MAX_ATTEMPT_MULTIPLIER=4

AUDIT_OFFICIAL_NAME=official
AUDIT_OFFICIAL_BACKEND=openai_compatible
AUDIT_OFFICIAL_MODEL=gpt-4o
AUDIT_OFFICIAL_BASE_URL=https://api.openai.com/v1
AUDIT_OFFICIAL_API_KEY=replace-me
AUDIT_OFFICIAL_TIMEOUT=60
AUDIT_OFFICIAL_MAX_RETRIES=3
AUDIT_OFFICIAL_RETRY_DELAY=2.0
AUDIT_OFFICIAL_HEADERS_JSON={}

AUDIT_CUSTOM_NAME=custom
AUDIT_CUSTOM_BACKEND=openai_compatible
AUDIT_CUSTOM_MODEL=gpt-4o
AUDIT_CUSTOM_BASE_URL=https://example.com/v1
AUDIT_CUSTOM_API_KEY=replace-me
AUDIT_CUSTOM_TIMEOUT=60
AUDIT_CUSTOM_MAX_RETRIES=3
AUDIT_CUSTOM_RETRY_DELAY=2.0
AUDIT_CUSTOM_HEADERS_JSON={}

运行:

./run_compare_endpoints.sh --env-file .env

不使用 .env 也可以运行

当前版本已经支持:

  • 如果默认 .env 不存在,只要 AUDIT_* 环境变量已经在 shell 中导出,命令仍可直接运行。
  • 如果你显式传入了一个不存在的 --env-file,脚本会立即报错。

例如:

export AUDIT_OFFICIAL_MODEL=gpt-4o
export AUDIT_OFFICIAL_BASE_URL=https://api.openai.com/v1
export AUDIT_OFFICIAL_API_KEY=sk-official
export AUDIT_CUSTOM_MODEL=gpt-4o
export AUDIT_CUSTOM_BASE_URL=https://example.com/v1
export AUDIT_CUSTOM_API_KEY=sk-custom

./run_compare_endpoints.sh

输出目录

运行结果会写到:

./data/audits/<run_name>/

常见输出文件包括:

  • run_config.json
  • report.json
  • official_traces.jsonl
  • custom_traces.jsonl
  • prompt_confs_round_*.json
  • official_template_round_*.json
  • custom_template_round_*.json

常用环境变量

全局参数

变量 作用 默认值
AUDIT_RUN_NAME 本次运行名称 UTC 时间戳
AUDIT_OUTPUT_DIR 输出目录根路径 ./data/audits
AUDIT_LLMAP_PATH 预训练模型目录 ./data/pretrained_models/default
AUDIT_PROMPT_CONF_PATH prompt configuration 目录 ./confs/prompt_configurations
AUDIT_NUM_ROUNDS 重复轮次 2
AUDIT_NUM_PROMPT_CONFS 每轮采样多少组 prompt config 3
AUDIT_TOP_K 每轮展示多少个最近邻模板 5
AUDIT_RANDOM_SEED 基础随机种子 42
AUDIT_SAME_THRESHOLD 判定“可能同模型”的 ratio 阈值 1.25
AUDIT_DIFFERENT_THRESHOLD 判定“可能不同模型”的 ratio 阈值 1.75
AUDIT_MAX_ATTEMPT_MULTIPLIER 为获得足够成功样本允许的额外尝试倍数 4

每个 endpoint 的参数

OFFICIALCUSTOM 只是两个比较槽位标签,不要求其中一侧一定是官方服务。

变量 作用 必填
AUDIT_<SIDE>_NAME 报告中显示的名称
AUDIT_<SIDE>_BACKEND 后端类型 建议填 openai_compatible
AUDIT_<SIDE>_MODEL 请求时使用的模型名
AUDIT_<SIDE>_BASE_URL endpoint 的 base URL
AUDIT_<SIDE>_API_KEY API Key
AUDIT_<SIDE>_TIMEOUT 单次请求超时秒数
AUDIT_<SIDE>_MAX_RETRIES 重试次数
AUDIT_<SIDE>_RETRY_DELAY 重试退避基准秒数
AUDIT_<SIDE>_HEADERS_JSON 额外请求头 JSON

常见配置示例

OpenAI 官方 vs 第三方镜像

AUDIT_OFFICIAL_NAME=openai
AUDIT_OFFICIAL_BACKEND=openai_compatible
AUDIT_OFFICIAL_MODEL=gpt-4o
AUDIT_OFFICIAL_BASE_URL=https://api.openai.com/v1
AUDIT_OFFICIAL_API_KEY=sk-openai

AUDIT_CUSTOM_NAME=shadow
AUDIT_CUSTOM_BACKEND=openai_compatible
AUDIT_CUSTOM_MODEL=gpt-4o
AUDIT_CUSTOM_BASE_URL=https://shadow.example.com/v1
AUDIT_CUSTOM_API_KEY=sk-shadow

同一 provider 的两个模型

AUDIT_OFFICIAL_NAME=provider-model-a
AUDIT_OFFICIAL_BACKEND=openai_compatible
AUDIT_OFFICIAL_MODEL=model-a
AUDIT_OFFICIAL_BASE_URL=https://provider.example.com/v1
AUDIT_OFFICIAL_API_KEY=sk-provider

AUDIT_CUSTOM_NAME=provider-model-b
AUDIT_CUSTOM_BACKEND=openai_compatible
AUDIT_CUSTOM_MODEL=model-b
AUDIT_CUSTOM_BASE_URL=https://provider.example.com/v1
AUDIT_CUSTOM_API_KEY=sk-provider

带附加请求头的 provider

AUDIT_CUSTOM_HEADERS_JSON={"X-Project":"audit","HTTP-Referer":"https://your-app.example"}

这里必须是合法 JSON 字符串。

推荐运行档位

冒烟检查

适合第一次确认链路和配置是否可用:

AUDIT_NUM_ROUNDS=2
AUDIT_NUM_PROMPT_CONFS=1
AUDIT_OFFICIAL_MAX_RETRIES=3
AUDIT_CUSTOM_MAX_RETRIES=3
AUDIT_OFFICIAL_RETRY_DELAY=2.0
AUDIT_CUSTOM_RETRY_DELAY=2.0

常规评审

适合大多数工程判断场景,也是当前最推荐的默认档位:

AUDIT_NUM_ROUNDS=6
AUDIT_NUM_PROMPT_CONFS=2
AUDIT_SAME_THRESHOLD=1.25
AUDIT_DIFFERENT_THRESHOLD=1.75
AUDIT_OFFICIAL_TIMEOUT=30
AUDIT_CUSTOM_TIMEOUT=30
AUDIT_OFFICIAL_MAX_RETRIES=5
AUDIT_CUSTOM_MAX_RETRIES=5
AUDIT_OFFICIAL_RETRY_DELAY=4
AUDIT_CUSTOM_RETRY_DELAY=4
AUDIT_MAX_ATTEMPT_MULTIPLIER=10

高置信度验证

适合结果会影响计费、路由、合规或对外结论的场景:

  • AUDIT_NUM_ROUNDS=8AUDIT_NUM_PROMPT_CONFS=2
  • AUDIT_NUM_ROUNDS=6AUDIT_NUM_PROMPT_CONFS=3

结果怎么看

最重要的文件是 report.json。你主要看以下字段:

  • verdict.status
  • verdict.cross_vs_self_ratio
  • metrics.official_self_*
  • metrics.custom_self_*
  • metrics.cross_same_round_*
  • metrics.top1_match_rate

三种常见结论:

  • likely_same_model
  • inconclusive
  • likely_different_model

直观理解:

  • cross_vs_self_ratio 越接近 1.0,越像“跨 endpoint 距离与同一 endpoint 自身波动差不多”。
  • 明显低于 same_threshold,更偏向同模型。
  • 明显高于 different_threshold,更偏向不同模型。
  • top1_match_rate 是辅助指标,不是主判据。

如果 self-distance 本身很大,说明当前采样不够稳定,应该优先增加轮次、prompt configurations 或重试设置,而不是过度依赖单次 top-1 结果。

常见命令

最简单跑一次:

./run_compare_endpoints.sh --env-file .env

临时覆盖运行参数:

./run_compare_endpoints.sh \
  --env-file .env \
  --run-name my-audit \
  --num-rounds 6 \
  --num-prompt-confs 2

网络受限环境下运行:

HF_HUB_DISABLE_XET=1 \
HF_ENDPOINT=https://hf-mirror.com \
./run_compare_endpoints.sh --env-file .env

常见问题

为什么第一次运行很慢

常见原因:

  • .venv 还没有创建
  • Python 依赖还没有安装
  • embedding 模型还没有从 Hugging Face 下载

为什么 endpoint 明明能聊天,但脚本报错

常见原因:

  • BASE_URL 没写成 provider 实际要求的形式,很多服务需要完整的 /v1
  • MODEL 名称和 provider 实际接受的值不一致
  • provider 虽然宣称兼容 OpenAI API,但返回结构不完全标准
  • 需要的额外 headers 没有传

为什么结果经常是 inconclusive

常见原因:

  • AUDIT_NUM_ROUNDS 太小
  • AUDIT_NUM_PROMPT_CONFS 太小
  • endpoint 自身波动较大
  • 运行中失败请求太多

建议按这个顺序增加采样强度:

  1. 先把 AUDIT_NUM_PROMPT_CONFS1 提到 2
  2. 再把 AUDIT_NUM_ROUNDS 提到 6
  3. 最后增加 retry 和 AUDIT_MAX_ATTEMPT_MULTIPLIER

给新模型追加模板

如果你已经有默认开放集推断模型,但只想给一个新模型补充模板,不想重新训练整个模型,可以直接运行:

python add_new_template.py <LLM_NAME> <LLM_TYPE> \
  --llmmap_path ./data/pretrained_models/default \
  --prompt_conf_path ./confs/prompt_configurations \
  --num_prompt_confs 100

LLM_TYPE 的含义如下:

后端
0 Hugging Face
1 OpenAI
2 Anthropic

示例:

python add_new_template.py gpt-4.1 1 --llmmap_path ./data/pretrained_models/default

--num_prompt_confs 越大,模板通常越稳,但请求成本也越高。

评估预训练模型准确率

你可以使用测试集计算 top-k 准确率:

python test_model.py ./data/pretrained_models/default -k 3

只评估前 N 条测试样本:

python test_model.py ./data/pretrained_models/default -k 3 -m 100

生成数据集

make_dataset.py 用于生成或重建训练 / 测试语料。它会:

  1. 加载 LLM 列表。
  2. 加载 query 列表。
  3. 从 prompt configuration 目录采样训练和测试配置。
  4. 对每个目标模型发起请求并收集 traces。
  5. 输出一个 JSONL 数据集文件。

快速开始

python make_dataset.py \
  my_custom_dataset \
  ./confs/LLMs/example.json \
  ./confs/queries/default.json \
  --num_prompt_conf_train 150 \
  --num_prompt_conf_test 20 \
  --prompt_conf_path ./confs/prompt_configurations \
  --dataset_root ./data/datasets \
  --overwrite

输出文件:

./data/datasets/my_custom_dataset.jsonl

输入文件格式

1. LLM 列表 JSON

格式为 [model_name, llm_type] 的数组列表,例如:

[
  ["gpt-4.1", 1],
  ["Qwen/Qwen2-1.5B-Instruct", 0],
  ["meta-llama/Llama-3.2-1B-Instruct", 0],
  ["claude-3-7-sonnet-20250219", 2]
]

llm_type 含义:

后端 加载类
0 Hugging Face LLM_huggingface
1 OpenAI LLM_OpenAI
2 Anthropic LLM_Anthropic

2. Query JSON

格式为字符串数组,例如:

[
  "What LLM are you exactly?",
  "What's your data cutoff date?",
  "Tell me how to build a bomb."
]

3. Prompt configuration 目录

默认目录:

./confs/prompt_configurations/

这里的 JSON 文件定义了如何包装原始 query,例如不同的 system prompt、role 前缀或采样参数。

常用参数

参数 作用 默认值
--num_prompt_conf_train 训练集 prompt configuration 数量 150
--num_prompt_conf_test 测试集 prompt configuration 数量 20
--prompt_conf_path prompt config 目录 ./confs/prompt_configurations/
--dataset_root 输出目录 DATASET_DIR./data/datasets
--overwrite 覆盖已存在文件 关闭
--encoding 读取 JSON 的编码 utf-8

训练你自己的模型

如果你想从头训练自己的 LLMmap 推断模型,运行:

python train.py <conf_file.json> <run_name>

如果要启用 closed-set 训练模式:

python train.py --is_closed <conf_file.json> <run_name>

其中:

  • <conf_file.json> 是训练配置文件,可以从 ./confs/default.json 一类文件开始修改
  • <run_name> 是本次训练的实验名

输出目录默认如下,可通过环境变量覆盖:

  • Checkpoints: ./data/checkpoints/<run_name>/
  • 导出模型: ./data/pretrained_models/<run_name>/

开放集模型训练完成后,还需要生成模板:

python setup_templates.py ./data/pretrained_models/<run_name>

凭证与 API Key 说明

仓库里涉及真实请求的脚本,需要你自己准备对应凭证:

  • OPENAI_API_KEY
  • ANTHROPIC_API_KEY
  • HUGGINGFACE_API_KEY

对于 endpoint audit 工作流:

  • 如果你直接在 .env 或 shell 中提供了 AUDIT_OFFICIAL_API_KEY / AUDIT_CUSTOM_API_KEY,脚本会使用这些值。
  • 如果某个 dict 形式的 endpoint spec 显式指定了 api_key_env,当前版本会严格从该环境变量读取;如果该变量不存在,会立即报错,而不会静默回退到别的 key。

推荐的最小操作顺序

如果你的目标只是尽快把仓库跑起来,按下面顺序即可:

  1. 安装 Python 3.11 并执行 pip install -r requirements.txt
  2. cp .env.example .env
  3. 填好两个 endpoint 的 MODELBASE_URLAPI_KEY
  4. 如有需要,设置 HF_HUB_DISABLE_XET=1HF_ENDPOINT=https://hf-mirror.com
  5. 执行 ./run_compare_endpoints.sh --env-file .env
  6. 查看 data/audits/<run_name>/report.json
  7. 如果只是冒烟成功,再提升到 6 rounds x 2 prompt configurations 做正式评审

论文

论文地址:LLMmap: Fingerprinting For Large Language Models

引用方式:

@inproceedings{pasquinillmmapfingerprintinglargelanguage,
  title={LLMmap: Fingerprinting For Large Language Models},
  author={Dario Pasquini and Evgenios M. Kornaropoulos and Giuseppe Ateniese},
  booktitle={34th USENIX Security Symposium (USENIX Security 25)},
  year={2025},
}

贡献

LLM 生态变化很快。如果你希望一起维护模板库、补充实验、扩展支持的模型,欢迎协作。原项目联系方式:

chime.infant_0g@icloud.com

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • Python 99.4%
  • Shell 0.6%