How to verify model weights with SHA-256
Last updated: 2026-09-01
You can check any downloaded model file with one command. The hard part is knowing which published value to compare it against. Run sha256sum on the large weight files and compare the output against a digest from a source you already trust. Model repositories store files two ways, so the digest you check depends on the file: sha256 for LFS files, sha1+size for git blobs. And when the list of digests is signed, one signature check covers every file at once.
sha256sum model-00001-of-00003.safetensors
minisign -V -m torrents.json -p minisign.pubThe first command asks whether your bytes are intact. The second asks whether the list of digests deserves trust at all. The rest of this page takes those two questions in order.
What a hash check proves, and what it does not
A digest match answers exactly one question: are these the bytes the digest was computed from. Flip one bit of a 4 GB safetensors file and its sha256 changes completely, which is what makes a digest the standard tool for checking a model file's integrity after a download.
What the match does not tell you is who published the digest. If the hash reaches you over the same wire as the file, someone who can swap one can swap both, and your check passes against the attacker's own value. That is why the Hugging Face Hub runs malware scanning and pickle scanning on every upload: the platform treats incoming model files as potentially hostile. Scanning an upload is still not the same as proving what landed on your disk, and confusing the two is the most common error in this whole area.
So split the job in two. Integrity comes from a digest: the file is unchanged. Authentication comes from a signature: the digest list was produced by a key you chose to trust and was not edited on the way to you. Each is one command. The sections below run them in order.
Why model files carry two different hashes
A model repository on Hugging Face is a git repository. The small files (README, config.json, tokenizer configs, vocabularies) are stored as git blob objects. The large files (the .safetensors weights, a big tokenizer.json) go through Git LFS. The two storage paths compute digests differently, which is why a model's file list carries two hash types: sha256 for LFS files, sha1+size for git blobs. Every digest is labeled with the algorithm actually used, never relabeled.
In this archive's signed manifest every file row carries its method verbatim, sha256-lfs or sha1-git-blob. On the model page the label rides the digest column: hover a digest and the label appears with it, alongside the command that reproduces it.
sha256-lfs: a straight sha256 of the file bytes. Reproduce it withsha256sum <file>.sha1-git-blob: the digest of the file as git stores it. Reproduce it withgit hash-object <file>.
The git side is where nearly everyone trips. Git does not hash your raw bytes. It puts a small header in front of the content, the word blob, the file size, and a null byte, then hashes header plus content as one stream. The size riding inside the digest is why the method reads sha1+size rather than plain sha1.
If sha1sum does not match the listed hash on a small file, that is expected, not corruption. Plain sha1sum hashes the raw bytes; the listed value covers header plus bytes. Run git hash-object <file> instead and it matches. A 40-hex value can never be reproduced by sha1sum, and a source that presents one as a sha256 is mislabeling it.
The same logic covers safetensors integrity questions: the format has no built-in checksum, and a request to add one was closed as not planned, so you check a safetensors file from outside, the same way as any other file.
Where to find a published hash you can trust
The digest is half the check. The source it came from is the other half, and four kinds of place publish model digests.
The file page on the platform of record. In a Hugging Face repo, open the files tab and click a large file's name; the page shows a SHA256 line in the file details. The URL shape matters: a path containing /blob/main/ answers at whatever commit main points to today, and replacing main with the full commit hash pins the page to that commit for good. Note that downloading at a specific commit takes the full-length hash, not a 7-character short one.
The repository tree API. /api/models/Qwen/Qwen3-4B/tree/main returns one entry per file: a 40-hex git oid, and for large files a 64-hex LFS oid plus the size. The same values the file pages show, in machine-readable form.
Release notes and model cards. Some publishers list digests there. Treat those as convenience copies: they drift when someone edits the page after you saved it.
A signed manifest. Digests, method labels, sizes, provenance, and the pinned revision in one file, covered by a signature. That is what this archive ships, and the rest of this page uses it.
What if the model publishes no checksum at all? Use the tree API values. They are served by the platform that hosts the bytes, which beats a digest pasted into a forum reply or a mirror's README. And if no published value exists anywhere, that absence describes the publisher, not your download.
Verify a model download in five steps
Verifying a downloaded LLM, or any other model, compresses to five steps.
- Get the file list. Every file's digest, its method, and its size, from one place: the file pages, the tree API at a pinned revision, or a signed manifest.
- Match the method to the file. A 64-hex digest on a large file is a sha256: use
sha256sum. A 40-hex digest on a small file is a git blob id: usegit hash-object. - Run the command inside the payload directory. sha256sum prints the digest and the file name; git hash-object prints only the digest.
- Compare character by character against the pinned value. One wrong character means download the file again, not "close enough".
- Check the signature on the list itself. One minisign command proves the list you compared against came from the key holder, unedited in transit.
Step 5 is the one people skip, and it is the one that makes the other four meaningful whenever your bytes came from anywhere other than the publisher.
Worked example: every file of a real model, checked
This example is real start to finish. The digests below come from this archive's signed manifest for Qwen_Qwen3-4B, a 4B-parameter model under apache-2.0, 12 files, about 8 GB. The manifest pins revision 1cfa9a7208912126459214e8b04321603b3df60c, and the model page carries the full 12-row files and hashes table.
| File | Method | Digest | Size |
|---|---|---|---|
| model-00001-of-00003.safetensors | sha256-lfs | 328a91d3122359d5547f9d79521205bc0a46e1f79a792dfe650e99fc2d651223 | 3,957,900,840 B |
| model-00002-of-00003.safetensors | sha256-lfs | 6cd087b316306a68c562436b5492edbcf6e16c6dba3a1308279caa5a58e21ca5 | 3,987,450,520 B |
| config.json | sha1-git-blob | e49eccdc32f36da9c09cfa0e737084f9e0105e5e | 726 B |
| README.md | sha1-git-blob | 2de5ee7eee214bb55ea33ec7505c5838a7adf7f6 | 16,857 B |
Two commands cover those four rows, run inside the payload directory:
$ sha256sum model-00001-of-00003.safetensors model-00002-of-00003.safetensors
328a91d3122359d5547f9d79521205bc0a46e1f79a792dfe650e99fc2d651223 model-00001-of-00003.safetensors
6cd087b316306a68c562436b5492edbcf6e16c6dba3a1308279caa5a58e21ca5 model-00002-of-00003.safetensors
$ git hash-object config.json README.md
e49eccdc32f36da9c09cfa0e737084f9e0105e5e
2de5ee7eee214bb55ea33ec7505c5838a7adf7f6Four matches, character for character, and those files are exactly the bytes the manifest recorded.
You do not have to take the manifest's word for the values. Open the upstream file page at the pinned revision and the same file shows the same SHA256 line. Two records that never met agree on the digest. If they ever disagree, trust neither until you find out why.
And if a digest does not match, the file changed. Delete it and download it again. Do not repair, truncate, or re-hash a mismatching file to force a pass: a mismatch is a result, not an obstacle.
Checksum, size check, or signature: what each one proves
Three checks get talked about as if they were interchangeable. They are not, and picking the wrong one is how people end up confident and wrong.
| Check | Command that reproduces it | What it proves | Where it lives | What defeats it |
|---|---|---|---|---|
| sha256 digest | sha256sum <file> | Your bytes are the bytes the digest was computed from | File pages, tree API, signed manifest | A swapped digest delivered over the same channel as the file |
| sha1 git blob digest and size | git hash-object <file> | The file is the exact git object at that revision | Git oids in the tree API | The same swap; SHA-1 collisions are also known |
| minisign signature | minisign -Vm <file> -p <pubkey> | The digest list came from the key holder, unedited | A .minisig file beside the manifest | Only the theft of the signing key |
The signature row is minisign: Ed25519 keys, verification with minisign -Vm <file> -p <pubkey>, signature files ending in .minisig, and signed trusted comments that travel with the file. The minisign docs and the project README carry the exact command forms.
Directory-level signing exists as a spec too. OpenSSF model signing covers a whole model directory with one detached Sigstore bundle, and today it is a specification with a conformance suite rather than a default anyone ships.
The decision rule: a digest answers "did the bytes survive the trip", a signature answers "who says these are the right bytes". If you have time for one check on files from a source you do not know, check the signature first. It decides which digest list is worth comparing against.
What your download tool already verifies for you
Your tools are not silent. Knowing what each one already checks tells you what is left for you.
The Hugging Face side scans every upload for malware, pickled-object risks, and secrets. On the way down, the download stack addresses large files by their LFS sha256: the Xet storage backend is queried with that exact hash, which catches most transfer corruption. What the client library does not do is re-hash every file after download and fail on mismatch. That enforcement was requested in huggingface_hub and closed as a feature request. The platform checks what it stores and how it addresses it; the last mile to your disk is yours.
Ollama takes the blob-by-digest route. Every stored blob is named by its sha256 digest, and pulls are checked against the manifest. A failed check stops the pull with an error saying digest mismatch and that the file must be downloaded again. That protects the transfer between the registry and you, and only that: it says nothing about any source outside the registry.
A torrent client verifies continuously. Every piece of a torrent carries a SHA-1 hash from the torrent's info dictionary; the client checks each piece as it arrives and re-fetches the ones that fail, per the BitTorrent spec. Piece boundaries follow a chosen power-of-two piece length, not file boundaries, so the per-piece checks prove the byte stream matches the torrent file. Whether the torrent file matches what the publisher released is a separate question, answered by the infohash inside the swarm and by the manifest signature outside it; the magnet links and infohashes guide covers those mechanics.
The gap is real enough that people file issues about it. One supply-chain tool requested Hugging Face model hash verification for downloaded files, and the request was closed unresolved. The workflow that issue describes, hash lists checked against a trusted source after download, is the default state of this archive rather than a feature request.
Verify a download from this archive
For files from this archive the general method collapses, because the digest list is already signed and pinned.
Fetch three files from aiseedbank.org: torrents.json, which lists every published model with its infohash, per-file digests, method labels, and provenance; torrents.json.minisig, its signature; and minisign.pub, the public key. Then one command:
minisign -V -m torrents.json -p minisign.pubA good signature means every digest you compare against came from the maintainers, not from whatever served you the bytes. The verify page is the command card for this flow, download step included; this guide does not repeat it.
On top of the manifest, each model ships a signed SHA256SUMS pair: a sha256 for every file in the model whatever its storage method, plus its minisign signature, checked with minisign -V and then sha256sum -c. The Cite this release card on a model page links the pair when that model's sums are complete.
The claim, stated the way the verify page states it: every payload in this archive was verified against upstream Hugging Face at fetch time, with the exact upstream revision pinned in the signed manifest. That is the whole claim. This archive does not audit model behavior; it preserves and re-distributes upstream bytes.
To run the five steps on something small first, Qwen_Qwen2-0.5B is about 1 GB and HuggingFaceTB_SmolVLM-256M-Instruct about half a GB. The 7B class is covered by Qwen_Qwen2.5-7B-Instruct and the Llama-licensed NousResearch_Hermes-3-Llama-3.1-8B. All of them are in the catalog. Client choice and the safetensors versus GGUF question live on the help page, the guides index collects the rest, and getting models as torrents is its own walkthrough.
One command per file, one for the list. After the first full run, the procedure stops being a research task and becomes a habit you run before every load.
Frequently asked questions
Why does sha1sum not match the hash listed for a small file?
The small files in a model repo (README, configs, tokenizer text files) are stored as git objects. Git hashes the file with a small header in front: the word blob, the file size, and a null byte. Plain sha1sum hashes the raw bytes only, so the two values differ even for a perfect copy. Run git hash-object on the file instead and it will match. Large weight files are not stored this way; for those, sha256sum matches directly.
Where do I find the SHA-256 of a Hugging Face file?
Open the file page in the repo (click the file name in the files list). For large files, the page shows a SHA256 line in the file details. You can read the same value from the repo tree API, which lists a 64-character oid for large files and a 40-character git oid for the rest. To check a specific release, replace main in the URL with the commit hash you expect.
What does a checksum prove, and what does it not prove?
A matching checksum proves the bytes on your disk are the same bytes the digest was computed from. It proves nothing about who published the digest. If the hash travels over the same wire as the file, someone who can swap one can swap both. A signature from a key you already trust is what makes the hash list itself tamper evident.
Does Hugging Face verify my download for me?
Partly. The Hub scans uploads for malware and pickle risks, and the download stack addresses large files by their SHA-256, which catches most transfer corruption. But the client library does not re-hash every file after download by default; that enforcement was requested and closed as a feature request. If you need certainty, run the hash yourself against a value you trust.
Does Ollama verify models when I pull them?
Yes, per blob. Ollama names each stored blob by its SHA-256 digest and checks digests against the manifest. When the check fails you get an error that says digest mismatch and the file must be downloaded again. That protects the transfer between the registry and you; it does not prove the model matches any source outside that registry.
How do I verify a download from this archive?
Fetch three files from aiseedbank.org: torrents.json, torrents.json.minisig, and minisign.pub. Run minisign -V -m torrents.json -p minisign.pub. If the signature is good, every per-file digest you compare against came from the maintainers, not from whatever mirror served you the bytes. The full walkthrough with every command is on the verify page.
Can I verify GGUF files the same way?
Yes. A digest works on any file, so sha256sum works on a GGUF exactly as on a safetensors file. The hard part is finding a value worth trusting; many third-party GGUF repacks publish none. Unless a GGUF is listed in the signed manifest, it did not come from this archive. Help choosing which file you need is on the help page.
Is SHA-1 safe for verifying model files?
For catching a corrupted transfer, yes: random damage never matches a digest. Against a deliberate attack, SHA-1 collisions are known, which is one reason the large payload files here carry sha256 and only the small git-stored files carry the git blob digest plus size, each labeled with its method. The signature, not the digest algorithm, is what carries the trust.