Cheat sheet · Checked Oct 28, 2026

Hugging Face cheat sheet

Everything you need to work with Hugging Face from Python: install and log in, load and run models with transformers 5, work with datasets, fine tune with LoRA and TRL, serve through Inference Providers, and ship a Space. Every fact is checked against the official docs and releases, and the code was checked against the installed packages.

transformers · released Oct 26, 2026
transformers 5.21.0
huggingface_hub · released Oct 23, 2026
huggingface_hub 2.3.0
datasets · released Oct 5, 2026
datasets 5.1.0
trl · released Oct 15, 2026
trl 1.16.0
A clay diorama of a library shelf of small boxes, with a tiny robot sliding one box into a glowing slot in a friendly machine

Explore with AI

Browse by topic

Topic 1 of 6

Get started

Install, log in, move the cache, and avoid the traps.

Install and check your versions

STEP 1

Check your Python

transformers 5 needs Python 3.11 or newer. On a default Python 3.9, pip quietly installs transformers 4.57.6.

STEP 2

Install with PyTorch

Plain pip install transformers does not install PyTorch. Use the torch extra to get PyTorch and Accelerate.

STEP 3

Log in once

hf auth login opens the browser and stores a token. A read token is enough for downloads.

$ pip install "transformers[torch]" datasets huggingface_hub
$ hf auth login
PackageVersionReleasedPython
transformers5.21.0Oct 26, 20263.11+
huggingface_hub2.3.0Oct 23, 20263.10+
datasets5.1.0Oct 5, 20263.10+
tokenizers0.23.3Oct 9, 20263.10+
safetensors0.8.0Jun 9, 20263.10+
peft0.21.2Oct 1, 20263.10+
trl1.16.0Oct 15, 20263.11+
accelerate1.15.0Sep 9, 20263.10+
diffusers0.42.1Oct 27, 20263.11+
gradio6.31.0Oct 28, 20263.10+
evaluate0.4.6Sep 18, 20253.8+

Sources: transformers installation · transformers on PyPI · transformers v5 migration guide

The hf CLI, tokens and the cache

Python
import os
from huggingface_hub import login, hf_hub_download, snapshot_download

# The token comes from the environment; never paste it into the file.
if os.environ.get("HF_TOKEN"):
    login(token=os.environ["HF_TOKEN"])

repo = "Qwen/Qwen2.5-0.5B-Instruct"

# One file, cached under $HF_HOME/hub
config_path = hf_hub_download(repo, "config.json", revision="main")

# A filtered snapshot into a plain folder
folder = snapshot_download(
    repo,
    allow_patterns=["*.json", "*.safetensors"],
    local_dir="./qwen-0.5b",
)
print(config_path, folder)
CommandWhat it does
hf auth login / whoami / logoutLog in with the browser or a pasted token, check who you are, log out.
hf download REPO [FILES]Download files or a whole repo. Flags: --repo-type, --revision, --include, --exclude, --local-dir.
hf upload REPO LOCAL PATHUpload a file or folder. An interrupted folder upload resumes when you run the same command again.
hf repos create NAMECreate a repo. Add --repo-type dataset or space, and --private.
hf cache ls / rm / prune / verifyList, delete, clean and verify the local cache.
Environment variableWhat it does
HF_TOKENYour token. It beats the one stored by hf auth login, and hf auth logout does not clear it.
HF_HOMEMoves the token, the hub cache and the Xet cache. The default is ~/.cache/huggingface.
HF_HUB_OFFLINESet to 1 for no network calls. Only cached files are used.
HF_XET_HIGH_PERFORMANCESet to 1 to use all the bandwidth and CPU cores for downloads.
HF_HUB_DISABLE_XETSet to 1 to turn off the Xet transfer backend.
  • There are three token types. read downloads, write can also push, and fine-grained is scoped to chosen resources. Use read unless you must write.
  • huggingface-cli is gone. Use hf. In hub 2.0 hf repo became hf repos.
  • The datasets cache is separate, at HF_DATASETS_CACHE. To move everything, set HF_HOME.
  • hf_transfer is dead. The hub package installs hf-xet for you, so downloads are fast by default.

Sources: hf CLI guide · Environment variables · User access tokens

Defaults that bite

Eight defaults that bite, most of them changed in 2026, each with the one line fix.

  1. transformers 5Jan 26, 2026

    torch_dtype is now dtype

    In transformers 5 the argument is dtype, and the default is "auto", so a model loads in the dtype it was saved in. torch_dtype still works but warns.

    Do thisWrite dtype="auto" or a real dtype, and stop passing torch_dtype.

    transformers v5 migration guide

  2. transformers

    generate() stops at 20 tokens

    Unless the model's generation config sets more, generate() returns up to 20 tokens. For a decoder only model that count includes your prompt, so answers look cut off.

    Do thisAlways set max_new_tokens, and do_sample=True if you want temperature or top_p to matter.

    Text generation tutorial

  3. Install

    The wrong Python installs an old stack

    On Python 3.9, pip install transformers gives 4.57.6 and the 5.x examples fail. Plain pip install transformers also has no PyTorch.

    Do thisUse Python 3.11 or newer and pip install "transformers[torch]".

    transformers installation · transformers on PyPI

  4. huggingface_hubSep 24, 2026

    huggingface-cli no longer exists

    It was deleted in huggingface_hub 1.0 and replaced by hf. Hub 2.0 also renamed hf repo to hf repos and moved HTTP to httpx2.

    Do thisUse hf auth login, hf cache ls and hf repos create.

    huggingface_hub 2.0 migration · huggingface_hub 1.0.0 release

  5. Trainer

    Trainer arguments were renamed

    evaluation_strategy, warmup_ratio, no_cuda and Trainer(tokenizer=) all raise TypeError now. report_to defaults to "none".

    Do thisUse eval_strategy, a float warmup_steps, use_cpu and processing_class=.

    transformers v5 migration guide · Trainer

  6. Security

    trust_remote_code runs code from the Hub

    It executes whatever code sits in the repo on your machine. Pickle weights can run code the moment you load them.

    Do thisKeep it False, prefer model.safetensors, and pin revision to a commit hash.

    Pickle security

  7. TRL 1.x

    SFTConfig is not TrainingArguments

    max_seq_length is now max_length. SFTConfig turns on gradient_checkpointing and bf16 for you, and a model passed as a string loads in float32.

    Do thisSet max_length, bf16=False on CPU, and model_init_kwargs={"dtype": ...}.

    TRL SFT trainer

Topic 2 of 6

Load and run models

Pipelines, generate, chat templates, quantization.

Run a model with pipeline()

The shortest way to run a model

A pipeline picks the model, tokenizer and pre and post processing for a task. For chat, hand it a list of messages.

A paper sheet slides into a friendly machine and a glowing card slides out
A pipeline
Python
from transformers import pipeline

# dtype="auto" is the default; device_map="auto" needs accelerate
pipe = pipeline(
    "text-generation",
    model="Qwen/Qwen2.5-0.5B-Instruct",
    dtype="auto",
    device_map="auto",
)

messages = [{"role": "user", "content": "Explain safetensors in one sentence."}]
out = pipe(messages, max_new_tokens=64, do_sample=False)

# With chat messages in, the last message of generated_text is the reply
print(out[0]["generated_text"][-1]["content"])
  • dtype defaults to "auto". Use device_map="auto" to place the model on your GPUs with Accelerate. Pick device_map rather than device.
  • A chat model returns the whole message list. The reply is out[0]["generated_text"][-1]["content"].
  • Version 5 removed the pipelines for summarization, translation, text2text, question answering, image to text and visual question answering. Use a chat model through text-generation, or a vision language model through image-text-to-text.
  • The task list in 5.21.0 has 24 tasks, including text-generation, automatic-speech-recognition, image-classification, zero-shot-classification and feature-extraction.

Sources: Pipelines tutorial · transformers v5 migration guide

Load a model and generate

Python
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "Qwen/Qwen2.5-0.5B-Instruct"

# Pin revision to a commit hash in production; "main" moves.
tok = AutoTokenizer.from_pretrained(model_id, revision="main", padding_side="left")
if tok.pad_token is None:
    tok.pad_token = tok.eos_token

model = AutoModelForCausalLM.from_pretrained(
    model_id,
    revision="main",
    dtype=torch.bfloat16,
    device_map="auto",
    attn_implementation="sdpa",
)

prompts = ["The capital of France is", "A haiku about caches:"]
inputs = tok(prompts, return_tensors="pt", padding=True).to(model.device)
out = model.generate(
    **inputs, max_new_tokens=30, do_sample=True, temperature=0.7, top_p=0.9
)
print(tok.batch_decode(out, skip_special_tokens=True))
  • from_pretrained takes dtype, device_map, attn_implementation, quantization_config and trust_remote_code as keyword arguments. revision can be a branch, a tag or a commit hash.
  • generate() returns up to 20 tokens by default, unless the model's generation config sets more. Set max_new_tokens. max_length counts the prompt too.
  • temperature and top_p only matter when do_sample=True.
  • For a batch of prompts on a decoder only model, use padding_side="left". Many tokenizers have no pad token, so set tokenizer.pad_token = tokenizer.eos_token when it is None.
  • attn_implementation takes "sdpa", "flash_attention_2", "flash_attention_3", "flex_attention" or "eager". The paged| prefix is deprecated since 5.19.0.
  • Weights load from safetensors when they exist. weights_only is True by default, and torch.load needs torch 2.6 or newer.

Sources: Text generation tutorial · transformers v5 migration guide

Chat templates and streaming

Python
from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct")
messages = [
    {"role": "system", "content": "You answer in one sentence."},
    {"role": "user", "content": "What is Xet?"},
]

# Inspect the exact prompt text the model will see
text = tok.apply_chat_template(messages, tokenize=False, add_generation_prompt=True)
print(text)

# v5 returns a BatchEncoding (input_ids and attention_mask), not a bare tensor
batch = tok.apply_chat_template(
    messages, add_generation_prompt=True, return_dict=True, return_tensors="pt"
)
print(batch["input_ids"].shape)
# model.generate(**batch, max_new_tokens=64)
Python
from threading import Thread
from transformers import (
    AutoModelForCausalLM,
    AutoTokenizer,
    TextIteratorStreamer,
    TextStreamer,
)

model_id = "Qwen/Qwen2.5-0.5B-Instruct"
tok = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(model_id, device_map="auto")
inputs = tok.apply_chat_template(
    [{"role": "user", "content": "Count to five."}],
    add_generation_prompt=True, return_dict=True, return_tensors="pt",
).to(model.device)

# 1. Print tokens to stdout as they arrive
model.generate(**inputs, streamer=TextStreamer(tok, skip_prompt=True), max_new_tokens=60)

# 2. Iterate over chunks (for a web response); generate runs in a thread
streamer = TextIteratorStreamer(tok, skip_prompt=True, skip_special_tokens=True)
Thread(target=model.generate, kwargs={**inputs, "streamer": streamer, "max_new_tokens": 60}).start()
for chunk in streamer:
    print(chunk, end="", flush=True)
TextIteratorStreamer: run generate in a thread and read the text as it arrives.
  • apply_chat_template(..., add_generation_prompt=True) adds the tokens that open the assistant turn. Without them the model may carry on the user message instead of replying.
  • In version 5 it returns a BatchEncoding with input_ids and attention_mask, so pass it to model.generate(**batch). Use tokenize=False to get the prompt string.
  • TextStreamer prints to stdout. TextIteratorStreamer yields chunks and needs generate in a threading.Thread.

Sources: Chat templating · transformers v5 migration guide

Quantization and memory

Python
import torch
from transformers import AutoModelForCausalLM, BitsAndBytesConfig

# pip install bitsandbytes  (v5 removed load_in_4bit as a from_pretrained argument)
bnb = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",
    bnb_4bit_compute_dtype=torch.bfloat16,
    bnb_4bit_use_double_quant=True,
)

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen2.5-7B-Instruct",
    quantization_config=bnb,
    device_map="auto",
)
print(f"{model.get_memory_footprint() / 1e9:.1f} GB")
The config object was checked. I had no CUDA GPU, so a real 4 bit load was not run.
PrecisionBytes per parameterWeights of a 7B model
float32428 GB
float16 or bfloat16214 GB
int817 GB
int40.53.5 GB
  • The weights take parameters times bytes per parameter. The activations and the KV cache come on top, so leave headroom. The sizes above are weights only.
  • accelerate estimate-memory MODEL estimates a model without downloading it.
  • bitsandbytes gives on the fly 4 and 8 bit loading. NF4 is the type to use for training 4 bit base models. Other methods in the docs include AWQ, GGUF and compressed tensors.
  • On Apple Silicon do not promise bfloat16. A tiny model crashed with bf16 and device_map="auto" on MPS, while float32 and CPU bf16 were fine.

Sources: Quantization overview

Load models safely

  • Pickle files can run code when you load them. safetensors removes that risk, but a safetensors model from a stranger can still be badly behaved, so it is not proof of trust.
  • trust_remote_code=True runs code from the repo on your machine whatever the weight format. Leave it off unless you have read the code.
  • Pin revision to a commit hash. A branch name or tag can move.
  • Never run torch.load on a downloaded .bin, .pt or .pth file with weights_only=False.
  • The Hub scans every file under 2 GB for malware at each commit. The docs say that is not foolproof, and checking is your job.
  • Gated models need an approved account. Without a token, hf_hub_download raises GatedRepoError with a 401.

Sources: Pickle security · Gated models · safetensors

Topic 3 of 6

Datasets and the Hub

Load, map, stream, push, search and download.

Datasets: load, map and filter

Python
from datasets import load_dataset

ds = load_dataset("rajpurkar/squad", split="train")  # cached after the first run
ds = ds.filter(lambda r: len(r["context"]) > 200)
ds = ds.map(
    lambda batch: {"q_words": [len(q.split()) for q in batch["question"]]},
    batched=True,
    num_proc=4,
)
ds = ds.remove_columns(["id", "title"]).shuffle(seed=42).select(range(1000))
splits = ds.train_test_split(test_size=0.1, seed=42)
print(splits)

# Streaming: no full download, you get an IterableDataset
stream = load_dataset("rajpurkar/squad", split="train", streaming=True)
for row in stream.shuffle(seed=42, buffer_size=1_000).take(2):
    print(row["question"])
MethodWhat it does
load_dataset(path, split=..., streaming=...)Loads a Hub dataset or local csv, json, parquet and txt files. No split returns a DatasetDict.
ds.map(fn, batched=True, num_proc=4)Transforms rows. batched passes lists of 1,000 rows, and num_proc runs on several CPU cores.
ds.filter(fn)Keeps the rows where the function returns true.
ds.train_test_split(test_size=0.1, seed=42)Returns a DatasetDict with train and test, shuffled by default.
ds.select_columns, remove_columns, rename_columnChoose, drop and rename columns.
ds.with_format("torch")Return tensors when you index.
Dataset.from_dict, from_pandasBuild a dataset in memory.
save_to_disk, load_from_disk, to_parquetSave and reload a dataset.
  • streaming=True returns an IterableDataset and downloads nothing up front. It has map, filter, shuffle, take, skip and batch, but no select, train_test_split or num_proc.
  • Streaming shuffle uses a buffer of 1,000 rows. Since datasets 5.0 it draws from several shards, and max_buffer_input_shards=1 gives the old behavior.
  • Transforms cache to Arrow files. Pass load_from_cache_file=False to map to skip the cache.
  • datasets 4.0 removed dataset loading scripts and trust_remote_code. Use Parquet or another packaged format.

Sources: Load a dataset · Stream a dataset · Process a dataset · Datasets cache

Push a dataset to the Hub

Python
import os
from datasets import Dataset, load_from_disk

ds = Dataset.from_dict({"text": ["hello", "world"], "label": [0, 1]})
# Dataset.from_pandas(df) works the same way

ds.save_to_disk("./my_ds")          # Arrow folder, reload with load_from_disk
ds = load_from_disk("./my_ds")
ds.to_parquet("./my_ds.parquet")    # single parquet file

# Needs a write token and a repo you own
ds.push_to_hub(
    "your-username/my-dataset",
    private=True,
    token=os.environ["HF_TOKEN"],
)
push_to_hub needs a write token and was not run.
  • push_to_hub also works on a streaming IterableDataset since datasets 4.0, so you can map, filter and push without writing to disk.
  • Pass private=True for a private repo and num_proc to speed up the upload.

Search the Hub and check licenses

Find a model and read its terms in code

model_info returns the license, the gating status, the parameter count and the file list before you download anything.

A tiny robot slides a box into a compartment on a tall cloud shaped shelf
The Hub
Python
from huggingface_hub import HfApi

api = HfApi()  # reads HF_TOKEN from the environment if set

# Small, ungated text-generation models, most downloaded first
for m in api.list_models(
    pipeline_tag="text-generation", gated=False,
    num_parameters="max:1B", sort="downloads", limit=3,
):
    print(m.id)

# Check license, gating and weight format before you download anything
info = api.model_info("meta-llama/Llama-3.2-1B")
print("license:", info.card_data.license if info.card_data else None)
print("gated:", info.gated)  # False, "auto" or "manual"
print("safetensors:", any(s.rfilename.endswith(".safetensors") for s in info.siblings))
  • list_models filters on pipeline_tag, gated, num_parameters such as "max:1B", author, search and sort. The old model_name= argument is gone, so use search=.
  • model_info(...).gated is False, "auto" or "manual". The license is in card_data.license.
  • A permissive library license does not cover the weights. Read the model card. Some models carry a custom license and a use policy file.
  • Gated access is granted to individual users, never to a whole organization.

Sources: Gated models · huggingface_hub docs

Topic 4 of 6

Fine tune

Trainer, LoRA, TRL and Accelerate.

Trainer and TrainingArguments

Python
from datasets import load_dataset
from transformers import (AutoModelForSequenceClassification, AutoTokenizer,
                          DataCollatorWithPadding, Trainer, TrainingArguments)

name = "distilbert/distilbert-base-uncased"
tok = AutoTokenizer.from_pretrained(name)
model = AutoModelForSequenceClassification.from_pretrained(name, num_labels=2)

ds = load_dataset("stanfordnlp/imdb")
ds = ds.map(lambda b: tok(b["text"], truncation=True), batched=True)

args = TrainingArguments(
    output_dir="imdb-distilbert",
    eval_strategy="epoch",
    save_strategy="epoch",
    per_device_train_batch_size=16,
    gradient_accumulation_steps=2,
    warmup_steps=0.1,  # warmup_ratio was removed; warmup_steps accepts a float
    report_to="none",
    push_to_hub=False,
)
trainer = Trainer(
    model=model,
    args=args,
    train_dataset=ds["train"],
    eval_dataset=ds["test"],
    data_collator=DataCollatorWithPadding(tok),
    processing_class=tok,
)
trainer.train()
Old nameUse now
evaluation_strategyeval_strategy
warmup_ratiowarmup_steps as a float
no_cudause_cpu
Trainer(tokenizer=...)Trainer(processing_class=...)
train(model_path=...)train(resume_from_checkpoint=...)
logging_dirSet TENSORBOARD_LOGGING_DIR
  • report_to defaults to "none" in version 5. Set it to "wandb", "tensorboard" or "mlflow" to log.
  • load_best_model_at_end=True needs eval_strategy set and a matching save_strategy.
  • The defaults are 3 epochs, a learning rate of 5e-05, a batch size of 8 per device and bf16 off. The Trainer sets use_cache=False on the model.
  • Seq2SeqTrainingArguments adds predict_with_generate and the generation settings, for use with Seq2SeqTrainer.

Sources: Trainer · transformers v5 migration guide

LoRA with PEFT

Train a small adapter instead of the whole model

LoRA freezes the base model and trains small matrices next to it. You save and share only the adapter.

A tiny robot snaps a small glowing tile into a notch on a large heavy block
LoRA
Python
import torch
from peft import LoraConfig, get_peft_model
from transformers import AutoModelForCausalLM

model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen3-0.6B", dtype=torch.bfloat16)

config = LoraConfig(
    r=16,
    lora_alpha=32,
    lora_dropout=0.05,
    target_modules="all-linear",
    task_type="CAUSAL_LM",
)
model = get_peft_model(model, config)
model.print_trainable_parameters()

# after training, save only the adapter weights
model.save_pretrained("qwen3-lora-adapter")
  • LoraConfig defaults are r=8 and lora_alpha=8. target_modules="all-linear" covers every linear layer, which is the QLoRA style setup.
  • save_pretrained writes only the adapter: adapter_config.json and adapter_model.safetensors, plus a README.md.
  • PeftModel.from_pretrained(model, path) loads an adapter frozen. Pass is_trainable=True to keep training it.
  • QLoRA means loading the base in 4 bit with BitsAndBytesConfig, then prepare_model_for_kbit_training. I had no CUDA GPU, so I did not run it for this sheet.

Sources: PEFT LoRA guide · PEFT quantization

Python
import torch
from peft import PeftModel
from transformers import AutoModelForCausalLM, AutoTokenizer

base_id = "Qwen/Qwen3-0.6B"
base = AutoModelForCausalLM.from_pretrained(base_id, dtype=torch.bfloat16)
model = PeftModel.from_pretrained(base, "qwen3-lora-adapter")

merged = model.merge_and_unload()  # returns the merged model, not in place
merged.save_pretrained("qwen3-merged")
AutoTokenizer.from_pretrained(base_id).save_pretrained("qwen3-merged")
merge_and_unload is not in place: keep the model it returns.

Supervised fine tuning with TRL

Python
import torch
from datasets import load_dataset
from peft import LoraConfig
from trl import SFTConfig, SFTTrainer

dataset = load_dataset("trl-lib/Capybara", split="train")

args = SFTConfig(
    output_dir="qwen3-sft",
    max_length=2048,
    packing=True,
    per_device_train_batch_size=2,
    gradient_accumulation_steps=8,
    model_init_kwargs={"dtype": torch.bfloat16},  # a model id string loads in float32 by default
)
trainer = SFTTrainer(
    model="Qwen/Qwen3-0.6B",
    args=args,
    train_dataset=dataset,
    peft_config=LoraConfig(r=16, lora_alpha=32, target_modules="all-linear"),
)
trainer.train()
trainer.save_model()
  • TRL 1.0 shipped on Mar 31, 2026. The stable trainers are SFT, DPO, KTO, GRPO, RLOO, Reward and Distillation. Many others live in trl.experimental.
  • SFT takes four dataset shapes: plain {"text": ...}, conversational {"messages": [...]}, and prompt and completion pairs in either style. Conversational data gets the chat template applied for you.
  • SFTConfig differs from TrainingArguments: logging_steps 10, gradient_checkpointing on, bf16 on unless fp16 is set, and a learning rate of 2e-5. max_seq_length is now max_length.
  • A model passed as a string loads in float32 unless you set model_init_kwargs={"dtype": ...}.
  • Accelerate launches multi GPU runs: accelerate config, then accelerate launch train.py. torchrun still works.

Sources: TRL SFT trainer · TRL docs · Accelerate launch

Topic 5 of 6

Serve and share

Inference Providers, Spaces, diffusers and evaluation.

Inference Providers

Python
import os

from huggingface_hub import InferenceClient

client = InferenceClient(provider="auto", api_key=os.environ["HF_TOKEN"])

completion = client.chat.completions.create(
    model="openai/gpt-oss-120b",  # add :cheapest, :fastest or :groq to pick a provider
    messages=[{"role": "user", "content": "Explain LoRA in two sentences."}],
    max_tokens=300,
)
print(completion.choices[0].message.content)

stream = client.chat_completion(
    messages=[{"role": "user", "content": "Count to five."}],
    model="openai/gpt-oss-120b",
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="")
Python
import os

from openai import OpenAI

client = OpenAI(
    base_url="https://router.huggingface.co/v1",
    api_key=os.environ["HF_TOKEN"],  # a Hugging Face token, not an OpenAI key
)

completion = client.chat.completions.create(
    model="openai/gpt-oss-120b:cheapest",
    messages=[{"role": "user", "content": "What is the capital of France?"}],
)
print(completion.choices[0].message.content)
The same models through the OpenAI SDK, pointed at the Hugging Face router.
  • The router base URL is https://router.huggingface.co/v1, and it speaks the OpenAI chat completions protocol. Other tasks need the Hugging Face clients.
  • Routed through Hugging Face, you pay the provider rate with no markup. Included credits apply to that mode only: free accounts get none, PRO gets $2.00 a month, and Team or Enterprise gets $2.00 per seat. A key from the provider is billed by the provider.
  • Choose a provider with a suffix on the model name: :fastest (the default), :cheapest, :preferred, or a provider name such as :groq. In InferenceClient use provider="auto" or a provider name.
  • Team and Enterprise organizations can bill an org with InferenceClient(bill_to="my-org").
  • Text Generation Inference is in maintenance mode and its repo is archived. The docs point to vLLM, SGLang, llama.cpp and MLX for self hosting.
  • transformers serve starts a small OpenAI compatible server at localhost:8000 after pip install "transformers[serving]". The docs call it a lightweight option, so use vLLM or SGLang at scale.

Sources: Inference Providers pricing · Inference Providers · transformers serve · Text Generation Inference

Spaces and Gradio

Python
import os

import gradio as gr
from huggingface_hub import InferenceClient

client = InferenceClient(api_key=os.environ["HF_TOKEN"])  # set as a Space secret


def respond(message, history):
    messages = [*history, {"role": "user", "content": message}]
    out = client.chat_completion(messages, model="openai/gpt-oss-120b", max_tokens=512)
    return out.choices[0].message.content


demo = gr.ChatInterface(respond, title="My chat demo")

if __name__ == "__main__":
    demo.launch()
  • A Space is a git repo. Every push rebuilds it. The README header holds sdk, app_file, python_version and suggested_hardware.
  • python_version defaults to 3.10, and transformers 5, TRL 1.x and diffusers 0.42 need 3.11 or newer. Set python_version: "3.12" in the header.
  • Secrets and variables live in the Space settings. Both arrive as environment variables. Secrets cannot be read back and are not copied to duplicates.
  • Static Spaces are free. Gradio and Docker Spaces need a paid plan to create, except that free accounts in good standing can host up to 2 Gradio Spaces on ZeroGPU. PRO can host 10.
  • @spaces.GPU allocates half an RTX Pro 6000 Blackwell by default. size="xlarge" is a full GPU and costs 2x the daily quota.
  • Gradio 6 moved theme and css from Blocks to launch(), and removed the tuple chat history. ChatInterface history is a list of {"role", "content"} dicts.
Space hardwarePrice per hour
CPU Basic (2 vCPU, 16 GB)$0
CPU Upgrade (8 vCPU, 32 GB)$0.03
T4 small$0.40
T4 medium$0.60
1x L4$0.80
1x L40S$1.80
A100 large$2.50

Sources: Spaces overview · Spaces configuration · ZeroGPU · Gradio ChatInterface · Gradio 6 migration guide

Images with diffusers

Python
import torch
from diffusers import DiffusionPipeline

pipe = DiffusionPipeline.from_pretrained(
    "Qwen/Qwen-Image",
    dtype=torch.bfloat16,
    device_map="cuda",  # or "mps", "xpu", "cpu"
)

prompt = "A lighthouse on a cliff at dawn, film still, soft fog"
image = pipe(prompt, num_inference_steps=30).images[0]
image.save("lighthouse.png")
The call follows the current quickstart. The model was not downloaded.
  • diffusers 0.42 loads with dtype= and device_map="cuda", not torch_dtype. Use "mps", "xpu" or "cpu" on other hardware.
  • Gated models such as FLUX need an account, an accepted license and a login.
  • Check each model card for its license before you ship anything built on it.

Sources: diffusers quickstart

Evaluate

Python
import evaluate

accuracy = evaluate.load("accuracy")
print(accuracy.compute(predictions=[0, 1, 1, 0], references=[0, 1, 0, 0]))


# pass this to Trainer(compute_metrics=...)
def compute_metrics(eval_pred):
    logits, labels = eval_pred
    return accuracy.compute(predictions=logits.argmax(-1), references=labels)
  • evaluate.load("accuracy") needs scikit-learn, and it downloads the metric script from the Hub when you call it.
  • The evaluate repo is not archived, but its recent commits are CI upkeep and the last release was 0.4.6 on Sep 18, 2025. The official docs call LightEval more actively maintained for newer evaluation work.

Sources: evaluate docs

Topic 6 of 6

Reference

The PDF, what changed in 2026, answers and sources.

Take it with you

PDF · 11 pages · 1.2 MB

Get the PDF

The whole sheet in one file: a cover, a poster of the eight defaults that bite, every table, all the recipes with their code, and the sources.

Enter your email and the PDF arrives in your inbox.

A fan of pages from the Hugging Face cheat sheet

What changed in 2026

  1. Jan 26 · transformers 5.0.0

    TensorFlow and Jax support removed. dtype replaced torch_dtype with a default of "auto". load_in_4bit and load_in_8bit removed. Several pipelines removed. transformers v5 migration guide

  2. Mar 2026 · TGI

    The Text Generation Inference repo was archived, with its last commit on Mar 21. Its docs say it is in maintenance mode. Text Generation Inference

  3. Mar 31 · TRL 1.0.0

    Stable release, with the less settled trainers moved into an experimental namespace. trl 1.16 needs Python 3.11. TRL 1.0.0 release

  4. Jun 5 · datasets 5.0.0

    The default streaming shuffle draws from several shards. max_buffer_input_shards=1 restores the old behavior. Stream a dataset

  5. Sep 24 · huggingface_hub 2.0.0

    HTTP moved to httpx2, deprecated 1.x APIs were removed, hf repo became hf repos and text_generation(stop_sequences=) became stop=. huggingface_hub 2.0 migration

  6. Oct 6 · transformers 5.19.0

    The paged| prefix on attn_implementation was deprecated. transformers v5 migration guide

  7. Oct 22 to 26 · Latest releases

    huggingface_hub 2.3.0 sped up HfFileSystem listings. transformers 5.21.0 shards tensor parallel embeddings by default. huggingface_hub docstransformers on PyPI

All dates are 2026. These libraries release often, so read each changelog before you take a minor release.

Questions people ask

Why does pip install an old transformers?

transformers 5 needs Python 3.11 or newer. On Python 3.9, pip quietly resolves to 4.57.6. Check python --version first, then run pip install "transformers[torch]".

Why does my model stop after a few words?

generate() returns up to 20 tokens by default unless the model's generation config sets more. Set max_new_tokens, and do_sample=True if you want temperature or top_p to have any effect.

What replaced the old Hugging Face CLI?

The hf command. It was introduced in huggingface_hub 0.34 and huggingface-cli was deleted in 1.0. Use hf auth login to sign in and hf cache ls to see your cache.

Is it safe to turn on trust_remote_code?

Only for repos you trust and whose code you have read, because it runs that code on your machine. Pin revision to a commit hash, and prefer models that ship model.safetensors.

How do I move the Hugging Face cache?

Set HF_HOME. It moves the token, the hub cache and the Xet cache. The datasets cache has its own HF_DATASETS_CACHE, so set that as well if you want it moved.

Do free accounts get Inference Providers credits?

The pricing page lists none for free accounts, which can still buy credits. PRO gets $2.00 a month and Team or Enterprise gets $2.00 per seat. Hugging Face adds no markup when it routes the request, and a provider key is billed by the provider.

Why can my Space not install transformers?

Spaces default to Python 3.10 and transformers 5 needs 3.11. Set python_version: "3.12" in the README header of the Space.

Should I still use evaluate?

It is a stable, light metrics helper. The repo is not archived, but recent commits are CI upkeep, the last release was Sep 18, 2025, and the official docs point to LightEval for newer evaluation work.

Sources

Your AI agents, built by an AI engineer. No handoffs, no lock in. Start my agent build.