
بصمة نماذج LLM المتوافقة مع OpenAI من خلال إشارات المُرمِّز (tokenizer) والسلوك.

يبصم حزمة الخدمة الكامنة خلف نقطة نهاية محادثة متوافقة مع OpenAI.
يسجّل محاسبة المُرمِّز (tokenizer)، وإزاحة القالب المخفية، ونثر التحقق، وشكل JSON/SSE، وقبول الأدوار، والحدود المُسمّاة، وترويسات البوابة. لا يحمل الأوزان، ولا يخزّن مفاتيح API، ولا يسأل النموذج عن هويته.
| الاستيراد | lm_fingerprint |
| CLI | lm-fingerprint |
| ما هو | فحوصات بنية تحتية مُصدَّرة بإصدارات ضد /chat/completions. مكتبة تركيبية دون اتصال. تحقق محلي من مُرمِّز Hugging Face (بدون أوزان). |
| ما ليس هو | ليس هجوم تدرّج. ليس كسر حماية (jailbreak). ليس هوية خريطة الترميز (tokprint). ليس "أي ملف تنفيذي على هذا المنفذ" (Julius). |
للاستخدام المصرّح به فقط: نقاط النهاية التي تملكها، والمختبرات التي تتحكم بها، والمكافآت ضمن النطاق، واختبارات الاختراق المكتوبة. راجع SECURITY.md.
--api-key-envيسمّي متغير بيئة. لا يُسجَّل المفتاح أبدًا.
المحادثة المتوافقة مع OpenAI هي سلك شائع. vLLM وSGLang وبوابة مختبر
وموزّع إعادة بيع يمكنهم جميعًا التحدث بـ /chat/completions. حقل model هو تسمية.
يمكن للمضيف تبديل الواجهة الخلفية، أو تغليف المُرمِّز، أو وضع موجّه
في المقدمة. تتحرك فحوصات الشخصية عندما يتحرك موجه النظام.
ما يبقى ثابتًا هو السباكة: كيف يعدّ الخادم الرموز، وكم عدد رموز
القالب المخفية التي يضيفها، والنثر الذي كتبه مُدقِّقه، ولهجة SSE،
وأي الأدوار يقبل، والرقم الذي يسمّيه عندما يكون max_tokens سخيفًا،
وترويسات Server / المزوّد.
هذا هو السؤال الذي تجيب عنه هذه الأداة: أي حزمة تتعامل مع مسار المحادثة هذا؟ ليس أي نقطة تفتيش، وليس أي عملية مرتبطة بالمنفذ، وليس من كتب إكمالًا.
طرح ModelPrint السؤال نفسه في متصفح بتسعة فحوصات. هذه الحزمة هي صيغة CLI والمكتبة: فحوصات مُصدَّرة بإصدارات، ومكتبة قابلة للتسجيل، وأدلة زوجية، وانحراف، ومسار مُرمِّز محلي لا يستدعي أبدًا Inference API مستضافًا.
البصمة هي سجل JSON مُصدَّر بإصدار لقيم الفحوصات value. يجب أن يعيد كل فحص
القيمة نفسها عند ضرب الحزمة نفسها مرتين. تُجرَّد الطوابع الزمنية،
ومعرّفات الطلبات، والزمن الكامن، والمفاتيح.
تعيد أعداد المُرمِّز استخدام نصوص ModelPrint 1.0.0 (MIT، unclecode/modelprint)،
مطابقة بايتًا ببايت، ناقص أساس "a" بحرف واحد حتى يُلغى القالب المخفي.
تلك الأعداد الأربعة هي إسقاط لخريطة الترميز (T).
الأعداد المتساوية لا تعني (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 38 ProbeSpec rows (tokenizer / errors / shape / roles / limits / proxy / surface)
engine.py run suite → Fingerprint
schema.py schema_version=1, probe_suite_version=lm-fingerprint-probes-v2
similarity.py weighted exact-match, coverage, confidence, library rank, drift
align.py constant-shift MAE + residual on the 15-script suite
catalog.py offline supported_parameters twins
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.
| ما تملكه | ما يمكنك ملاحظته | ما تفعله هذه الأداة |
|---|---|---|
| عنوان URL أساسي متوافق مع OpenAI مصرّح به + مفتاح | HTTP للدردشة: الاستخدام، الأخطاء، الترويسات، SSE | fingerprint / compare / match / drift |
| ملفات tokenizer محلية | encode و chat_template | fingerprint-hf / verify-hf. تبقى الأوزان على القرص |
| لا شيء سوى host:port | Banner / /health / /api/tags | خارج النطاق. استخدم Julius |
التطابق يعني بنية تحتية مشتركة. يمكن لمختبر واحد أن يخدم نقطتي تحقق على حزمة واحدة. يمكن لموجّه أن يجيب بمغلّف الخطأ الخاص به. توافق العدّ ليس هوية (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 المحلية إذا لم يكن tokenizer مخزّنًا مؤقتًا.
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. هذه عناصر اختبار ثابتة، وليست
مزوّدين مجلوبين آليًا. قارن بين اثنين منها دون اتصال بالشبكة:
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.62. تتطابق عدّادات 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