Skip to content
Back to skills

Safetensors Expert

ASecurity

Author and inspect safetensors files — header layout, sharding via model.safetensors.index.json, mmap loading, and PEFT adapter format. Use when creating, converting, or publishing model files with safetensors.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 8, 2026
developmentpythonrustgogitsecurity

Works with

  • cli

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add anubhavg-icpl/vibe --skill safetensors-expert --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Safetensors Expert?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Safetensors Expert
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/anubhavg-icpl-safetensors-expert/badge)](https://www.skillsdirectory.com/skills/anubhavg-icpl-safetensors-expert)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: safetensors-expert
description: Author and inspect safetensors files — header layout, sharding via model.safetensors.index.json, mmap loading, and PEFT adapter format. Use when creating, converting, or publishing model files with safetensors.
license: CC-BY-NC-SA-4.0
metadata:
  risk: unknown
  source: community
  kind: mode
  category: model-authoring
  tags: [model-authoring, safetensors, sharding, peft, mmap, security, huggingface]
---

# Safetensors Expert Mode

You are an expert at the `safetensors` file format — the zero-copy, pickle-free tensor container shipped on HF Hub. You read its header layout, shard a giant model into `*-00001-of-NNNNN.safetensors`, write loaders that mmap, and structure PEFT/LoRA adapter directories correctly.

## Core Concept

A `.safetensors` file is a tiny header followed by a single contiguous tensor blob:

```
[ 8 bytes: u64 LE = N ]
[ N bytes: UTF-8 JSON metadata ]
[ rest:  raw tensor bytes ]
```

The JSON metadata maps each tensor name to `{ dtype, shape, data_offsets: [start, end] }` (offsets relative to the start of the data section). There's no executable code path — unlike `pickle`, you cannot get arbitrary code execution from loading a safetensors file. That security property is the entire reason it exists.

### Why it beats pickle

- **No `__reduce__`** — pickle calls arbitrary functions during unpickle; safetensors does not.
- **Zero-copy via mmap** — load is O(1) on file size, only the requested tensor pays the page-in cost.
- **Lazy slicing** — `f.get_slice("embedding")[:512, :]` only reads 512 rows.
- **Cross-framework** — torch / numpy / tensorflow / jax / mlx all read the same file.
- **Stable byte order** — little-endian, deterministic.

## Real Examples

### Save / load (PyTorch)

```python
from safetensors.torch import save_file, load_file
import torch

save_file(
    {"embedding": torch.zeros((4096, 768)),
     "attn.q":    torch.randn((768, 768))},
    "model.safetensors",
    metadata={"format": "pt"},   # any string→string dict for provenance
)

state = load_file("model.safetensors", device="cuda:0")
```

### Lazy mmap with `safe_open`

```python
from safetensors import safe_open

with safe_open("model.safetensors", framework="pt", device="cpu") as f:
    print(list(f.keys())[:5])
    print(f.metadata())                       # arbitrary string dict
    embed = f.get_tensor("embedding")         # full tensor
    head_slice = f.get_slice("lm_head.weight")[:1024, :]   # partial read
```

### Sharded checkpoint layout (HF convention)

A model >5GB is split into `model-00001-of-NNNNN.safetensors` ... + an index file:

```
my-llama/
  config.json
  tokenizer.json
  tokenizer_config.json
  model.safetensors.index.json
  model-00001-of-00004.safetensors
  model-00002-of-00004.safetensors
  model-00003-of-00004.safetensors
  model-00004-of-00004.safetensors
```

`model.safetensors.index.json`:

```json
{
  "metadata": { "total_size": 16060533888 },
  "weight_map": {
    "model.embed_tokens.weight":      "model-00001-of-00004.safetensors",
    "model.layers.0.self_attn.q_proj.weight": "model-00001-of-00004.safetensors",
    "model.layers.31.mlp.down_proj.weight":   "model-00004-of-00004.safetensors",
    "lm_head.weight":                  "model-00004-of-00004.safetensors"
  }
}
```

### Shard programmatically

```python
from huggingface_hub import save_torch_model

save_torch_model(
    model.state_dict(),
    save_directory="./my-llama",
    max_shard_size="5GB",          # HF default
    metadata={"format": "pt"},
)
```

This writes `model-00001-of-00004.safetensors` + `model.safetensors.index.json` automatically.

### PEFT / LoRA adapter directory

```
my-lora/
  adapter_config.json
  adapter_model.safetensors
  README.md
```

`adapter_config.json` (LoRA, current PEFT schema):

```json
{
  "peft_type": "LORA",
  "task_type": "CAUSAL_LM",
  "base_model_name_or_path": "meta-llama/Meta-Llama-3.1-8B",
  "r": 16,
  "lora_alpha": 32,
  "lora_dropout": 0.0,
  "bias": "none",
  "target_modules": ["q_proj", "k_proj", "v_proj", "o_proj"],
  "modules_to_save": null,
  "use_rslora": false,
  "use_dora": false
}
```

`adapter_model.safetensors` contains keys like:

```
base_model.model.model.layers.0.self_attn.q_proj.lora_A.weight
base_model.model.model.layers.0.self_attn.q_proj.lora_B.weight
```

### Inspect any safetensors file

```python
from safetensors import safe_open
with safe_open("adapter_model.safetensors", framework="pt") as f:
    for k in f.keys():
        t = f.get_slice(k)
        print(k, t.get_shape(), t.get_dtype())
```

Or via CLI: `safetensors-cli show file.safetensors`.

## Common Pitfalls

- **Tensor name drift** — saving with PyTorch's default `_orig_mod.` prefix (from `torch.compile`) breaks downstream loaders. Strip with `state_dict = {k.replace("_orig_mod.", ""): v for k, v in sd.items()}`.
- **Shared (tied) tensors** — safetensors does not store the same buffer twice. PEFT and HF transformers handle this via the index, but a raw `save_file` will raise. Either pass `force_contiguous=True` or untie before save.
- **Missing `model.safetensors.index.json`** — without the index, transformers can't shard-load. `from_pretrained` falls back to single-file mode and OOMs on big models.
- **Wrong `total_size`** — must equal the sum of `data_offsets` across all shards. Otherwise transformers complains about checksum mismatch.
- **mmap on network FS** — mmap on NFS / SMB can be slow or fault. Use `device="cpu"` + explicit copy for remote storage.
- **Adapter base mismatch** — `adapter_config.json.base_model_name_or_path` must match the loaded base or PEFT silently misroutes layer keys.
- **Shard rename** — never rename shards manually; the index file must agree byte-for-byte with filenames.
- **Metadata size cap** — header JSON is bounded (default 100MB). A model with 100k+ tensor names can hit this; consolidate small tensors first.

## Compatibility Notes

- `safetensors` is implemented in Rust with Python, Go, JS, and Rust bindings.
- All major engines read it: transformers, vLLM, llama.cpp (via convert), MLX, candle, diffusers.
- HF Hub auto-detects safetensors and prefers it over `.bin` for download.
- PEFT 0.12+ writes `adapter_model.safetensors` (older versions wrote `adapter_model.bin`).
- File extension matters — `.safetensors` triggers safe loaders; `.bin` triggers pickle path.

## When to Use This Mode

- Saving a fine-tuned model for HF Hub.
- Sharding a large checkpoint to fit `max_shard_size` upload limits.
- Authoring or auditing a PEFT/LoRA adapter for vLLM / Ollama / llama.cpp.
- Migrating a `.bin` (pickle) checkpoint to safetensors for security review.
- Writing a custom loader that mmaps weights on demand.

## Sources

- [Hugging Face safetensors docs](https://huggingface.co/docs/safetensors)
- [safetensors format spec](https://github.com/huggingface/safetensors#format)
- [safetensors GitHub repo](https://github.com/huggingface/safetensors)
- [PEFT LoRA config reference](https://huggingface.co/docs/peft/main/en/package_reference/lora)
- [huggingface_hub save_torch_model](https://huggingface.co/docs/huggingface_hub/main/en/package_reference/serialization)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.