Recipe: writing a model card
The 30-minute version. Produces a card that survives external review without embarrassing you.
Prerequisites
Before opening the editor:
- The model is trained. Checkpoint exists.
- Benchmarks have been run. Results files committed.
- You can name the dataset, license, version, and exact source.
- You have at least one runnable code example.
If any of these are missing, fix that first. A model card without measured numbers and a working example is decoration.
The flow
The drafting is fast (~5 minutes). Verification is the slow part (~15-20). Don't skip it.
Step 1 — let the agent draft
Draft a model card at docs/models/<name>.md based on:
- Training run: runs/<date>-<id>/
- Benchmarks: benchmarks/results/<id>-*.json
- Dataset: <dataset name + version>
Use the template in docs/06-documentation/model-cards-with-ai.md.
Hard rules for this draft:
- Pull every numeric claim from the source files. Do not invent.
- If a number is not measurable from the artifacts, write "TBD" — never
guess.
- Cite a real author and contact email in the authors block.
- Use the apache-2.0 license unless overridden.
- Pipeline tag, library_name: pick from the HF valid list. If unsure,
ask before deciding.
Read what comes back. Diff it against your expectations.
Step 2 — verify every numeric claim
Walk the metrics table top to bottom. For each row:
- Open the cited file (
runs/<id>/metrics.jsonorbenchmarks/results/<id>.json). - Confirm the number matches.
- Confirm the conditions match (split, hardware, batch size).
If a row fails, either:
- Remove it.
- Re-measure and update.
- Fix the doc to match the measured value.
This pass takes 10–15 minutes. It is not optional.
Step 3 — verify the code example
Copy the "How to use" code into a fresh Python REPL:
from transformers import AutoModelForSequenceClassification, AutoTokenizer
model = AutoModelForSequenceClassification.from_pretrained(
"vietanhdev/<name>", revision="abc123"
)
tokenizer = AutoTokenizer.from_pretrained("vietanhdev/<name>", revision="abc123")
#... rest of example...
If it doesn't run as written, fix it. The most common failure: the agent
forgets the revision= pin or uses an outdated import path.
Step 4 — the metadata block
The YAML at the top is what HF Hub uses to render the page. Every field matters.
---
license: apache-2.0
language: en
library_name: transformers
pipeline_tag: text-classification
tags:
- text-classification
- finance
authors:
- Viet-Anh Nguyen
datasets:
- vietanhdev/<dataset-name>
metrics:
- f1
---
Common mistakes:
pipeline_tagis from a finite valid list.text2text-generationis NOT valid. Usetext-generation. The current valid list shows up in the yellow warning banner if you get it wrong.library_namecontrols the "Use this model" widget. Set it to the framework you actually use (transformers,sentence-transformers,diffusers, etc.).languageis required for many auto-detection features.
Step 5 — push and verify rendering
huggingface-cli upload vietanhdev/<name> docs/models/<name>.md README.md
Then immediately:
- Open
https://huggingface.co/vietanhdev/<name>in a browser. - Look for the yellow "YAML Metadata Warning" banner at the top of the model card. If present: read the message, fix the YAML, push only the README again.
- Check that the "Use this model" widget appears (means
library_nameis correct). - Check that the model is discoverable by tag.
A successful upload only confirms transport, not rendering. You only know the card is good when you've seen it on the live page.
Step 6 — for datasets, also load it
For dataset cards, the verification is stronger:
from datasets import load_dataset
ds = load_dataset("vietanhdev/<dataset-name>", split="train")
print(ds[0])
print(ds.features)
If load_dataset fails, the dataset README's YAML is wrong (config or split
definitions don't match the file structure). Fix and re-push README only.
Step 7 — commit locally
git add docs/models/<name>.md
git commit -m "docs: model card for <name>"
Push.
What separates good cards from average cards
- Specific limitations. "Performs poorly on negation" beats "may have limitations." The first lets a user decide; the second is filler.
- Honest "out of scope." Saying "not for medical diagnostics" is strong. Saying "use responsibly" is weak.
- Reproducibility command. A reader who follows your link can re-run.
- Author + contact. A real person, a real email. Not "the team."
What sinks cards
- Numbers nobody can trace.
- "Coming soon" sections that are still empty six months later.
- Code examples that don't run.
- Generic license text without the actual license file.
- AI-disclaimer boilerplate ("This model card was AI-assisted" — fine internally, often wrong externally).
A 30-minute timer
If your card takes longer than 30 minutes total — drafting plus verification — something is missing in the source artifacts. Common gaps:
- Missing benchmark file → measure it first, then draft.
- Missing dataset version → pin it first.
- Missing license clarity → resolve it first.
The card itself should be fast. The fast-ness assumes the underlying work is defensible.