
토크나이저와 동작을 기반으로 대규모 언어 모델(LLM)을 핑거프린팅하는 고유한 도구입니다.

OpenAI 호환 채팅 엔드포인트 뒤에 있는 서빙 스택을 지문화합니다.
토크나이저 회계, 숨은 템플릿 오프셋, 검증 문구, JSON/SSE 형태, 역할 수용 여부, 명명된 한도, 게이트웨이 헤더를 기록합니다. 가중치를 로드하지 않으며, API 키를 저장하지 않고, 모델에게 자신이 누구인지 묻지 않습니다.
| 가져오기 | lm_fingerprint |
| CLI | lm-fingerprint |
| 용도 | /chat/completions에 대한 버전 관리된 인프라 프로브. 오프라인 합성 라이브러리. 로컬 Hugging Face 토크나이저 검증(가중치 없음). |
| 아님 | 그레이디언트 공격이 아님. 탈옥이 아님. 인코드 맵 식별(tokprint)이 아님. "이 포트에 어떤 바이너리가 있는지"가 아님(Julius). |
승인된 사용만 가능합니다: 소유한 엔드포인트, 관리하는 랩, 범위 내 버그 바운티, 서면 계약된 펜테스트. SECURITY.md를 참조하십시오.
--api-key-env는 환경 변수를 지정합니다. 키는 절대 로그에 남지 않습니다.
OpenAI 호환 채팅은 흔한 배선(wire)입니다. vLLM, SGLang, 연구소 게이트웨이, 리셀러 모두 /chat/completions로 통신할 수 있습니다. model 필드는 라벨일 뿐입니다. 호스트는 백엔드를 바꾸거나, 토크나이저를 감싸거나, 앞에 라우터를 둘 수 있습니다. 성격 프로브는 시스템 프롬프트가 움직이면 함께 움직입니다.
그 자리에 남는 것은 배관(plumbing)입니다: 서버가 토큰을 세는 방식, 추가하는 숨은 템플릿 토큰 수, 검증기가 작성한 산문, SSE 방언, 수용하는 역할, max_tokens이 터무니없을 때 응답하는 숫자, Server / 공급자 헤더.
이 도구가 답하는 질문이 바로 그것입니다: 이 채팅 경로를 처리하는 스택은 무엇인가? 어떤 체크포인트인지, 어떤 프로세스가 포트에 바인딩되어 있는지, 누가 완성본을 작성했는지는 묻지 않습니다.
ModelPrint는 브라우저에서 아홉 개의 프로브로 같은 질문을 했습니다. 이 패키지는 그 CLI 및 라이브러리 형태입니다: 버전 관리된 프로브, 등록 가능한 라이브러리, 쌍별 증거, 드리프트, 그리고 호스팅된 Inference API를 호출하지 않는 로컬 토크나이저 경로.
지문은 프로브 value 들의 버전 관리된 JSON 레코드입니다. 동일한 스택을 두 번 호출하면 각 프로브는 동일한 값을 반환해야 합니다. 타임스탬프, 요청 ID, 지연 시간, 키는 제거됩니다.
토크나이저 카운트는 ModelPrint 1.0.0 텍스트(MIT, unclecode/modelprint)를 바이트 단위 그대로 재사용하며, 숨은 템플릿이 상쇄되도록 한 글자 "a" 기준값을 뺍니다. 이 네 숫자는 인코드 맵 (T)의 **투영(projection)**입니다. 카운트가 같다고 해서 (T_1 \equiv T_2)는 아닙니다. GPT-2와 OPT는 이들에서 충돌하지만, rust 파이프라인 해시는 그렇지 않습니다.
hf_identity(로컬 HF 경로 전용)는 해당 파이프라인 커밋먼트와 채팅 템플릿 해시의 SHA-256입니다. 동일한 (T)와 동일한 템플릿이 일치합니다(tiny-gpt2 / gpt2). 이는 체크포인트가 아니라 계열 + 템플릿입니다.
구조:
src/lm_fingerprint/
cli.py argparse. --api-key-env only. No --api-key.
client.py HttpTransport, InProcessTransport, redact_secrets
probes.py 23 ProbeSpec rows (tokenizer / errors / shape / roles / limits / proxy)
engine.py run suite → Fingerprint
schema.py schema_version=1, probe_suite_version=lm-fingerprint-probes-v1
similarity.py weighted exact-match, coverage, confidence, library rank, drift
library.py enroll / match. Packaged rows are synthetic fixtures
synthetic.py in-process stacks for tests and the shipped library
hf.py local AutoTokenizer + named validation profile. No weights
localmap.py encode-pipeline-v2 commitment (rust tokenizer.json)
proof.py measured ModelPrint 9-probe identity
report.py text reports
data/library.json
동일한 프로브 스위트로 들어가는 두 경로:
live endpoint local Hub tokenizer (optional [hf])
| |
HttpTransport.chat HfChatTransport
POST /chat/completions encode / chat_template for counts
| synthetic profile for errors/shape
+------------------+----------------------+
|
engine.run_probes
|
Fingerprint (JSON, keyless)
|
compare | match | drift | enroll
프로브 작성: docs/PROBES.md. 모듈 맵: docs/ARCHITECTURE.md.
일치란 공유 인프라를 의미합니다. 하나의 연구소가 하나의 스택에서 두 체크포인트를 서빙할 수 있습니다. 라우터는 자체 오류 래퍼로 응답할 수 있습니다. 카운트 일치는 (T)의 동일성을 뜻하지 않습니다.
Python 3.10+. 핵심 런타임은 표준 라이브러리입니다.
git clone https://gitlab.com/WattoCyber/lm-fingerprint.git
cd lm-fingerprint
pip install -e ".[dev]"
PYTHONPATH=src python3 scripts/repro.py
REPRO_OK가 출력되어야 합니다. 이 게이트는 오프라인입니다: GPU 없음, 프로덕션 API 없음. 로컬 HF 테스트는 토크나이저가 캐시되어 있지 않으면 건너뜁니다.
pip install -e ".[hf]" # transformers, for fingerprint-hf / verify-hf
lm-fingerprint list-probes
lm-fingerprint list
list는 패키징된 스택을 출력합니다: openai-chat-strict, glm-compat, router-openai, permissive-compat. 이들은 픽스처(fixture)이지 스크래핑된 프로바이더가 아닙니다. 네트워크 없이 둘을 비교해 보세요:
from lm_fingerprint.client import InProcessTransport
from lm_fingerprint.engine import fingerprint_endpoint
from lm_fingerprint.similarity import compare_fingerprints
from lm_fingerprint.synthetic import SYNTHETIC_STACKS, handler_for
def fp(stack_id):
t = InProcessTransport(handler_for(stack_id), headers=SYNTHETIC_STACKS[stack_id].headers)
return fingerprint_endpoint(t, model=f"synthetic/{stack_id}", base_url=f"inprocess://{stack_id}")
print(compare_fingerprints(fp("openai-chat-strict"), fp("router-openai"))["note"])
같은 단어 토크나이저, 다른 오류와 헤더. 점수는 0.58 부근에 머뭅니다. ModelPrint의 네 카운트는 일치하지만, 이 도구는 그것을 공유 스택이라고 부르지 않습니다.
lm-fingerprint fingerprint \
--base-url https://your-lab.example/v1 \
--model the-label \
--api-key-env OPENAI_API_KEY \
--out lab.json
lm-fingerprint match --fingerprint lab.json
lm-fingerprint enroll --fingerprint lab.json --stack-id my-lab --library my-lib.json
키를 명령줄에 전달하지 마십시오. 공용 라이브러리를 채우기 위해 프로덕션 API를 스크래핑하지 마십시오.
lm-fingerprint fingerprint-hf --model sshleifer/tiny-gpt2 --local-files-only
lm-fingerprint verify-hf --local-files-only
카운트는 템플릿이 있으면 apply_chat_template에서, 그렇지 않으면 encode(..., add_special_tokens=False)에서 가져옵니다. 오류 분류는 이름이 지정된 합성 프로필(기본값 openai-chat-strict)에서 오므로 실행은 오프라인으로 유지됩니다. 원격 핸들(https://, api://, …)은 거부됩니다.
lm-fingerprint list-probes
lm-fingerprint list [--library PATH]
lm-fingerprint fingerprint --base-url URL --model MODEL --api-key-env VAR [--out PATH]
lm-fingerprint fingerprint-hf --model HANDLE [--profile NAME] [--local-files-only]
lm-fingerprint verify-hf [--models a,b,c] [--local-files-only]
lm-fingerprint prove [--local-files-only]
lm-fingerprint compare --a a.json --b b.json
lm-fingerprint match --fingerprint a.json [--library PATH]
lm-fingerprint drift --baseline old.json --current new.json
lm-fingerprint enroll --fingerprint a.json --stack-id ID --library PATH
lm-fingerprint export --fingerprint a.json
--api-key 플래그는 없습니다. 이전 버전의 wireprint-fingerprint / stackprint-fingerprint JSON도 여전히 로드됩니다.
from lm_fingerprint import (
StackLibrary,
compare_fingerprints,
fingerprint_endpoint,
fingerprint_hf,
match_library,
)
from lm_fingerprint.client import HttpTransport
fp = fingerprint_endpoint(HttpTransport(url, api_key=key), model="x", base_url=url)
hit = match_library(fp, StackLibrary.load())
local = fingerprint_hf("sshleifer/tiny-gpt2", local_files_only=True)
schema_version = 1, probe_suite_version = lm-fingerprint-probes-v1.
비교: 양쪽에서 ok이고 stable인 프로브에 대한 가중 정확히 일치(weighted exact-match). 신뢰도는 score × coverage입니다. 라이브러리 매치는 certainty(exact / strong / possible / unknown)와 두 번째 이웃과의 차이(margin)를 보고합니다.
다시 실행:
lm-fingerprint prove --local-files-only
ModelPrint와 동일한 잔여물입니다(probes/index.js의 아홉 프로브). 그들의 README가 점수 규칙입니다: 일치하는 지문은 정체성이 아니라 공유 인프라를 증명합니다.
상세 문서: docs/PROOF.md.
fingerprint-hf는 가중치를 로드하지 않으며 호스팅된 Inference를 호출하지 않습니다.--api-key-env에서 가져옵니다. 산출물에 sk- 또는 Authorization이 포함되어서는 안 됩니다.scripts/repro.py가 제품 게이트입니다. 방금 실행하지 않았다면 그린(green)이라고 주장하지 마십시오.MIT. LICENSE를 참조하십시오. ModelPrint 토크나이저 텍스트는 MIT(unclecode/modelprint)이며 바이트 단위로 정확하게 유지됩니다.
| 당신이 가진 것 | 관찰할 수 있는 것 | 이 도구가 하는 일 |
|---|
| 승인된 OpenAI 호환 base URL + 키 | 채팅 HTTP: 사용량, 오류, 헤더, SSE | fingerprint / compare / match / drift |
| 로컬 토크나이저 파일 | encode 및 chat_template | fingerprint-hf / verify-hf. 가중치는 디스크에 남습니다 |
| 호스트:포트 외에는 없음 | 배너 / /health / /api/tags | 범위 밖. Julius 사용 |
| 필드 | 의미 |
|---|
kind | lm-fingerprint |
target.model / target.base_url_host | 가리킨 대상. 호스트만; 키 없음 |
features.tokenizer_norm | 네 가지 ModelPrint급 카운트(영어, 중국어, 코드, 이모지) |
features.template_offset | 숨은 서빙 템플릿 크기 |
probes.<id>.value | 비교 가능한 셀. 안정적이어야 함 |
probes.<id>.weight | 유사도에 대한 기여도 |
keys_stored | 항상 false |
weights_loaded | 항상 false |
| 테스트 | ModelPrint | 이 도구 |
|---|
동일한 토크나이저, 다른 스택(openai-chat-strict vs router-openai) | 토크나이저 4/4 + 템플릿 일치 | 점수 0.58, 공유 회계(shared accounting)로 표시 |
gpt2 vs facebook/opt-125m | 네 카운트 및 템플릿 충돌 | encode_commitment가 구분 |
| Qwen2 / 2.5 / 3 | 토크나이저 4/4 충돌; 템플릿 구분 | hf_identity가 구분 |
tiny-gpt2 vs gpt2 | 일치(동일한 (T)) | 일치(필수) |
| 프로브 세트 | 9 | 23 + HF 인코드/템플릿 커밋먼트 |
logprobs, 스트림 형태, 시스템 역할 | 아이디어로 나열됨 | 제공됨 |
| 도구 | 대상 |
|---|
| ModelPrint | 동일한 잔여물, 브라우저, 아홉 개의 프로브 |
| tokprint | 로컬 인코드 맵 계열 ID. gradient-untangler에 포함 |
| gradient-untangler | 로컬 가중치를 통한 그레이디언트 |
| Julius | 포트에서 실행 중인 서버 소프트웨어 식별 |
| TokenPrint / LLMmap / UTF | 생성된 텍스트, 계보(lineage) 또는 이식된 토큰 |