Evidence ledger
One row per claim in Keep the format dumb: ten years of Hugging Face, measured from its own releases: who published it, what grade it carries, when it was written, when the link was last checked, and the quote or figure it rests on. Nothing in the guide is cited from memory, so anything not in this table is not in the guide.
Field guide: Keep the format dumb: ten years of Hugging Face, measured from its own releases. Research date 2026-09-18. Every URL below was fetched during that session.
A note on the collection method, because it shapes everything
This session's network egress policy blocked every engineering-blog, video, paper and vendor
host it was pointed at, including huggingface.co, discord.com, scylladb.com, thenewstack.io,
infoq.com, arxiv.org, issues.apache.org, web.archive.org and youtube.com. Five hosts
answered: github.com, raw.githubusercontent.com, pypi.org, files.pythonhosted.org,
crates.io and registry.npmjs.org.
The guide is therefore built from repositories, package registries and published release artefacts only. Nothing here is cited from memory, and nothing is cited that was not fetched. Two consequences the reader should hold onto:
- There are no engineering-blog, talk or paper sources in this guide. Not because none exist for this topic, but because none were reachable. Where the public narrative account would normally be the evidence, this guide substitutes the artefact the narrative describes.
- Several rows are measurements I made, not claims anyone published. They are marked
measured (this guide)and the exact procedure is in the guide's "Keep hunting" section so anyone can reproduce or refute them.
Grading convention
Tiers follow references/evidence.md. Two judgement calls, stated so they can be disagreed with:
- GitHub security advisories are graded
postmortem. Each one records what happened when a design met reality: the false assumption, the mechanism, the affected versions and the structural fix. That is the postmortem's job. They are not incident narratives and carry no timeline or blast radius, so every claim drawn from them is limited to mechanism and fix. - PyPI yank notices are graded
postmortemas well. A yank is a maintainer withdrawing a shipped release and writing down why, in public, with a date. It is the shortest postmortem there is.
| # | Org | Title | Tier | Published | Checked | URL | Claim I take from it | Supporting quote or figure |
|---|---|---|---|---|---|---|---|---|
| 1 | PyPI / community | transformers 0.1 |
source | 2016-08-17 | 2026-09-18 | https://pypi.org/project/transformers/0.1/ | The name transformers on PyPI predates Hugging Face by three years and belonged to an unrelated project |
summary: "Experimental module for AST transformations."; author "Vladimir Iakovlev"; home page https://github.com/nvbn/__transformers__ |
| 2 | Hugging Face | pytorch-pretrained-bert release history |
source | 2018-11-17 to 2019-04-25 | 2026-09-18 | https://pypi.org/project/pytorch-pretrained-bert/ | The library shipped first as a single-model package | 10 releases, first 0.1.1 on 2018-11-17, last 0.6.2 on 2019-04-25; summary "PyTorch version of Google AI BERT model with script to load Google pre-trained models" |
| 3 | Hugging Face | pytorch-transformers release history |
source | 2019-07-05 to 2019-09-04 | 2026-09-18 | https://pypi.org/project/pytorch-transformers/ | The second name lasted two months and named its models in the summary | 4 releases; summary lists "BERT & RoBERTa, GPT & GPT-2, Transformer-XL, XLNet and XLM" |
| 4 | Hugging Face | transformers release history |
source | 2019-09-26 to 2026-09-09 | 2026-09-18 | https://pypi.org/project/transformers/ | The third name is the durable one; 242 releases; v2.0.0 on 2019-09-26, v5.17.0 on 2026-09-09 | major-version first uploads: 2.0.0 2019-09-26, 3.0.0 2020-06-29, 4.0.0rc1 2020-11-19, 5.0.0rc0 2025-12-01, 5.0.0 2026-01-26 |
| 5 | Hugging Face | transformers yanked releases |
postmortem | 2021-12-15 to 2026-06-03 | 2026-09-18 | https://pypi.org/project/transformers/ | The library's public failure record is its yank reasons | 5.10.0: "We pushed from a week old main branch. It does include the latest model but uncertain its gonna be working properly and mostly it is missing a bunch of fixes!"; 4.57.0: "Error in the setup causing installation issues"; 4.46.0: "This version unfortunately does not work with 3.8 but we did not drop the support yet" |
| 6 | Hugging Face | hf-xet yanked release 1.2.1 |
postmortem | 2025-11-21 | 2026-09-18 | https://pypi.org/project/hf-xet/ | A default-on cache regression shipped in the storage client | yanked_reason: "This release contains a regression that enables the disk cache by default." |
| 7 | Hugging Face | huggingface-hub yanked releases |
postmortem | 2022-06-16 to 2026-05-26 | 2026-09-18 | https://pypi.org/project/huggingface-hub/ | Release-process failures dominate the withdrawal record, not code defects | 0.26.4: "The version contains duplicate code with huggingface-hub==0.26.5 and includes unnecessary code that was accidentally merged."; 1.16.3: "Companion hf CLI package was not published for this version." |
| 8 | Hugging Face | huggingface-hub dependency metadata across releases |
source | 2025-03-27 to 2026-08-07 | 2026-09-18 | https://pypi.org/project/huggingface-hub/ | The Xet client went from opt-in extra to unconditional dependency in about six weeks, gated on CPU architecture rather than user choice | 0.30.0rc0 (2025-03-27) requires hf-xet>=0.1.4; extra == "hf-xet"; 0.31.0rc0 (2025-05-06) requires hf-xet<2.0.0,>=1.1.0; platform_machine == "x86_64" or ... "aarch64" |
| 9 | Hugging Face | hf-xet release history |
source | 2025-01-10 to 2026-08-13 | 2026-09-18 | https://pypi.org/project/hf-xet/ | The Rust transfer client is a 2025 artefact, not an original component | first release 0.1.0 on 2025-01-10; 1.0.0 on 2025-04-01 |
| 10 | Hugging Face | safetensors release history |
source | 2022-09-22 onward | 2026-09-18 | https://pypi.org/project/safetensors/ | The format shipped in late 2022, three years before the framework consolidation it enabled | first release 0.0.1 on 2022-09-22 |
| 11 | Hugging Face | tokenizers release history |
source | 2019-11-01 onward | 2026-09-18 | https://pypi.org/project/tokenizers/ | Rust entered the stack in 2019, five years before the storage client | first release 0.0.1 on 2019-11-01 |
| 12 | Hugging Face | safetensors README, "Yet another format?" and "Main oppositions" |
adr | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/safetensors | The format's rationale is a written comparison against eight alternatives with the rejection reason for each | "The main rationale for this crate is to remove the need to use pickle on PyTorch which is used by default."; "H5: ... 210k lines of code vs ~400 lines for this lib currently"; "Protobuf: Hard 2Go max file size limit" |
| 13 | Hugging Face | safetensors README, format specification |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/safetensors | The file is a length prefix, a JSON header and a packed byte buffer, with the anti-abuse rules stated in the spec | "8 bytes: N, an unsigned little-endian 64-bit integer"; "The byte buffer needs to be entirely indexed, and cannot contain holes. This prevents the creation of polyglot files."; "there's a limit on the size of the header of 100MB" |
| 14 | Hugging Face | safetensors README, BLOOM loading figure |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/safetensors | Lazy loading was justified by a measured distributed-load time, not a throughput benchmark | "using this format enabled to load the model on 8 GPUs from 10mn with regular PyTorch weights down to 45s" |
| 15 | Hugging Face | safetensors attacks/ directory README |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/safetensors/blob/main/attacks/README.md | The project ships working exploits against the formats it replaces, and a written record of red-teaming its own format | "Torch Arbitrary code execution ... This will create a seemingly innocuous torch_ace.pt file."; "Proposal 4: The offsets could overlap. |
| 16 | Hugging Face | safetensors PR #197, "Q4 quantization support" | adr | opened 2023-03-17, closed 2023-12-24 | 2026-09-18 | https://github.com/huggingface/safetensors/pull/197 | The format's own author proposed quantization support and then let it die, because the ecosystem had not converged on a packing scheme | Narsil: "Temporary PR, need to figure out a way to make sure this is usable in practice."; "I will only merge this after being showcased in a real model example." |
| 17 | Hugging Face | safetensors PR #676, "nvidia gds support" | adr | opened 2025-11-22, closed 2026-04-13 | 2026-09-18 | https://github.com/huggingface/safetensors/pull/676 | Transport optimisation was refused in the format and moved to a loading backend | McPatate: "we won't move along with this PR, we're in the midst of building an optimised loading backend for safetensors which will eventually support GDS directly."; Narsil: "GDS should be an implementation detail, not something users should care about" |
| 18 | Hugging Face | transformers philosophy document and core tenets |
adr | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/transformers/blob/main/docs/source/en/philosophy.md | The single-file policy is a written, enforced review rule, and v5 states a single-backend identity | "Transformers is a PyTorch-first library."; "One Model, One File. Core inference/training logic is visible top-to-bottom in the model file users read."; "DRY* (Repeat when it helps users)" |
| 19 | Hugging Face | transformers modular-transformers document |
adr | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/transformers/blob/main/docs/source/en/modular_transformers.md | The repair for the single-file policy was a code generator, not a repeal | "A converter generates standalone files from the modular file. Users get the same single-file interface they already know."; "Modular transformers isn't meant to replace the legacy modeling code" |
| 20 | Hugging Face | xet-core README |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/xet-core | The Hub's transfer layer is content-defined chunking over a content-addressed store, with an LFS-compatible CLI | "chunk-based deduplication, efficient storage/retrieval with local disk caching, and backwards compatibility with Git LFS"; "git-xet Git LFS compatible command-line tool" |
| 21 | Hugging Face | xet-core chunking and xorb constants |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/xet-core/blob/main/xet_core_structures/src/xorb_object/constants.rs | The dedup geometry is fixed in source: 64 KiB target chunk, 8 KiB floor, 128 KiB ceiling, 64 MiB block | TARGET_CHUNK_SIZE: usize = 64 * 1024; MINIMUM_CHUNK_DIVISOR: usize = 8; MAXIMUM_CHUNK_MULTIPLIER: usize = 2; MAX_XORB_BYTES: usize = 64 * 1024 * 1024; MAX_XORB_CHUNKS: usize = 8 * 1024 |
| 22 | Hugging Face | xet_data crate README and chunking module |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/xet-core/blob/main/xet_data/src/deduplication/chunking.rs | The chunker is gear-hash content-defined chunking, not fixed-size blocks | "Content-defined chunking — Gear-hash based chunking for deduplication" |
| 23 | Hugging Face | huggingface_hub v0.30.0 release notes |
source | 2025-03-31 | 2026-09-18 | https://github.com/huggingface/huggingface_hub/releases/tag/v0.30.0 | Xet was introduced to the client as an LFS replacement operating at chunk level | "Xet is a groundbreaking new protocol for storing large objects in Git repositories, designed to replace Git LFS. Unlike LFS, which deduplicates files, Xet operates at the chunk level." |
| 24 | Hugging Face | text-generation-inference LICENSE commit history | adr | 2022-10-22, 2023-07-28, 2024-04-08 | 2026-09-18 | https://github.com/huggingface/text-generation-inference/commits/main/LICENSE | The serving product was relicensed away from Apache 2.0 and back again inside nine months | commits: "Create LICENSE (#2)" 2022-10-22; "chore: update license to HFOIL (#725)" 2023-07-28; "Revert license to Apache 2.0 (#1714)" 2024-04-08 |
| 25 | Hugging Face | text-generation-inference LICENSE file, current | source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/text-generation-inference/blob/main/LICENSE | The reversion stuck: the shipped licence today is Apache 2.0 | file begins "Apache License / Version 2.0, January 2004" |
| 26 | Hugging Face | transformers v5.0.0 release notes |
source | 2026-01-26 | 2026-09-18 | https://github.com/huggingface/transformers/releases/tag/v5.0.0 | The first major release in five years is framed as consolidation, and the notes do not narrate the framework removals | "This is the first major release in five years, and the release is significant: 1200 commits have been pushed to main since the latest minor release."; "dropped support for two torch APIs: torchscript" |
| 27 | Hugging Face | transformers issue #43489, "Transformers' version 5 is out!" |
source | 2026-01-26 | 2026-09-18 | https://github.com/huggingface/transformers/issues/43489 | The v5 announcement thread confirms the date and the release-candidate sequence | "Thank you all for your patience while we released RC0, RC1, RC2, and RC3." |
| 28 | measured (this guide) | Model directories, per-framework modeling files, # Copied from markers and line counts across 13 transformers wheels |
casestudy | artefacts dated 2019-09-26 to 2026-09-09 | 2026-09-18 | https://pypi.org/project/transformers/#history | TensorFlow and Flax file counts were frozen at 73 and 40 from 4.46.0 (2024-10-24) through 4.57.0 (2025-10-03), then went to zero in 5.0.0 (2026-01-26) | measured from published wheels; procedure and script in the guide's hunt section |
| 29 | measured (this guide) | Total Python lines shipped in transformers |
casestudy | artefacts dated 2019 to 2026 | 2026-09-18 | https://pypi.org/project/transformers/#history | The library crossed one million lines at 4.46.0 and fell 17.7% at v5 while adding 29 model directories | 4.57.0: 1,165,404 lines, 383 model directories; 5.0.0: 958,925 lines, 412 model directories |
| 30 | measured (this guide) | # Copied from transformers. occurrences |
casestudy | artefacts dated 2020 to 2026 | 2026-09-18 | https://pypi.org/project/transformers/#history | Deliberate duplication peaked at 3,395 markers and has fallen as generated modular files rose from 0 to 294 | 4.46.0: 3,395 markers, 5 modular files; 5.17.0: 1,139 markers, 294 modular files |
| 31 | measured (this guide) | trust_remote_code identifier occurrences |
casestudy | artefacts dated 2019 to 2026 | 2026-09-18 | https://pypi.org/project/transformers/#history | The remote-code escape hatch first appears in 4.15.0 and survived the v5 cleanup untouched | 4.15.0: 25 occurrences; 4.57.0: 231; 5.17.0: 230 |
| 32 | GitHub Advisory Database | GHSA-fgcw-684q-jj6r, LightGlue arbitrary code execution | postmortem | 2026-06-03 | 2026-09-18 | https://github.com/advisories/GHSA-fgcw-684q-jj6r | A model repository could supply its own permission to execute code, defeating an explicit refusal | "the trust_remote_code value from the untrusted config.json file" is propagated into downstream configuration loading; affected < 5.5.0, patched 5.5.0, CVSS High 8.0 |
| 33 | GitHub Advisory Database | GHSA-9xq9-36w5-q796, lmdeploy hardcoded trust_remote_code=True |
postmortem | 2026-05 | 2026-09-18 | https://github.com/advisories/GHSA-9xq9-36w5-q796 | A downstream server can delete the user's ability to refuse, and the safe default then counts for nothing | "LMDeploy unilaterally passes trust_remote_code=True to transformers.AutoConfig.from_pretrained()"; "A malicious HF repo with a configuration_*.py shim runs Python code as the LMDeploy user at the very first call to get_model_arch(...)" |
| 34 | GitHub Advisory Database | Advisory listing for "transformers" | postmortem | 2026-05 to 2026-09 | 2026-09-18 | https://github.com/advisories?query=transformers | Model-loading code execution is an ecosystem-wide 2026 failure class, not one library's bug | listed in one page of results: transformers path traversal via chat template names (2026-08-02), LightGlue RCE (2026-06-03), diffusers TOCTOU trust bypass (2026-05-20), lmdeploy hardcoded trust_remote_code (2026-05), sentence-transformers control bypass (2026-07-31), xinference unsafe model loading (2026-08-24) |
| 35 | PyTorch | PyTorch 2.6.0 release notes, torch.load default change |
adr | 2025-01-29 | 2026-09-18 | https://github.com/pytorch/pytorch/releases/tag/v2.6.0 | The incumbent format was repaired rather than replaced, and its maintainers still point at safetensors for untrusted files | "the increased security by default is a tradeoff that is worth it"; "we still recommend only loading trusted checkpoints and rely on more constrained (and even safer) formats like safetensors for un-trusted checkpoints" |
| 36 | Keras | saving_api.py, load_model safe_mode contract |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/keras-team/keras/blob/master/keras/src/saving/saving_api.py | A third strategy: keep the format, gate the dangerous construct at load time, default closed | "safe_mode: Boolean, whether to disallow unsafe lambda deserialization. When safe_mode=False, loading an object has the potential to trigger arbitrary code execution ... Defaults to True." |
| 37 | Keras | saving_lib.py, hf:// load path |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/keras-team/keras/blob/master/keras/src/saving/saving_lib.py | A competing framework treats the Hub as a first-class source, calling huggingface_hub.snapshot_download from its own loader |
elif str(filepath).startswith("hf://") then huggingface_hub.snapshot_download(repo_id=repo_id, library_name="keras", ...) |
| 38 | ggml / llama.cpp | GGUF specification | adr | current at 2026-09-18 | 2026-09-18 | https://github.com/ggml-org/ggml/blob/master/docs/gguf.md | The opposite bet: put everything in the format, including quantization types, and pay for it with removals | "Single-file deployment: they can be easily distributed and loaded, and do not require any external files"; type enum contains GGML_TYPE_Q4_0, and also // GGML_TYPE_Q4_2 = 4, support has been removed |
| 39 | crates.io | safetensors, tokenizers, hf-xet crate metadata |
source | checked 2026-09-18 | 2026-09-18 | https://crates.io/crates/safetensors | Adoption figures for the Rust half of the stack | safetensors 25,903,163 all-time downloads, created 2022-12-13; tokenizers 32,865,800, created 2019-08-08; hf-xet 1,197,063 |
| 40 | npm registry | @xenova/transformers and @huggingface/transformers |
source | 2023-03-03 and 2024-08-08 | 2026-09-18 | https://registry.npmjs.org/@huggingface/transformers | The browser runtime was a community package adopted in-house, with version numbering continued rather than restarted | @xenova/transformers created 2023-03-03, last version 2.17.2 on 2024-05-29; @huggingface/transformers created 2024-08-08, first version 3.0.0-alpha.0 |
| 41 | Hugging Face | datasets 3.0.0 release notes |
source | 2024-09-11 | 2026-09-18 | https://github.com/huggingface/datasets/releases/tag/3.0.0 | The data library removed its deprecated execution and integration surface in a major release | "removed deprecated apache beam datasets support"; "remove deprecated load_metric, please use the evaluate library instead" |
| 42 | Hugging Face | huggingface_hub constants |
source | current at 2026-09-18 | 2026-09-18 | https://github.com/huggingface/huggingface_hub/blob/main/src/huggingface_hub/constants.py | The previous Rust accelerator was superseded by the Xet path, in a deprecation warning in shipped code | HF_HUB_ENABLE_HF_TRANSFER ... "Please use HF_XET_HIGH_PERFORMANCE instead to enable high performance transfer with Xet." |
Deliberate gaps
- No engineering blogs, talks or papers. See the method note above. This is the single largest weakness of the guide and the reader should treat the narrative reconstruction between artefacts as inference rather than as reporting.
- No Hub-side numbers at all. Repository counts, stored bytes, achieved deduplication ratios, egress and storage cost: none of it is in this corpus, because the only place it is published was unreachable. Anything you read elsewhere about Xet's production dedup ratio is not corroborated here.
- No incident timelines. The advisories and yank notices give mechanism and fix, never duration, detection delay or blast radius.