Downloads · 30 days
374
44% of all-time downloads
AndrewAndrewsen/distilbert-secret-masker-v3.3a-rs
distilbert-secret-masker-v3.3a-rs is a token classification model from AndrewAndrewsen. Use it when you need labels on individual words, such as names. It is set up for transformers. The card lists the license as apache-2.0.
Recommended standalone checkpoint. A DistilBERT token-classification model that finds secrets (credentials, tokens, keys, passwords) in code and text and emits character spans for masking. This card documents the v3.3…
Downloads · 30 days
374
44% of all-time downloads
All-time downloads
854
Public
Parameters
66.4M
265 MB on disk
Likes
2
Public
Click a slice to open those files.
.safetensors265 MB · 100%
From the Hugging Face model README
Recommended standalone checkpoint. A DistilBERT token-classification model that finds secrets (credentials, tokens, keys, passwords) in code and text and emits character spans for masking. This card documents the v3.3a-RS revision and supersedes the older v2-era documentation (which reported NER F1 ~0.52 and a 512-token limit — both outdated; see Changes below).
Recommended current standalone release: v3.3a-RS.
Previous release:AndrewAndrewsen/distilbert-secret-masker— kept for reproducibility.
O, B-SECRET, I-SECRET)v3.2 real-code precision fix (public DistilBERT collapse 0.004 -> 0.53)
v3.3a-1 data+loss revision; stronger on some STRUCTURED lookalikes
v3.3a-RS ← current recommended standalone
Two negative/selection results are part of this model's provenance and are reported deliberately:
Out of scope: a guarantee of finding all secrets; standalone compliance gating; chat/log/prose is weaker than source code (see Limitations).
All evaluation is on frozen real code held out from training (repo-disjoint). Benchmarks B/C/D are observed regression sets — repo-disjoint from training, but watched repeatedly during development, so they are not blind. RealCode-1 (below) is the purpose-built, never-observed adjudicator. Headline metric is strict exact span + line (exact character span AND correct line); file-level and line-level are also reported because rule scanners are line/file detectors, not span labelers.
| set | files (pos/total) | strict span+line P/R/F1 | line P/R/F1 | file P/R/F1 |
|---|---|---|---|---|
| Benchmark B (non-pattern real OSS) | 153/300 | 0.739/0.545/0.627 | 0.850/0.597/0.701 | 0.982/0.719/0.830 |
| Benchmark C (non-pattern real OSS) | 128/275 | 0.735/0.626/0.676 | 0.851/0.697/0.766 | 0.954/0.805/0.873 |
| Benchmark D (regex-friendly real OSS) | 150/300 | 0.714/0.680/0.696 | 0.935/0.898/0.916 | 0.979/0.927/0.952 |
Note the strict F1 is corpus-stable (0.63–0.70) while rule scanners swing 0.4→0.9 with corpus regex-friendliness.
| dataset | P | R | F1 |
|---|---|---|---|
| CodeSecret (balanced code) | 1.000 | 0.892 | 0.943 |
| Prowl (code & English slice) | 0.874 | 0.826 | 0.849 |
| Prowl (all sources/langs) | 0.848 | 0.651 | 0.736 |
Prowl by source F1: code 0.850 > jira 0.722 > slack 0.675 > confluence 0.645 > log 0.532; non-English recall 0.46 (precision 0.97). Source code is the strong domain; chat, logs, and non-English prose are weaker. This is row-level detection on a synthetic multilingual set, not the strict-span metric used for the headline numbers.
| tool | B | C | D |
|---|---|---|---|
| gitleaks | 0.500 / 0.393 | 0.431 / 0.381 | 0.948 / 0.885 |
| detect-secrets | 0.641 / 0.407 | 0.679 / 0.365 | 0.953 / 0.891 |
| trufflehog | 0.099 / n/a* | 0.231 / n/a* | 0.736 / n/a* |
| semgrep | 0.145 / 0.058 | 0.171 / 0.072 | 0.527 / 0.421 |
| v3.3a-RS | 0.830 / 0.701 | 0.873 / 0.766 | 0.952 / 0.916 |
v3.3a-RS is the only tool strong in both regimes: it dominates on non-pattern code (B/C) and ties/leads the best rule tool on regex-friendly code (D). trufflehog line-level not reliably recoverable in this harness; semgrep hit parse errors on some files.
These results were produced with SecMask's manual sliding-window inference
(tokenize once without truncation → (max_len−2)-piece windows with stride 128 →
per-WordPiece BIO decode → char spans in the original text; first window wins on
overlap). span_infer.py is included in this repo; the full SecMask toolchain and benchmarks are at https://github.com/AndrewAndrewsen/secmask .
A plain
transformers.pipeline("token-classification", ...)call does not reproduce this behavior on documents beyond 512 tokens and does not apply the frozen span aggregation / threshold — it will not match these benchmarks. Use the SecMask inference path as the reference.
from span_infer import load_model, infer_spans
tok, model, id2label = load_model("AndrewAndrewsen/distilbert-secret-masker-v3.3a-rs")
spans, _ = infer_spans(text, tok, model, id2label, mode="threshold", tau=0.99)
# spans: [{"start","end","line","value","score"}]
PREREG_* + REALCODE1_FREEZE.json).